summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_fs.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-01-08 21:38:27 +0100
committerAl Viro <viro@zeniv.linux.org.uk>2012-01-09 02:17:17 +0100
commit5b5f9560354dc5a3a27ce57a86aec6b98531ee21 (patch)
tree908448da30e77e931f62080e3d836cf0f070d389 /drivers/usb/gadget/f_fs.c
parentMerge tag 'infiniband-for-linus' of git://git.kernel.org/pub/scm/linux/kernel... (diff)
downloadlinux-5b5f9560354dc5a3a27ce57a86aec6b98531ee21.tar.xz
linux-5b5f9560354dc5a3a27ce57a86aec6b98531ee21.zip
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: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/usb/gadget/f_fs.c')
-rw-r--r--drivers/usb/gadget/f_fs.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index acb38004eec0..b5f6f9fef9c7 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -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 inode *inode;
- struct dentry *d;
struct ffs_data *ffs;
ENTER();
@@ -1045,7 +1044,7 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
/* Initialise data */
ffs = ffs_data_new();
if (unlikely(!ffs))
- goto enomem0;
+ goto Enomem;
ffs->sb = sb;
ffs->dev_name = data->dev_name;
@@ -1065,26 +1064,21 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
&simple_dir_inode_operations,
&data->perms);
if (unlikely(!inode))
- goto enomem1;
- d = d_alloc_root(inode);
- if (unlikely(!d))
- goto enomem2;
- sb->s_root = d;
+ goto Enomem;
+ sb->s_root = d_alloc_root(inode);
+ if (unlikely(!sb->s_root)) {
+ iput(inode);
+ goto Enomem;
+ }
/* EP0 file */
if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs,
&ffs_ep0_operations, NULL)))
- goto enomem3;
+ goto Enomem;
return 0;
-enomem3:
- dput(d);
-enomem2:
- iput(inode);
-enomem1:
- ffs_data_put(ffs);
-enomem0:
+Enomem:
return -ENOMEM;
}
@@ -1196,14 +1190,11 @@ ffs_fs_mount(struct file_system_type *t, int flags,
static void
ffs_fs_kill_sb(struct super_block *sb)
{
- void *ptr;
-
ENTER();
kill_litter_super(sb);
- ptr = xchg(&sb->s_fs_info, NULL);
- if (ptr)
- ffs_data_put(ptr);
+ if (sb->s_fs_info)
+ ffs_data_put(sb->s_fs_info);
}
static struct file_system_type ffs_fs_type = {