Skip to content

Commit 74d8fc2

Browse files
committed
Merge tag 'bcachefs-2023-12-19' of https://evilpiepirate.org/git/bcachefs
Pull more bcachefs fixes from Kent Overstreet: - Fix a deadlock in the data move path with nocow locks (vs. update in place writes); when trylock failed we were incorrectly waiting for in flight ios to flush. - Fix reporting of NFS file handle length - Fix early error path in bch2_fs_alloc() - list head wasn't being initialized early enough - Make sure correct (hardware accelerated) crc modules get loaded - Fix a rare overflow in the btree split path, when the packed bkey format grows and all the keys have no value (LRU btree). - Fix error handling in the sector allocator This was causing writes to spuriously fail in multidevice setups, and another bug meant that the errors weren't being logged, only reported via fsync. * tag 'bcachefs-2023-12-19' of https://evilpiepirate.org/git/bcachefs: bcachefs: Fix bch2_alloc_sectors_start_trans() error handling bcachefs; guard against overflow in btree node split bcachefs: btree_node_u64s_with_format() takes nr keys bcachefs: print explicit recovery pass message only once bcachefs: improve modprobe support by providing softdeps bcachefs: fix invalid memory access in bch2_fs_alloc() error path bcachefs: Fix determining required file handle length bcachefs: Fix nocow locks deadlock
2 parents ac1c13e + 247ce5f commit 74d8fc2

File tree

9 files changed

+70
-28
lines changed

9 files changed

+70
-28
lines changed

fs/bcachefs/alloc_foreground.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,8 +1374,17 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans,
13741374
goto alloc_done;
13751375

13761376
/* Don't retry from all devices if we're out of open buckets: */
1377-
if (bch2_err_matches(ret, BCH_ERR_open_buckets_empty))
1378-
goto allocate_blocking;
1377+
if (bch2_err_matches(ret, BCH_ERR_open_buckets_empty)) {
1378+
int ret = open_bucket_add_buckets(trans, &ptrs, wp, devs_have,
1379+
target, erasure_code,
1380+
nr_replicas, &nr_effective,
1381+
&have_cache, watermark,
1382+
flags, cl);
1383+
if (!ret ||
1384+
bch2_err_matches(ret, BCH_ERR_transaction_restart) ||
1385+
bch2_err_matches(ret, BCH_ERR_open_buckets_empty))
1386+
goto alloc_done;
1387+
}
13791388

13801389
/*
13811390
* Only try to allocate cache (durability = 0 devices) from the
@@ -1389,7 +1398,6 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans,
13891398
&have_cache, watermark,
13901399
flags, cl);
13911400
} else {
1392-
allocate_blocking:
13931401
ret = open_bucket_add_buckets(trans, &ptrs, wp, devs_have,
13941402
target, erasure_code,
13951403
nr_replicas, &nr_effective,

fs/bcachefs/btree_iter.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,10 +3214,9 @@ void bch2_fs_btree_iter_exit(struct bch_fs *c)
32143214
mempool_exit(&c->btree_trans_pool);
32153215
}
32163216

3217-
int bch2_fs_btree_iter_init(struct bch_fs *c)
3217+
void bch2_fs_btree_iter_init_early(struct bch_fs *c)
32183218
{
32193219
struct btree_transaction_stats *s;
3220-
int ret;
32213220

32223221
for (s = c->btree_transaction_stats;
32233222
s < c->btree_transaction_stats + ARRAY_SIZE(c->btree_transaction_stats);
@@ -3228,6 +3227,11 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
32283227

32293228
INIT_LIST_HEAD(&c->btree_trans_list);
32303229
seqmutex_init(&c->btree_trans_lock);
3230+
}
3231+
3232+
int bch2_fs_btree_iter_init(struct bch_fs *c)
3233+
{
3234+
int ret;
32313235

32323236
c->btree_trans_bufs = alloc_percpu(struct btree_trans_buf);
32333237
if (!c->btree_trans_bufs)

fs/bcachefs/btree_iter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,7 @@ unsigned bch2_trans_get_fn_idx(const char *);
938938
void bch2_btree_trans_to_text(struct printbuf *, struct btree_trans *);
939939

940940
void bch2_fs_btree_iter_exit(struct bch_fs *);
941+
void bch2_fs_btree_iter_init_early(struct bch_fs *);
941942
int bch2_fs_btree_iter_init(struct bch_fs *);
942943

943944
#endif /* _BCACHEFS_BTREE_ITER_H */

fs/bcachefs/btree_update_interior.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static void btree_node_interior_verify(struct bch_fs *c, struct btree *b)
9999

100100
/* Calculate ideal packed bkey format for new btree nodes: */
101101

102-
void __bch2_btree_calc_format(struct bkey_format_state *s, struct btree *b)
102+
static void __bch2_btree_calc_format(struct bkey_format_state *s, struct btree *b)
103103
{
104104
struct bkey_packed *k;
105105
struct bset_tree *t;
@@ -125,38 +125,39 @@ static struct bkey_format bch2_btree_calc_format(struct btree *b)
125125
return bch2_bkey_format_done(&s);
126126
}
127127

128-
static size_t btree_node_u64s_with_format(struct btree *b,
128+
static size_t btree_node_u64s_with_format(struct btree_nr_keys nr,
129+
struct bkey_format *old_f,
129130
struct bkey_format *new_f)
130131
{
131-
struct bkey_format *old_f = &b->format;
132-
133132
/* stupid integer promotion rules */
134133
ssize_t delta =
135134
(((int) new_f->key_u64s - old_f->key_u64s) *
136-
(int) b->nr.packed_keys) +
135+
(int) nr.packed_keys) +
137136
(((int) new_f->key_u64s - BKEY_U64s) *
138-
(int) b->nr.unpacked_keys);
137+
(int) nr.unpacked_keys);
139138

140-
BUG_ON(delta + b->nr.live_u64s < 0);
139+
BUG_ON(delta + nr.live_u64s < 0);
141140

142-
return b->nr.live_u64s + delta;
141+
return nr.live_u64s + delta;
143142
}
144143

145144
/**
146145
* bch2_btree_node_format_fits - check if we could rewrite node with a new format
147146
*
148147
* @c: filesystem handle
149148
* @b: btree node to rewrite
149+
* @nr: number of keys for new node (i.e. b->nr)
150150
* @new_f: bkey format to translate keys to
151151
*
152152
* Returns: true if all re-packed keys will be able to fit in a new node.
153153
*
154154
* Assumes all keys will successfully pack with the new format.
155155
*/
156-
bool bch2_btree_node_format_fits(struct bch_fs *c, struct btree *b,
156+
static bool bch2_btree_node_format_fits(struct bch_fs *c, struct btree *b,
157+
struct btree_nr_keys nr,
157158
struct bkey_format *new_f)
158159
{
159-
size_t u64s = btree_node_u64s_with_format(b, new_f);
160+
size_t u64s = btree_node_u64s_with_format(nr, &b->format, new_f);
160161

161162
return __vstruct_bytes(struct btree_node, u64s) < btree_bytes(c);
162163
}
@@ -391,7 +392,7 @@ static struct btree *bch2_btree_node_alloc_replacement(struct btree_update *as,
391392
* The keys might expand with the new format - if they wouldn't fit in
392393
* the btree node anymore, use the old format for now:
393394
*/
394-
if (!bch2_btree_node_format_fits(as->c, b, &format))
395+
if (!bch2_btree_node_format_fits(as->c, b, b->nr, &format))
395396
format = b->format;
396397

397398
SET_BTREE_NODE_SEQ(n->data, BTREE_NODE_SEQ(b->data) + 1);
@@ -1345,8 +1346,11 @@ static void __btree_split_node(struct btree_update *as,
13451346
struct bkey_packed *out[2];
13461347
struct bkey uk;
13471348
unsigned u64s, n1_u64s = (b->nr.live_u64s * 3) / 5;
1349+
struct { unsigned nr_keys, val_u64s; } nr_keys[2];
13481350
int i;
13491351

1352+
memset(&nr_keys, 0, sizeof(nr_keys));
1353+
13501354
for (i = 0; i < 2; i++) {
13511355
BUG_ON(n[i]->nsets != 1);
13521356

@@ -1368,6 +1372,9 @@ static void __btree_split_node(struct btree_update *as,
13681372
if (!i)
13691373
n1_pos = uk.p;
13701374
bch2_bkey_format_add_key(&format[i], &uk);
1375+
1376+
nr_keys[i].nr_keys++;
1377+
nr_keys[i].val_u64s += bkeyp_val_u64s(&b->format, k);
13711378
}
13721379

13731380
btree_set_min(n[0], b->data->min_key);
@@ -1380,6 +1387,12 @@ static void __btree_split_node(struct btree_update *as,
13801387
bch2_bkey_format_add_pos(&format[i], n[i]->data->max_key);
13811388

13821389
n[i]->data->format = bch2_bkey_format_done(&format[i]);
1390+
1391+
unsigned u64s = nr_keys[i].nr_keys * n[i]->data->format.key_u64s +
1392+
nr_keys[i].val_u64s;
1393+
if (__vstruct_bytes(struct btree_node, u64s) > btree_bytes(as->c))
1394+
n[i]->data->format = b->format;
1395+
13831396
btree_node_set_format(n[i], n[i]->data->format);
13841397
}
13851398

@@ -1822,8 +1835,8 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
18221835
bch2_bkey_format_add_pos(&new_s, next->data->max_key);
18231836
new_f = bch2_bkey_format_done(&new_s);
18241837

1825-
sib_u64s = btree_node_u64s_with_format(b, &new_f) +
1826-
btree_node_u64s_with_format(m, &new_f);
1838+
sib_u64s = btree_node_u64s_with_format(b->nr, &b->format, &new_f) +
1839+
btree_node_u64s_with_format(m->nr, &m->format, &new_f);
18271840

18281841
if (sib_u64s > BTREE_FOREGROUND_MERGE_HYSTERESIS(c)) {
18291842
sib_u64s -= BTREE_FOREGROUND_MERGE_HYSTERESIS(c);

fs/bcachefs/btree_update_interior.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
#include "btree_locking.h"
77
#include "btree_update.h"
88

9-
void __bch2_btree_calc_format(struct bkey_format_state *, struct btree *);
10-
bool bch2_btree_node_format_fits(struct bch_fs *c, struct btree *,
11-
struct bkey_format *);
12-
139
#define BTREE_UPDATE_NODES_MAX ((BTREE_MAX_DEPTH - 2) * 2 + GC_MERGE_NODES)
1410

1511
#define BTREE_UPDATE_JOURNAL_RES (BTREE_UPDATE_NODES_MAX * (BKEY_BTREE_PTR_U64s_MAX + 1))

fs/bcachefs/data_update.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,8 @@ int bch2_data_update_init(struct btree_trans *trans,
560560
move_ctxt_wait_event(ctxt,
561561
(locked = bch2_bucket_nocow_trylock(&c->nocow_locks,
562562
PTR_BUCKET_POS(c, &p.ptr), 0)) ||
563-
!atomic_read(&ctxt->read_sectors));
563+
(!atomic_read(&ctxt->read_sectors) &&
564+
!atomic_read(&ctxt->write_sectors)));
564565

565566
if (!locked)
566567
bch2_bucket_nocow_lock(&c->nocow_locks,

fs/bcachefs/fs.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,24 +1143,33 @@ static int bch2_encode_fh(struct inode *vinode, u32 *fh, int *len,
11431143
{
11441144
struct bch_inode_info *inode = to_bch_ei(vinode);
11451145
struct bch_inode_info *dir = to_bch_ei(vdir);
1146-
1147-
if (*len < sizeof(struct bcachefs_fid_with_parent) / sizeof(u32))
1148-
return FILEID_INVALID;
1146+
int min_len;
11491147

11501148
if (!S_ISDIR(inode->v.i_mode) && dir) {
11511149
struct bcachefs_fid_with_parent *fid = (void *) fh;
11521150

1151+
min_len = sizeof(*fid) / sizeof(u32);
1152+
if (*len < min_len) {
1153+
*len = min_len;
1154+
return FILEID_INVALID;
1155+
}
1156+
11531157
fid->fid = bch2_inode_to_fid(inode);
11541158
fid->dir = bch2_inode_to_fid(dir);
11551159

1156-
*len = sizeof(*fid) / sizeof(u32);
1160+
*len = min_len;
11571161
return FILEID_BCACHEFS_WITH_PARENT;
11581162
} else {
11591163
struct bcachefs_fid *fid = (void *) fh;
11601164

1165+
min_len = sizeof(*fid) / sizeof(u32);
1166+
if (*len < min_len) {
1167+
*len = min_len;
1168+
return FILEID_INVALID;
1169+
}
11611170
*fid = bch2_inode_to_fid(inode);
11621171

1163-
*len = sizeof(*fid) / sizeof(u32);
1172+
*len = min_len;
11641173
return FILEID_BCACHEFS_WITHOUT_PARENT;
11651174
}
11661175
}

fs/bcachefs/recovery.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ extern const char * const bch2_recovery_passes[];
1010
static inline int bch2_run_explicit_recovery_pass(struct bch_fs *c,
1111
enum bch_recovery_pass pass)
1212
{
13+
if (c->recovery_passes_explicit & BIT_ULL(pass))
14+
return 0;
15+
1316
bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)",
1417
bch2_recovery_passes[pass], pass,
1518
bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass);

fs/bcachefs/super.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@
7272
MODULE_LICENSE("GPL");
7373
MODULE_AUTHOR("Kent Overstreet <[email protected]>");
7474
MODULE_DESCRIPTION("bcachefs filesystem");
75+
MODULE_SOFTDEP("pre: crc32c");
76+
MODULE_SOFTDEP("pre: crc64");
77+
MODULE_SOFTDEP("pre: sha256");
78+
MODULE_SOFTDEP("pre: chacha20");
79+
MODULE_SOFTDEP("pre: poly1305");
80+
MODULE_SOFTDEP("pre: xxhash");
7581

7682
#define KTYPE(type) \
7783
static const struct attribute_group type ## _group = { \
@@ -714,6 +720,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
714720

715721
bch2_fs_copygc_init(c);
716722
bch2_fs_btree_key_cache_init_early(&c->btree_key_cache);
723+
bch2_fs_btree_iter_init_early(c);
717724
bch2_fs_btree_interior_update_init_early(c);
718725
bch2_fs_allocator_background_init(c);
719726
bch2_fs_allocator_foreground_init(c);

0 commit comments

Comments
 (0)