Skip to content

Commit fa33065

Browse files
osandovmasoncl
authored andcommitted
Btrfs: clean up error handling in mount_subvol()
In preparation for new functionality in mount_subvol(), give it ownership of subvol_name and tidy up the error paths. Reviewed-by: David Sterba <[email protected]> Signed-off-by: Omar Sandoval <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent e6e4dbe commit fa33065

File tree

1 file changed

+33
-28
lines changed

1 file changed

+33
-28
lines changed

fs/btrfs/super.c

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,55 +1171,61 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags,
11711171
const char *device_name, char *data)
11721172
{
11731173
struct dentry *root;
1174-
struct vfsmount *mnt;
1174+
struct vfsmount *mnt = NULL;
11751175
char *newargs;
1176+
int ret;
11761177

11771178
newargs = setup_root_args(data);
1178-
if (!newargs)
1179-
return ERR_PTR(-ENOMEM);
1180-
mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name,
1181-
newargs);
1179+
if (!newargs) {
1180+
root = ERR_PTR(-ENOMEM);
1181+
goto out;
1182+
}
11821183

1183-
if (PTR_RET(mnt) == -EBUSY) {
1184+
mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name, newargs);
1185+
if (PTR_ERR_OR_ZERO(mnt) == -EBUSY) {
11841186
if (flags & MS_RDONLY) {
1185-
mnt = vfs_kern_mount(&btrfs_fs_type, flags & ~MS_RDONLY, device_name,
1186-
newargs);
1187+
mnt = vfs_kern_mount(&btrfs_fs_type, flags & ~MS_RDONLY,
1188+
device_name, newargs);
11871189
} else {
1188-
int r;
1189-
mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY, device_name,
1190-
newargs);
1190+
mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY,
1191+
device_name, newargs);
11911192
if (IS_ERR(mnt)) {
1192-
kfree(newargs);
1193-
return ERR_CAST(mnt);
1193+
root = ERR_CAST(mnt);
1194+
mnt = NULL;
1195+
goto out;
11941196
}
11951197

11961198
down_write(&mnt->mnt_sb->s_umount);
1197-
r = btrfs_remount(mnt->mnt_sb, &flags, NULL);
1199+
ret = btrfs_remount(mnt->mnt_sb, &flags, NULL);
11981200
up_write(&mnt->mnt_sb->s_umount);
1199-
if (r < 0) {
1200-
/* FIXME: release vfsmount mnt ??*/
1201-
kfree(newargs);
1202-
return ERR_PTR(r);
1201+
if (ret < 0) {
1202+
root = ERR_PTR(ret);
1203+
goto out;
12031204
}
12041205
}
12051206
}
1206-
1207-
kfree(newargs);
1208-
1209-
if (IS_ERR(mnt))
1210-
return ERR_CAST(mnt);
1207+
if (IS_ERR(mnt)) {
1208+
root = ERR_CAST(mnt);
1209+
mnt = NULL;
1210+
goto out;
1211+
}
12111212

12121213
root = mount_subtree(mnt, subvol_name);
1214+
/* mount_subtree() drops our reference on the vfsmount. */
1215+
mnt = NULL;
12131216

12141217
if (!IS_ERR(root) && !is_subvolume_inode(d_inode(root))) {
12151218
struct super_block *s = root->d_sb;
12161219
dput(root);
12171220
root = ERR_PTR(-EINVAL);
12181221
deactivate_locked_super(s);
1219-
printk(KERN_ERR "BTRFS: '%s' is not a valid subvolume\n",
1220-
subvol_name);
1222+
pr_err("BTRFS: '%s' is not a valid subvolume\n", subvol_name);
12211223
}
12221224

1225+
out:
1226+
mntput(mnt);
1227+
kfree(newargs);
1228+
kfree(subvol_name);
12231229
return root;
12241230
}
12251231

@@ -1305,9 +1311,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
13051311
}
13061312

13071313
if (subvol_name) {
1308-
root = mount_subvol(subvol_name, flags, device_name, data);
1309-
kfree(subvol_name);
1310-
return root;
1314+
/* mount_subvol() will free subvol_name. */
1315+
return mount_subvol(subvol_name, flags, device_name, data);
13111316
}
13121317

13131318
security_init_mnt_opts(&new_sec_opts);

0 commit comments

Comments
 (0)