From bf145974607928c32c14d27c5c57e1220cad195d Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Fri, 7 May 2021 23:48:50 -0400 Subject: [PATCH] Update bcachefs sources to b6d5426551 bcachefs: Fix bch2_btree_iter_peek_with_updates() --- .bcachefs_revision | 2 +- libbcachefs/alloc_background.c | 2 +- libbcachefs/btree_gc.c | 6 +++-- libbcachefs/btree_io.c | 3 +++ libbcachefs/btree_iter.c | 14 +++++------ libbcachefs/buckets.c | 45 ++++++++++++++++++++++++++++------ libbcachefs/io.c | 5 +++- libbcachefs/journal.c | 3 ++- libbcachefs/journal_io.c | 7 +++--- libbcachefs/journal_types.h | 1 + libbcachefs/recovery.c | 4 ++- libbcachefs/s128.h | 29 ---------------------- libbcachefs/super.c | 12 ++++++--- libbcachefs/super.h | 5 +--- 14 files changed, 76 insertions(+), 62 deletions(-) delete mode 100644 libbcachefs/s128.h diff --git a/.bcachefs_revision b/.bcachefs_revision index 7ceb5bb5..80991d76 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -a5c0e1bb306e79b40b2432a22f164697c8b22110 +b6d54265513ceb7532e3983163338c1ad28a0284 diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c index 3ac8b030..da634739 100644 --- a/libbcachefs/alloc_background.c +++ b/libbcachefs/alloc_background.c @@ -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); diff --git a/libbcachefs/btree_gc.c b/libbcachefs/btree_gc.c index 24fa279d..ec6eb106 100644 --- a/libbcachefs/btree_gc.c +++ b/libbcachefs/btree_gc.c @@ -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; diff --git a/libbcachefs/btree_io.c b/libbcachefs/btree_io.c index e609bc49..094285bd 100644 --- a/libbcachefs/btree_io.c +++ b/libbcachefs/btree_io.c @@ -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) { diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c index cdec05c8..6bac80ae 100644 --- a/libbcachefs/btree_iter.c +++ b/libbcachefs/btree_iter.c @@ -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; diff --git a/libbcachefs/buckets.c b/libbcachefs/buckets.c index 70008603..87266179 100644 --- a/libbcachefs/buckets.c +++ b/libbcachefs/buckets.c @@ -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)); } diff --git a/libbcachefs/io.c b/libbcachefs/io.c index d1a62399..7d0035d8 100644 --- a/libbcachefs/io.c +++ b/libbcachefs/io.c @@ -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; diff --git a/libbcachefs/journal.c b/libbcachefs/journal.c index c2773126..1400774e 100644 --- a/libbcachefs/journal.c +++ b/libbcachefs/journal.c @@ -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)); diff --git a/libbcachefs/journal_io.c b/libbcachefs/journal_io.c index c7fa03cf..635cceb4 100644 --- a/libbcachefs/journal_io.c +++ b/libbcachefs/journal_io.c @@ -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 { diff --git a/libbcachefs/journal_types.h b/libbcachefs/journal_types.h index a7aa12e9..cacab22a 100644 --- a/libbcachefs/journal_types.h +++ b/libbcachefs/journal_types.h @@ -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 */ diff --git a/libbcachefs/recovery.c b/libbcachefs/recovery.c index b35b297d..cd538ecc 100644 --- a/libbcachefs/recovery.c +++ b/libbcachefs/recovery.c @@ -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 index 6d775543..00000000 --- a/libbcachefs/s128.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _BCACHEFS_S128_H -#define _BCACHEFS_S128_H - -#include - -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 */ diff --git a/libbcachefs/super.c b/libbcachefs/super.c index bbd313a4..e5936041 100644 --- a/libbcachefs/super.c +++ b/libbcachefs/super.c @@ -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; } diff --git a/libbcachefs/super.h b/libbcachefs/super.h index 6cab5061..739e8fd1 100644 --- a/libbcachefs/super.h +++ b/libbcachefs/super.h @@ -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) {