Skip to content

Commit

Permalink
inode numbering: change libfs sb creation routines to avoid collision…
Browse files Browse the repository at this point in the history
…s with their root inodes

This patch makes it so that simple_fill_super and get_sb_pseudo assign their
root inodes to be number 1.  It also fixes up a couple of callers of
simple_fill_super that were passing in files arrays that had an index at
number 1, and adds a warning for any caller that sends in such an array.

It would have been nice to have made it so that it wasn't possible to make
such a collision, but some callers need to be able to control what inode
number their entries get, so I think this is the best that can be done.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Jeff Layton authored and Linus Torvalds committed May 8, 2007
1 parent 866b04f commit 1a1c9bb
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/ipath/ipath_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data,
int ret;

static struct tree_descr files[] = {
[1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
[2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
{""},
};

Expand Down
4 changes: 2 additions & 2 deletions fs/binfmt_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,8 +727,8 @@ static const struct super_operations s_ops = {
static int bm_fill_super(struct super_block * sb, void * data, int silent)
{
static struct tree_descr bm_files[] = {
[1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
[2] = {"register", &bm_register_operations, S_IWUSR},
[2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
[3] = {"register", &bm_register_operations, S_IWUSR},
/* last one */ {""}
};
int err = simple_fill_super(sb, 0x42494e4d, bm_files);
Expand Down
23 changes: 23 additions & 0 deletions fs/libfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
root = new_inode(s);
if (!root)
goto Enomem;
/*
* since this is the first inode, make it number 1. New inodes created
* after this must take care not to collide with it (by passing
* max_reserved of 1 to iunique).
*/
root->i_ino = 1;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
Expand Down Expand Up @@ -360,6 +366,11 @@ int simple_commit_write(struct file *file, struct page *page,
return 0;
}

/*
* the inodes created here are not hashed. If you use iunique to generate
* unique inode values later for this filesystem, then you must take care
* to pass it an appropriate max_reserved value to avoid collisions.
*/
int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
{
struct inode *inode;
Expand All @@ -376,6 +387,11 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files
inode = new_inode(s);
if (!inode)
return -ENOMEM;
/*
* because the root inode is 1, the files array must not contain an
* entry at index 1
*/
inode->i_ino = 1;
inode->i_mode = S_IFDIR | 0755;
inode->i_uid = inode->i_gid = 0;
inode->i_blocks = 0;
Expand All @@ -391,6 +407,13 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files
for (i = 0; !files->name || files->name[0]; i++, files++) {
if (!files->name)
continue;

/* warn if it tries to conflict with the root inode */
if (unlikely(i == 1))
printk(KERN_WARNING "%s: %s passed in a files array"
"with an index of 1!\n", __func__,
s->s_type->name);

dentry = d_alloc_name(root, files->name);
if (!dentry)
goto out;
Expand Down

0 comments on commit 1a1c9bb

Please sign in to comment.