Commit 1a1c9bb4 authored by Jeff Layton's avatar Jeff Layton Committed by Linus Torvalds

inode numbering: change libfs sb creation routines to avoid collisions 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: default avatarJeff Layton <jlayton@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 866b04fc
...@@ -523,7 +523,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data, ...@@ -523,7 +523,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data,
int ret; int ret;
static struct tree_descr files[] = { static struct tree_descr files[] = {
[1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO}, [2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
{""}, {""},
}; };
......
...@@ -727,8 +727,8 @@ static const struct super_operations s_ops = { ...@@ -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 int bm_fill_super(struct super_block * sb, void * data, int silent)
{ {
static struct tree_descr bm_files[] = { static struct tree_descr bm_files[] = {
[1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
[2] = {"register", &bm_register_operations, S_IWUSR}, [3] = {"register", &bm_register_operations, S_IWUSR},
/* last one */ {""} /* last one */ {""}
}; };
int err = simple_fill_super(sb, 0x42494e4d, bm_files); int err = simple_fill_super(sb, 0x42494e4d, bm_files);
......
...@@ -220,6 +220,12 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name, ...@@ -220,6 +220,12 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
root = new_inode(s); root = new_inode(s);
if (!root) if (!root)
goto Enomem; 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_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0; root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
...@@ -360,6 +366,11 @@ int simple_commit_write(struct file *file, struct page *page, ...@@ -360,6 +366,11 @@ int simple_commit_write(struct file *file, struct page *page,
return 0; 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) int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
{ {
struct inode *inode; struct inode *inode;
...@@ -376,6 +387,11 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files ...@@ -376,6 +387,11 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files
inode = new_inode(s); inode = new_inode(s);
if (!inode) if (!inode)
return -ENOMEM; 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_mode = S_IFDIR | 0755;
inode->i_uid = inode->i_gid = 0; inode->i_uid = inode->i_gid = 0;
inode->i_blocks = 0; inode->i_blocks = 0;
...@@ -391,6 +407,13 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files ...@@ -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++) { for (i = 0; !files->name || files->name[0]; i++, files++) {
if (!files->name) if (!files->name)
continue; 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); dentry = d_alloc_name(root, files->name);
if (!dentry) if (!dentry)
goto out; goto out;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment