mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 18:51:21 +02:00
bcachefs: Single device mode
Single device filesystems are now identified by the block device name, not the UUID - and single device filesystems with the same UUID can be mounted simultaneously, without any special options. This allocates a new bit in the superblock, BCH_SB_MULTI_DEVICE, which indicates whether a filesystem has ever been multi device. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
58c36e6710
commit
c02e5b5728
|
|
@ -780,6 +780,7 @@ struct bch_fs {
|
|||
|
||||
u8 nr_devices;
|
||||
u8 clean;
|
||||
bool multi_device; /* true if we've ever had more than one device */
|
||||
|
||||
u8 encryption_type;
|
||||
|
||||
|
|
|
|||
|
|
@ -846,7 +846,7 @@ LE64_BITMASK(BCH_SB_SHARD_INUMS, struct bch_sb, flags[3], 28, 29);
|
|||
LE64_BITMASK(BCH_SB_INODES_USE_KEY_CACHE,struct bch_sb, flags[3], 29, 30);
|
||||
LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DELAY,struct bch_sb, flags[3], 30, 62);
|
||||
LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DISABLED,struct bch_sb, flags[3], 62, 63);
|
||||
/* one free bit */
|
||||
LE64_BITMASK(BCH_SB_MULTI_DEVICE, struct bch_sb, flags[3], 63, 64);
|
||||
LE64_BITMASK(BCH_SB_JOURNAL_RECLAIM_DELAY,struct bch_sb, flags[4], 0, 32);
|
||||
LE64_BITMASK(BCH_SB_JOURNAL_TRANSACTION_NAMES,struct bch_sb, flags[4], 32, 33);
|
||||
LE64_BITMASK(BCH_SB_NOCOW, struct bch_sb, flags[4], 33, 34);
|
||||
|
|
|
|||
|
|
@ -933,7 +933,11 @@ void bch2_fs_debug_init(struct bch_fs *c)
|
|||
if (IS_ERR_OR_NULL(bch_debug))
|
||||
return;
|
||||
|
||||
snprintf(name, sizeof(name), "%pU", c->sb.user_uuid.b);
|
||||
if (c->sb.multi_device)
|
||||
snprintf(name, sizeof(name), "%pU", c->sb.user_uuid.b);
|
||||
else
|
||||
strscpy(name, c->name, sizeof(name));
|
||||
|
||||
c->fs_debug_dir = debugfs_create_dir(name, bch_debug);
|
||||
if (IS_ERR_OR_NULL(c->fs_debug_dir))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@
|
|||
x(EINVAL, device_has_been_removed) \
|
||||
x(EINVAL, device_splitbrain) \
|
||||
x(EINVAL, device_already_online) \
|
||||
x(EINVAL, filesystem_uuid_already_open) \
|
||||
x(EINVAL, insufficient_devices_to_start) \
|
||||
x(EINVAL, invalid) \
|
||||
x(EINVAL, internal_fsck_err) \
|
||||
|
|
|
|||
|
|
@ -2514,7 +2514,12 @@ static int bch2_fs_get_tree(struct fs_context *fc)
|
|||
sb->s_time_min = div_s64(S64_MIN, c->sb.time_units_per_sec) + 1;
|
||||
sb->s_time_max = div_s64(S64_MAX, c->sb.time_units_per_sec);
|
||||
super_set_uuid(sb, c->sb.user_uuid.b, sizeof(c->sb.user_uuid));
|
||||
super_set_sysfs_name_uuid(sb);
|
||||
|
||||
if (c->sb.multi_device)
|
||||
super_set_sysfs_name_uuid(sb);
|
||||
else
|
||||
strscpy(sb->s_sysfs_name, c->name, sizeof(sb->s_sysfs_name));
|
||||
|
||||
sb->s_shrink->seeks = 0;
|
||||
c->vfs_sb = sb;
|
||||
strscpy(sb->s_id, c->name, sizeof(sb->s_id));
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ enum fsck_err_opts {
|
|||
BCH_MEMBER_DATA_ALLOWED, BIT(BCH_DATA_journal)|BIT(BCH_DATA_btree)|BIT(BCH_DATA_user),\
|
||||
"types", "Allowed data types for this device: journal, btree, and/or user")\
|
||||
x(discard, u8, \
|
||||
OPT_MOUNT|OPT_DEVICE|OPT_RUNTIME, \
|
||||
OPT_MOUNT|OPT_FS|OPT_DEVICE|OPT_RUNTIME, \
|
||||
OPT_BOOL(), \
|
||||
BCH_MEMBER_DISCARD, true, \
|
||||
NULL, "Enable discard/TRIM support") \
|
||||
|
|
@ -526,7 +526,7 @@ enum fsck_err_opts {
|
|||
OPT_FS|OPT_MOUNT|OPT_RUNTIME, \
|
||||
OPT_BOOL(), \
|
||||
BCH2_NO_SB_OPT, true, \
|
||||
NULL, "BTREE_ITER_prefetch casuse btree nodes to be\n"\
|
||||
NULL, "BTREE_ITER_prefetch causes btree nodes to be\n"\
|
||||
" prefetched sequentially")
|
||||
|
||||
struct bch_opts {
|
||||
|
|
|
|||
|
|
@ -468,6 +468,9 @@ int bch2_sb_validate(struct bch_sb *sb, u64 read_offset,
|
|||
SET_BCH_SB_VERSION_INCOMPAT_ALLOWED(sb, BCH_SB_VERSION_INCOMPAT(sb));
|
||||
}
|
||||
|
||||
if (sb->nr_devices > 1)
|
||||
SET_BCH_SB_MULTI_DEVICE(sb, true);
|
||||
|
||||
if (!flags) {
|
||||
/*
|
||||
* Been seeing a bug where these are getting inexplicably
|
||||
|
|
@ -612,6 +615,7 @@ static void bch2_sb_update(struct bch_fs *c)
|
|||
|
||||
c->sb.features = le64_to_cpu(src->features[0]);
|
||||
c->sb.compat = le64_to_cpu(src->compat[0]);
|
||||
c->sb.multi_device = BCH_SB_MULTI_DEVICE(src);
|
||||
|
||||
memset(c->sb.errors_silent, 0, sizeof(c->sb.errors_silent));
|
||||
|
||||
|
|
|
|||
|
|
@ -699,9 +699,10 @@ static int bch2_fs_online(struct bch_fs *c)
|
|||
|
||||
lockdep_assert_held(&bch_fs_list_lock);
|
||||
|
||||
if (__bch2_uuid_to_fs(c->sb.uuid)) {
|
||||
if (c->sb.multi_device &&
|
||||
__bch2_uuid_to_fs(c->sb.uuid)) {
|
||||
bch_err(c, "filesystem UUID already open");
|
||||
return -EINVAL;
|
||||
return -BCH_ERR_filesystem_uuid_already_open;
|
||||
}
|
||||
|
||||
ret = bch2_fs_chardev_init(c);
|
||||
|
|
@ -712,7 +713,9 @@ static int bch2_fs_online(struct bch_fs *c)
|
|||
|
||||
bch2_fs_debug_init(c);
|
||||
|
||||
ret = kobject_add(&c->kobj, NULL, "%pU", c->sb.user_uuid.b) ?:
|
||||
ret = (c->sb.multi_device
|
||||
? kobject_add(&c->kobj, NULL, "%pU", c->sb.user_uuid.b)
|
||||
: kobject_add(&c->kobj, NULL, "%s", c->name)) ?:
|
||||
kobject_add(&c->internal, &c->kobj, "internal") ?:
|
||||
kobject_add(&c->opts_dir, &c->kobj, "options") ?:
|
||||
#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT
|
||||
|
|
@ -902,7 +905,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (sbs->nr != 1)
|
||||
if (c->sb.multi_device)
|
||||
pr_uuid(&name, c->sb.user_uuid.b);
|
||||
else
|
||||
prt_bdevname(&name, sbs->data[0].bdev);
|
||||
|
|
@ -1792,11 +1795,11 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags)
|
|||
int bch2_dev_add(struct bch_fs *c, const char *path)
|
||||
{
|
||||
struct bch_opts opts = bch2_opts_empty();
|
||||
struct bch_sb_handle sb;
|
||||
struct bch_sb_handle sb = {};
|
||||
struct bch_dev *ca = NULL;
|
||||
struct printbuf errbuf = PRINTBUF;
|
||||
struct printbuf label = PRINTBUF;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
ret = bch2_read_super(path, &opts, &sb);
|
||||
bch_err_msg(c, ret, "reading super");
|
||||
|
|
@ -1813,6 +1816,20 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
|
|||
}
|
||||
}
|
||||
|
||||
if (list_empty(&c->list)) {
|
||||
mutex_lock(&bch_fs_list_lock);
|
||||
if (__bch2_uuid_to_fs(c->sb.uuid))
|
||||
ret = -BCH_ERR_filesystem_uuid_already_open;
|
||||
else
|
||||
list_add(&c->list, &bch_fs_list);
|
||||
mutex_unlock(&bch_fs_list_lock);
|
||||
|
||||
if (ret) {
|
||||
bch_err(c, "filesystem UUID already open");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = bch2_dev_may_add(sb.sb, c);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
@ -1829,6 +1846,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
|
|||
|
||||
down_write(&c->state_lock);
|
||||
mutex_lock(&c->sb_lock);
|
||||
SET_BCH_SB_MULTI_DEVICE(c->disk_sb.sb, true);
|
||||
|
||||
ret = bch2_sb_from_fs(c, ca);
|
||||
bch_err_msg(c, ret, "setting up new superblock");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user