]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
bcachefs: reserve space in journal for fs usage entries
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 24 Jan 2019 22:12:00 +0000 (17:12 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:15 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/bcachefs_format.h
fs/bcachefs/journal_io.c
fs/bcachefs/recovery.c
fs/bcachefs/replicas.c
fs/bcachefs/replicas.h
fs/bcachefs/super.c

index 4a0e2f63e645b58badd7f34d050f9c19d0685cb4..90c44ef0fbe056d95f82a84fa3fc41a64f0f18b5 100644 (file)
@@ -545,6 +545,8 @@ struct bch_fs {
        struct bch_replicas_cpu replicas_gc;
        struct mutex            replicas_gc_lock;
 
+       struct journal_entry_res replicas_journal_res;
+
        struct bch_disk_groups_cpu __rcu *disk_groups;
 
        struct bch_opts         opts;
index f6cf4ccedcb1080c82296ccecc38e7d3697d8b15..bd41628f2995cdc2503505c1c6aa7556ad75f692 100644 (file)
@@ -1362,7 +1362,8 @@ static inline __u64 __bset_magic(struct bch_sb *sb)
        x(btree_root,           1)              \
        x(prio_ptrs,            2)              \
        x(blacklist,            3)              \
-       x(blacklist_v2,         4)
+       x(blacklist_v2,         4)              \
+       x(usage,                5)
 
 enum {
 #define x(f, nr)       BCH_JSET_ENTRY_##f      = nr,
@@ -1392,6 +1393,20 @@ struct jset_entry_blacklist_v2 {
        __le64                  end;
 };
 
+enum {
+       FS_USAGE_REPLICAS               = 0,
+       FS_USAGE_INODES                 = 1,
+       FS_USAGE_KEY_VERSION            = 2,
+       FS_USAGE_NR                     = 3
+};
+
+struct jset_entry_usage {
+       struct jset_entry       entry;
+       __le64                  sectors;
+       __u8                    type;
+       struct bch_replicas_entry r;
+} __attribute__((packed));
+
 /*
  * On disk format for a journal entry:
  * seq is monotonically increasing; every journal entry has its own unique
index 9c794c9a1924ba1c3e2378916cfd006e35337ff9..173aecfaebc26227550f311d436bf03312096a92 100644 (file)
@@ -284,6 +284,7 @@ static int journal_entry_validate_blacklist_v2(struct bch_fs *c,
        if (journal_entry_err_on(le16_to_cpu(entry->u64s) != 2, c,
                "invalid journal seq blacklist entry: bad size")) {
                journal_entry_null_range(entry, vstruct_next(entry));
+               goto out;
        }
 
        bl_entry = container_of(entry, struct jset_entry_blacklist_v2, entry);
@@ -293,6 +294,28 @@ static int journal_entry_validate_blacklist_v2(struct bch_fs *c,
                "invalid journal seq blacklist entry: start > end")) {
                journal_entry_null_range(entry, vstruct_next(entry));
        }
+out:
+fsck_err:
+       return ret;
+}
+
+static int journal_entry_validate_usage(struct bch_fs *c,
+                                       struct jset *jset,
+                                       struct jset_entry *entry,
+                                       int write)
+{
+       struct jset_entry_usage *u =
+               container_of(entry, struct jset_entry_usage, entry);
+       unsigned bytes = jset_u64s(le16_to_cpu(entry->u64s)) * sizeof(u64);
+       int ret = 0;
+
+       if (journal_entry_err_on(bytes < sizeof(*u) ||
+                                bytes < sizeof(*u) + u->r.nr_devs,
+                                c,
+                                "invalid journal entry usage: bad size")) {
+               journal_entry_null_range(entry, vstruct_next(entry));
+               return ret;
+       }
 
 fsck_err:
        return ret;
@@ -315,18 +338,10 @@ static const struct jset_entry_ops bch2_jset_entry_ops[] = {
 static int journal_entry_validate(struct bch_fs *c, struct jset *jset,
                                  struct jset_entry *entry, int write)
 {
-       int ret = 0;
-
-       if (entry->type >= BCH_JSET_ENTRY_NR) {
-               journal_entry_err(c, "invalid journal entry type %u",
-                                 entry->type);
-               journal_entry_null_range(entry, vstruct_next(entry));
-               return 0;
-       }
-
-       ret = bch2_jset_entry_ops[entry->type].validate(c, jset, entry, write);
-fsck_err:
-       return ret;
+       return entry->type < BCH_JSET_ENTRY_NR
+               ? bch2_jset_entry_ops[entry->type].validate(c, jset,
+                                                           entry, write)
+               : 0;
 }
 
 static int jset_validate_entries(struct bch_fs *c, struct jset *jset,
index 2ff86262d41c66245df9c077aceeb83519d4e271..cb9601dfcd3721c7d2ae53819e631981caeb8c2c 100644 (file)
@@ -108,7 +108,8 @@ static bool journal_empty(struct list_head *journal)
 
        list_for_each_entry(i, journal, list) {
                vstruct_for_each(&i->j, entry) {
-                       if (entry->type == BCH_JSET_ENTRY_btree_root)
+                       if (entry->type == BCH_JSET_ENTRY_btree_root ||
+                           entry->type == BCH_JSET_ENTRY_usage)
                                continue;
 
                        if (entry->type == BCH_JSET_ENTRY_btree_keys &&
index 5663441fd7ced43bfd82382b70273f006ba6fb47..991d409b6a86ce92137b7a146c86e5e059d147ee 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include "bcachefs.h"
+#include "journal.h"
 #include "replicas.h"
 #include "super-io.h"
 
@@ -302,6 +303,27 @@ err:
        return ret;
 }
 
+static unsigned reserve_journal_replicas(struct bch_fs *c,
+                                    struct bch_replicas_cpu *r)
+{
+       struct bch_replicas_entry *e;
+       unsigned journal_res_u64s = 0;
+
+       /* nr_inodes: */
+       journal_res_u64s +=
+               DIV_ROUND_UP(sizeof(struct jset_entry_usage), sizeof(u64));
+
+       /* key_version: */
+       journal_res_u64s +=
+               DIV_ROUND_UP(sizeof(struct jset_entry_usage), sizeof(u64));
+
+       for_each_cpu_replicas_entry(r, e)
+               journal_res_u64s +=
+                       DIV_ROUND_UP(sizeof(struct jset_entry_usage) +
+                                    e->nr_devs, sizeof(u64));
+       return journal_res_u64s;
+}
+
 noinline
 static int bch2_mark_replicas_slowpath(struct bch_fs *c,
                                struct bch_replicas_entry *new_entry)
@@ -329,6 +351,10 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c,
                ret = bch2_cpu_replicas_to_sb_replicas(c, &new_r);
                if (ret)
                        goto err;
+
+               bch2_journal_entry_res_resize(&c->journal,
+                               &c->replicas_journal_res,
+                               reserve_journal_replicas(c, &new_r));
        }
 
        if (!new_r.entries &&
@@ -595,6 +621,7 @@ int bch2_sb_replicas_to_cpu_replicas(struct bch_fs *c)
        bch2_cpu_replicas_sort(&new_r);
 
        percpu_down_write(&c->mark_lock);
+
        ret = replicas_table_update(c, &new_r);
        percpu_up_write(&c->mark_lock);
 
@@ -915,3 +942,10 @@ unsigned bch2_dev_has_data(struct bch_fs *c, struct bch_dev *ca)
 
        return ret;
 }
+
+int bch2_fs_replicas_init(struct bch_fs *c)
+{
+       c->journal.entry_u64s_reserved +=
+               reserve_journal_replicas(c, &c->replicas);
+       return 0;
+}
index 923bddb21ec34f1048fcca4064d7961fce24c6ba..4fabe0372ec39796ed792c547b8e905e286be449 100644 (file)
@@ -80,4 +80,6 @@ int bch2_sb_replicas_to_cpu_replicas(struct bch_fs *);
 extern const struct bch_sb_field_ops bch_sb_field_ops_replicas;
 extern const struct bch_sb_field_ops bch_sb_field_ops_replicas_v0;
 
+int bch2_fs_replicas_init(struct bch_fs *);
+
 #endif /* _BCACHEFS_REPLICAS_H */
index 9ec05410aeb43e197c8bbc074dc58f659e60e573..8a5ee2835bbdfaba479b4842afd4a75f8c93fd69 100644 (file)
@@ -658,6 +658,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
            bch2_io_clock_init(&c->io_clock[READ]) ||
            bch2_io_clock_init(&c->io_clock[WRITE]) ||
            bch2_fs_journal_init(&c->journal) ||
+           bch2_fs_replicas_init(c) ||
            bch2_fs_btree_cache_init(c) ||
            bch2_fs_io_init(c) ||
            bch2_fs_encryption_init(c) ||