Skip to content

Commit

Permalink
proc: Generalize proc inode allocation
Browse files Browse the repository at this point in the history
Generalize the proc inode allocation so that it can be
used without having to having to create a proc_dir_entry.

This will allow namespace file descriptors to remain light
weight entitities but still have the same inode number
when the backing namespace is the same.

Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
  • Loading branch information
Eric W. Biederman committed Nov 20, 2012
1 parent 4f326c0 commit 33d6dce
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
26 changes: 13 additions & 13 deletions fs/proc/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,33 +350,34 @@ static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
* Return an inode number between PROC_DYNAMIC_FIRST and
* 0xffffffff, or zero on failure.
*/
static unsigned int get_inode_number(void)
int proc_alloc_inum(unsigned int *inum)
{
unsigned int i;
int error;

retry:
if (ida_pre_get(&proc_inum_ida, GFP_KERNEL) == 0)
return 0;
if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
return -ENOMEM;

spin_lock(&proc_inum_lock);
error = ida_get_new(&proc_inum_ida, &i);
spin_unlock(&proc_inum_lock);
if (error == -EAGAIN)
goto retry;
else if (error)
return 0;
return error;

if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
spin_lock(&proc_inum_lock);
ida_remove(&proc_inum_ida, i);
spin_unlock(&proc_inum_lock);
return 0;
return -ENOSPC;
}
return PROC_DYNAMIC_FIRST + i;
*inum = PROC_DYNAMIC_FIRST + i;
return 0;
}

static void release_inode_number(unsigned int inum)
void proc_free_inum(unsigned int inum)
{
spin_lock(&proc_inum_lock);
ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
Expand Down Expand Up @@ -554,13 +555,12 @@ static const struct inode_operations proc_dir_inode_operations = {

static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
unsigned int i;
struct proc_dir_entry *tmp;
int ret;

i = get_inode_number();
if (i == 0)
return -EAGAIN;
dp->low_ino = i;
ret = proc_alloc_inum(&dp->low_ino);
if (ret)
return ret;

if (S_ISDIR(dp->mode)) {
if (dp->proc_iops == NULL) {
Expand Down Expand Up @@ -764,7 +764,7 @@ EXPORT_SYMBOL(proc_create_data);

static void free_proc_entry(struct proc_dir_entry *de)
{
release_inode_number(de->low_ino);
proc_free_inum(de->low_ino);

if (S_ISLNK(de->mode))
kfree(de->data);
Expand Down
10 changes: 10 additions & 0 deletions include/linux/proc_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
extern struct file *proc_ns_fget(int fd);
extern bool proc_ns_inode(struct inode *inode);

extern int proc_alloc_inum(unsigned int *pino);
extern void proc_free_inum(unsigned int inum);
#else

#define proc_net_fops_create(net, name, mode, fops) ({ (void)(mode), NULL; })
Expand Down Expand Up @@ -235,6 +237,14 @@ static inline bool proc_ns_inode(struct inode *inode)
return false;
}

static inline int proc_alloc_inum(unsigned int *inum)
{
*inum = 1;
return 0;
}
static inline void proc_free_inum(unsigned int inum)
{
}
#endif /* CONFIG_PROC_FS */

#if !defined(CONFIG_PROC_KCORE)
Expand Down

0 comments on commit 33d6dce

Please sign in to comment.