Skip to content

Commit 8f60227

Browse files
committed
Merge tag 'bcachefs-2024-10-05' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet: "A lot of little fixes, bigger ones include: - bcachefs's __wait_on_freeing_inode() was broken in rc1 due to vfs changes, now fixed along with another lost wakeup - fragmentation LRU fixes; fsck now repairs successfully (this is the data structure copygc uses); along with some nice simplification. - Rework logged op error handling, so that if logged op replay errors (due to another filesystem error) we delete the logged op instead of going into an infinite loop) - Various small filesystem connectivitity repair fixes" * tag 'bcachefs-2024-10-05' of git://evilpiepirate.org/bcachefs: bcachefs: Rework logged op error handling bcachefs: Add warn param to subvol_get_snapshot, peek_inode bcachefs: Kill snapshot arg to fsck_write_inode() bcachefs: Check for unlinked, non-empty dirs in check_inode() bcachefs: Check for unlinked inodes with dirents bcachefs: Check for directories with no backpointers bcachefs: Kill alloc_v4.fragmentation_lru bcachefs: minor lru fsck fixes bcachefs: Mark more errors AUTOFIX bcachefs: Make sure we print error that causes fsck to bail out bcachefs: bkey errors are only AUTOFIX during read bcachefs: Create lost+found in correct snapshot bcachefs: Fix reattach_inode() bcachefs: Add missing wakeup to bch2_inode_hash_remove() bcachefs: Fix trans_commit disk accounting revert bcachefs: Fix bch2_inode_is_open() check bcachefs: Fix return type of dirent_points_to_inode_nowarn() bcachefs: Fix bad shift in bch2_read_flag_list()
2 parents fc20a3e + 0f25eb4 commit 8f60227

20 files changed

+342
-209
lines changed

fs/bcachefs/alloc_background.c

+20-10
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ void bch2_alloc_v4_swab(struct bkey_s k)
332332
a->io_time[1] = swab64(a->io_time[1]);
333333
a->stripe = swab32(a->stripe);
334334
a->nr_external_backpointers = swab32(a->nr_external_backpointers);
335-
a->fragmentation_lru = swab64(a->fragmentation_lru);
336335
a->stripe_sectors = swab32(a->stripe_sectors);
337336

338337
bps = alloc_v4_backpointers(a);
@@ -347,6 +346,7 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
347346
{
348347
struct bch_alloc_v4 _a;
349348
const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a);
349+
struct bch_dev *ca = c ? bch2_dev_bucket_tryget_noerror(c, k.k->p) : NULL;
350350

351351
prt_newline(out);
352352
printbuf_indent_add(out, 2);
@@ -364,9 +364,13 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
364364
prt_printf(out, "stripe_redundancy %u\n", a->stripe_redundancy);
365365
prt_printf(out, "io_time[READ] %llu\n", a->io_time[READ]);
366366
prt_printf(out, "io_time[WRITE] %llu\n", a->io_time[WRITE]);
367-
prt_printf(out, "fragmentation %llu\n", a->fragmentation_lru);
367+
368+
if (ca)
369+
prt_printf(out, "fragmentation %llu\n", alloc_lru_idx_fragmentation(*a, ca));
368370
prt_printf(out, "bp_start %llu\n", BCH_ALLOC_V4_BACKPOINTERS_START(a));
369371
printbuf_indent_sub(out, 2);
372+
373+
bch2_dev_put(ca);
370374
}
371375

372376
void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out)
@@ -882,12 +886,13 @@ int bch2_trigger_alloc(struct btree_trans *trans,
882886
goto err;
883887
}
884888

885-
new_a->fragmentation_lru = alloc_lru_idx_fragmentation(*new_a, ca);
886-
if (old_a->fragmentation_lru != new_a->fragmentation_lru) {
889+
old_lru = alloc_lru_idx_fragmentation(*old_a, ca);
890+
new_lru = alloc_lru_idx_fragmentation(*new_a, ca);
891+
if (old_lru != new_lru) {
887892
ret = bch2_lru_change(trans,
888893
BCH_LRU_FRAGMENTATION_START,
889894
bucket_to_u64(new.k->p),
890-
old_a->fragmentation_lru, new_a->fragmentation_lru);
895+
old_lru, new_lru);
891896
if (ret)
892897
goto err;
893898
}
@@ -1629,18 +1634,22 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
16291634
if (ret)
16301635
return ret;
16311636

1637+
struct bch_dev *ca = bch2_dev_tryget_noerror(c, alloc_k.k->p.inode);
1638+
if (!ca)
1639+
return 0;
1640+
16321641
a = bch2_alloc_to_v4(alloc_k, &a_convert);
16331642

1634-
if (a->fragmentation_lru) {
1643+
u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca);
1644+
if (lru_idx) {
16351645
ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START,
1636-
a->fragmentation_lru,
1637-
alloc_k, last_flushed);
1646+
lru_idx, alloc_k, last_flushed);
16381647
if (ret)
1639-
return ret;
1648+
goto err;
16401649
}
16411650

16421651
if (a->data_type != BCH_DATA_cached)
1643-
return 0;
1652+
goto err;
16441653

16451654
if (fsck_err_on(!a->io_time[READ],
16461655
trans, alloc_key_cached_but_read_time_zero,
@@ -1669,6 +1678,7 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
16691678
goto err;
16701679
err:
16711680
fsck_err:
1681+
bch2_dev_put(ca);
16721682
printbuf_exit(&buf);
16731683
return ret;
16741684
}

fs/bcachefs/alloc_background_format.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct bch_alloc_v4 {
7070
__u32 stripe;
7171
__u32 nr_external_backpointers;
7272
/* end of fields in original version of alloc_v4 */
73-
__u64 fragmentation_lru;
73+
__u64 _fragmentation_lru; /* obsolete */
7474
__u32 stripe_sectors;
7575
__u32 pad;
7676
} __packed __aligned(8);

fs/bcachefs/btree_gc.c

-3
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
828828
return ret;
829829
}
830830

831-
gc.fragmentation_lru = alloc_lru_idx_fragmentation(gc, ca);
832-
833831
if (fsck_err_on(new.data_type != gc.data_type,
834832
trans, alloc_key_data_type_wrong,
835833
"bucket %llu:%llu gen %u has wrong data_type"
@@ -857,7 +855,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
857855
copy_bucket_field(alloc_key_cached_sectors_wrong, cached_sectors);
858856
copy_bucket_field(alloc_key_stripe_wrong, stripe);
859857
copy_bucket_field(alloc_key_stripe_redundancy_wrong, stripe_redundancy);
860-
copy_bucket_field(alloc_key_fragmentation_lru_wrong, fragmentation_lru);
861858
#undef copy_bucket_field
862859

863860
if (!bch2_alloc_v4_cmp(*old, new))

fs/bcachefs/btree_trans_commit.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,8 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
832832
for (struct jset_entry *entry2 = trans->journal_entries;
833833
entry2 != entry;
834834
entry2 = vstruct_next(entry2))
835-
if (jset_entry_is_key(entry2) && entry2->start->k.type == KEY_TYPE_accounting) {
835+
if (entry2->type == BCH_JSET_ENTRY_write_buffer_keys &&
836+
entry2->start->k.type == KEY_TYPE_accounting) {
836837
struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start);
837838

838839
bch2_accounting_neg(a);

fs/bcachefs/error.c

+18-5
Original file line numberDiff line numberDiff line change
@@ -393,16 +393,22 @@ int __bch2_fsck_err(struct bch_fs *c,
393393
!(flags & FSCK_CAN_IGNORE)))
394394
ret = -BCH_ERR_fsck_errors_not_fixed;
395395

396+
bool exiting =
397+
test_bit(BCH_FS_fsck_running, &c->flags) &&
398+
(ret != -BCH_ERR_fsck_fix &&
399+
ret != -BCH_ERR_fsck_ignore);
400+
401+
if (exiting)
402+
print = true;
403+
396404
if (print) {
397405
if (bch2_fs_stdio_redirect(c))
398406
bch2_print(c, "%s\n", out->buf);
399407
else
400408
bch2_print_string_as_lines(KERN_ERR, out->buf);
401409
}
402410

403-
if (test_bit(BCH_FS_fsck_running, &c->flags) &&
404-
(ret != -BCH_ERR_fsck_fix &&
405-
ret != -BCH_ERR_fsck_ignore))
411+
if (exiting)
406412
bch_err(c, "Unable to continue, halting");
407413
else if (suppressing)
408414
bch_err(c, "Ratelimiting new instances of previous error");
@@ -430,10 +436,17 @@ int __bch2_fsck_err(struct bch_fs *c,
430436

431437
int __bch2_bkey_fsck_err(struct bch_fs *c,
432438
struct bkey_s_c k,
433-
enum bch_fsck_flags flags,
439+
enum bch_validate_flags validate_flags,
434440
enum bch_sb_error_id err,
435441
const char *fmt, ...)
436442
{
443+
if (validate_flags & BCH_VALIDATE_silent)
444+
return -BCH_ERR_fsck_delete_bkey;
445+
446+
unsigned fsck_flags = 0;
447+
if (!(validate_flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)))
448+
fsck_flags |= FSCK_AUTOFIX|FSCK_CAN_FIX;
449+
437450
struct printbuf buf = PRINTBUF;
438451
va_list args;
439452

@@ -445,7 +458,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *c,
445458
va_end(args);
446459
prt_str(&buf, ": delete?");
447460

448-
int ret = __bch2_fsck_err(c, NULL, flags, err, "%s", buf.buf);
461+
int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s", buf.buf);
449462
printbuf_exit(&buf);
450463
return ret;
451464
}

fs/bcachefs/error.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,11 @@ void bch2_flush_fsck_errs(struct bch_fs *);
167167
#define fsck_err_on(cond, c, _err_type, ...) \
168168
__fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__)
169169

170+
enum bch_validate_flags;
170171
__printf(5, 6)
171172
int __bch2_bkey_fsck_err(struct bch_fs *,
172173
struct bkey_s_c,
173-
enum bch_fsck_flags,
174+
enum bch_validate_flags,
174175
enum bch_sb_error_id,
175176
const char *, ...);
176177

@@ -180,11 +181,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *,
180181
*/
181182
#define bkey_fsck_err(c, _err_type, _err_msg, ...) \
182183
do { \
183-
if ((flags & BCH_VALIDATE_silent)) { \
184-
ret = -BCH_ERR_fsck_delete_bkey; \
185-
goto fsck_err; \
186-
} \
187-
int _ret = __bch2_bkey_fsck_err(c, k, FSCK_CAN_FIX|FSCK_AUTOFIX,\
184+
int _ret = __bch2_bkey_fsck_err(c, k, flags, \
188185
BCH_FSCK_ERR_##_err_type, \
189186
_err_msg, ##__VA_ARGS__); \
190187
if (_ret != -BCH_ERR_fsck_fix && \

fs/bcachefs/fs.c

+21-12
Original file line numberDiff line numberDiff line change
@@ -174,20 +174,24 @@ static const struct rhashtable_params bch2_vfs_inodes_params = {
174174
.automatic_shrinking = true,
175175
};
176176

177-
static void __wait_on_freeing_inode(struct inode *inode)
177+
struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
178178
{
179-
wait_queue_head_t *wq;
180-
DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW);
181-
wq = bit_waitqueue(&inode->i_state, __I_NEW);
182-
prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);
183-
spin_unlock(&inode->i_lock);
184-
schedule();
185-
finish_wait(wq, &wait.wq_entry);
179+
return rhashtable_lookup_fast(&c->vfs_inodes_table, &inum, bch2_vfs_inodes_params);
186180
}
187181

188-
struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
182+
static void __wait_on_freeing_inode(struct bch_fs *c,
183+
struct bch_inode_info *inode,
184+
subvol_inum inum)
189185
{
190-
return rhashtable_lookup_fast(&c->vfs_inodes_table, &inum, bch2_vfs_inodes_params);
186+
wait_queue_head_t *wq;
187+
DEFINE_WAIT_BIT(wait, &inode->v.i_state, __I_NEW);
188+
wq = inode_bit_waitqueue(&wait, &inode->v, __I_NEW);
189+
prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);
190+
spin_unlock(&inode->v.i_lock);
191+
192+
if (__bch2_inode_hash_find(c, inum) == inode)
193+
schedule_timeout(HZ * 10);
194+
finish_wait(wq, &wait.wq_entry);
191195
}
192196

193197
static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btree_trans *trans,
@@ -204,10 +208,10 @@ static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btre
204208
}
205209
if ((inode->v.i_state & (I_FREEING|I_WILL_FREE))) {
206210
if (!trans) {
207-
__wait_on_freeing_inode(&inode->v);
211+
__wait_on_freeing_inode(c, inode, inum);
208212
} else {
209213
bch2_trans_unlock(trans);
210-
__wait_on_freeing_inode(&inode->v);
214+
__wait_on_freeing_inode(c, inode, inum);
211215
int ret = bch2_trans_relock(trans);
212216
if (ret)
213217
return ERR_PTR(ret);
@@ -232,6 +236,11 @@ static void bch2_inode_hash_remove(struct bch_fs *c, struct bch_inode_info *inod
232236
&inode->hash, bch2_vfs_inodes_params);
233237
BUG_ON(ret);
234238
inode->v.i_hash.pprev = NULL;
239+
/*
240+
* This pairs with the bch2_inode_hash_find() ->
241+
* __wait_on_freeing_inode() path
242+
*/
243+
inode_wake_up_bit(&inode->v, __I_NEW);
235244
}
236245
}
237246

0 commit comments

Comments
 (0)