UBIFS: use anonymous device
UBIFS has erroneuosly set 'sb->s_dev' to the UBI volume character device major/minor. This may lead to clashes if there is another FS mounted to a block device with the same major/minor numbers. User-space programs which use 'stat->st_dev' may get confused because of this. This problem was found by Al Viro. He also pointed the way to fix the problem - use 'set_anon_super()' and 'kill_anon_super()' VFS helpers. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
This commit is contained in:
@@ -1945,7 +1945,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
sb->s_magic = UBIFS_SUPER_MAGIC;
|
sb->s_magic = UBIFS_SUPER_MAGIC;
|
||||||
sb->s_blocksize = UBIFS_BLOCK_SIZE;
|
sb->s_blocksize = UBIFS_BLOCK_SIZE;
|
||||||
sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT;
|
sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT;
|
||||||
sb->s_dev = c->vi.cdev;
|
|
||||||
sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c);
|
sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c);
|
||||||
if (c->max_inode_sz > MAX_LFS_FILESIZE)
|
if (c->max_inode_sz > MAX_LFS_FILESIZE)
|
||||||
sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
|
sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
|
||||||
@@ -1990,16 +1989,9 @@ out_free:
|
|||||||
static int sb_test(struct super_block *sb, void *data)
|
static int sb_test(struct super_block *sb, void *data)
|
||||||
{
|
{
|
||||||
dev_t *dev = data;
|
dev_t *dev = data;
|
||||||
|
struct ubifs_info *c = sb->s_fs_info;
|
||||||
|
|
||||||
return sb->s_dev == *dev;
|
return c->vi.cdev == *dev;
|
||||||
}
|
|
||||||
|
|
||||||
static int sb_set(struct super_block *sb, void *data)
|
|
||||||
{
|
|
||||||
dev_t *dev = data;
|
|
||||||
|
|
||||||
sb->s_dev = *dev;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
|
static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
|
||||||
@@ -2027,7 +2019,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
|
|||||||
|
|
||||||
dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id);
|
dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id);
|
||||||
|
|
||||||
sb = sget(fs_type, &sb_test, &sb_set, &vi.cdev);
|
sb = sget(fs_type, &sb_test, &set_anon_super, &vi.cdev);
|
||||||
if (IS_ERR(sb)) {
|
if (IS_ERR(sb)) {
|
||||||
err = PTR_ERR(sb);
|
err = PTR_ERR(sb);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
@@ -2068,16 +2060,11 @@ out_close:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ubifs_kill_sb(struct super_block *sb)
|
|
||||||
{
|
|
||||||
generic_shutdown_super(sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct file_system_type ubifs_fs_type = {
|
static struct file_system_type ubifs_fs_type = {
|
||||||
.name = "ubifs",
|
.name = "ubifs",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.get_sb = ubifs_get_sb,
|
.get_sb = ubifs_get_sb,
|
||||||
.kill_sb = ubifs_kill_sb
|
.kill_sb = kill_anon_super,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user