diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-18 13:22:35 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-02-19 18:00:35 -0500 |
commit | 02d7c0e4b51b52fccb937617b4b448ed278e17b6 (patch) | |
tree | 59678be4ac81a153391a1d759f150138a99ea3df | |
parent | 1fe226203d3d85f18cb3557ea7413fd9de12fe30 (diff) |
bcachefs: fixes for check_set_has_compressed_data()
-rw-r--r-- | fs/bcachefs/bcachefs.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/compress.c | 70 | ||||
-rw-r--r-- | fs/bcachefs/fs-io.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/super-io.c | 1 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 1 | ||||
-rw-r--r-- | fs/bcachefs/sysfs.c | 9 | ||||
-rw-r--r-- | fs/bcachefs/xattr.c | 6 |
7 files changed, 60 insertions, 30 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index 5a3e99b3b79a..e50aa3dd49bc 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -522,6 +522,7 @@ struct bch_fs { u64 time_base_lo; u32 time_base_hi; u32 time_precision; + u64 features; } sb; struct bch_sb *disk_sb; 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); + +} diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index 00475b99dff8..d7fb28cc95c7 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -2351,7 +2351,7 @@ static long bch2_fallocate(struct bch_inode_info *inode, int mode, loff_t block_start, block_end; loff_t end = offset + len; unsigned sectors; - unsigned replicas = READ_ONCE(c->opts.data_replicas); + unsigned replicas = io_opts(c, inode).data_replicas; int ret; bch2_btree_iter_init(&iter, c, BTREE_ID_EXTENTS, POS_MIN, diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index c747391707b3..1c4f67cc4bd4 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -400,6 +400,7 @@ static void bch2_sb_update(struct bch_fs *c) c->sb.time_base_lo = le64_to_cpu(src->time_base_lo); c->sb.time_base_hi = le32_to_cpu(src->time_base_hi); c->sb.time_precision = le32_to_cpu(src->time_precision); + c->sb.features = le64_to_cpu(src->features[0]); for_each_member_device(ca, c, i) ca->mi = bch2_mi_to_cpu(mi->members + i); diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 58bcd7d1ee06..777d60d3a4de 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -626,7 +626,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts) bch2_fs_btree_cache_init(c) || bch2_fs_encryption_init(c) || bch2_fs_compress_init(c) || - bch2_check_set_has_compressed_data(c, c->opts.compression) || bch2_fs_fsio_init(c)) goto err; diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c index 2e958a8ef381..722aa2642b92 100644 --- a/fs/bcachefs/sysfs.c +++ b/fs/bcachefs/sysfs.c @@ -546,9 +546,8 @@ STORE(bch2_fs_opts_dir) if (ret < 0) return ret; - mutex_lock(&c->sb_lock); - - if (id == Opt_compression) { + if (id == Opt_compression || + id == Opt_background_compression) { int ret = bch2_check_set_has_compressed_data(c, v); if (ret) { mutex_unlock(&c->sb_lock); @@ -557,14 +556,14 @@ STORE(bch2_fs_opts_dir) } if (opt->set_sb != SET_NO_SB_OPT) { + mutex_lock(&c->sb_lock); opt->set_sb(c->disk_sb, v); bch2_write_super(c); + mutex_unlock(&c->sb_lock); } bch2_opt_set_by_id(&c->opts, id, v); - mutex_unlock(&c->sb_lock); - return size; } SYSFS_OPS(bch2_fs_opts_dir); diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c index 1d6cbe72e05b..c286f3f8859a 100644 --- a/fs/bcachefs/xattr.c +++ b/fs/bcachefs/xattr.c @@ -441,11 +441,9 @@ static int bch2_xattr_bcachefs_set(const struct xattr_handler *handler, if (ret < 0) return ret; - if (s.id == Opt_compression) { - mutex_lock(&c->sb_lock); + if (s.id == Opt_compression || + s.id == Opt_background_compression) { ret = bch2_check_set_has_compressed_data(c, s.v); - mutex_unlock(&c->sb_lock); - if (ret) return ret; } |