bcachefs: BCH_FEATURE_small_image
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 15 Apr 2025 19:15:36 +0000 (15:15 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:14:20 +0000 (20:14 -0400)
We can't go RW if it's an image file that hasn't been resized.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/alloc_background.c
fs/bcachefs/bcachefs_format.h
fs/bcachefs/errcode.h
fs/bcachefs/journal.c
fs/bcachefs/journal_reclaim.c
fs/bcachefs/recovery.c
fs/bcachefs/super.c

index 8b8c2344855f1f32395c5aeef60aa7efb5bc347a..6ac8bd49c629d9d4a8f91e266414107a891e0460 100644 (file)
@@ -2392,14 +2392,16 @@ bkey_err:
 
 int bch2_fs_freespace_init(struct bch_fs *c)
 {
-       int ret = 0;
-       bool doing_init = false;
+       if (c->sb.features & BIT_ULL(BCH_FEATURE_small_image))
+               return 0;
+
 
        /*
         * We can crash during the device add path, so we need to check this on
         * every mount:
         */
 
+       bool doing_init = false;
        for_each_member_device(c, ca) {
                if (ca->mi.freespace_initialized)
                        continue;
@@ -2409,7 +2411,7 @@ int bch2_fs_freespace_init(struct bch_fs *c)
                        doing_init = true;
                }
 
-               ret = bch2_dev_freespace_init(c, ca, 0, ca->mi.nbuckets);
+               int ret = bch2_dev_freespace_init(c, ca, 0, ca->mi.nbuckets);
                if (ret) {
                        bch2_dev_put(ca);
                        bch_err_fn(c, ret);
index c0041391e2e8265ba6aa62c59e9e6d6d0ee66654..7ce475c565b53de9af069e4950661de2d0653021 100644 (file)
@@ -924,7 +924,8 @@ static inline void SET_BCH_SB_BACKGROUND_COMPRESSION_TYPE(struct bch_sb *sb, __u
        x(extents_across_btree_nodes,   18)     \
        x(incompat_version_field,       19)     \
        x(casefolding,                  20)     \
-       x(no_alloc_info,                21)
+       x(no_alloc_info,                21)     \
+       x(small_image,                  22)
 
 #define BCH_SB_FEATURES_ALWAYS                         \
        (BIT_ULL(BCH_FEATURE_new_extent_overwrite)|     \
index 8a4435660d86b9ba6f3ba8ab750e15bc2d46a902..6a4b3fe9ea9954f1697de088b6b8be8b30b43eda 100644 (file)
        x(EROFS,                        erofs_norecovery)                       \
        x(EROFS,                        erofs_nochanges)                        \
        x(EROFS,                        erofs_no_alloc_info)                    \
+       x(EROFS,                        erofs_filesystem_full)                  \
        x(EROFS,                        insufficient_devices)                   \
        x(0,                            operation_blocked)                      \
        x(BCH_ERR_operation_blocked,    btree_cache_cannibalize_lock_blocked)   \
index 5442d526a4483eb5c63c06dc2ba278dc877d0833..3694b83af8cc2a009596b8b37b4a79a4b4f27e31 100644 (file)
@@ -1295,9 +1295,16 @@ int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
 
 int bch2_dev_journal_alloc(struct bch_dev *ca, bool new_fs)
 {
+       struct bch_fs *c = ca->fs;
+
        if (!(ca->mi.data_allowed & BIT(BCH_DATA_journal)))
                return 0;
 
+       if (c->sb.features & BIT_ULL(BCH_FEATURE_small_image)) {
+               bch_err(c, "cannot allocate journal, filesystem is an unresized image file");
+               return -BCH_ERR_erofs_filesystem_full;
+       }
+
        unsigned nr;
        int ret;
 
@@ -1318,7 +1325,7 @@ int bch2_dev_journal_alloc(struct bch_dev *ca, bool new_fs)
                     min(1 << 13,
                         (1 << 24) / ca->mi.bucket_size));
 
-       ret = bch2_set_nr_journal_buckets_loop(ca->fs, ca, nr, new_fs);
+       ret = bch2_set_nr_journal_buckets_loop(c, ca, nr, new_fs);
 err:
        bch_err_fn(ca, ret);
        return ret;
index cc00b0fc40d8e338934338803f81dc4098638f5b..a02f483a016a34da8f2b5731361341e5e5a30280 100644 (file)
@@ -215,18 +215,20 @@ void bch2_journal_space_available(struct journal *j)
        j->can_discard = can_discard;
 
        if (nr_online < metadata_replicas_required(c)) {
-               struct printbuf buf = PRINTBUF;
-               buf.atomic++;
-               prt_printf(&buf, "insufficient writeable journal devices available: have %u, need %u\n"
-                          "rw journal devs:", nr_online, metadata_replicas_required(c));
-
-               rcu_read_lock();
-               for_each_member_device_rcu(c, ca, &c->rw_devs[BCH_DATA_journal])
-                       prt_printf(&buf, " %s", ca->name);
-               rcu_read_unlock();
-
-               bch_err(c, "%s", buf.buf);
-               printbuf_exit(&buf);
+               if (!(c->sb.features & BIT_ULL(BCH_FEATURE_small_image))) {
+                       struct printbuf buf = PRINTBUF;
+                       buf.atomic++;
+                       prt_printf(&buf, "insufficient writeable journal devices available: have %u, need %u\n"
+                                  "rw journal devs:", nr_online, metadata_replicas_required(c));
+
+                       rcu_read_lock();
+                       for_each_member_device_rcu(c, ca, &c->rw_devs[BCH_DATA_journal])
+                               prt_printf(&buf, " %s", ca->name);
+                       rcu_read_unlock();
+
+                       bch_err(c, "%s", buf.buf);
+                       printbuf_exit(&buf);
+               }
                ret = -BCH_ERR_insufficient_journal_devices;
                goto out;
        }
index b5ab77f3c69200dd225d2ac91dec3f21f786fba7..2436f334dde4c1e22da789cc9ed5346aec7ce7bb 100644 (file)
@@ -734,6 +734,11 @@ int bch2_fs_recovery(struct bch_fs *c)
                c->opts.read_only = true;
        }
 
+       if (c->sb.features & BIT_ULL(BCH_FEATURE_small_image)) {
+               bch_info(c, "filesystem is an unresized image file, mounting ro");
+               c->opts.read_only = true;
+       }
+
        mutex_lock(&c->sb_lock);
        struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext);
        bool write_sb = false;
index 6ab3e63ef13913d4321c6c86e9f8c88f68a68325..7cd075303f95692c34c532f4fea260753dcfe4f7 100644 (file)
@@ -451,6 +451,11 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
                return -BCH_ERR_erofs_unfixed_errors;
        }
 
+       if (c->sb.features & BIT_ULL(BCH_FEATURE_small_image)) {
+               bch_err(c, "cannot go rw, filesystem is an unresized image file");
+               return -BCH_ERR_erofs_filesystem_full;
+       }
+
        if (test_bit(BCH_FS_rw, &c->flags))
                return 0;