diff options
author | Jeff Layton <jlayton@redhat.com> | 2007-05-08 03:32:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:16 -0400 |
commit | 1a1c9bb433af252767ee90d6394d287afa30cf8b (patch) | |
tree | 586225fc9f3ca52d60d59400a3c7d4e90ca0667e /fs | |
parent | 866b04fccbf125cd39f2bdbcfeaa611d39a061a8 (diff) |
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: 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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_misc.c | 4 | ||||
-rw-r--r-- | fs/libfs.c | 23 |
2 files changed, 25 insertions, 2 deletions
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index e6f57990b121..18657f001b43 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -727,8 +727,8 @@ static const struct super_operations s_ops = { | |||
727 | static int bm_fill_super(struct super_block * sb, void * data, int silent) | 727 | static int bm_fill_super(struct super_block * sb, void * data, int silent) |
728 | { | 728 | { |
729 | static struct tree_descr bm_files[] = { | 729 | static struct tree_descr bm_files[] = { |
730 | [1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, | 730 | [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, |
731 | [2] = {"register", &bm_register_operations, S_IWUSR}, | 731 | [3] = {"register", &bm_register_operations, S_IWUSR}, |
732 | /* last one */ {""} | 732 | /* last one */ {""} |
733 | }; | 733 | }; |
734 | int err = simple_fill_super(sb, 0x42494e4d, bm_files); | 734 | int err = simple_fill_super(sb, 0x42494e4d, bm_files); |
diff --git a/fs/libfs.c b/fs/libfs.c index d93842d3c0a0..1247ee90253a 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -220,6 +220,12 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name, | |||
220 | root = new_inode(s); | 220 | root = new_inode(s); |
221 | if (!root) | 221 | if (!root) |
222 | goto Enomem; | 222 | goto Enomem; |
223 | /* | ||
224 | * since this is the first inode, make it number 1. New inodes created | ||
225 | * after this must take care not to collide with it (by passing | ||
226 | * max_reserved of 1 to iunique). | ||
227 | */ | ||
228 | root->i_ino = 1; | ||
223 | root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; | 229 | root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; |
224 | root->i_uid = root->i_gid = 0; | 230 | root->i_uid = root->i_gid = 0; |
225 | root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; | 231 | 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 | return 0; | 366 | return 0; |
361 | } | 367 | } |
362 | 368 | ||
369 | /* | ||
370 | * the inodes created here are not hashed. If you use iunique to generate | ||
371 | * unique inode values later for this filesystem, then you must take care | ||
372 | * to pass it an appropriate max_reserved value to avoid collisions. | ||
373 | */ | ||
363 | int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files) | 374 | int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files) |
364 | { | 375 | { |
365 | struct inode *inode; | 376 | struct inode *inode; |
@@ -376,6 +387,11 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files | |||
376 | inode = new_inode(s); | 387 | inode = new_inode(s); |
377 | if (!inode) | 388 | if (!inode) |
378 | return -ENOMEM; | 389 | return -ENOMEM; |
390 | /* | ||
391 | * because the root inode is 1, the files array must not contain an | ||
392 | * entry at index 1 | ||
393 | */ | ||
394 | inode->i_ino = 1; | ||
379 | inode->i_mode = S_IFDIR | 0755; | 395 | inode->i_mode = S_IFDIR | 0755; |
380 | inode->i_uid = inode->i_gid = 0; | 396 | inode->i_uid = inode->i_gid = 0; |
381 | inode->i_blocks = 0; | 397 | inode->i_blocks = 0; |
@@ -391,6 +407,13 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files | |||
391 | for (i = 0; !files->name || files->name[0]; i++, files++) { | 407 | for (i = 0; !files->name || files->name[0]; i++, files++) { |
392 | if (!files->name) | 408 | if (!files->name) |
393 | continue; | 409 | continue; |
410 | |||
411 | /* warn if it tries to conflict with the root inode */ | ||
412 | if (unlikely(i == 1)) | ||
413 | printk(KERN_WARNING "%s: %s passed in a files array" | ||
414 | "with an index of 1!\n", __func__, | ||
415 | s->s_type->name); | ||
416 | |||
394 | dentry = d_alloc_name(root, files->name); | 417 | dentry = d_alloc_name(root, files->name); |
395 | if (!dentry) | 418 | if (!dentry) |
396 | goto out; | 419 | goto out; |