Commit 5b5f9560 authored by Al Viro's avatar Al Viro

functionfs: unfuck failure exits on mount

* if you do dput() of root dentry, do *not* follow that with iput() of root
inode.
* while we are at it, don't do that dput() at all - you are leaving the pointer
in ->s_root and your ->kill_sb() will be very unhappy with that.  It will do
proper dput(), though, so the easiest way is to leave that to it entirely.
* freeing ->s_fs_info is also best left to ->kill_sb() (which will do it
anyway), especially since we leave the pointer in place.
* that xchg() in ->kill_sb() is not a bug per se, but it's a plain and simple
masturbation with fewer excuses than Onan had...
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 48fa57ac
...@@ -1037,7 +1037,6 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) ...@@ -1037,7 +1037,6 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
{ {
struct ffs_sb_fill_data *data = _data; struct ffs_sb_fill_data *data = _data;
struct inode *inode; struct inode *inode;
struct dentry *d;
struct ffs_data *ffs; struct ffs_data *ffs;
ENTER(); ENTER();
...@@ -1045,7 +1044,7 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) ...@@ -1045,7 +1044,7 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
/* Initialise data */ /* Initialise data */
ffs = ffs_data_new(); ffs = ffs_data_new();
if (unlikely(!ffs)) if (unlikely(!ffs))
goto enomem0; goto Enomem;
ffs->sb = sb; ffs->sb = sb;
ffs->dev_name = data->dev_name; ffs->dev_name = data->dev_name;
...@@ -1065,26 +1064,21 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) ...@@ -1065,26 +1064,21 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
&simple_dir_inode_operations, &simple_dir_inode_operations,
&data->perms); &data->perms);
if (unlikely(!inode)) if (unlikely(!inode))
goto enomem1; goto Enomem;
d = d_alloc_root(inode); sb->s_root = d_alloc_root(inode);
if (unlikely(!d)) if (unlikely(!sb->s_root)) {
goto enomem2; iput(inode);
sb->s_root = d; goto Enomem;
}
/* EP0 file */ /* EP0 file */
if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs,
&ffs_ep0_operations, NULL))) &ffs_ep0_operations, NULL)))
goto enomem3; goto Enomem;
return 0; return 0;
enomem3: Enomem:
dput(d);
enomem2:
iput(inode);
enomem1:
ffs_data_put(ffs);
enomem0:
return -ENOMEM; return -ENOMEM;
} }
...@@ -1196,14 +1190,11 @@ ffs_fs_mount(struct file_system_type *t, int flags, ...@@ -1196,14 +1190,11 @@ ffs_fs_mount(struct file_system_type *t, int flags,
static void static void
ffs_fs_kill_sb(struct super_block *sb) ffs_fs_kill_sb(struct super_block *sb)
{ {
void *ptr;
ENTER(); ENTER();
kill_litter_super(sb); kill_litter_super(sb);
ptr = xchg(&sb->s_fs_info, NULL); if (sb->s_fs_info)
if (ptr) ffs_data_put(sb->s_fs_info);
ffs_data_put(ptr);
} }
static struct file_system_type ffs_fs_type = { static struct file_system_type ffs_fs_type = {
......
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