bcachefs: Check for unsupported features
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 12 Nov 2018 23:30:55 +0000 (18:30 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:11 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs_format.h
fs/bcachefs/opts.c
fs/bcachefs/opts.h
fs/bcachefs/super-io.c
fs/bcachefs/sysfs.c
fs/bcachefs/xattr.c

index d74f1e5c21e0e722b6dfa9e07c311fe11d59271e..eb14fcf15a96bdaa3fc27a1b991ce3da751123e2 100644 (file)
@@ -1234,7 +1234,8 @@ enum bch_sb_features {
        BCH_FEATURE_LZ4                 = 0,
        BCH_FEATURE_GZIP                = 1,
        BCH_FEATURE_ZSTD                = 2,
-       BCH_FEATURE_ATOMIC_NLINK        = 3,
+       BCH_FEATURE_ATOMIC_NLINK        = 3, /* should have gone under compat */
+       BCH_FEATURE_NR,
 };
 
 /* options: */
index c12af1a86f0b42d5f007f82c3f9391bc032e0bc5..74e92a196ccd4a44b9c8606ba6712e0c025dc485 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/kernel.h>
 
 #include "bcachefs.h"
+#include "compress.h"
 #include "disk_groups.h"
 #include "opts.h"
 #include "super-io.h"
@@ -269,6 +270,20 @@ void bch2_opt_to_text(struct printbuf *out, struct bch_fs *c,
        }
 }
 
+int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v)
+{
+       int ret = 0;
+
+       switch (id) {
+       case Opt_compression:
+       case Opt_background_compression:
+               ret = bch2_check_set_has_compressed_data(c, v);
+               break;
+       }
+
+       return ret;
+}
+
 int bch2_parse_mount_opts(struct bch_opts *opts, char *options)
 {
        char *opt, *name, *val;
index 47617cd011ffe9d61cc77912d1e808044076dc18..8f4fab7f7dc829fe58ef80e8366897c87a17a097 100644 (file)
@@ -269,6 +269,7 @@ int bch2_opt_parse(struct bch_fs *, const struct bch_option *, const char *, u64
 void bch2_opt_to_text(struct printbuf *, struct bch_fs *,
                      const struct bch_option *, u64, unsigned);
 
+int bch2_opt_check_may_set(struct bch_fs *, int, u64);
 int bch2_parse_mount_opts(struct bch_opts *, char *);
 
 /* inode opts: */
index 0c2b20c9e8c417270102a1125ce7272a96851993..22e28d1eeadcb777c3149c21918cf2547e7c3c20 100644 (file)
@@ -230,6 +230,10 @@ const char *bch2_sb_validate(struct bch_sb_handle *disk_sb)
            le16_to_cpu(sb->version) > BCH_SB_VERSION_MAX)
                return "Unsupported superblock version";
 
+       if (sb->features[1] ||
+           (le64_to_cpu(sb->features[0]) & (~0ULL << BCH_FEATURE_NR)))
+               return "Filesystem has incompatible features";
+
        if (le16_to_cpu(sb->version) < BCH_SB_VERSION_EXTENT_MAX) {
                SET_BCH_SB_ENCODED_EXTENT_MAX_BITS(sb, 7);
                SET_BCH_SB_POSIX_ACL(sb, 1);
index 4ca84de6ab0e5d8c01e393a4579d3a796ad9ca60..4273aad166757c0f5be5eb07555e23d045b8afa6 100644 (file)
@@ -10,7 +10,6 @@
 
 #include "bcachefs.h"
 #include "alloc_background.h"
-#include "compress.h"
 #include "sysfs.h"
 #include "btree_cache.h"
 #include "btree_io.h"
@@ -581,14 +580,9 @@ STORE(bch2_fs_opts_dir)
        if (ret < 0)
                return ret;
 
-       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);
-                       return ret;
-               }
-       }
+       ret = bch2_opt_check_may_set(c, id, v);
+       if (ret < 0)
+               return ret;
 
        if (opt->set_sb != SET_NO_SB_OPT) {
                mutex_lock(&c->sb_lock);
index 7f6258e09a0d385e700d70f11bc06704a63e69fd..ab358c43475388dbc6eeaa3be100ea71bc5fe1c8 100644 (file)
@@ -3,7 +3,6 @@
 #include "bcachefs.h"
 #include "bkey_methods.h"
 #include "btree_update.h"
-#include "compress.h"
 #include "extents.h"
 #include "fs.h"
 #include "rebalance.h"
@@ -433,12 +432,9 @@ static int bch2_xattr_bcachefs_set(const struct xattr_handler *handler,
                if (ret < 0)
                        return ret;
 
-               if (s.id == Opt_compression ||
-                   s.id == Opt_background_compression) {
-                       ret = bch2_check_set_has_compressed_data(c, s.v);
-                       if (ret)
-                               return ret;
-               }
+               ret = bch2_opt_check_may_set(c, s.id, s.v);
+               if (ret < 0)
+                       return ret;
 
                s.defined = true;
        } else {