mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-22 00:00:03 +03:00
Update bcachefs sources to b6d5426551 bcachefs: Fix bch2_btree_iter_peek_with_updates()
This commit is contained in:
parent
7942d5cab4
commit
bf14597460
@ -1 +1 @@
|
||||
a5c0e1bb306e79b40b2432a22f164697c8b22110
|
||||
b6d54265513ceb7532e3983163338c1ad28a0284
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user