diff options
Diffstat (limited to 'fs/bcachefs/compress.c')
-rw-r--r-- | fs/bcachefs/compress.c | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/fs/bcachefs/compress.c b/fs/bcachefs/compress.c index 7726cfd8cfac..18c945985636 100644 --- a/fs/bcachefs/compress.c +++ b/fs/bcachefs/compress.c @@ -360,6 +360,9 @@ static unsigned __bio_compress(struct bch_fs *c, unsigned pad; int ret = 0; + BUG_ON(compression_type >= BCH_COMPRESSION_NR); + BUG_ON(!mempool_initialized(&c->compress_workspace[compression_type])); + /* If it's only one block, don't bother trying to compress: */ if (bio_sectors(src) <= c->opts.block_size) return 0; @@ -465,6 +468,8 @@ unsigned bch2_bio_compress(struct bch_fs *c, return compression_type; } +static int __bch2_fs_compress_init(struct bch_fs *, u64); + #define BCH_FEATURE_NONE 0 static const unsigned bch2_compression_opt_to_feature[] = { @@ -475,29 +480,42 @@ static const unsigned bch2_compression_opt_to_feature[] = { #undef BCH_FEATURE_NONE -/* doesn't write superblock: */ -int bch2_check_set_has_compressed_data(struct bch_fs *c, - unsigned compression_type) +int __bch2_check_set_has_compressed_data(struct bch_fs *c, u64 f) { - unsigned f; int ret = 0; - pr_verbose_init(c->opts, ""); + if ((c->sb.features & f) == f) + return 0; - BUG_ON(compression_type >= ARRAY_SIZE(bch2_compression_opt_to_feature)); + mutex_lock(&c->sb_lock); - if (!compression_type) - goto out; + if ((c->sb.features & f) == f) { + mutex_unlock(&c->sb_lock); + return 0; + } - f = bch2_compression_opt_to_feature[compression_type]; - if (bch2_sb_test_feature(c->disk_sb, f)) - goto out; + ret = __bch2_fs_compress_init(c, c->sb.features|f); + if (ret) { + mutex_unlock(&c->sb_lock); + return ret; + } - bch2_sb_set_feature(c->disk_sb, f); - ret = bch2_fs_compress_init(c); -out: - pr_verbose_init(c->opts, "ret %i", ret); - return ret; + c->disk_sb->features[0] |= cpu_to_le64(f); + bch2_write_super(c); + mutex_unlock(&c->sb_lock); + + return 0; +} + +int bch2_check_set_has_compressed_data(struct bch_fs *c, + unsigned compression_type) +{ + BUG_ON(compression_type >= ARRAY_SIZE(bch2_compression_opt_to_feature)); + + return compression_type + ? __bch2_check_set_has_compressed_data(c, + 1ULL << bch2_compression_opt_to_feature[compression_type]) + : 0; } void bch2_fs_compress_exit(struct bch_fs *c) @@ -531,7 +549,7 @@ static int mempool_init_kvpmalloc_pool(mempool_t *pool, int min_nr, size_t size) : 0; } -int bch2_fs_compress_init(struct bch_fs *c) +static int __bch2_fs_compress_init(struct bch_fs *c, u64 features) { size_t max_extent = c->sb.encoded_extent_max << 9; size_t order = get_order(max_extent); @@ -561,7 +579,7 @@ int bch2_fs_compress_init(struct bch_fs *c) for (i = compression_types; i < compression_types + ARRAY_SIZE(compression_types); i++) - if (bch2_sb_test_feature(c->disk_sb, i->feature)) + if (features & (1 << i->feature)) goto have_compressed; goto out; @@ -587,7 +605,7 @@ have_compressed: decompress_workspace_size = max(decompress_workspace_size, i->decompress_workspace); - if (!bch2_sb_test_feature(c->disk_sb, i->feature)) + if (!(features & (1 << i->feature))) continue; if (i->decompress_workspace) @@ -609,3 +627,17 @@ out: pr_verbose_init(c->opts, "ret %i", ret); return ret; } + +int bch2_fs_compress_init(struct bch_fs *c) +{ + u64 f = c->sb.features; + + if (c->opts.compression) + f |= 1ULL << bch2_compression_opt_to_feature[c->opts.compression]; + + if (c->opts.background_compression) + f |= 1ULL << bch2_compression_opt_to_feature[c->opts.background_compression]; + + return __bch2_fs_compress_init(c, f); + +} |