diff options
Diffstat (limited to 'fs/bcachefs/super.c')
-rw-r--r-- | fs/bcachefs/super.c | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index de1e8912975c..03b12c2da097 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -238,6 +238,7 @@ static int bch2_dev_sysfs_online(struct bch_fs *, struct bch_dev *); static void bch2_dev_io_ref_stop(struct bch_dev *, int); static void __bch2_dev_read_only(struct bch_fs *, struct bch_dev *); static int bch2_dev_attach_bdev(struct bch_fs *, struct bch_sb_handle *, struct printbuf *); +static bool bch2_fs_will_resize_on_mount(struct bch_fs *); struct bch_fs *bch2_dev_to_fs(dev_t dev) { @@ -322,6 +323,8 @@ static void __bch2_fs_read_only(struct bch_fs *c) do { clean_passes++; + bch2_do_discards_going_ro(c); + if (bch2_btree_interior_updates_flush(c) || bch2_btree_write_buffer_flush_going_ro(c) || bch2_journal_flush_all_pins(&c->journal) || @@ -833,8 +836,6 @@ int bch2_fs_init_rw(struct bch_fs *c) if (test_bit(BCH_FS_rw_init_done, &c->flags)) return 0; - bch_verbose(c, "doing rw allocations"); - if (!(c->btree_update_wq = alloc_workqueue("bcachefs", WQ_HIGHPRI|WQ_FREEZABLE|WQ_MEM_RECLAIM|WQ_UNBOUND, 512)) || !(c->btree_write_complete_wq = alloc_workqueue("bcachefs_btree_write_complete", @@ -964,6 +965,9 @@ static int bch2_fs_opt_version_init(struct bch_fs *c) if (c->opts.journal_rewind) c->opts.fsck = true; + bool may_upgrade_downgrade = !(c->sb.features & BIT_ULL(BCH_FEATURE_small_image)) || + bch2_fs_will_resize_on_mount(c); + CLASS(printbuf, p)(); bch2_log_msg_start(c, &p); @@ -1040,22 +1044,24 @@ static int bch2_fs_opt_version_init(struct bch_fs *c) prt_bitflags(&p, __bch2_btree_ids, btrees_lost_data); } - if (bch2_check_version_downgrade(c)) { - prt_str(&p, "\nVersion downgrade required:"); - - __le64 passes = ext->recovery_passes_required[0]; - bch2_sb_set_downgrade(c, - BCH_VERSION_MINOR(bcachefs_metadata_version_current), - BCH_VERSION_MINOR(c->sb.version)); - passes = ext->recovery_passes_required[0] & ~passes; - if (passes) { - prt_str(&p, "\nrunning recovery passes: "); - prt_bitflags(&p, bch2_recovery_passes, - bch2_recovery_passes_from_stable(le64_to_cpu(passes))); + if (may_upgrade_downgrade) { + if (bch2_check_version_downgrade(c)) { + prt_str(&p, "\nVersion downgrade required:"); + + __le64 passes = ext->recovery_passes_required[0]; + bch2_sb_set_downgrade(c, + BCH_VERSION_MINOR(bcachefs_metadata_version_current), + BCH_VERSION_MINOR(c->sb.version)); + passes = ext->recovery_passes_required[0] & ~passes; + if (passes) { + prt_str(&p, "\nrunning recovery passes: "); + prt_bitflags(&p, bch2_recovery_passes, + bch2_recovery_passes_from_stable(le64_to_cpu(passes))); + } } - } - check_version_upgrade(c); + check_version_upgrade(c); + } c->opts.recovery_passes |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0])); @@ -1211,12 +1217,14 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts, bch2_opts_apply(&c->opts, *opts); +#ifdef __KERNEL__ if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && c->opts.block_size > PAGE_SIZE) { bch_err(c, "cannot mount bs > ps filesystem without CONFIG_TRANSPARENT_HUGEPAGE"); ret = -EINVAL; goto err; } +#endif c->btree_key_cache_btrees |= 1U << BTREE_ID_alloc; if (c->opts.inodes_use_key_cache) @@ -1991,7 +1999,8 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags, struct printbuf *err) { unsigned dev_idx = ca->dev_idx, data; - bool fast_device_removal = !bch2_request_incompat_feature(c, + bool fast_device_removal = (c->sb.compat & BIT_ULL(BCH_COMPAT_no_stale_ptrs)) && + !bch2_request_incompat_feature(c, bcachefs_metadata_version_fast_device_removal); int ret; @@ -2419,15 +2428,29 @@ int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets, struct p return 0; } +static bool bch2_dev_will_resize_on_mount(struct bch_dev *ca) +{ + return ca->mi.resize_on_mount && + ca->mi.nbuckets < div64_u64(get_capacity(ca->disk_sb.bdev->bd_disk), + ca->mi.bucket_size); +} + +static bool bch2_fs_will_resize_on_mount(struct bch_fs *c) +{ + for_each_online_member(c, ca, BCH_DEV_READ_REF_fs_resize_on_mount) + if (bch2_dev_will_resize_on_mount(ca)) + return true; + return false; +} + int bch2_fs_resize_on_mount(struct bch_fs *c) { for_each_online_member(c, ca, BCH_DEV_READ_REF_fs_resize_on_mount) { - u64 old_nbuckets = ca->mi.nbuckets; - u64 new_nbuckets = div64_u64(get_capacity(ca->disk_sb.bdev->bd_disk), - ca->mi.bucket_size); + if (bch2_dev_will_resize_on_mount(ca)) { + u64 old_nbuckets = ca->mi.nbuckets; + u64 new_nbuckets = div64_u64(get_capacity(ca->disk_sb.bdev->bd_disk), + ca->mi.bucket_size); - if (ca->mi.resize_on_mount && - new_nbuckets > ca->mi.nbuckets) { bch_info(ca, "resizing to size %llu", new_nbuckets * ca->mi.bucket_size); int ret = bch2_dev_buckets_resize(c, ca, new_nbuckets); bch_err_fn(ca, ret); |