mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +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);
|
ret = bch2_alloc_write_key(&trans, iter, flags);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
percpu_ref_put(&ca->io_ref);
|
percpu_ref_put(&ca->ref);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
bch2_btree_iter_next_slot(iter);
|
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,
|
static int bch2_gc_done(struct bch_fs *c,
|
||||||
bool initial, bool metadata_only)
|
bool initial, bool metadata_only)
|
||||||
{
|
{
|
||||||
struct bch_dev *ca;
|
struct bch_dev *ca = NULL;
|
||||||
bool verify = !metadata_only && (!initial ||
|
bool verify = !metadata_only && (!initial ||
|
||||||
(c->sb.compat & (1ULL << BCH_COMPAT_alloc_info)));
|
(c->sb.compat & (1ULL << BCH_COMPAT_alloc_info)));
|
||||||
unsigned i, dev;
|
unsigned i, dev;
|
||||||
@ -1166,6 +1166,8 @@ static int bch2_gc_done(struct bch_fs *c,
|
|||||||
#undef copy_stripe_field
|
#undef copy_stripe_field
|
||||||
#undef copy_field
|
#undef copy_field
|
||||||
fsck_err:
|
fsck_err:
|
||||||
|
if (ca)
|
||||||
|
percpu_ref_put(&ca->ref);
|
||||||
if (ret)
|
if (ret)
|
||||||
bch_err(c, "%s: ret %i", __func__, ret);
|
bch_err(c, "%s: ret %i", __func__, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -1174,7 +1176,7 @@ fsck_err:
|
|||||||
static int bch2_gc_start(struct bch_fs *c,
|
static int bch2_gc_start(struct bch_fs *c,
|
||||||
bool metadata_only)
|
bool metadata_only)
|
||||||
{
|
{
|
||||||
struct bch_dev *ca;
|
struct bch_dev *ca = NULL;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int ret;
|
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: */
|
/* bch2_varint_decode may read up to 7 bytes past the end of the buffer: */
|
||||||
bytes += 8;
|
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);
|
data = btree_bounce_alloc(c, bytes, &used_mempool);
|
||||||
|
|
||||||
if (!b->written) {
|
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)
|
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 bpos search_key = btree_iter_search_key(iter);
|
||||||
struct bkey_i *next_update = with_updates
|
struct bkey_i *next_update;
|
||||||
? btree_trans_peek_updates(iter->trans, iter->btree_id, search_key)
|
|
||||||
: NULL;
|
|
||||||
struct bkey_s_c k;
|
struct bkey_s_c k;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
|
EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
|
||||||
bch2_btree_iter_verify(iter);
|
bch2_btree_iter_verify(iter);
|
||||||
bch2_btree_iter_verify_entry_exit(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);
|
btree_iter_set_search_pos(iter, search_key);
|
||||||
|
|
||||||
while (1) {
|
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 (likely(k.k)) {
|
||||||
if (bkey_deleted(k.k)) {
|
if (bkey_deleted(k.k)) {
|
||||||
btree_iter_set_search_pos(iter,
|
search_key = bkey_successor(iter, k.k->p);
|
||||||
bkey_successor(iter, k.k->p));
|
goto start;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
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,
|
static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
|
||||||
struct bkey_s_c_reflink_p p,
|
struct bkey_s_c_reflink_p p,
|
||||||
u64 idx, unsigned sectors,
|
u64 idx, unsigned sectors,
|
||||||
|
unsigned front_frag,
|
||||||
|
unsigned back_frag,
|
||||||
unsigned flags)
|
unsigned flags)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
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_s_c k;
|
||||||
struct bkey_i *n;
|
struct bkey_i *n;
|
||||||
__le64 *refcount;
|
__le64 *refcount;
|
||||||
|
int add = !(flags & BTREE_TRIGGER_OVERWRITE) ? 1 : -1;
|
||||||
s64 ret;
|
s64 ret;
|
||||||
|
|
||||||
ret = trans_get_key(trans, BTREE_ID_reflink,
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((flags & BTREE_TRIGGER_OVERWRITE) &&
|
if (reflink_p_frag_references(p, 0, front_frag, k) &&
|
||||||
(bkey_start_offset(k.k) < idx ||
|
reflink_p_frag_references(p, back_frag, p.k->size, k)) {
|
||||||
k.k->p.offset > idx + sectors))
|
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;
|
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));
|
n = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
|
||||||
ret = PTR_ERR_OR_ZERO(n);
|
ret = PTR_ERR_OR_ZERO(n);
|
||||||
@ -1747,7 +1772,8 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
|
|||||||
goto err;
|
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) {
|
if (!*refcount) {
|
||||||
n->k.type = KEY_TYPE_deleted;
|
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)
|
s64 sectors, unsigned flags)
|
||||||
{
|
{
|
||||||
u64 idx = le64_to_cpu(p.v->idx) + offset;
|
u64 idx = le64_to_cpu(p.v->idx) + offset;
|
||||||
|
unsigned front_frag, back_frag;
|
||||||
s64 ret = 0;
|
s64 ret = 0;
|
||||||
|
|
||||||
sectors = abs(sectors);
|
sectors = abs(sectors);
|
||||||
BUG_ON(offset + sectors > p.k->size);
|
BUG_ON(offset + sectors > p.k->size);
|
||||||
|
|
||||||
|
front_frag = offset;
|
||||||
|
back_frag = offset + sectors;
|
||||||
|
|
||||||
while (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)
|
if (ret < 0)
|
||||||
break;
|
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)
|
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));
|
__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 &&
|
if (k.k->type != KEY_TYPE_reflink_v &&
|
||||||
k.k->type != KEY_TYPE_indirect_inline_data) {
|
k.k->type != KEY_TYPE_indirect_inline_data) {
|
||||||
bch_err_inum_ratelimited(trans->c, orig_k->k->k.p.inode,
|
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);
|
bch2_inconsistent_error(trans->c);
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto err;
|
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
|
* Hence, we want update/set last_seq on the current journal entry right
|
||||||
* before we open a new one:
|
* 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));
|
__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));
|
bch2_bkey_devs(bkey_i_to_s_c(&w->key));
|
||||||
struct bch_replicas_padded replicas;
|
struct bch_replicas_padded replicas;
|
||||||
union journal_res_state old, new;
|
union journal_res_state old, new;
|
||||||
u64 v, seq, last_seq;
|
u64 v, seq;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
bch2_time_stats_update(j->write_time, j->write_start_time);
|
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);
|
spin_lock(&j->lock);
|
||||||
seq = le64_to_cpu(w->data->seq);
|
seq = le64_to_cpu(w->data->seq);
|
||||||
last_seq = le64_to_cpu(w->data->last_seq);
|
|
||||||
|
|
||||||
if (seq >= j->pin.front)
|
if (seq >= j->pin.front)
|
||||||
journal_seq_pin(j, seq)->devs = devs;
|
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)) {
|
if (!JSET_NO_FLUSH(w->data)) {
|
||||||
j->flushed_seq_ondisk = seq;
|
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)) {
|
test_bit(JOURNAL_MAY_SKIP_FLUSH, &j->flags)) {
|
||||||
w->noflush = true;
|
w->noflush = true;
|
||||||
SET_JSET_NO_FLUSH(jset, true);
|
SET_JSET_NO_FLUSH(jset, true);
|
||||||
jset->last_seq = 0;
|
jset->last_seq = w->last_seq = 0;
|
||||||
|
|
||||||
j->nr_noflush_writes++;
|
j->nr_noflush_writes++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,6 +23,7 @@ struct journal_buf {
|
|||||||
__BKEY_PADDED(key, BCH_REPLICAS_MAX);
|
__BKEY_PADDED(key, BCH_REPLICAS_MAX);
|
||||||
|
|
||||||
struct closure_waitlist wait;
|
struct closure_waitlist wait;
|
||||||
|
u64 last_seq; /* copy of data->last_seq */
|
||||||
|
|
||||||
unsigned buf_size; /* size in bytes of @data */
|
unsigned buf_size; /* size in bytes of @data */
|
||||||
unsigned sectors; /* maximum size for current entry */
|
unsigned sectors; /* maximum size for current entry */
|
||||||
|
@ -1328,9 +1328,11 @@ int bch2_fs_initialize(struct bch_fs *c)
|
|||||||
err = "error marking superblock and journal";
|
err = "error marking superblock and journal";
|
||||||
for_each_member_device(ca, c, i) {
|
for_each_member_device(ca, c, i) {
|
||||||
ret = bch2_trans_mark_dev_sb(c, ca);
|
ret = bch2_trans_mark_dev_sb(c, ca);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
percpu_ref_put(&ca->ref);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bch2_inode_init(c, &root_inode, 0, 0,
|
bch2_inode_init(c, &root_inode, 0, 0,
|
||||||
S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0, NULL);
|
S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0, 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 */
|
|
@ -627,9 +627,11 @@ static const char *bch2_fs_online(struct bch_fs *c)
|
|||||||
down_write(&c->state_lock);
|
down_write(&c->state_lock);
|
||||||
|
|
||||||
err = "error creating sysfs objects";
|
err = "error creating sysfs objects";
|
||||||
__for_each_member_device(ca, c, i, NULL)
|
for_each_member_device(ca, c, i)
|
||||||
if (bch2_dev_sysfs_online(c, ca))
|
if (bch2_dev_sysfs_online(c, ca)) {
|
||||||
|
percpu_ref_put(&ca->ref);
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
list_add(&c->list, &bch_fs_list);
|
list_add(&c->list, &bch_fs_list);
|
||||||
err = NULL;
|
err = NULL;
|
||||||
@ -1841,12 +1843,14 @@ struct bch_dev *bch2_dev_lookup(struct bch_fs *c, const char *path)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ERR_PTR(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)
|
if (ca->disk_sb.bdev->bd_dev == dev)
|
||||||
goto found;
|
goto found;
|
||||||
|
|
||||||
ca = ERR_PTR(-ENOENT);
|
ca = ERR_PTR(-ENOENT);
|
||||||
found:
|
found:
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
return ca;
|
return ca;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,11 +107,8 @@ static inline struct bch_dev *__bch2_next_dev(struct bch_fs *c, unsigned *iter,
|
|||||||
return ca;
|
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) \
|
#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)
|
static inline struct bch_dev *bch2_get_next_dev(struct bch_fs *c, unsigned *iter)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user