bcachefs: bch_member.last_journal_bucket
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 26 Apr 2024 04:32:56 +0000 (00:32 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:21 +0000 (17:29 -0400)
On recovery from clean shutdown we don't typically read the journal, but
we still want to avoid overwriting existing entries in the journal for
list_journal debugging.

Thus, add some fields to the member info section so we can remember
where we left off.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs_format.h
fs/bcachefs/journal_io.c
fs/bcachefs/journal_io.h
fs/bcachefs/recovery.c
fs/bcachefs/sb-clean.c

index 2e8b1a489c2092be316aa08217477a9f3389337e..d5b90439e581f48c52f129e603a73567b868ff22 100644 (file)
@@ -589,6 +589,13 @@ struct bch_member {
        __le64                  errors_reset_time;
        __le64                  seq;
        __le64                  btree_allocated_bitmap;
+       /*
+        * On recovery from a clean shutdown we don't normally read the journal,
+        * but we still want to resume writing from where we left off so we
+        * don't overwrite more than is necessary, for list journal debugging:
+        */
+       __le32                  last_journal_bucket;
+       __le32                  last_journal_bucket_offset;
 };
 
 /*
index 98cf9a65216f6799dd262704d507fbeea8288b6e..f3c5e9a423fd17130a9d0977ee106af735d9459d 100644 (file)
 #include "sb-clean.h"
 #include "trace.h"
 
+void bch2_journal_pos_from_member_info_set(struct bch_fs *c)
+{
+       lockdep_assert_held(&c->sb_lock);
+
+       for_each_member_device(c, ca) {
+               struct bch_member *m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
+
+               m->last_journal_bucket = cpu_to_le32(ca->journal.cur_idx);
+               m->last_journal_bucket_offset = cpu_to_le32(ca->mi.bucket_size - ca->journal.sectors_free);
+       }
+}
+
+void bch2_journal_pos_from_member_info_resume(struct bch_fs *c)
+{
+       mutex_lock(&c->sb_lock);
+       for_each_member_device(c, ca) {
+               struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, ca->dev_idx);
+
+               unsigned idx = le32_to_cpu(m.last_journal_bucket);
+               if (idx < ca->journal.nr)
+                       ca->journal.cur_idx = idx;
+               unsigned offset = le32_to_cpu(m.last_journal_bucket_offset);
+               if (offset <= ca->mi.bucket_size)
+                       ca->journal.sectors_free = ca->mi.bucket_size - offset;
+       }
+       mutex_unlock(&c->sb_lock);
+}
+
 void bch2_journal_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
                               struct journal_replay *j)
 {
index 4f1e763ab506007c4488b81285b2a6464e5a2f2c..43cfed58ef33f0dae7243efc08e2ebbb6132109e 100644 (file)
@@ -4,6 +4,9 @@
 
 #include "darray.h"
 
+void bch2_journal_pos_from_member_info_set(struct bch_fs *);
+void bch2_journal_pos_from_member_info_resume(struct bch_fs *);
+
 struct journal_ptr {
        bool            csum_good;
        u8              dev;
index c33e20aa56a2876724fb9e93e3ae7d618c937622..a6447ffd336e3dbf691908f0e2a9f965420fdefe 100644 (file)
@@ -670,6 +670,8 @@ int bch2_fs_recovery(struct bch_fs *c)
                goto err;
        }
 
+       bch2_journal_pos_from_member_info_resume(c);
+
        if (!c->sb.clean || c->opts.retain_recovery_info) {
                struct genradix_iter iter;
                struct journal_replay **i;
index c2d4be52c8c521ed11d8ea63b6003214f4ab991e..e2beb2308c70c740409b756427a18a71426788be 100644 (file)
@@ -390,6 +390,8 @@ void bch2_fs_mark_clean(struct bch_fs *c)
                goto out;
        }
 
+       bch2_journal_pos_from_member_info_set(c);
+
        bch2_write_super(c);
 out:
        mutex_unlock(&c->sb_lock);