Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts: fs/nfs/inode.c fs/super.c Fix conflicts between patch 'NFS: Split fs/nfs/inode.c' and patch 'VFS: Permit filesystem to override root dentry on mount'
This commit is contained in:
95
fs/super.c
95
fs/super.c
@@ -231,7 +231,7 @@ void generic_shutdown_super(struct super_block *sb)
|
||||
if (root) {
|
||||
sb->s_root = NULL;
|
||||
shrink_dcache_parent(root);
|
||||
shrink_dcache_anon(&sb->s_anon);
|
||||
shrink_dcache_sb(sb);
|
||||
dput(root);
|
||||
fsync_super(sb);
|
||||
lock_super(sb);
|
||||
@@ -486,7 +486,7 @@ asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
|
||||
s = user_get_super(new_decode_dev(dev));
|
||||
if (s == NULL)
|
||||
goto out;
|
||||
err = vfs_statfs(s, &sbuf);
|
||||
err = vfs_statfs(s->s_root, &sbuf);
|
||||
drop_super(s);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -676,9 +676,10 @@ static void bdev_uevent(struct block_device *bdev, enum kobject_action action)
|
||||
}
|
||||
}
|
||||
|
||||
struct super_block *get_sb_bdev(struct file_system_type *fs_type,
|
||||
int get_sb_bdev(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *data,
|
||||
int (*fill_super)(struct super_block *, void *, int))
|
||||
int (*fill_super)(struct super_block *, void *, int),
|
||||
struct vfsmount *mnt)
|
||||
{
|
||||
struct block_device *bdev;
|
||||
struct super_block *s;
|
||||
@@ -686,7 +687,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
|
||||
|
||||
bdev = open_bdev_excl(dev_name, flags, fs_type);
|
||||
if (IS_ERR(bdev))
|
||||
return (struct super_block *)bdev;
|
||||
return PTR_ERR(bdev);
|
||||
|
||||
/*
|
||||
* once the super is inserted into the list by sget, s_umount
|
||||
@@ -697,15 +698,17 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
|
||||
s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
|
||||
mutex_unlock(&bdev->bd_mount_mutex);
|
||||
if (IS_ERR(s))
|
||||
goto out;
|
||||
goto error_s;
|
||||
|
||||
if (s->s_root) {
|
||||
if ((flags ^ s->s_flags) & MS_RDONLY) {
|
||||
up_write(&s->s_umount);
|
||||
deactivate_super(s);
|
||||
s = ERR_PTR(-EBUSY);
|
||||
error = -EBUSY;
|
||||
goto error_bdev;
|
||||
}
|
||||
goto out;
|
||||
|
||||
close_bdev_excl(bdev);
|
||||
} else {
|
||||
char b[BDEVNAME_SIZE];
|
||||
|
||||
@@ -716,18 +719,21 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
|
||||
if (error) {
|
||||
up_write(&s->s_umount);
|
||||
deactivate_super(s);
|
||||
s = ERR_PTR(error);
|
||||
} else {
|
||||
s->s_flags |= MS_ACTIVE;
|
||||
bdev_uevent(bdev, KOBJ_MOUNT);
|
||||
goto error;
|
||||
}
|
||||
|
||||
s->s_flags |= MS_ACTIVE;
|
||||
bdev_uevent(bdev, KOBJ_MOUNT);
|
||||
}
|
||||
|
||||
return s;
|
||||
return simple_set_mnt(mnt, s);
|
||||
|
||||
out:
|
||||
error_s:
|
||||
error = PTR_ERR(s);
|
||||
error_bdev:
|
||||
close_bdev_excl(bdev);
|
||||
return s;
|
||||
error:
|
||||
return error;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(get_sb_bdev);
|
||||
@@ -744,15 +750,16 @@ void kill_block_super(struct super_block *sb)
|
||||
|
||||
EXPORT_SYMBOL(kill_block_super);
|
||||
|
||||
struct super_block *get_sb_nodev(struct file_system_type *fs_type,
|
||||
int get_sb_nodev(struct file_system_type *fs_type,
|
||||
int flags, void *data,
|
||||
int (*fill_super)(struct super_block *, void *, int))
|
||||
int (*fill_super)(struct super_block *, void *, int),
|
||||
struct vfsmount *mnt)
|
||||
{
|
||||
int error;
|
||||
struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
|
||||
|
||||
if (IS_ERR(s))
|
||||
return s;
|
||||
return PTR_ERR(s);
|
||||
|
||||
s->s_flags = flags;
|
||||
|
||||
@@ -760,10 +767,10 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type,
|
||||
if (error) {
|
||||
up_write(&s->s_umount);
|
||||
deactivate_super(s);
|
||||
return ERR_PTR(error);
|
||||
return error;
|
||||
}
|
||||
s->s_flags |= MS_ACTIVE;
|
||||
return s;
|
||||
return simple_set_mnt(mnt, s);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(get_sb_nodev);
|
||||
@@ -773,28 +780,29 @@ static int compare_single(struct super_block *s, void *p)
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct super_block *get_sb_single(struct file_system_type *fs_type,
|
||||
int get_sb_single(struct file_system_type *fs_type,
|
||||
int flags, void *data,
|
||||
int (*fill_super)(struct super_block *, void *, int))
|
||||
int (*fill_super)(struct super_block *, void *, int),
|
||||
struct vfsmount *mnt)
|
||||
{
|
||||
struct super_block *s;
|
||||
int error;
|
||||
|
||||
s = sget(fs_type, compare_single, set_anon_super, NULL);
|
||||
if (IS_ERR(s))
|
||||
return s;
|
||||
return PTR_ERR(s);
|
||||
if (!s->s_root) {
|
||||
s->s_flags = flags;
|
||||
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
|
||||
if (error) {
|
||||
up_write(&s->s_umount);
|
||||
deactivate_super(s);
|
||||
return ERR_PTR(error);
|
||||
return error;
|
||||
}
|
||||
s->s_flags |= MS_ACTIVE;
|
||||
}
|
||||
do_remount_sb(s, flags, data, 0);
|
||||
return s;
|
||||
return simple_set_mnt(mnt, s);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(get_sb_single);
|
||||
@@ -802,52 +810,51 @@ EXPORT_SYMBOL(get_sb_single);
|
||||
struct vfsmount *
|
||||
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
|
||||
{
|
||||
struct super_block *sb = ERR_PTR(-ENOMEM);
|
||||
struct vfsmount *mnt;
|
||||
int error;
|
||||
char *secdata = NULL;
|
||||
int error;
|
||||
|
||||
if (!type)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
error = -ENOMEM;
|
||||
mnt = alloc_vfsmnt(name);
|
||||
if (!mnt)
|
||||
goto out;
|
||||
|
||||
if (data) {
|
||||
secdata = alloc_secdata();
|
||||
if (!secdata) {
|
||||
sb = ERR_PTR(-ENOMEM);
|
||||
if (!secdata)
|
||||
goto out_mnt;
|
||||
}
|
||||
|
||||
error = security_sb_copy_data(type, data, secdata);
|
||||
if (error) {
|
||||
sb = ERR_PTR(error);
|
||||
if (error)
|
||||
goto out_free_secdata;
|
||||
}
|
||||
}
|
||||
|
||||
sb = type->get_sb(type, flags, name, data);
|
||||
if (IS_ERR(sb))
|
||||
error = type->get_sb(type, flags, name, data, mnt);
|
||||
if (error < 0)
|
||||
goto out_free_secdata;
|
||||
error = security_sb_kern_mount(sb, secdata);
|
||||
|
||||
error = security_sb_kern_mount(mnt->mnt_sb, secdata);
|
||||
if (error)
|
||||
goto out_sb;
|
||||
mnt->mnt_sb = sb;
|
||||
mnt->mnt_root = dget(sb->s_root);
|
||||
mnt->mnt_mountpoint = sb->s_root;
|
||||
|
||||
mnt->mnt_mountpoint = mnt->mnt_root;
|
||||
mnt->mnt_parent = mnt;
|
||||
up_write(&sb->s_umount);
|
||||
up_write(&mnt->mnt_sb->s_umount);
|
||||
free_secdata(secdata);
|
||||
return mnt;
|
||||
out_sb:
|
||||
up_write(&sb->s_umount);
|
||||
deactivate_super(sb);
|
||||
sb = ERR_PTR(error);
|
||||
dput(mnt->mnt_root);
|
||||
up_write(&mnt->mnt_sb->s_umount);
|
||||
deactivate_super(mnt->mnt_sb);
|
||||
out_free_secdata:
|
||||
free_secdata(secdata);
|
||||
out_mnt:
|
||||
free_vfsmnt(mnt);
|
||||
out:
|
||||
return (struct vfsmount *)sb;
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(vfs_kern_mount);
|
||||
|
Reference in New Issue
Block a user