summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-03-22 03:38:43 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-03-22 04:03:01 -0400
commitef097245223f66434a6b0d3156fd27ef842f5342 (patch)
tree357d6e4b622f146ee31c53a6db697234fc3159c1
parent67de55671cebd30548395ea59599de56fd596ce5 (diff)
bcachefs: go online before bch2_fs_start()
-rw-r--r--fs/bcachefs/bcachefs.h1
-rw-r--r--fs/bcachefs/chardev.c18
-rw-r--r--fs/bcachefs/super.c126
3 files changed, 70 insertions, 75 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 369d078c3d2e..c144f8f498d4 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -436,6 +436,7 @@ enum {
BCH_FS_ALLOCATOR_STARTED,
BCH_FS_INITIAL_GC_DONE,
BCH_FS_FSCK_DONE,
+ BCH_FS_STARTED,
/* shutdown: */
BCH_FS_EMERGENCY_RO,
diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c
index ab6dc665186e..ab5adca496bb 100644
--- a/fs/bcachefs/chardev.c
+++ b/fs/bcachefs/chardev.c
@@ -372,6 +372,9 @@ static long bch2_ioctl_usage(struct bch_fs *c,
unsigned i, j;
int ret;
+ if (!test_bit(BCH_FS_STARTED, &c->flags))
+ return -EINVAL;
+
if (copy_from_user(&arg, user_arg, sizeof(arg)))
return -EFAULT;
@@ -535,13 +538,22 @@ long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- /* ioctls that do require admin cap: */
switch (cmd) {
case BCH_IOCTL_START:
BCH_IOCTL(start, struct bch_ioctl_start);
case BCH_IOCTL_STOP:
return bch2_ioctl_stop(c);
+ case BCH_IOCTL_READ_SUPER:
+ BCH_IOCTL(read_super, struct bch_ioctl_read_super);
+ case BCH_IOCTL_DISK_GET_IDX:
+ BCH_IOCTL(disk_get_idx, struct bch_ioctl_disk_get_idx);
+ }
+ if (!test_bit(BCH_FS_STARTED, &c->flags))
+ return -EINVAL;
+
+ /* ioctls that do require admin cap: */
+ switch (cmd) {
case BCH_IOCTL_DISK_ADD:
BCH_IOCTL(disk_add, struct bch_ioctl_disk);
case BCH_IOCTL_DISK_REMOVE:
@@ -554,10 +566,6 @@ long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg)
BCH_IOCTL(disk_set_state, struct bch_ioctl_disk_set_state);
case BCH_IOCTL_DATA:
BCH_IOCTL(data, struct bch_ioctl_data);
- case BCH_IOCTL_READ_SUPER:
- BCH_IOCTL(read_super, struct bch_ioctl_read_super);
- case BCH_IOCTL_DISK_GET_IDX:
- BCH_IOCTL(disk_get_idx, struct bch_ioctl_disk_get_idx);
case BCH_IOCTL_DISK_RESIZE:
BCH_IOCTL(disk_resize, struct bch_ioctl_disk_resize);
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 77670ea6e077..f901c3757651 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -501,11 +501,54 @@ void bch2_fs_stop(struct bch_fs *c)
kobject_put(&c->kobj);
}
+static const char *bch2_fs_online(struct bch_fs *c)
+{
+ struct bch_dev *ca;
+ const char *err = NULL;
+ unsigned i;
+ int ret;
+
+ lockdep_assert_held(&bch_fs_list_lock);
+
+ if (!list_empty(&c->list))
+ return NULL;
+
+ if (__bch2_uuid_to_fs(c->sb.uuid))
+ return "filesystem UUID already open";
+
+ ret = bch2_fs_chardev_init(c);
+ if (ret)
+ return "error creating character device";
+
+ bch2_fs_debug_init(c);
+
+ if (kobject_add(&c->kobj, NULL, "%pU", c->sb.user_uuid.b) ||
+ kobject_add(&c->internal, &c->kobj, "internal") ||
+ kobject_add(&c->opts_dir, &c->kobj, "options") ||
+ kobject_add(&c->time_stats, &c->kobj, "time_stats") ||
+ bch2_opts_create_sysfs_files(&c->opts_dir))
+ return "error creating sysfs objects";
+
+ mutex_lock(&c->state_lock);
+
+ err = "error creating sysfs objects";
+ __for_each_member_device(ca, c, i, NULL)
+ if (bch2_dev_sysfs_online(c, ca))
+ goto err;
+
+ list_add(&c->list, &bch_fs_list);
+ err = NULL;
+err:
+ mutex_unlock(&c->state_lock);
+ return err;
+}
+
static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
{
struct bch_sb_field_members *mi;
struct bch_fs *c;
unsigned i, iter_size;
+ const char *err;
pr_verbose_init(opts, "");
@@ -644,6 +687,14 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
kobject_init(&c->internal, &bch2_fs_internal_ktype);
kobject_init(&c->opts_dir, &bch2_fs_opts_dir_ktype);
kobject_init(&c->time_stats, &bch2_fs_time_stats_ktype);
+
+ mutex_lock(&bch_fs_list_lock);
+ err = bch2_fs_online(c);
+ mutex_unlock(&bch_fs_list_lock);
+ if (err) {
+ bch_err(c, "bch2_fs_online() error: %s", err);
+ goto err;
+ }
out:
pr_verbose_init(opts, "ret %i", c ? 0 : -ENOMEM);
return c;
@@ -653,60 +704,7 @@ err:
goto out;
}
-static const char *__bch2_fs_online(struct bch_fs *c)
-{
- struct bch_dev *ca;
- const char *err = NULL;
- unsigned i;
- int ret;
-
- lockdep_assert_held(&bch_fs_list_lock);
-
- if (!list_empty(&c->list))
- return NULL;
-
- if (__bch2_uuid_to_fs(c->sb.uuid))
- return "filesystem UUID already open";
-
- ret = bch2_fs_chardev_init(c);
- if (ret)
- return "error creating character device";
-
- bch2_fs_debug_init(c);
-
- if (kobject_add(&c->kobj, NULL, "%pU", c->sb.user_uuid.b) ||
- kobject_add(&c->internal, &c->kobj, "internal") ||
- kobject_add(&c->opts_dir, &c->kobj, "options") ||
- kobject_add(&c->time_stats, &c->kobj, "time_stats") ||
- bch2_opts_create_sysfs_files(&c->opts_dir))
- return "error creating sysfs objects";
-
- mutex_lock(&c->state_lock);
-
- err = "error creating sysfs objects";
- __for_each_member_device(ca, c, i, NULL)
- if (bch2_dev_sysfs_online(c, ca))
- goto err;
-
- list_add(&c->list, &bch_fs_list);
- err = NULL;
-err:
- mutex_unlock(&c->state_lock);
- return err;
-}
-
-static const char *bch2_fs_online(struct bch_fs *c)
-{
- const char *err;
-
- mutex_lock(&bch_fs_list_lock);
- err = __bch2_fs_online(c);
- mutex_unlock(&bch_fs_list_lock);
-
- return err;
-}
-
-static const char *__bch2_fs_start(struct bch_fs *c)
+const char *bch2_fs_start(struct bch_fs *c)
{
const char *err = "cannot allocate memory";
struct bch_sb_field_members *mi;
@@ -901,6 +899,8 @@ recovery_done:
bch2_write_super(c);
mutex_unlock(&c->sb_lock);
+ set_bit(BCH_FS_STARTED, &c->flags);
+
err = NULL;
out:
mutex_unlock(&c->state_lock);
@@ -939,11 +939,6 @@ fsck_err:
goto out;
}
-const char *bch2_fs_start(struct bch_fs *c)
-{
- return __bch2_fs_start(c) ?: bch2_fs_online(c);
-}
-
static const char *bch2_dev_may_add(struct bch_sb *sb, struct bch_fs *c)
{
struct bch_sb_field_members *sb_mi;
@@ -1856,15 +1851,10 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
goto err_print;
if (!c->opts.nostart) {
- err = __bch2_fs_start(c);
+ err = bch2_fs_start(c);
if (err)
goto err_print;
}
-
- err = bch2_fs_online(c);
- if (err)
- goto err_print;
-
out:
kfree(sb);
module_put(THIS_MODULE);
@@ -1922,15 +1912,11 @@ static const char *__bch2_fs_open_incremental(struct bch_sb_handle *sb,
mutex_unlock(&c->sb_lock);
if (!c->opts.nostart && bch2_fs_may_start(c)) {
- err = __bch2_fs_start(c);
+ err = bch2_fs_start(c);
if (err)
goto err;
}
- err = __bch2_fs_online(c);
- if (err)
- goto err;
-
closure_put(&c->cl);
mutex_unlock(&bch_fs_list_lock);