]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/journal_io.c
Update bcachefs sources to a180af9dd349 bcachefs: Refactor memcpy into direct assignment
[bcachefs-tools-debian] / libbcachefs / journal_io.c
index d141c749e39bc2c5cff0315402b647809fe0c0a2..6a3d6a374e9cc4385547eaf8a32894cfda15b49e 100644 (file)
@@ -8,7 +8,6 @@
 #include "checksum.h"
 #include "disk_groups.h"
 #include "error.h"
-#include "io.h"
 #include "journal.h"
 #include "journal_io.h"
 #include "journal_reclaim.h"
@@ -238,17 +237,17 @@ static void journal_entry_err_msg(struct printbuf *out,
 
 #define journal_entry_err(c, version, jset, entry, msg, ...)           \
 ({                                                                     \
-       struct printbuf buf = PRINTBUF;                                 \
+       struct printbuf _buf = PRINTBUF;                                \
                                                                        \
-       journal_entry_err_msg(&buf, version, jset, entry);              \
-       prt_printf(&buf, msg, ##__VA_ARGS__);                           \
+       journal_entry_err_msg(&_buf, version, jset, entry);             \
+       prt_printf(&_buf, msg, ##__VA_ARGS__);                          \
                                                                        \
        switch (flags & BKEY_INVALID_WRITE) {                           \
        case READ:                                                      \
-               mustfix_fsck_err(c, "%s", buf.buf);                     \
+               mustfix_fsck_err(c, "%s", _buf.buf);                    \
                break;                                                  \
        case WRITE:                                                     \
-               bch_err(c, "corrupt metadata before write: %s\n", buf.buf);\
+               bch_err(c, "corrupt metadata before write: %s\n", _buf.buf);\
                if (bch2_fs_inconsistent(c)) {                          \
                        ret = -BCH_ERR_fsck_errors_not_fixed;           \
                        goto fsck_err;                                  \
@@ -256,7 +255,7 @@ static void journal_entry_err_msg(struct printbuf *out,
                break;                                                  \
        }                                                               \
                                                                        \
-       printbuf_exit(&buf);                                            \
+       printbuf_exit(&_buf);                                           \
        true;                                                           \
 })
 
@@ -319,7 +318,6 @@ static int journal_validate_key(struct bch_fs *c,
                                  __btree_node_type(level, btree_id), write, &buf);
 
                mustfix_fsck_err(c, "%s", buf.buf);
-               BUG();
 
                le16_add_cpu(&entry->u64s, -((u16) k->k.u64s));
                memmove(k, bkey_next(k), next - (void *) bkey_next(k));
@@ -1054,6 +1052,7 @@ found:
                bch_err(c, "cur_idx %u/%u", ja->cur_idx, ja->nr);
                for (i = 0; i < 3; i++) {
                        unsigned idx = (ja->cur_idx + ja->nr - 1 + i) % ja->nr;
+
                        bch_err(c, "bucket_seq[%u] = %llu", idx, ja->bucket_seq[idx]);
                }
                ja->sectors_free = 0;
@@ -1282,7 +1281,7 @@ int bch2_journal_read(struct bch_fs *c,
                        continue;
 
                for (ptr = 0; ptr < i->nr_ptrs; ptr++) {
-                       struct bch_dev *ca = bch_dev_bkey_exists(c, i->ptrs[ptr].dev);
+                       ca = bch_dev_bkey_exists(c, i->ptrs[ptr].dev);
 
                        if (!i->ptrs[ptr].csum_good)
                                bch_err_dev_offset(ca, i->ptrs[ptr].sector,
@@ -1304,18 +1303,14 @@ int bch2_journal_read(struct bch_fs *c,
 
                bch2_replicas_entry_sort(&replicas.e);
 
-               /*
-                * If we're mounting in degraded mode - if we didn't read all
-                * the devices - this is wrong:
-                */
-
                printbuf_reset(&buf);
                bch2_replicas_entry_to_text(&buf, &replicas.e);
 
                if (!degraded &&
-                   fsck_err_on(!bch2_replicas_marked(c, &replicas.e), c,
-                               "superblock not marked as containing replicas %s",
-                               buf.buf)) {
+                   !bch2_replicas_marked(c, &replicas.e) &&
+                   (le64_to_cpu(i->j.seq) == *last_seq ||
+                    fsck_err(c, "superblock not marked as containing replicas for journal entry %llu\n  %s",
+                             le64_to_cpu(i->j.seq), buf.buf))) {
                        ret = bch2_mark_replicas(c, &replicas.e);
                        if (ret)
                                goto err;
@@ -1384,16 +1379,21 @@ static void __journal_write_alloc(struct journal *j,
 }
 
 /**
- * journal_next_bucket - move on to the next journal bucket if possible
+ * journal_write_alloc - decide where to write next journal entry
+ *
+ * @j:         journal object
+ * @w:         journal buf (entry to be written)
+ *
+ * Returns: 0 on success, or -EROFS on failure
  */
-static int journal_write_alloc(struct journal *j, struct journal_buf *w,
-                              unsigned sectors)
+static int journal_write_alloc(struct journal *j, struct journal_buf *w)
 {
        struct bch_fs *c = container_of(j, struct bch_fs, journal);
        struct bch_devs_mask devs;
        struct journal_device *ja;
        struct bch_dev *ca;
        struct dev_alloc_list devs_sorted;
+       unsigned sectors = vstruct_sectors(w->data, c->block_bits);
        unsigned target = c->opts.metadata_target ?:
                c->opts.foreground_target;
        unsigned i, replicas = 0, replicas_want =
@@ -1482,6 +1482,7 @@ static void journal_write_done(struct closure *cl)
        struct journal *j = container_of(cl, struct journal, io);
        struct bch_fs *c = container_of(j, struct bch_fs, journal);
        struct journal_buf *w = journal_last_unwritten_buf(j);
+       struct bch_replicas_padded replicas;
        union journal_res_state old, new;
        u64 v, seq;
        int err = 0;
@@ -1493,7 +1494,13 @@ static void journal_write_done(struct closure *cl)
        if (!w->devs_written.nr) {
                bch_err(c, "unable to write journal to sufficient devices");
                err = -EIO;
+       } else {
+               bch2_devlist_to_replicas(&replicas.e, BCH_DATA_journal,
+                                        w->devs_written);
+               if (bch2_mark_replicas(c, &replicas.e))
+                       err = -EIO;
        }
+
        if (err)
                bch2_fatal_error(c);
 
@@ -1547,6 +1554,7 @@ static void journal_write_done(struct closure *cl)
 
        if (!journal_state_count(new, new.unwritten_idx) &&
            journal_last_unwritten_seq(j) <= journal_cur_seq(j)) {
+               spin_unlock(&j->lock);
                closure_call(&j->io, bch2_journal_write, c->io_complete_wq, NULL);
        } else if (journal_last_unwritten_seq(j) == journal_cur_seq(j) &&
                   new.cur_entry_offset < JOURNAL_ENTRY_CLOSED_VAL) {
@@ -1559,10 +1567,11 @@ static void journal_write_done(struct closure *cl)
                 * might want to be written now:
                 */
 
+               spin_unlock(&j->lock);
                mod_delayed_work(c->io_complete_wq, &j->write_work, max(0L, delta));
+       } else {
+               spin_unlock(&j->lock);
        }
-
-       spin_unlock(&j->lock);
 }
 
 static void journal_write_endio(struct bio *bio)
@@ -1630,7 +1639,6 @@ static void do_journal_write(struct closure *cl)
        }
 
        continue_at(cl, journal_write_done, c->io_complete_wq);
-       return;
 }
 
 static void bch2_journal_entries_postprocess(struct bch_fs *c, struct jset *jset)
@@ -1811,7 +1819,7 @@ void bch2_journal_write(struct closure *cl)
 
 retry_alloc:
        spin_lock(&j->lock);
-       ret = journal_write_alloc(j, w, sectors);
+       ret = journal_write_alloc(j, w);
 
        if (ret && j->can_discard) {
                spin_unlock(&j->lock);