]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 76f72a0cc7 bcachefs: Improve error message in fsck
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 25 Mar 2020 20:15:56 +0000 (16:15 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Wed, 25 Mar 2020 20:15:56 +0000 (16:15 -0400)
.bcachefs_revision
libbcachefs/bcachefs.h
libbcachefs/fsck.c
libbcachefs/opts.h
libbcachefs/recovery.c
libbcachefs/recovery.h
libbcachefs/super.c

index 330c6bddd5f4d084b56aa24f791953a9e1f5b583..4600d638557e23e3de4dfd43ab14137b09917738 100644 (file)
@@ -1 +1 @@
-fd637ebda030609b15a473f01f1ef54bbe818f27
+76f72a0cc7392f83567b3f477496d6efe8a98f6b
index 5a8440ccc5b9e9f0db2b7b0d36e88e9a7698e6a1..fa9593764f0c01d52505c13e5a2d68e7dd8ab6ef 100644 (file)
@@ -521,6 +521,18 @@ struct journal_seq_blacklist_table {
        }                       entries[0];
 };
 
+struct journal_keys {
+       struct journal_key {
+               enum btree_id   btree_id:8;
+               unsigned        level:8;
+               struct bkey_i   *k;
+               u32             journal_seq;
+               u32             journal_offset;
+       }                       *d;
+       size_t                  nr;
+       u64                     journal_seq_base;
+};
+
 struct bch_fs {
        struct closure          cl;
 
@@ -787,6 +799,8 @@ struct bch_fs {
        mempool_t               btree_bounce_pool;
 
        struct journal          journal;
+       struct list_head        journal_entries;
+       struct journal_keys     journal_keys;
 
        u64                     last_bucket_seq_cleanup;
 
index 936e6366cb0470da857456b7d4f7e07097881ab2..822541e6adfc8b999adbb42c079442d50995c1bc 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include "bcachefs.h"
+#include "bkey_on_stack.h"
 #include "btree_update.h"
 #include "dirent.h"
 #include "error.h"
@@ -469,10 +470,12 @@ static int check_extents(struct bch_fs *c)
        struct btree_trans trans;
        struct btree_iter *iter;
        struct bkey_s_c k;
-       struct bkey prev = KEY(0, 0, 0);
+       struct bkey_on_stack prev;
        u64 i_sectors;
        int ret = 0;
 
+       bkey_on_stack_init(&prev);
+       prev.k->k = KEY(0, 0, 0);
        bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
 
        bch_verbose(c, "checking extents");
@@ -482,24 +485,24 @@ static int check_extents(struct bch_fs *c)
                                   BTREE_ITER_INTENT);
 retry:
        for_each_btree_key_continue(iter, 0, k, ret) {
-               if (bkey_cmp(prev.p, bkey_start_pos(k.k)) > 0) {
-                       char buf1[100];
-                       char buf2[100];
+               if (bkey_cmp(prev.k->k.p, bkey_start_pos(k.k)) > 0) {
+                       char buf1[200];
+                       char buf2[200];
 
-                       bch2_bkey_to_text(&PBUF(buf1), &prev);
-                       bch2_bkey_to_text(&PBUF(buf2), k.k);
+                       bch2_bkey_val_to_text(&PBUF(buf1), c, bkey_i_to_s_c(prev.k));
+                       bch2_bkey_val_to_text(&PBUF(buf2), c, k);
 
-                       if (fsck_err(c, "overlapping extents: %s, %s", buf1, buf2)) {
+                       if (fsck_err(c, "overlapping extents:\n%s\n%s", buf1, buf2)) {
                                ret = __bch2_trans_do(&trans, NULL, NULL,
                                                      BTREE_INSERT_NOFAIL|
                                                      BTREE_INSERT_LAZY_RW,
                                                bch2_fix_overlapping_extent(&trans,
-                                                               iter, k, prev.p));
+                                                               iter, k, prev.k->k.p));
                                if (ret)
                                        goto err;
                        }
                }
-               prev = *k.k;
+               bkey_on_stack_reassemble(&prev, c, k);
 
                ret = walk_inode(&trans, &w, k.k->p.inode);
                if (ret)
@@ -525,7 +528,8 @@ retry:
                        !(w.inode.bi_flags & BCH_INODE_I_SECTORS_DIRTY) &&
                        w.inode.bi_sectors !=
                        (i_sectors = bch2_count_inode_sectors(&trans, w.cur_inum)),
-                       c, "i_sectors wrong: got %llu, should be %llu",
+                       c, "inode %llu has incorrect i_sectors: got %llu, should be %llu",
+                       w.inode.bi_inum,
                        w.inode.bi_sectors, i_sectors)) {
                        struct bkey_inode_buf p;
 
@@ -567,6 +571,7 @@ err:
 fsck_err:
        if (ret == -EINTR)
                goto retry;
+       bkey_on_stack_exit(&prev, c);
        return bch2_trans_exit(&trans) ?: ret;
 }
 
index 1c05effa71e645087d0aa35d5fe3b80daebb2cee..ba49033523434e3aa07c8eaaa8c157ba133ae76e 100644 (file)
@@ -255,6 +255,11 @@ enum opt_type {
          OPT_BOOL(),                                                   \
          NO_SB_OPT,                    false,                          \
          NULL,         "Don't replay the journal")                     \
+       x(keep_journal,                 u8,                             \
+         OPT_MOUNT,                                                    \
+         OPT_BOOL(),                                                   \
+         NO_SB_OPT,                    false,                          \
+         NULL,         "Don't free journal entries/keys after startup")\
        x(noexcl,                       u8,                             \
          OPT_MOUNT,                                                    \
          OPT_BOOL(),                                                   \
index 2b428ee73364cf3e9560d46cae808d1cb4843f0c..320fea2b2ccd38d6ae24687a6b27d39a4a978da1 100644 (file)
@@ -198,7 +198,7 @@ void bch2_btree_and_journal_iter_init_node_iter(struct btree_and_journal_iter *i
 
 /* sort and dedup all keys in the journal: */
 
-static void journal_entries_free(struct list_head *list)
+void bch2_journal_entries_free(struct list_head *list)
 {
 
        while (!list_empty(list)) {
@@ -236,7 +236,7 @@ static int journal_sort_seq_cmp(const void *_l, const void *_r)
                bkey_cmp(l->k->k.p,     r->k->k.p);
 }
 
-static void journal_keys_free(struct journal_keys *keys)
+void bch2_journal_keys_free(struct journal_keys *keys)
 {
        kvfree(keys->d);
        keys->d = NULL;
@@ -801,8 +801,6 @@ int bch2_fs_recovery(struct bch_fs *c)
        const char *err = "cannot allocate memory";
        struct bch_sb_field_clean *clean = NULL;
        u64 journal_seq;
-       LIST_HEAD(journal_entries);
-       struct journal_keys journal_keys = { NULL };
        bool wrote = false, write_sb = false;
        int ret;
 
@@ -824,30 +822,30 @@ int bch2_fs_recovery(struct bch_fs *c)
        if (!c->sb.clean || c->opts.fsck) {
                struct jset *j;
 
-               ret = bch2_journal_read(c, &journal_entries);
+               ret = bch2_journal_read(c, &c->journal_entries);
                if (ret)
                        goto err;
 
-               if (mustfix_fsck_err_on(c->sb.clean && !journal_empty(&journal_entries), c,
+               if (mustfix_fsck_err_on(c->sb.clean && !journal_empty(&c->journal_entries), c,
                                "filesystem marked clean but journal not empty")) {
                        c->sb.compat &= ~(1ULL << BCH_COMPAT_FEAT_ALLOC_INFO);
                        SET_BCH_SB_CLEAN(c->disk_sb.sb, false);
                        c->sb.clean = false;
                }
 
-               if (!c->sb.clean && list_empty(&journal_entries)) {
+               if (!c->sb.clean && list_empty(&c->journal_entries)) {
                        bch_err(c, "no journal entries found");
                        ret = BCH_FSCK_REPAIR_IMPOSSIBLE;
                        goto err;
                }
 
-               journal_keys = journal_keys_sort(&journal_entries);
-               if (!journal_keys.d) {
+               c->journal_keys = journal_keys_sort(&c->journal_entries);
+               if (!c->journal_keys.d) {
                        ret = -ENOMEM;
                        goto err;
                }
 
-               j = &list_last_entry(&journal_entries,
+               j = &list_last_entry(&c->journal_entries,
                                     struct journal_replay, list)->j;
 
                ret = verify_superblock_clean(c, &clean, j);
@@ -866,7 +864,7 @@ int bch2_fs_recovery(struct bch_fs *c)
                goto err;
        }
 
-       ret = journal_replay_early(c, clean, &journal_entries);
+       ret = journal_replay_early(c, clean, &c->journal_entries);
        if (ret)
                goto err;
 
@@ -884,15 +882,15 @@ int bch2_fs_recovery(struct bch_fs *c)
 
        ret = bch2_blacklist_table_initialize(c);
 
-       if (!list_empty(&journal_entries)) {
+       if (!list_empty(&c->journal_entries)) {
                ret = verify_journal_entries_not_blacklisted_or_missing(c,
-                                                       &journal_entries);
+                                                       &c->journal_entries);
                if (ret)
                        goto err;
        }
 
        ret = bch2_fs_journal_start(&c->journal, journal_seq,
-                                   &journal_entries);
+                                   &c->journal_entries);
        if (ret)
                goto err;
 
@@ -902,14 +900,14 @@ int bch2_fs_recovery(struct bch_fs *c)
 
        bch_verbose(c, "starting alloc read");
        err = "error reading allocation information";
-       ret = bch2_alloc_read(c, &journal_keys);
+       ret = bch2_alloc_read(c, &c->journal_keys);
        if (ret)
                goto err;
        bch_verbose(c, "alloc read done");
 
        bch_verbose(c, "starting stripes_read");
        err = "error reading stripes";
-       ret = bch2_stripes_read(c, &journal_keys);
+       ret = bch2_stripes_read(c, &c->journal_keys);
        if (ret)
                goto err;
        bch_verbose(c, "stripes_read done");
@@ -925,7 +923,7 @@ int bch2_fs_recovery(struct bch_fs *c)
                 */
                bch_info(c, "starting metadata mark and sweep");
                err = "error in mark and sweep";
-               ret = bch2_gc(c, &journal_keys, true, true);
+               ret = bch2_gc(c, &c->journal_keys, true, true);
                if (ret)
                        goto err;
                bch_verbose(c, "mark and sweep done");
@@ -936,7 +934,7 @@ int bch2_fs_recovery(struct bch_fs *c)
            test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags)) {
                bch_info(c, "starting mark and sweep");
                err = "error in mark and sweep";
-               ret = bch2_gc(c, &journal_keys, true, false);
+               ret = bch2_gc(c, &c->journal_keys, true, false);
                if (ret)
                        goto err;
                bch_verbose(c, "mark and sweep done");
@@ -957,7 +955,7 @@ int bch2_fs_recovery(struct bch_fs *c)
 
        bch_verbose(c, "starting journal replay");
        err = "journal replay failed";
-       ret = bch2_journal_replay(c, journal_keys);
+       ret = bch2_journal_replay(c, c->journal_keys);
        if (ret)
                goto err;
        bch_verbose(c, "journal replay done");
@@ -1053,8 +1051,10 @@ fsck_err:
        set_bit(BCH_FS_FSCK_DONE, &c->flags);
        bch2_flush_fsck_errs(c);
 
-       journal_keys_free(&journal_keys);
-       journal_entries_free(&journal_entries);
+       if (!c->opts.keep_journal) {
+               bch2_journal_keys_free(&c->journal_keys);
+               bch2_journal_entries_free(&c->journal_entries);
+       }
        kfree(clean);
        if (ret)
                bch_err(c, "Error in recovery: %s (%i)", err, ret);
index fa1f2818817d4b10cfd305275c554a773fa92c42..19f2f172a26b327709279b4cdcaac5bcbfbf58c0 100644 (file)
@@ -2,18 +2,6 @@
 #ifndef _BCACHEFS_RECOVERY_H
 #define _BCACHEFS_RECOVERY_H
 
-struct journal_keys {
-       struct journal_key {
-               enum btree_id   btree_id:8;
-               unsigned        level:8;
-               struct bkey_i   *k;
-               u32             journal_seq;
-               u32             journal_offset;
-       }                       *d;
-       size_t                  nr;
-       u64                     journal_seq_base;
-};
-
 #define for_each_journal_key(keys, i)                          \
        for (i = (keys).d; i < (keys).d + (keys).nr; (i)++)
 
@@ -56,6 +44,9 @@ void bch2_btree_and_journal_iter_init_node_iter(struct btree_and_journal_iter *,
                                                struct journal_keys *,
                                                struct btree *);
 
+void bch2_journal_keys_free(struct journal_keys *);
+void bch2_journal_entries_free(struct list_head *);
+
 int bch2_fs_recovery(struct bch_fs *);
 int bch2_fs_initialize(struct bch_fs *);
 
index b990c16b3596ac05e2c35a71a2b87eb8a1947f50..d2c275ce79ab0ed33c54345c002f5f87931abc15 100644 (file)
@@ -500,6 +500,8 @@ static void bch2_fs_free(struct bch_fs *c)
        bch2_io_clock_exit(&c->io_clock[WRITE]);
        bch2_io_clock_exit(&c->io_clock[READ]);
        bch2_fs_compress_exit(c);
+       bch2_journal_keys_free(&c->journal_keys);
+       bch2_journal_entries_free(&c->journal_entries);
        percpu_free_rwsem(&c->mark_lock);
        kfree(c->usage_scratch);
        free_percpu(c->usage[1]);
@@ -689,6 +691,8 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
        INIT_WORK(&c->journal_seq_blacklist_gc_work,
                  bch2_blacklist_entries_gc);
 
+       INIT_LIST_HEAD(&c->journal_entries);
+
        INIT_LIST_HEAD(&c->fsck_errors);
        mutex_init(&c->fsck_error_lock);