summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-03-13 19:51:56 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-05-22 00:44:18 -0400
commit50e7b972ab4e945bb261f01814ba94e11243ba06 (patch)
tree9356c138ab703ea2b9210bfc7bc2c8616e324638
parent31c85f9d68ee9da315ef5ac971727ae3cdb27dd0 (diff)
bcachefs: fix BCH_IOCTL_ASSEMBLE
-rw-r--r--fs/bcachefs/chardev.c42
-rw-r--r--fs/bcachefs/fs.c9
2 files changed, 24 insertions, 27 deletions
diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c
index ab6dc665186e..fc53d4691d4d 100644
--- a/fs/bcachefs/chardev.c
+++ b/fs/bcachefs/chardev.c
@@ -58,7 +58,6 @@ static long bch2_ioctl_assemble(struct bch_ioctl_assemble __user *user_arg)
{
struct bch_ioctl_assemble arg;
struct bch_fs *c;
- u64 *user_devs = NULL;
char **devs = NULL;
unsigned i;
int ret = -EFAULT;
@@ -69,30 +68,31 @@ static long bch2_ioctl_assemble(struct bch_ioctl_assemble __user *user_arg)
if (arg.flags || arg.pad)
return -EINVAL;
- user_devs = kmalloc_array(arg.nr_devs, sizeof(u64), GFP_KERNEL);
- if (!user_devs)
+ devs = kcalloc(arg.nr_devs, sizeof(char *), GFP_KERNEL);
+ if (!devs)
return -ENOMEM;
- devs = kcalloc(arg.nr_devs, sizeof(char *), GFP_KERNEL);
+ for (i = 0; i < arg.nr_devs; i++) {
+ u64 user_dev;
+ char *s;
- if (copy_from_user(user_devs, user_arg->devs,
- sizeof(u64) * arg.nr_devs))
- goto err;
+ ret = get_user(user_dev, &user_arg->devs[i]);
+ if (ret) {
+ goto err;
+ }
- for (i = 0; i < arg.nr_devs; i++) {
- devs[i] = strndup_user((const char __user *)(unsigned long)
- user_devs[i],
- PATH_MAX);
- if (!devs[i]) {
- ret = -ENOMEM;
+ s = strndup_user((const char __user *)(unsigned long)
+ user_dev, PATH_MAX);
+ if (IS_ERR(s)) {
+ ret = PTR_ERR(s);
goto err;
}
+
+ devs[i] = s;
}
c = bch2_fs_open(devs, arg.nr_devs, bch2_opts_empty());
ret = PTR_ERR_OR_ZERO(c);
- if (!ret)
- closure_put(&c->cl);
err:
if (devs)
for (i = 0; i < arg.nr_devs; i++)
@@ -114,8 +114,8 @@ static long bch2_ioctl_incremental(struct bch_ioctl_incremental __user *user_arg
return -EINVAL;
path = strndup_user((const char __user *)(unsigned long) arg.dev, PATH_MAX);
- if (!path)
- return -ENOMEM;
+ if (IS_ERR(path))
+ return PTR_ERR(path);
err = bch2_fs_open_incremental(path);
kfree(path);
@@ -171,8 +171,8 @@ static long bch2_ioctl_disk_add(struct bch_fs *c, struct bch_ioctl_disk arg)
return -EINVAL;
path = strndup_user((const char __user *)(unsigned long) arg.dev, PATH_MAX);
- if (!path)
- return -ENOMEM;
+ if (IS_ERR(path))
+ return PTR_ERR(path);
ret = bch2_dev_add(c, path);
kfree(path);
@@ -207,8 +207,8 @@ static long bch2_ioctl_disk_online(struct bch_fs *c, struct bch_ioctl_disk arg)
return -EINVAL;
path = strndup_user((const char __user *)(unsigned long) arg.dev, PATH_MAX);
- if (!path)
- return -ENOMEM;
+ if (IS_ERR(path))
+ return PTR_ERR(path);
ret = bch2_dev_online(c, path);
kfree(path);
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index c7e842ee8437..83b2ec955b8d 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -1177,9 +1177,10 @@ static struct bch_fs *__bch2_open_as_blockdevs(const char *dev_name, char * cons
mutex_lock(&c->state_lock);
+ closure_put(&c->cl);
+
if (!bch2_fs_running(c)) {
mutex_unlock(&c->state_lock);
- closure_put(&c->cl);
pr_err("err mounting %s: incomplete filesystem", dev_name);
return ERR_PTR(-EINVAL);
}
@@ -1419,11 +1420,7 @@ static void bch2_kill_sb(struct super_block *sb)
struct bch_fs *c = sb->s_fs_info;
generic_shutdown_super(sb);
-
- if (test_bit(BCH_FS_BDEV_MOUNTED, &c->flags))
- bch2_fs_stop(c);
- else
- closure_put(&c->cl);
+ bch2_fs_stop(c);
}
static struct file_system_type bcache_fs_type = {