Skip to content

Commit 9e99c1a

Browse files
committed
Merge tag 'bcachefs-2025-04-17' of git://evilpiepirate.org/bcachefs
Pull bcachefs fixes from Kent Overstreet: "Usual set of small fixes/logging improvements. One bigger user reported fix, for inode <-> dirent inconsistencies reported in fsck, after moving a subvolume that had been snapshotted" * tag 'bcachefs-2025-04-17' of git://evilpiepirate.org/bcachefs: bcachefs: Fix snapshotting a subvolume, then renaming it bcachefs: Add missing READ_ONCE() for metadata replicas bcachefs: snapshot_node_missing is now autofix bcachefs: Log message when incompat version requested but not enabled bcachefs: Print version_incompat_allowed on startup bcachefs: Silence extent_poisoned error messages bcachefs: btree_root_unreadable_and_scan_found_nothing now AUTOFIX bcachefs: fix bch2_dev_usage_full_read_fast() bcachefs: Don't print data read retry success on non-errors bcachefs: Add missing error handling bcachefs: Prevent granting write refs when filesystem is read-only
2 parents 399537b + 261592b commit 9e99c1a

File tree

13 files changed

+98
-26
lines changed

13 files changed

+98
-26
lines changed

fs/bcachefs/bcachefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,8 @@ struct bch_fs {
788788
unsigned long errors_silent[BITS_TO_LONGS(BCH_FSCK_ERR_MAX)];
789789
u64 btrees_lost_data;
790790
} sb;
791+
DARRAY(enum bcachefs_metadata_version)
792+
incompat_versions_requested;
791793

792794
#ifdef CONFIG_UNICODE
793795
struct unicode_map *cf_encoding;

fs/bcachefs/btree_update_interior.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,7 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
12211221

12221222
ret = bch2_disk_reservation_get(c, &as->disk_res,
12231223
(nr_nodes[0] + nr_nodes[1]) * btree_sectors(c),
1224-
c->opts.metadata_replicas,
1224+
READ_ONCE(c->opts.metadata_replicas),
12251225
disk_res_flags);
12261226
if (ret)
12271227
goto err;

fs/bcachefs/buckets.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ void bch2_dev_usage_read_fast(struct bch_dev *ca, struct bch_dev_usage *usage)
3737
void bch2_dev_usage_full_read_fast(struct bch_dev *ca, struct bch_dev_usage_full *usage)
3838
{
3939
memset(usage, 0, sizeof(*usage));
40-
acc_u64s_percpu((u64 *) usage, (u64 __percpu *) ca->usage, dev_usage_u64s());
40+
acc_u64s_percpu((u64 *) usage, (u64 __percpu *) ca->usage,
41+
sizeof(struct bch_dev_usage_full) / sizeof(u64));
4142
}
4243

4344
static u64 reserve_factor(u64 r)

fs/bcachefs/buckets.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,6 @@ static inline u64 dev_buckets_available(struct bch_dev *ca,
242242

243243
/* Filesystem usage: */
244244

245-
static inline unsigned dev_usage_u64s(void)
246-
{
247-
return sizeof(struct bch_dev_usage) / sizeof(u64);
248-
}
249-
250245
struct bch_fs_usage_short
251246
bch2_fs_usage_read_short(struct bch_fs *);
252247

fs/bcachefs/errcode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@
287287
x(EIO, mark_stripe) \
288288
x(EIO, stripe_reconstruct) \
289289
x(EIO, key_type_error) \
290-
x(EIO, extent_poisened) \
290+
x(EIO, extent_poisoned) \
291291
x(EIO, missing_indirect_extent) \
292292
x(EIO, invalidate_stripe_to_dev) \
293293
x(EIO, no_encryption_key) \

fs/bcachefs/extents.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ int bch2_bkey_pick_read_device(struct bch_fs *c, struct bkey_s_c k,
139139
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
140140

141141
if (bch2_bkey_extent_ptrs_flags(ptrs) & BIT_ULL(BCH_EXTENT_FLAG_poisoned))
142-
return -BCH_ERR_extent_poisened;
142+
return -BCH_ERR_extent_poisoned;
143143

144144
rcu_read_lock();
145145
const union bch_extent_entry *entry;

fs/bcachefs/fs-ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static int bch2_inode_flags_set(struct btree_trans *trans,
6969
if (ret < 0)
7070
return ret;
7171

72-
ret = bch2_request_incompat_feature(c,bcachefs_metadata_version_casefolding);
72+
ret = bch2_request_incompat_feature(c, bcachefs_metadata_version_casefolding);
7373
if (ret)
7474
return ret;
7575

fs/bcachefs/fsck.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,31 @@ static inline bool inode_should_reattach(struct bch_inode_unpacked *inode)
321321
inode->bi_subvol == BCACHEFS_ROOT_SUBVOL)
322322
return false;
323323

324+
/*
325+
* Subvolume roots are special: older versions of subvolume roots may be
326+
* disconnected, it's only the newest version that matters.
327+
*
328+
* We only keep a single dirent pointing to a subvolume root, i.e.
329+
* older versions of snapshots will not have a different dirent pointing
330+
* to the same subvolume root.
331+
*
332+
* This is because dirents that point to subvolumes are only visible in
333+
* the parent subvolume - versioning is not needed - and keeping them
334+
* around would break fsck, because when we're crossing subvolumes we
335+
* don't have a consistent snapshot ID to do check the inode <-> dirent
336+
* relationships.
337+
*
338+
* Thus, a subvolume root that's been renamed after a snapshot will have
339+
* a disconnected older version - that's expected.
340+
*
341+
* Note that taking a snapshot always updates the root inode (to update
342+
* the dirent backpointer), so a subvolume root inode with
343+
* BCH_INODE_has_child_snapshot is never visible.
344+
*/
345+
if (inode->bi_subvol &&
346+
(inode->bi_flags & BCH_INODE_has_child_snapshot))
347+
return false;
348+
324349
return !inode->bi_dir && !(inode->bi_flags & BCH_INODE_unlinked);
325350
}
326351

@@ -1007,6 +1032,23 @@ static int check_inode_dirent_inode(struct btree_trans *trans,
10071032
if (ret && !bch2_err_matches(ret, ENOENT))
10081033
return ret;
10091034

1035+
if ((ret || dirent_points_to_inode_nowarn(d, inode)) &&
1036+
inode->bi_subvol &&
1037+
(inode->bi_flags & BCH_INODE_has_child_snapshot)) {
1038+
/* Older version of a renamed subvolume root: we won't have a
1039+
* correct dirent for it. That's expected, see
1040+
* inode_should_reattach().
1041+
*
1042+
* We don't clear the backpointer field when doing the rename
1043+
* because there might be arbitrarily many versions in older
1044+
* snapshots.
1045+
*/
1046+
inode->bi_dir = 0;
1047+
inode->bi_dir_offset = 0;
1048+
*write_inode = true;
1049+
goto out;
1050+
}
1051+
10101052
if (fsck_err_on(ret,
10111053
trans, inode_points_to_missing_dirent,
10121054
"inode points to missing dirent\n%s",
@@ -1027,7 +1069,7 @@ static int check_inode_dirent_inode(struct btree_trans *trans,
10271069
inode->bi_dir_offset = 0;
10281070
*write_inode = true;
10291071
}
1030-
1072+
out:
10311073
ret = 0;
10321074
fsck_err:
10331075
bch2_trans_iter_exit(trans, &dirent_iter);

fs/bcachefs/io_read.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,8 @@ static void bch2_rbio_retry(struct work_struct *work)
487487
.inum = rbio->read_pos.inode,
488488
};
489489
struct bch_io_failures failed = { .nr = 0 };
490+
int orig_error = rbio->ret;
491+
490492
struct btree_trans *trans = bch2_trans_get(c);
491493

492494
trace_io_read_retry(&rbio->bio);
@@ -519,7 +521,9 @@ static void bch2_rbio_retry(struct work_struct *work)
519521
if (ret) {
520522
rbio->ret = ret;
521523
rbio->bio.bi_status = BLK_STS_IOERR;
522-
} else {
524+
} else if (orig_error != -BCH_ERR_data_read_retry_csum_err_maybe_userspace &&
525+
orig_error != -BCH_ERR_data_read_ptr_stale_race &&
526+
!failed.nr) {
523527
struct printbuf buf = PRINTBUF;
524528

525529
lockrestart_do(trans,
@@ -1345,14 +1349,16 @@ int __bch2_read(struct btree_trans *trans, struct bch_read_bio *rbio,
13451349

13461350
bch2_trans_iter_exit(trans, &iter);
13471351

1348-
if (ret) {
1349-
struct printbuf buf = PRINTBUF;
1350-
lockrestart_do(trans,
1351-
bch2_inum_offset_err_msg_trans(trans, &buf, inum,
1352-
bvec_iter.bi_sector << 9));
1353-
prt_printf(&buf, "read error: %s", bch2_err_str(ret));
1354-
bch_err_ratelimited(c, "%s", buf.buf);
1355-
printbuf_exit(&buf);
1352+
if (unlikely(ret)) {
1353+
if (ret != -BCH_ERR_extent_poisoned) {
1354+
struct printbuf buf = PRINTBUF;
1355+
lockrestart_do(trans,
1356+
bch2_inum_offset_err_msg_trans(trans, &buf, inum,
1357+
bvec_iter.bi_sector << 9));
1358+
prt_printf(&buf, "data read error: %s", bch2_err_str(ret));
1359+
bch_err_ratelimited(c, "%s", buf.buf);
1360+
printbuf_exit(&buf);
1361+
}
13561362

13571363
rbio->bio.bi_status = BLK_STS_IOERR;
13581364
rbio->ret = ret;

fs/bcachefs/recovery.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,10 @@ int bch2_fs_initialize(struct bch_fs *c)
11251125
* journal_res_get() will crash if called before this has
11261126
* set up the journal.pin FIFO and journal.cur pointer:
11271127
*/
1128-
bch2_fs_journal_start(&c->journal, 1);
1128+
ret = bch2_fs_journal_start(&c->journal, 1);
1129+
if (ret)
1130+
goto err;
1131+
11291132
set_bit(BCH_FS_accounting_replay_done, &c->flags);
11301133
bch2_journal_set_replay_done(&c->journal);
11311134

0 commit comments

Comments
 (0)