]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to b6d5426551 bcachefs: Fix bch2_btree_iter_peek_with_updates()
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 8 May 2021 03:48:50 +0000 (23:48 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Fri, 14 May 2021 18:58:07 +0000 (14:58 -0400)
14 files changed:
.bcachefs_revision
libbcachefs/alloc_background.c
libbcachefs/btree_gc.c
libbcachefs/btree_io.c
libbcachefs/btree_iter.c
libbcachefs/buckets.c
libbcachefs/io.c
libbcachefs/journal.c
libbcachefs/journal_io.c
libbcachefs/journal_types.h
libbcachefs/recovery.c
libbcachefs/s128.h [deleted file]
libbcachefs/super.c
libbcachefs/super.h

index 7ceb5bb5e8502c06881eda0ffab8eb29e125b0d1..80991d76ef07d84bcfb7462670750281eb6ecf2c 100644 (file)
@@ -1 +1 @@
-a5c0e1bb306e79b40b2432a22f164697c8b22110
+b6d54265513ceb7532e3983163338c1ad28a0284
index 3ac8b03029f8b6391b9a538d14672d3c7cd249e8..da6347390c4841e8297fbb1a2b5847c8c85d4101 100644 (file)
@@ -371,7 +371,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
 
                        ret = bch2_alloc_write_key(&trans, iter, flags);
                        if (ret) {
-                               percpu_ref_put(&ca->io_ref);
+                               percpu_ref_put(&ca->ref);
                                goto err;
                        }
                        bch2_btree_iter_next_slot(iter);
index 24fa279d1cdbcb146c6b7151fd131fc376826d64..ec6eb106e5e626bbb353e2ac5ea3c797198b2dbe 100644 (file)
@@ -1020,7 +1020,7 @@ static void bch2_gc_free(struct bch_fs *c)
 static int bch2_gc_done(struct bch_fs *c,
                        bool initial, bool metadata_only)
 {
-       struct bch_dev *ca;
+       struct bch_dev *ca = NULL;
        bool verify = !metadata_only && (!initial ||
                       (c->sb.compat & (1ULL << BCH_COMPAT_alloc_info)));
        unsigned i, dev;
@@ -1166,6 +1166,8 @@ static int bch2_gc_done(struct bch_fs *c,
 #undef copy_stripe_field
 #undef copy_field
 fsck_err:
+       if (ca)
+               percpu_ref_put(&ca->ref);
        if (ret)
                bch_err(c, "%s: ret %i", __func__, ret);
        return ret;
@@ -1174,7 +1176,7 @@ fsck_err:
 static int bch2_gc_start(struct bch_fs *c,
                         bool metadata_only)
 {
-       struct bch_dev *ca;
+       struct bch_dev *ca = NULL;
        unsigned i;
        int ret;
 
index e609bc49cefe55d27e7e3fba994d89a38d1d5de2..094285bd1cc202d5f5306ab48520c79d8067a981 100644 (file)
@@ -1491,6 +1491,9 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b)
        /* bch2_varint_decode may read up to 7 bytes past the end of the buffer: */
        bytes += 8;
 
+       /* buffer must be a multiple of the block size */
+       bytes = round_up(bytes, block_bytes(c));
+
        data = btree_bounce_alloc(c, bytes, &used_mempool);
 
        if (!b->written) {
index cdec05c86173f468f960d08d9c3fa449d022064c..6bac80aea958ceb3940143850d3ec7dfdb05ab20 100644 (file)
@@ -1611,16 +1611,17 @@ static struct bkey_i *btree_trans_peek_updates(struct btree_trans *trans,
 static inline struct bkey_s_c __btree_iter_peek(struct btree_iter *iter, bool with_updates)
 {
        struct bpos search_key = btree_iter_search_key(iter);
-       struct bkey_i *next_update = with_updates
-               ? btree_trans_peek_updates(iter->trans, iter->btree_id, search_key)
-               : NULL;
+       struct bkey_i *next_update;
        struct bkey_s_c k;
        int ret;
 
        EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
        bch2_btree_iter_verify(iter);
        bch2_btree_iter_verify_entry_exit(iter);
-
+start:
+       next_update = with_updates
+               ? btree_trans_peek_updates(iter->trans, iter->btree_id, search_key)
+               : NULL;
        btree_iter_set_search_pos(iter, search_key);
 
        while (1) {
@@ -1636,9 +1637,8 @@ static inline struct bkey_s_c __btree_iter_peek(struct btree_iter *iter, bool wi
 
                if (likely(k.k)) {
                        if (bkey_deleted(k.k)) {
-                               btree_iter_set_search_pos(iter,
-                                               bkey_successor(iter, k.k->p));
-                               continue;
+                               search_key = bkey_successor(iter, k.k->p);
+                               goto start;
                        }
 
                        break;
index 70008603f047d51aa5e10ab8ae3bbffd635c2b11..87266179542b06372597a899857810c9a4ac0782 100644 (file)
@@ -1706,9 +1706,28 @@ static __le64 *bkey_refcount(struct bkey_i *k)
        }
 }
 
+static bool reflink_p_frag_references(struct bkey_s_c_reflink_p p,
+                                     u64 start, u64 end,
+                                     struct bkey_s_c k)
+{
+       if (start == end)
+               return false;
+
+       start   += le64_to_cpu(p.v->idx);
+       end     += le64_to_cpu(p.v->idx);
+
+       if (end <= bkey_start_offset(k.k))
+               return false;
+       if (start >= k.k->p.offset)
+               return false;
+       return true;
+}
+
 static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
                        struct bkey_s_c_reflink_p p,
                        u64 idx, unsigned sectors,
+                       unsigned front_frag,
+                       unsigned back_frag,
                        unsigned flags)
 {
        struct bch_fs *c = trans->c;
@@ -1716,6 +1735,7 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
        struct bkey_s_c k;
        struct bkey_i *n;
        __le64 *refcount;
+       int add = !(flags & BTREE_TRIGGER_OVERWRITE) ? 1 : -1;
        s64 ret;
 
        ret = trans_get_key(trans, BTREE_ID_reflink,
@@ -1723,12 +1743,17 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
        if (ret < 0)
                return ret;
 
-       if ((flags & BTREE_TRIGGER_OVERWRITE) &&
-           (bkey_start_offset(k.k) < idx ||
-            k.k->p.offset > idx + sectors))
+       if (reflink_p_frag_references(p, 0, front_frag, k) &&
+           reflink_p_frag_references(p, back_frag, p.k->size, k)) {
+               BUG_ON(!(flags & BTREE_TRIGGER_OVERWRITE_SPLIT));
+               add = -add;
+       } else if (reflink_p_frag_references(p, 0, front_frag, k) ||
+                  reflink_p_frag_references(p, back_frag, p.k->size, k)) {
+               BUG_ON(!(flags & BTREE_TRIGGER_OVERWRITE));
                goto out;
+       }
 
-       sectors = k.k->p.offset - idx;
+       sectors = min_t(u64, sectors, k.k->p.offset - idx);
 
        n = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
        ret = PTR_ERR_OR_ZERO(n);
@@ -1747,7 +1772,8 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
                goto err;
        }
 
-       le64_add_cpu(refcount, !(flags & BTREE_TRIGGER_OVERWRITE) ? 1 : -1);
+       BUG_ON(!*refcount && (flags & BTREE_TRIGGER_OVERWRITE));
+       le64_add_cpu(refcount, add);
 
        if (!*refcount) {
                n->k.type = KEY_TYPE_deleted;
@@ -1768,13 +1794,18 @@ static int bch2_trans_mark_reflink_p(struct btree_trans *trans,
                        s64 sectors, unsigned flags)
 {
        u64 idx = le64_to_cpu(p.v->idx) + offset;
+       unsigned front_frag, back_frag;
        s64 ret = 0;
 
        sectors = abs(sectors);
        BUG_ON(offset + sectors > p.k->size);
 
+       front_frag = offset;
+       back_frag = offset + sectors;
+
        while (sectors) {
-               ret = __bch2_trans_mark_reflink_p(trans, p, idx, sectors, flags);
+               ret = __bch2_trans_mark_reflink_p(trans, p, idx, sectors,
+                                       front_frag, back_frag, flags);
                if (ret < 0)
                        break;
 
@@ -2067,7 +2098,7 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
 
 int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca)
 {
-       return bch2_trans_do(c, NULL, NULL, 0,
+       return bch2_trans_do(c, NULL, NULL, BTREE_INSERT_LAZY_RW,
                        __bch2_trans_mark_dev_sb(&trans, ca));
 }
 
index d1a623991bbc7013202179f9f9a969befd3df47a..7d0035d853f671c068c15d5b6d340a43fc7c2ae4 100644 (file)
@@ -1967,7 +1967,10 @@ int __bch2_read_indirect_extent(struct btree_trans *trans,
        if (k.k->type != KEY_TYPE_reflink_v &&
            k.k->type != KEY_TYPE_indirect_inline_data) {
                bch_err_inum_ratelimited(trans->c, orig_k->k->k.p.inode,
-                               "pointer to nonexistent indirect extent");
+                       "%llu len %u points to nonexistent indirect extent %llu",
+                       orig_k->k->k.p.offset,
+                       orig_k->k->k.size,
+                       reflink_offset);
                bch2_inconsistent_error(trans->c);
                ret = -EIO;
                goto err;
index c2773126a8c6ed52feb5d8a65404a28e7efb8620..1400774e4c01886e5620e3f89c5609a82d581b3f 100644 (file)
@@ -190,7 +190,8 @@ static bool __journal_entry_close(struct journal *j)
         * Hence, we want update/set last_seq on the current journal entry right
         * before we open a new one:
         */
-       buf->data->last_seq     = cpu_to_le64(journal_last_seq(j));
+       buf->last_seq           = journal_last_seq(j);
+       buf->data->last_seq     = cpu_to_le64(buf->last_seq);
 
        __bch2_journal_pin_put(j, le64_to_cpu(buf->data->seq));
 
index c7fa03cfbde6c316095c66a0d896afdd8319b6c2..635cceb4dd21ddd8ddd55b7130e0f325eaa057d9 100644 (file)
@@ -1237,7 +1237,7 @@ static void journal_write_done(struct closure *cl)
                bch2_bkey_devs(bkey_i_to_s_c(&w->key));
        struct bch_replicas_padded replicas;
        union journal_res_state old, new;
-       u64 v, seq, last_seq;
+       u64 v, seq;
        int err = 0;
 
        bch2_time_stats_update(j->write_time, j->write_start_time);
@@ -1256,7 +1256,6 @@ static void journal_write_done(struct closure *cl)
 
        spin_lock(&j->lock);
        seq = le64_to_cpu(w->data->seq);
-       last_seq = le64_to_cpu(w->data->last_seq);
 
        if (seq >= j->pin.front)
                journal_seq_pin(j, seq)->devs = devs;
@@ -1267,7 +1266,7 @@ static void journal_write_done(struct closure *cl)
 
        if (!JSET_NO_FLUSH(w->data)) {
                j->flushed_seq_ondisk = seq;
-               j->last_seq_ondisk = last_seq;
+               j->last_seq_ondisk = w->last_seq;
        }
 
        /*
@@ -1403,7 +1402,7 @@ void bch2_journal_write(struct closure *cl)
            test_bit(JOURNAL_MAY_SKIP_FLUSH, &j->flags)) {
                w->noflush = true;
                SET_JSET_NO_FLUSH(jset, true);
-               jset->last_seq = 0;
+               jset->last_seq = w->last_seq = 0;
 
                j->nr_noflush_writes++;
        } else {
index a7aa12e919e278f8453b37ce3dfd8316bdf4c6d8..cacab22a35c160e3a4c9525b568ae4a50e0ea4b9 100644 (file)
@@ -23,6 +23,7 @@ struct journal_buf {
        __BKEY_PADDED(key, BCH_REPLICAS_MAX);
 
        struct closure_waitlist wait;
+       u64                     last_seq;       /* copy of data->last_seq */
 
        unsigned                buf_size;       /* size in bytes of @data */
        unsigned                sectors;        /* maximum size for current entry */
index b35b297d4446891a2aa812e8c31746602e8e3be9..cd538ecc1f3f871689520bdffb599955c4915adb 100644 (file)
@@ -1328,8 +1328,10 @@ int bch2_fs_initialize(struct bch_fs *c)
        err = "error marking superblock and journal";
        for_each_member_device(ca, c, i) {
                ret = bch2_trans_mark_dev_sb(c, ca);
-               if (ret)
+               if (ret) {
+                       percpu_ref_put(&ca->ref);
                        goto err;
+               }
        }
 
        bch2_inode_init(c, &root_inode, 0, 0,
diff --git a/libbcachefs/s128.h b/libbcachefs/s128.h
deleted file mode 100644 (file)
index 6d77554..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _BCACHEFS_S128_H
-#define _BCACHEFS_S128_H
-
-#include <linux/math64.h>
-
-typedef struct {
-       s64     lo;
-       s64     hi;
-} s128;
-
-typedef struct {
-       s64     lo;
-       s32     hi;
-} s96;
-
-static inline s128 s128_mul(s128 a, s128 b)
-{
-       return a.lo
-
-}
-
-static inline s96 s96_mul(s96 a, s96 b)
-{
-       return a.lo
-
-}
-
-#endif /* _BCACHEFS_S128_H */
index bbd313a4287edfee401e37d16888db761c95776e..e5936041b9e2442e7b9d21ba10b998a9c67a4cde 100644 (file)
@@ -627,9 +627,11 @@ static const char *bch2_fs_online(struct bch_fs *c)
        down_write(&c->state_lock);
 
        err = "error creating sysfs objects";
-       __for_each_member_device(ca, c, i, NULL)
-               if (bch2_dev_sysfs_online(c, ca))
+       for_each_member_device(ca, c, i)
+               if (bch2_dev_sysfs_online(c, ca)) {
+                       percpu_ref_put(&ca->ref);
                        goto err;
+               }
 
        list_add(&c->list, &bch_fs_list);
        err = NULL;
@@ -1841,12 +1843,14 @@ struct bch_dev *bch2_dev_lookup(struct bch_fs *c, const char *path)
        if (ret)
                return ERR_PTR(ret);
 
-       for_each_member_device(ca, c, i)
+       rcu_read_lock();
+       for_each_member_device_rcu(ca, c, i, NULL)
                if (ca->disk_sb.bdev->bd_dev == dev)
                        goto found;
-
        ca = ERR_PTR(-ENOENT);
 found:
+       rcu_read_unlock();
+
        return ca;
 }
 
index 6cab506150a86eebc9603a040e1031188244b089..739e8fd181763c3298d20c52df5c0cbf21d5868e 100644 (file)
@@ -107,11 +107,8 @@ static inline struct bch_dev *__bch2_next_dev(struct bch_fs *c, unsigned *iter,
        return ca;
 }
 
-#define __for_each_member_device(ca, c, iter, mask)                    \
-       for ((iter) = 0; ((ca) = __bch2_next_dev((c), &(iter), mask)); (iter)++)
-
 #define for_each_member_device_rcu(ca, c, iter, mask)                  \
-       __for_each_member_device(ca, c, iter, mask)
+       for ((iter) = 0; ((ca) = __bch2_next_dev((c), &(iter), mask)); (iter)++)
 
 static inline struct bch_dev *bch2_get_next_dev(struct bch_fs *c, unsigned *iter)
 {