Update bcachefs sources to b6d5426551 bcachefs: Fix bch2_btree_iter_peek_with_updates()

This commit is contained in:
Kent Overstreet 2021-05-07 23:48:50 -04:00
parent 7942d5cab4
commit bf14597460
14 changed files with 76 additions and 62 deletions

View File

@ -1 +1 @@
a5c0e1bb306e79b40b2432a22f164697c8b22110
b6d54265513ceb7532e3983163338c1ad28a0284

View 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);

View 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;

View 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) {

View 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;

View 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));
}

View 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;

View 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));

View 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 {

View 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 */

View 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,

View File

@ -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 */

View 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;
}

View 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)
{