sys-kernel/hardened-kernel and virtual/dist-kernel: bump v6.12.8
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
This commit is contained in:
parent
6c6d55d8fc
commit
9a5f90dc23
sys-kernel/hardened-kernel
Manifest
files/linux-6.12
0001-bcachefs-kill-retry_estale-in-bch2_ioctl_subvolume_c.patch0002-bcachefs-Fix-racy-use-of-jiffies.patch0003-bcachefs-remove-superfluous-after-statements.patch0004-bcachefs-bch2_inode_should_have_bp-bch2_inode_should.patch0005-bcachefs-remove_backpointer-now-uses-dirent_get_by_p.patch0006-bcachefs-__bch2_key_has_snapshot_overwrites-uses-for.patch0007-bcachefs-rcu_pending-don-t-invoke-__call_rcu-under-l.patch0008-bcachefs-bch_verbose_ratelimited.patch0009-bcachefs-Pull-disk-accounting-hooks-out-of-trans_com.patch0010-bcachefs-Delete-dead-code.patch0011-bcachefs-move-bch2_xattr_handlers-to-.rodata.patch0012-bcachefs-Remove-unnecessary-peek_slot.patch0013-bcachefs-kill-btree_trans_restart_nounlock.patch0014-docs-filesystems-bcachefs-fixed-some-spelling-mistak.patch0015-bcachefs-Remove-duplicate-included-headers.patch0016-bcachefs-Use-FOREACH_ACL_ENTRY-macro-to-iterate-over.patch0017-bcachefs-add-more-path-idx-debug-asserts.patch0018-bcachefs-bch2_run_explicit_recovery_pass-returns-dif.patch0019-bcachefs-lru-accounting-are-alloc-btrees.patch0020-bcachefs-Add-locking-for-bch_fs.curr_recovery_pass.patch0021-bcachefs-bch2_btree_lost_data-now-uses-run_explicit_.patch0022-bcachefs-improved-bkey_val_copy.patch0023-bcachefs-Factor-out-jset_entry_log_msg_bytes.patch0024-bcachefs-better-error-message-in-check_snapshot_tree.patch0025-bcachefs-Avoid-bch2_btree_id_str.patch0026-bcachefs-Refactor-new-stripe-path-to-reduce-dependen.patch0027-bcachefs-o-norecovery-now-bails-out-of-recovery-earl.patch0028-bcachefs-bch2_journal_meta-takes-ref-on-c-writes.patch0029-bcachefs-Fix-warning-about-passing-flex-array-member.patch0030-bcachefs-Add-block-plugging-to-read-paths.patch0031-bcachefs-Add-version-check-for-bch_btree_ptr_v2.sect.patch0032-bcachefs-Use-str_write_read-helper-function.patch0033-bcachefs-Use-str_write_read-helper-in-ec_block_endio.patch0034-bcachefs-Use-str_write_read-helper-in-write_super_en.patch0035-bcachefs-Annotate-struct-bucket_gens-with-__counted_.patch0036-bcachefs-avoid-unsigned-flags.patch0037-bcachefs-use-bch2_data_update_opts_to_text-in-trace_.patch0038-bcachefs-bch2_io_opts_fixups.patch0039-bcachefs-small-cleanup-for-extent-ptr-bitmasks.patch0040-bcachefs-kill-bch2_bkey_needs_rebalance.patch0041-bcachefs-kill-__bch2_bkey_sectors_need_rebalance.patch0042-bcachefs-rename-bch_extent_rebalance-fields-to-match.patch0043-bcachefs-io_opts_to_rebalance_opts.patch0044-bcachefs-Add-bch_io_opts-fields-for-indicating-wheth.patch0045-bcachefs-copygc_enabled-rebalance_enabled-now-opts.h.patch0046-bcachefs-bch2_prt_csum_opt.patch0047-bcachefs-New-bch_extent_rebalance-fields.patch0048-bcachefs-bch2_write_inode-now-checks-for-changing-re.patch0049-bcachefs-get_update_rebalance_opts.patch0050-bcachefs-Simplify-option-logic-in-rebalance.patch0051-bcachefs-Improve-trace_rebalance_extent.patch0052-bcachefs-Move-bch_extent_rebalance-code-to-rebalance.patch0053-bcachefs-remove-write-permission-for-gc_gens_pos-sys.patch0054-bcachefs-use-attribute-define-helper-for-sysfs-attri.patch0055-bcachefs-Add-assert-for-use-of-journal-replay-keys-f.patch0056-bcachefs-Kill-BCH_TRANS_COMMIT_lazy_rw.patch0057-bcachefs-Improved-check_topology-assert.patch0058-bcachefs-Fix-unhandled-transaction-restart-in-evacua.patch0059-bcachefs-Assert-we-re-not-in-a-restart-in-bch2_trans.patch0060-bcachefs-Better-in_restart-error.patch0061-bcachefs-bch2_trans_verify_not_unlocked_or_in_restar.patch0062-bcachefs-Assert-that-we-re-not-violating-key-cache-c.patch0063-bcachefs-Rename-btree_iter_peek_upto-btree_iter_peek.patch0064-bcachefs-Simplify-btree_iter_peek-filter_snapshots.patch0065-bcachefs-Kill-unnecessary-iter_rewind-in-bkey_get_em.patch0066-bcachefs-Move-fsck-ioctl-code-to-fsck.c.patch0067-bcachefs-add-support-for-true-false-yes-no-in-bool-t.patch0068-bcachefs-Correct-the-description-of-the-bucket-size-.patch0069-bcachefs-Add-support-for-FS_IOC_GETFSUUID.patch0070-bcachefs-Add-support-for-FS_IOC_GETFSSYSFSPATH.patch0071-bcachefs-Removes-NULL-pointer-checks-for-__filemap_g.patch0072-bcachefs-Remove-redundant-initialization-in-bch2_vfs.patch0073-bcachefs-Simplify-code-in-bch2_dev_alloc.patch0074-bcachefs-Don-t-use-page-allocator-for-sb_read_scratc.patch0075-bcachefs-Fix-shutdown-message.patch0076-bcachefs-delete-dead-code.patch0077-bcachefs-bch2_btree_bit_mod_iter.patch0078-bcachefs-Delete-dead-code-from-bch2_discard_one_buck.patch0079-bcachefs-lru-errors-are-expected-when-reconstructing.patch0080-bcachefs-Kill-FSCK_NEED_FSCK.patch0081-bcachefs-Reserve-8-bits-in-bch_reflink_p.patch0082-bcachefs-Reorganize-reflink.c-a-bit.patch0083-bcachefs-Don-t-delete-reflink-pointers-to-missing-in.patch0084-bcachefs-kill-inconsistent-err-in-invalidate_one_buc.patch0085-bcachefs-rework-bch2_bucket_alloc_freelist-freelist-.patch0086-bcachefs-try_alloc_bucket-now-uses-bch2_check_discar.patch0087-bcachefs-bch2_bucket_do_index-inconsistent_err-fsck_.patch0088-bcachefs-discard_one_bucket-now-uses-need_discard_or.patch0089-bcachefs-Implement-bch2_btree_iter_prev_min.patch0090-bcachefs-peek_prev_min-Search-forwards-for-extents-s.patch0091-bcachefs-Delete-backpointers-check-in-try_alloc_buck.patch0092-bcachefs-Kill-bch2_get_next_backpointer.patch0093-bcachefs-add-missing-BTREE_ITER_intent.patch0094-bcachefs-compression-workspaces-should-be-indexed-by.patch0095-bcachefs-Don-t-use-a-shared-decompress-workspace-mem.patch0096-bcachefs-Don-t-BUG_ON-when-superblock-feature-wasn-t.patch0097-bcachefs-kill-bch2_journal_entries_free.patch0098-bcachefs-journal-keys-sort-keys-for-interior-nodes-f.patch0099-bcachefs-btree_and_journal_iter-don-t-iterate-over-t.patch
@ -1,9 +1,9 @@
|
||||
DIST genpatches-6.11-10.base.tar.xz 757872 BLAKE2B 72566af9a781288f516dcd30881851fe371a0f3d072aeabbd9d3e57ea96896cb9d8f0d594f8729215baa83d9546c675789b596dac5781b3640e963059d23223b SHA512 ae04d309e3b97cfd7f09993cf297fa5825c53e83acc54805f1f6f2d09cd07aa1715866be3d59874d0131d1746a398b9449fda1987ea6bdbd66402e411569d874
|
||||
DIST genpatches-6.11-10.experimental.tar.xz 77928 BLAKE2B a0928f0ff7eb6b9a5659d0ab41dafcf3b474cd7aa357b65a7a147972132c08703a88467e51b7dbd8004781cb0cb8a9620190737963f1fcc1e9e5d98f68ba72d6 SHA512 2be91396f9ec97b2e051db72742e3db1edaa56255c7a2cde2ce2ecc1de4771e92ba6d55e863380fe4dc6ef8d8778bec1a9926a9ffe2dd5d1036b9c36a9afae13
|
||||
DIST genpatches-6.11-10.extras.tar.xz 4060 BLAKE2B a94b8799f6c1d338a17e25b1dde6aa616754bfde092eb5ad1da11a6ec8b1107dce827d05ecc756a4918339329190e6572bb089de89d9a11c8c08f067eb7b269d SHA512 1a166a0054827ac9bef700d075cc2a1e3934dbe7b7aa64b34109b521f5bb21e231d59be4643f6faf702e5d0b3cb7d82e8cc1ba1f77e3bf88c38f9b6ffc61e35f
|
||||
DIST genpatches-6.12-9.base.tar.xz 632912 BLAKE2B ed4f40958b1e3069213b309ef89bd7bab5aa7e9d5459fa35517ded1d2347abd4eea399c9df134989157e7b7a7ad68c3e777503884b9d7757be91ace970fb258e SHA512 cfdd660147ae7e686972d7ddaa1511fa4acfb1b5b4f9def30e8d11b5ae230a01fc0e1cb48c7af12b7fed435993936c0413cdfa9c41ecb354130db0ea4a653a0b
|
||||
DIST genpatches-6.12-9.experimental.tar.xz 78116 BLAKE2B fbd986e5185250b33abc1b77742996639e5b04a77d6e0c5802929d528d47dea61ae33ee515c95207963adc7705e875ea564273615e137ca28a04d6b0a675c488 SHA512 762f6e889e3ec9426005970cc5b8855111cafea6df889c301814924e46fd191ec63e5dec120b6bebeae890758da1aa927d0ebdb947f3dc580771fac05a345204
|
||||
DIST genpatches-6.12-9.extras.tar.xz 4056 BLAKE2B 718d47c2cb619bb1fab14dcf5c06d8137a3f778c728f50e6fd29972efaf0472b040e73cd88a510f35f53e3dcd1fac9a3c4cf5e16cc79d2c6a5ca384e1e2e9056 SHA512 d72cd080d56966d797a61f6b61bc471451296213475aa1b666ad58f8498657500641adc136ff7d07d3607f9eed2da4a0466877e423f67887bfd19a01f17a3aec
|
||||
DIST genpatches-6.12-11.base.tar.xz 711536 BLAKE2B a9911cbb7cca5e6f3b06adba52289957eaccbdef25aa1d1f610ac7d7fde2a1cce46095e3d48b281a9ff0a9e88559a492833f0f39cf151ba560d6f3ff8fa5a4b3 SHA512 d33a54716e726cc8d19b366a7ad1cc51822eba4fa329eda596e6e7dbd851a9725db4e5f4bb827f36a26604b7c0b5a60154a2310f99b18265fb3c68251420fc1c
|
||||
DIST genpatches-6.12-11.experimental.tar.xz 78152 BLAKE2B 20a933a7a74056026ef8b74fd0a4cf41c425855e042a0e6cf9a1b1f0eda77a2c186712fbf59188ffcb31a3c3ba954f7df4e35c5c2dce26c2479af6854af1381d SHA512 90cccbf1c8523197e56661ad34c71d2345dbbebf1f58e4678e45bb75f0b3a057614e996788e7eccec01b5bceffa93d77d6cf259475c1619d8907927a44cadb77
|
||||
DIST genpatches-6.12-11.extras.tar.xz 4056 BLAKE2B f8c2a145a06ea061100ba4d16e873a3186c4025d48610180aed135a8802494855decd8a58c24ffa4dd394cac843e41f45dd8aa93c28e03cdb1d46d8ce496da17 SHA512 e2808c8a70aaf3ef76348542a0aa0656f1ccdbe3523b22e5539d0c3952b4013aafddca5d881bc0458aab33f1b652f178d89ae4e596a9f541274f74eaf97ad16b
|
||||
DIST gentoo-kernel-config-g14.tar.gz 5686 BLAKE2B e5147ff4ffab92428b3e7f1b0897b997f8a298805f4f43b0a4d3047607bbb1a5ebfc268e0bb9688372a5eda561df9f256c78e00cdd7e3caf7868724214722f56 SHA512 f79638f9ff9dd0154512baf0234024216b6708d35a3c03a580ca5913286ad1ea13bdde5ea9b4722c6a7cd8d591c11ec52c1e225111a260343cd56aa1f1a88502
|
||||
DIST kernel-aarch64-fedora.config.6.11.5-gentoo 285046 BLAKE2B e8ae27d70fa023976e950d4edcb38963e2fff39efa5cd1ff5922278e871efe6e6cda11c609e721eb2a3f7b030ea75447be384065d3b177000c301fc287a34d7f SHA512 121bbeebace3b760ff6ef36cf9970def3073966ea2fc1089c19c08d27a0524502dedc8c988c5239e78ce04caea6feb5ba7b5d53e0319b22ba63ce6cbc2a07e75
|
||||
DIST kernel-aarch64-fedora.config.6.12.1-gentoo 287989 BLAKE2B fbf6183487ffc6d30543c6b9caedbca224cc9ce4ec917e35ab351030212b721af8cc33aafa1feb229a1d6b45c9f45329f8e4957bdb3d43bee7ac223eeb90a994 SHA512 fad6121dfe4a3c82039cfe77614e90b4a954fe12d156f29ef9a596745327a3d30c7a40fc4002405a692685c7deaf9a7d3d6f944d505bc51ed5c387f9c9fd6311
|
||||
@ -16,4 +16,4 @@ DIST kernel-x86_64-fedora.config.6.12.1-gentoo 256170 BLAKE2B 39e03735453c66f426
|
||||
DIST linux-6.11.tar.xz 146900704 BLAKE2B e7750c0878d71a56a0ce52d4c4c912199dad5bf5e2e8f872585a6494afbb37cbd852e612a6858936d2dc9b7776a3933818f540db408d57e90d18ea5249bba7ab SHA512 329c1f94008742e3f0c2ce7e591a16316d1b2cb9ea4596d4f45604097e07b7aa2f64afa40630a07f321a858455c77aa32ba57b271932ddcf4dc27863f9081cea
|
||||
DIST linux-6.12.tar.xz 147906904 BLAKE2B b2ec2fc69218cacabbbe49f78384a5d259ca581b717617c12b000b16f4a4c59ee348ea886b37147f5f70fb9a7a01c1e2c8f19021078f6b23f5bc62d1c48d5e5e SHA512 a37b1823df7b4f72542f689b65882634740ba0401a42fdcf6601d9efd2e132e5a7650e70450ba76f6cd1f13ca31180f2ccee9d54fe4df89bc0000ade4380a548
|
||||
DIST linux-hardened-v6.11.8-hardened1.patch 95386 BLAKE2B c8afa1a25191e73d0a1208ce3bc7dea7d856d2697adcd3f5a9d1ec9695f393aa42099353699c1f58dd056c6fb4215860661a6a17358c887877612ac58a4cf3f6 SHA512 d5baa895f069af8e8f3e6d605e86e10137de6a3d956d8dc092e6c3ed4c52ae6faa9dc10dce2bee6696a75e0d7e595f912e06f64a36965ef282918145567597b3
|
||||
DIST linux-hardened-v6.12.6-hardened1.patch 89620 BLAKE2B e33fc43320fa1b042370d7f708fd48fd7d0dd948ae3721b70400e4528f624e801fbcd56cac2ca1c8322397a9386e7e7de6a9c5085a3dcaa55b4a84ad2bd16dfb SHA512 1908cae710869e4f8b51df11ce0f71769e0f87619e0a1f8f224d77c492c6a7bed4192db6cc47eb129857f8bf1a354ccf2e997243fd3cc86c9917ea7e23da6613
|
||||
DIST linux-hardened-v6.12.8-hardened1.patch 89620 BLAKE2B a18bb10a7d184ca0374659c6dfe9efd56501482329f05bae2081510a887f7aa77fd651f635da05304f75b9e1bcad02dc4249123e6687a89e5be0eefe0d508ca8 SHA512 6ea3f25dbe3724799705d7f6cf49dce8884dd6cbbc479987db90e6fb3b0493cc71febddcca70c7bee129ec1c867b541485d61e95b09b3524e0746576396aa936
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 3d1ea1c0aeaf7baaf0c0a3d073a49671dfd3771a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 11 Oct 2024 16:21:14 -0400
|
||||
Subject: [PATCH 001/233] bcachefs: kill retry_estale() in
|
||||
bch2_ioctl_subvolume_create()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
this was likely originally cribbed, and has been dead code, and Al is
|
||||
working on removing it from the tree.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs-ioctl.c | 7 +------
|
||||
1 file changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c
|
||||
index 405cf08bda34..15725b4ce393 100644
|
||||
--- a/fs/bcachefs/fs-ioctl.c
|
||||
+++ b/fs/bcachefs/fs-ioctl.c
|
||||
@@ -406,7 +406,7 @@ static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp,
|
||||
sync_inodes_sb(c->vfs_sb);
|
||||
up_read(&c->vfs_sb->s_umount);
|
||||
}
|
||||
-retry:
|
||||
+
|
||||
if (arg.src_ptr) {
|
||||
error = user_path_at(arg.dirfd,
|
||||
(const char __user *)(unsigned long)arg.src_ptr,
|
||||
@@ -486,11 +486,6 @@ static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp,
|
||||
err2:
|
||||
if (arg.src_ptr)
|
||||
path_put(&src_path);
|
||||
-
|
||||
- if (retry_estale(error, lookup_flags)) {
|
||||
- lookup_flags |= LOOKUP_REVAL;
|
||||
- goto retry;
|
||||
- }
|
||||
err1:
|
||||
return error;
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 40cfa4d5b8dcf25ae12c8fca492212e0a2b1d2cc Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Wed, 9 Oct 2024 16:53:59 -0400
|
||||
Subject: [PATCH 002/233] bcachefs: Fix racy use of jiffies
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Calculate the timeout, then check if it's positive before calling
|
||||
schedule_timeout().
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/journal_reclaim.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c
|
||||
index ace291f175dd..3d8fc2642425 100644
|
||||
--- a/fs/bcachefs/journal_reclaim.c
|
||||
+++ b/fs/bcachefs/journal_reclaim.c
|
||||
@@ -758,10 +758,12 @@ static int bch2_journal_reclaim_thread(void *arg)
|
||||
journal_empty = fifo_empty(&j->pin);
|
||||
spin_unlock(&j->lock);
|
||||
|
||||
+ long timeout = j->next_reclaim - jiffies;
|
||||
+
|
||||
if (journal_empty)
|
||||
schedule();
|
||||
- else if (time_after(j->next_reclaim, jiffies))
|
||||
- schedule_timeout(j->next_reclaim - jiffies);
|
||||
+ else if (timeout > 0)
|
||||
+ schedule_timeout(timeout);
|
||||
else
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,67 +0,0 @@
|
||||
From 61b2134ccc24a8843a1c9bc8bfd28bdfe88a0aab Mon Sep 17 00:00:00 2001
|
||||
From: Colin Ian King <colin.i.king@gmail.com>
|
||||
Date: Mon, 7 Oct 2024 09:11:21 +0100
|
||||
Subject: [PATCH 003/233] bcachefs: remove superfluous ; after statements
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There are a several statements with two following semicolons, replace
|
||||
these with just one semicolon.
|
||||
|
||||
Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_update.c | 2 +-
|
||||
fs/bcachefs/ec.c | 2 +-
|
||||
fs/bcachefs/super.c | 4 ++--
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c
|
||||
index 5d809e8bd170..79a274dcd17b 100644
|
||||
--- a/fs/bcachefs/btree_update.c
|
||||
+++ b/fs/bcachefs/btree_update.c
|
||||
@@ -144,7 +144,7 @@ int __bch2_insert_snapshot_whiteouts(struct btree_trans *trans,
|
||||
!(ret = bkey_err(old_k)) &&
|
||||
bkey_eq(old_pos, old_k.k->p)) {
|
||||
struct bpos whiteout_pos =
|
||||
- SPOS(new_pos.inode, new_pos.offset, old_k.k->p.snapshot);;
|
||||
+ SPOS(new_pos.inode, new_pos.offset, old_k.k->p.snapshot);
|
||||
|
||||
if (!bch2_snapshot_is_ancestor(c, old_k.k->p.snapshot, old_pos.snapshot) ||
|
||||
snapshot_list_has_ancestor(c, &s, old_k.k->p.snapshot))
|
||||
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
|
||||
index 749dcf368841..d489a9e28702 100644
|
||||
--- a/fs/bcachefs/ec.c
|
||||
+++ b/fs/bcachefs/ec.c
|
||||
@@ -909,7 +909,7 @@ int bch2_ec_read_extent(struct btree_trans *trans, struct bch_read_bio *rbio,
|
||||
bch2_bkey_val_to_text(&msgbuf, c, orig_k);
|
||||
bch_err_ratelimited(c,
|
||||
"error doing reconstruct read: %s\n %s", msg, msgbuf.buf);
|
||||
- printbuf_exit(&msgbuf);;
|
||||
+ printbuf_exit(&msgbuf);
|
||||
ret = -BCH_ERR_stripe_reconstruct;
|
||||
goto out;
|
||||
}
|
||||
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
|
||||
index a6ed9a0bf1c7..17442df7326d 100644
|
||||
--- a/fs/bcachefs/super.c
|
||||
+++ b/fs/bcachefs/super.c
|
||||
@@ -1120,12 +1120,12 @@ static int bch2_dev_in_fs(struct bch_sb_handle *fs,
|
||||
|
||||
prt_bdevname(&buf, fs->bdev);
|
||||
prt_char(&buf, ' ');
|
||||
- bch2_prt_datetime(&buf, le64_to_cpu(fs->sb->write_time));;
|
||||
+ bch2_prt_datetime(&buf, le64_to_cpu(fs->sb->write_time));
|
||||
prt_newline(&buf);
|
||||
|
||||
prt_bdevname(&buf, sb->bdev);
|
||||
prt_char(&buf, ' ');
|
||||
- bch2_prt_datetime(&buf, le64_to_cpu(sb->sb->write_time));;
|
||||
+ bch2_prt_datetime(&buf, le64_to_cpu(sb->sb->write_time));
|
||||
prt_newline(&buf);
|
||||
|
||||
if (!opts->no_splitbrain_check)
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,58 +0,0 @@
|
||||
From cb9d3414d0b89b5b9803ea0531cbffe74925d54b Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 28 Sep 2024 14:27:24 -0400
|
||||
Subject: [PATCH 004/233] bcachefs: bch2_inode_should_have_bp ->
|
||||
bch2_inode_should_have_single_bp
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs.c | 2 +-
|
||||
fs/bcachefs/fsck.c | 2 +-
|
||||
fs/bcachefs/inode.h | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
|
||||
index a41d0d8a2f7b..646b74494a3f 100644
|
||||
--- a/fs/bcachefs/fs.c
|
||||
+++ b/fs/bcachefs/fs.c
|
||||
@@ -628,7 +628,7 @@ static struct bch_inode_info *bch2_lookup_trans(struct btree_trans *trans,
|
||||
goto err;
|
||||
|
||||
/* regular files may have hardlinks: */
|
||||
- if (bch2_fs_inconsistent_on(bch2_inode_should_have_bp(&inode_u) &&
|
||||
+ if (bch2_fs_inconsistent_on(bch2_inode_should_have_single_bp(&inode_u) &&
|
||||
!bkey_eq(k.k->p, POS(inode_u.bi_dir, inode_u.bi_dir_offset)),
|
||||
c,
|
||||
"dirent points to inode that does not point back:\n %s",
|
||||
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
|
||||
index 75c8a97a6954..285de12436dd 100644
|
||||
--- a/fs/bcachefs/fsck.c
|
||||
+++ b/fs/bcachefs/fsck.c
|
||||
@@ -2156,7 +2156,7 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
|
||||
return __bch2_fsck_write_inode(trans, target);
|
||||
}
|
||||
|
||||
- if (bch2_inode_should_have_bp(target) &&
|
||||
+ if (bch2_inode_should_have_single_bp(target) &&
|
||||
!fsck_err(trans, inode_wrong_backpointer,
|
||||
"dirent points to inode that does not point back:\n %s",
|
||||
(bch2_bkey_val_to_text(&buf, c, d.s_c),
|
||||
diff --git a/fs/bcachefs/inode.h b/fs/bcachefs/inode.h
|
||||
index eab82b5eb897..bdeb6be76038 100644
|
||||
--- a/fs/bcachefs/inode.h
|
||||
+++ b/fs/bcachefs/inode.h
|
||||
@@ -249,7 +249,7 @@ static inline void bch2_inode_nlink_set(struct bch_inode_unpacked *bi,
|
||||
int bch2_inode_nlink_inc(struct bch_inode_unpacked *);
|
||||
void bch2_inode_nlink_dec(struct btree_trans *, struct bch_inode_unpacked *);
|
||||
|
||||
-static inline bool bch2_inode_should_have_bp(struct bch_inode_unpacked *inode)
|
||||
+static inline bool bch2_inode_should_have_single_bp(struct bch_inode_unpacked *inode)
|
||||
{
|
||||
bool inode_has_bp = inode->bi_dir || inode->bi_dir_offset;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 61bf384a85f4ab4845a41762ca6aa91a18c67cca Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Tue, 1 Oct 2024 17:45:58 -0400
|
||||
Subject: [PATCH 005/233] bcachefs: remove_backpointer() now uses
|
||||
dirent_get_by_pos()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fsck.c | 26 ++++++++++++--------------
|
||||
1 file changed, 12 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
|
||||
index 285de12436dd..6b2ddbabe3e7 100644
|
||||
--- a/fs/bcachefs/fsck.c
|
||||
+++ b/fs/bcachefs/fsck.c
|
||||
@@ -482,6 +482,13 @@ static int reattach_inode(struct btree_trans *trans, struct bch_inode_unpacked *
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static struct bkey_s_c_dirent dirent_get_by_pos(struct btree_trans *trans,
|
||||
+ struct btree_iter *iter,
|
||||
+ struct bpos pos)
|
||||
+{
|
||||
+ return bch2_bkey_get_iter_typed(trans, iter, BTREE_ID_dirents, pos, 0, dirent);
|
||||
+}
|
||||
+
|
||||
static int remove_backpointer(struct btree_trans *trans,
|
||||
struct bch_inode_unpacked *inode)
|
||||
{
|
||||
@@ -490,13 +497,11 @@ static int remove_backpointer(struct btree_trans *trans,
|
||||
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_iter iter;
|
||||
- struct bkey_s_c_dirent d =
|
||||
- bch2_bkey_get_iter_typed(trans, &iter, BTREE_ID_dirents,
|
||||
- SPOS(inode->bi_dir, inode->bi_dir_offset, inode->bi_snapshot), 0,
|
||||
- dirent);
|
||||
- int ret = bkey_err(d) ?:
|
||||
- dirent_points_to_inode(c, d, inode) ?:
|
||||
- __remove_dirent(trans, d.k->p);
|
||||
+ struct bkey_s_c_dirent d = dirent_get_by_pos(trans, &iter,
|
||||
+ SPOS(inode->bi_dir, inode->bi_dir_offset, inode->bi_snapshot));
|
||||
+ int ret = bkey_err(d) ?:
|
||||
+ dirent_points_to_inode(c, d, inode) ?:
|
||||
+ __remove_dirent(trans, d.k->p);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
return ret;
|
||||
}
|
||||
@@ -1166,13 +1171,6 @@ static int hash_check_key(struct btree_trans *trans,
|
||||
goto out;
|
||||
}
|
||||
|
||||
-static struct bkey_s_c_dirent dirent_get_by_pos(struct btree_trans *trans,
|
||||
- struct btree_iter *iter,
|
||||
- struct bpos pos)
|
||||
-{
|
||||
- return bch2_bkey_get_iter_typed(trans, iter, BTREE_ID_dirents, pos, 0, dirent);
|
||||
-}
|
||||
-
|
||||
static struct bkey_s_c_dirent inode_get_dirent(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
struct bch_inode_unpacked *inode,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,44 +0,0 @@
|
||||
From be40edadb0b715809f25bade2827af050ae6fbaa Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 30 Sep 2024 00:14:09 -0400
|
||||
Subject: [PATCH 006/233] bcachefs: __bch2_key_has_snapshot_overwrites uses
|
||||
for_each_btree_key_reverse_norestart()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/snapshot.c | 16 ++++------------
|
||||
1 file changed, 4 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
|
||||
index ae57638506c3..feaf2aa0d900 100644
|
||||
--- a/fs/bcachefs/snapshot.c
|
||||
+++ b/fs/bcachefs/snapshot.c
|
||||
@@ -1735,18 +1735,10 @@ int __bch2_key_has_snapshot_overwrites(struct btree_trans *trans,
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
- bch2_trans_iter_init(trans, &iter, id, pos,
|
||||
- BTREE_ITER_not_extents|
|
||||
- BTREE_ITER_all_snapshots);
|
||||
- while (1) {
|
||||
- k = bch2_btree_iter_prev(&iter);
|
||||
- ret = bkey_err(k);
|
||||
- if (ret)
|
||||
- break;
|
||||
-
|
||||
- if (!k.k)
|
||||
- break;
|
||||
-
|
||||
+ for_each_btree_key_reverse_norestart(trans, iter, id, bpos_predecessor(pos),
|
||||
+ BTREE_ITER_not_extents|
|
||||
+ BTREE_ITER_all_snapshots,
|
||||
+ k, ret) {
|
||||
if (!bkey_eq(pos, k.k->p))
|
||||
break;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 1ef7af68e376ab89a6b8e49387f7a4bad4fc6657 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 22 Sep 2024 01:11:36 -0400
|
||||
Subject: [PATCH 007/233] bcachefs: rcu_pending: don't invoke __call_rcu()
|
||||
under lock
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In userspace we don't (yet) have an SRCU implementation, so call_srcu()
|
||||
recurses.
|
||||
|
||||
But we don't want to be invoking it under the lock anyways.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/rcu_pending.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/rcu_pending.c b/fs/bcachefs/rcu_pending.c
|
||||
index 40a20192eee8..67522aa344a7 100644
|
||||
--- a/fs/bcachefs/rcu_pending.c
|
||||
+++ b/fs/bcachefs/rcu_pending.c
|
||||
@@ -478,7 +478,9 @@ __rcu_pending_enqueue(struct rcu_pending *pending, struct rcu_head *head,
|
||||
*/
|
||||
if (!p->cb_armed) {
|
||||
p->cb_armed = true;
|
||||
+ spin_unlock_irqrestore(&p->lock, flags);
|
||||
__call_rcu(pending->srcu, &p->cb, rcu_pending_rcu_cb);
|
||||
+ goto free_node;
|
||||
} else {
|
||||
__start_poll_synchronize_rcu(pending->srcu);
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,59 +0,0 @@
|
||||
From bdb3bdcbc2ebcb2fc50be2c094184103b7ff5d30 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 28 Sep 2024 23:10:48 -0400
|
||||
Subject: [PATCH 008/233] bcachefs: bch_verbose_ratelimited
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
ratelimit "deleting unlinked inode" messages
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs.h | 8 ++++++++
|
||||
fs/bcachefs/inode.c | 3 ++-
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
||||
index e94a83b8113e..7db81e182c3c 100644
|
||||
--- a/fs/bcachefs/bcachefs.h
|
||||
+++ b/fs/bcachefs/bcachefs.h
|
||||
@@ -293,6 +293,8 @@ do { \
|
||||
|
||||
#define bch_info(c, fmt, ...) \
|
||||
bch2_print(c, KERN_INFO bch2_fmt(c, fmt), ##__VA_ARGS__)
|
||||
+#define bch_info_ratelimited(c, fmt, ...) \
|
||||
+ bch2_print_ratelimited(c, KERN_INFO bch2_fmt(c, fmt), ##__VA_ARGS__)
|
||||
#define bch_notice(c, fmt, ...) \
|
||||
bch2_print(c, KERN_NOTICE bch2_fmt(c, fmt), ##__VA_ARGS__)
|
||||
#define bch_warn(c, fmt, ...) \
|
||||
@@ -352,6 +354,12 @@ do { \
|
||||
bch_info(c, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
+#define bch_verbose_ratelimited(c, fmt, ...) \
|
||||
+do { \
|
||||
+ if ((c)->opts.verbose) \
|
||||
+ bch_info_ratelimited(c, fmt, ##__VA_ARGS__); \
|
||||
+} while (0)
|
||||
+
|
||||
#define pr_verbose_init(opts, fmt, ...) \
|
||||
do { \
|
||||
if (opt_get(opts, verbose)) \
|
||||
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
|
||||
index 039cb7a22244..43653cf050e9 100644
|
||||
--- a/fs/bcachefs/inode.c
|
||||
+++ b/fs/bcachefs/inode.c
|
||||
@@ -1380,7 +1380,8 @@ int bch2_delete_dead_inodes(struct bch_fs *c)
|
||||
NULL, NULL, BCH_TRANS_COMMIT_no_enospc, ({
|
||||
ret = may_delete_deleted_inode(trans, &iter, k.k->p, &need_another_pass);
|
||||
if (ret > 0) {
|
||||
- bch_verbose(c, "deleting unlinked inode %llu:%u", k.k->p.offset, k.k->p.snapshot);
|
||||
+ bch_verbose_ratelimited(c, "deleting unlinked inode %llu:%u",
|
||||
+ k.k->p.offset, k.k->p.snapshot);
|
||||
|
||||
ret = bch2_inode_rm_snapshot(trans, k.k->p.offset, k.k->p.snapshot);
|
||||
/*
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,142 +0,0 @@
|
||||
From 2aa08c451ebf753ed0170e1d8d05ac4b51221392 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Tue, 1 Oct 2024 16:59:08 -0400
|
||||
Subject: [PATCH 009/233] bcachefs: Pull disk accounting hooks out of
|
||||
trans_commit.c
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Also, fix a minor bug in the revert path, where we weren't checking the
|
||||
journal entry type correctly.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_trans_commit.c | 35 +++++------------------------
|
||||
fs/bcachefs/disk_accounting.h | 38 ++++++++++++++++++++++++++++++++
|
||||
2 files changed, 44 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c
|
||||
index 9bf471fa4361..3d951846a1be 100644
|
||||
--- a/fs/bcachefs/btree_trans_commit.c
|
||||
+++ b/fs/bcachefs/btree_trans_commit.c
|
||||
@@ -609,14 +609,6 @@ static noinline int bch2_trans_commit_run_gc_triggers(struct btree_trans *trans)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct bversion journal_pos_to_bversion(struct journal_res *res, unsigned offset)
|
||||
-{
|
||||
- return (struct bversion) {
|
||||
- .hi = res->seq >> 32,
|
||||
- .lo = (res->seq << 32) | (res->offset + offset),
|
||||
- };
|
||||
-}
|
||||
-
|
||||
static inline int
|
||||
bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
|
||||
struct btree_insert_entry **stopped_at,
|
||||
@@ -701,25 +693,14 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
|
||||
struct jset_entry *entry = trans->journal_entries;
|
||||
|
||||
percpu_down_read(&c->mark_lock);
|
||||
-
|
||||
for (entry = trans->journal_entries;
|
||||
entry != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
|
||||
entry = vstruct_next(entry))
|
||||
if (entry->type == BCH_JSET_ENTRY_write_buffer_keys &&
|
||||
entry->start->k.type == KEY_TYPE_accounting) {
|
||||
- BUG_ON(!trans->journal_res.ref);
|
||||
-
|
||||
- struct bkey_i_accounting *a = bkey_i_to_accounting(entry->start);
|
||||
-
|
||||
- a->k.bversion = journal_pos_to_bversion(&trans->journal_res,
|
||||
- (u64 *) entry - (u64 *) trans->journal_entries);
|
||||
- BUG_ON(bversion_zero(a->k.bversion));
|
||||
-
|
||||
- if (likely(!(flags & BCH_TRANS_COMMIT_skip_accounting_apply))) {
|
||||
- ret = bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a), BCH_ACCOUNTING_normal);
|
||||
- if (ret)
|
||||
- goto revert_fs_usage;
|
||||
- }
|
||||
+ ret = bch2_accounting_trans_commit_hook(trans, bkey_i_to_accounting(entry->start), flags);
|
||||
+ if (ret)
|
||||
+ goto revert_fs_usage;
|
||||
}
|
||||
percpu_up_read(&c->mark_lock);
|
||||
|
||||
@@ -833,13 +814,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
|
||||
entry2 != entry;
|
||||
entry2 = vstruct_next(entry2))
|
||||
if (entry2->type == BCH_JSET_ENTRY_write_buffer_keys &&
|
||||
- entry2->start->k.type == KEY_TYPE_accounting) {
|
||||
- struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start);
|
||||
-
|
||||
- bch2_accounting_neg(a);
|
||||
- bch2_accounting_mem_mod_locked(trans, a.c, BCH_ACCOUNTING_normal);
|
||||
- bch2_accounting_neg(a);
|
||||
- }
|
||||
+ entry2->start->k.type == KEY_TYPE_accounting)
|
||||
+ bch2_accounting_trans_commit_revert(trans,
|
||||
+ bkey_i_to_accounting(entry2->start), flags);
|
||||
percpu_up_read(&c->mark_lock);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/fs/bcachefs/disk_accounting.h b/fs/bcachefs/disk_accounting.h
|
||||
index 4ea6c8a092bc..6639535dc91c 100644
|
||||
--- a/fs/bcachefs/disk_accounting.h
|
||||
+++ b/fs/bcachefs/disk_accounting.h
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef _BCACHEFS_DISK_ACCOUNTING_H
|
||||
#define _BCACHEFS_DISK_ACCOUNTING_H
|
||||
|
||||
+#include "btree_update.h"
|
||||
#include "eytzinger.h"
|
||||
#include "sb-members.h"
|
||||
|
||||
@@ -204,6 +205,43 @@ static inline void bch2_accounting_mem_read(struct bch_fs *c, struct bpos p,
|
||||
bch2_accounting_mem_read_counters(acc, idx, v, nr, false);
|
||||
}
|
||||
|
||||
+static inline struct bversion journal_pos_to_bversion(struct journal_res *res, unsigned offset)
|
||||
+{
|
||||
+ EBUG_ON(!res->ref);
|
||||
+
|
||||
+ return (struct bversion) {
|
||||
+ .hi = res->seq >> 32,
|
||||
+ .lo = (res->seq << 32) | (res->offset + offset),
|
||||
+ };
|
||||
+}
|
||||
+
|
||||
+static inline int bch2_accounting_trans_commit_hook(struct btree_trans *trans,
|
||||
+ struct bkey_i_accounting *a,
|
||||
+ unsigned commit_flags)
|
||||
+{
|
||||
+ a->k.bversion = journal_pos_to_bversion(&trans->journal_res,
|
||||
+ (u64 *) a - (u64 *) trans->journal_entries);
|
||||
+
|
||||
+ EBUG_ON(bversion_zero(a->k.bversion));
|
||||
+
|
||||
+ return likely(!(commit_flags & BCH_TRANS_COMMIT_skip_accounting_apply))
|
||||
+ ? bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a), BCH_ACCOUNTING_normal)
|
||||
+ : 0;
|
||||
+}
|
||||
+
|
||||
+static inline void bch2_accounting_trans_commit_revert(struct btree_trans *trans,
|
||||
+ struct bkey_i_accounting *a_i,
|
||||
+ unsigned commit_flags)
|
||||
+{
|
||||
+ if (likely(!(commit_flags & BCH_TRANS_COMMIT_skip_accounting_apply))) {
|
||||
+ struct bkey_s_accounting a = accounting_i_to_s(a_i);
|
||||
+
|
||||
+ bch2_accounting_neg(a);
|
||||
+ bch2_accounting_mem_mod_locked(trans, a.c, BCH_ACCOUNTING_normal);
|
||||
+ bch2_accounting_neg(a);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int bch2_fs_replicas_usage_read(struct bch_fs *, darray_char *);
|
||||
int bch2_fs_accounting_read(struct bch_fs *, darray_char *, unsigned);
|
||||
void bch2_fs_accounting_to_text(struct printbuf *, struct bch_fs *);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 6952c5b0d70b70638a070f50668a614235a11175 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Huang <mmpgouride@gmail.com>
|
||||
Date: Fri, 27 Sep 2024 22:26:53 +0800
|
||||
Subject: [PATCH 010/233] bcachefs: Delete dead code
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
lock_fail_root_changed has not been used since commit
|
||||
0d7009d7ca99 ("bcachefs: Delete old deadlock avoidance code")
|
||||
|
||||
Remove it.
|
||||
|
||||
Signed-off-by: Alan Huang <mmpgouride@gmail.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 2 --
|
||||
fs/bcachefs/errcode.h | 1 -
|
||||
2 files changed, 3 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index eef9b89c561d..01152fd5ac57 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -748,8 +748,6 @@ static inline int btree_path_lock_root(struct btree_trans *trans,
|
||||
ret = btree_node_lock(trans, path, &b->c,
|
||||
path->level, lock_type, trace_ip);
|
||||
if (unlikely(ret)) {
|
||||
- if (bch2_err_matches(ret, BCH_ERR_lock_fail_root_changed))
|
||||
- continue;
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
return ret;
|
||||
BUG();
|
||||
diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h
|
||||
index 9c4fe5cdbfb7..e3b0ec7a0f73 100644
|
||||
--- a/fs/bcachefs/errcode.h
|
||||
+++ b/fs/bcachefs/errcode.h
|
||||
@@ -164,7 +164,6 @@
|
||||
x(BCH_ERR_btree_insert_fail, btree_insert_need_journal_res) \
|
||||
x(BCH_ERR_btree_insert_fail, btree_insert_need_journal_reclaim) \
|
||||
x(0, backpointer_to_overwritten_btree_node) \
|
||||
- x(0, lock_fail_root_changed) \
|
||||
x(0, journal_reclaim_would_deadlock) \
|
||||
x(EINVAL, fsck) \
|
||||
x(BCH_ERR_fsck, fsck_fix) \
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,51 +0,0 @@
|
||||
From cf3d513801562174506425a79a9e71050f1d5d77 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Bertschinger <tahbertschinger@gmail.com>
|
||||
Date: Fri, 13 Sep 2024 18:11:22 -0600
|
||||
Subject: [PATCH 011/233] bcachefs: move bch2_xattr_handlers to .rodata
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
A series posted previously moved all of the `struct xattr_handler`
|
||||
tables to .rodata for each filesystem [1].
|
||||
|
||||
However, this appears to have been done shortly before bcachefs was
|
||||
merged, so bcachefs was missed at that time.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230930050033.41174-1-wedsonaf@gmail.com [1]
|
||||
Cc: Wedson Almeida Filho <wedsonaf@gmail.com>
|
||||
Signed-off-by: Thomas Bertschinger <tahbertschinger@gmail.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/xattr.c | 2 +-
|
||||
fs/bcachefs/xattr.h | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c
|
||||
index 952aca400faf..bf3c6bb50495 100644
|
||||
--- a/fs/bcachefs/xattr.c
|
||||
+++ b/fs/bcachefs/xattr.c
|
||||
@@ -609,7 +609,7 @@ static const struct xattr_handler bch_xattr_bcachefs_effective_handler = {
|
||||
|
||||
#endif /* NO_BCACHEFS_FS */
|
||||
|
||||
-const struct xattr_handler *bch2_xattr_handlers[] = {
|
||||
+const struct xattr_handler * const bch2_xattr_handlers[] = {
|
||||
&bch_xattr_user_handler,
|
||||
&bch_xattr_trusted_handler,
|
||||
&bch_xattr_security_handler,
|
||||
diff --git a/fs/bcachefs/xattr.h b/fs/bcachefs/xattr.h
|
||||
index c188a5ad64ce..2c96de051f3e 100644
|
||||
--- a/fs/bcachefs/xattr.h
|
||||
+++ b/fs/bcachefs/xattr.h
|
||||
@@ -44,6 +44,6 @@ int bch2_xattr_set(struct btree_trans *, subvol_inum,
|
||||
|
||||
ssize_t bch2_xattr_list(struct dentry *, char *, size_t);
|
||||
|
||||
-extern const struct xattr_handler *bch2_xattr_handlers[];
|
||||
+extern const struct xattr_handler * const bch2_xattr_handlers[];
|
||||
|
||||
#endif /* _BCACHEFS_XATTR_H */
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 8ed4dcbbc3242c5c8004bb1ca5c1d47d0e8250f9 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Tue, 24 Sep 2024 05:08:39 -0400
|
||||
Subject: [PATCH 012/233] bcachefs: Remove unnecessary peek_slot()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
hash_lookup() used to return an errorcode, and a peek_slot() call was
|
||||
required to get the key it looked up. But we're adding fault injection
|
||||
for transaction restarts, so fix this old unconverted code.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fsck.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
|
||||
index 6b2ddbabe3e7..c96025b8b65d 100644
|
||||
--- a/fs/bcachefs/fsck.c
|
||||
+++ b/fs/bcachefs/fsck.c
|
||||
@@ -170,7 +170,7 @@ static int lookup_dirent_in_snapshot(struct btree_trans *trans,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- struct bkey_s_c_dirent d = bkey_s_c_to_dirent(bch2_btree_iter_peek_slot(&iter));
|
||||
+ struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k);
|
||||
*target = le64_to_cpu(d.v->d_inum);
|
||||
*type = d.v->d_type;
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,61 +0,0 @@
|
||||
From 250087e69e9c123ea58fba31cf301355ee6cb49a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 23 Sep 2024 22:11:41 -0400
|
||||
Subject: [PATCH 013/233] bcachefs: kill btree_trans_restart_nounlock()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Redundant, the normal btree_trans_restart() doesn't unlock.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.h | 7 +++----
|
||||
fs/bcachefs/btree_trans_commit.c | 2 +-
|
||||
2 files changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
|
||||
index 0bda054f80d7..24406f723283 100644
|
||||
--- a/fs/bcachefs/btree_iter.h
|
||||
+++ b/fs/bcachefs/btree_iter.h
|
||||
@@ -341,21 +341,20 @@ static inline void bch2_trans_verify_not_unlocked(struct btree_trans *trans)
|
||||
}
|
||||
|
||||
__always_inline
|
||||
-static int btree_trans_restart_nounlock(struct btree_trans *trans, int err)
|
||||
+static int btree_trans_restart_ip(struct btree_trans *trans, int err, unsigned long ip)
|
||||
{
|
||||
BUG_ON(err <= 0);
|
||||
BUG_ON(!bch2_err_matches(-err, BCH_ERR_transaction_restart));
|
||||
|
||||
trans->restarted = err;
|
||||
- trans->last_restarted_ip = _THIS_IP_;
|
||||
+ trans->last_restarted_ip = ip;
|
||||
return -err;
|
||||
}
|
||||
|
||||
__always_inline
|
||||
static int btree_trans_restart(struct btree_trans *trans, int err)
|
||||
{
|
||||
- btree_trans_restart_nounlock(trans, err);
|
||||
- return -err;
|
||||
+ return btree_trans_restart_ip(trans, err, _THIS_IP_);
|
||||
}
|
||||
|
||||
bool bch2_btree_node_upgrade(struct btree_trans *,
|
||||
diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c
|
||||
index 3d951846a1be..b47f11881fe4 100644
|
||||
--- a/fs/bcachefs/btree_trans_commit.c
|
||||
+++ b/fs/bcachefs/btree_trans_commit.c
|
||||
@@ -624,7 +624,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
|
||||
|
||||
if (race_fault()) {
|
||||
trace_and_count(c, trans_restart_fault_inject, trans, trace_ip);
|
||||
- return btree_trans_restart_nounlock(trans, BCH_ERR_transaction_restart_fault_inject);
|
||||
+ return btree_trans_restart(trans, BCH_ERR_transaction_restart_fault_inject);
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 43bf715a17c1be337b686fb4b5297739a704126e Mon Sep 17 00:00:00 2001
|
||||
From: Dennis Lam <dennis.lamerice@gmail.com>
|
||||
Date: Wed, 11 Sep 2024 21:16:28 -0400
|
||||
Subject: [PATCH 014/233] docs: filesystems: bcachefs: fixed some spelling
|
||||
mistakes in the bcachefs coding style page
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Specifically, fixed spelling of "commit" and pluralization of last sentence.
|
||||
|
||||
Signed-off-by: Dennis Lam <dennis.lamerice@gmail.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
Documentation/filesystems/bcachefs/CodingStyle.rst | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/filesystems/bcachefs/CodingStyle.rst b/Documentation/filesystems/bcachefs/CodingStyle.rst
|
||||
index 01de555e21d8..b29562a6bf55 100644
|
||||
--- a/Documentation/filesystems/bcachefs/CodingStyle.rst
|
||||
+++ b/Documentation/filesystems/bcachefs/CodingStyle.rst
|
||||
@@ -183,4 +183,4 @@ even better as a code comment.
|
||||
A good code comment is wonderful, but even better is the comment that didn't
|
||||
need to exist because the code was so straightforward as to be obvious;
|
||||
organized into small clean and tidy modules, with clear and descriptive names
|
||||
-for functions and variable, where every line of code has a clear purpose.
|
||||
+for functions and variables, where every line of code has a clear purpose.
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 0892d51393106dcb8c7d88cc2ee2f976d4a56c92 Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Blum <thorsten.blum@toblux.com>
|
||||
Date: Mon, 23 Sep 2024 16:20:29 +0200
|
||||
Subject: [PATCH 015/233] bcachefs: Remove duplicate included headers
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The header files dirent_format.h and disk_groups_format.h are included
|
||||
twice. Remove the redundant includes and the following warnings reported
|
||||
by make includecheck:
|
||||
|
||||
disk_groups_format.h is included more than once
|
||||
dirent_format.h is included more than once
|
||||
|
||||
Reviewed-by: Hongbo Li <lihongbo22@huawei.com>
|
||||
Signed-off-by: Thorsten Blum <thorsten.blum@toblux.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs_format.h | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
|
||||
index 5004f6ba997c..6a67df2a2fcd 100644
|
||||
--- a/fs/bcachefs/bcachefs_format.h
|
||||
+++ b/fs/bcachefs/bcachefs_format.h
|
||||
@@ -499,8 +499,6 @@ struct bch_sb_field {
|
||||
#include "disk_groups_format.h"
|
||||
#include "extents_format.h"
|
||||
#include "ec_format.h"
|
||||
-#include "dirent_format.h"
|
||||
-#include "disk_groups_format.h"
|
||||
#include "inode_format.h"
|
||||
#include "journal_seq_blacklist_format.h"
|
||||
#include "logged_ops_format.h"
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,60 +0,0 @@
|
||||
From e4753128a6cfda251b1dcb95320735c0a2e036c8 Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Date: Mon, 23 Sep 2024 16:44:53 +0200
|
||||
Subject: [PATCH 016/233] bcachefs: Use FOREACH_ACL_ENTRY() macro to iterate
|
||||
over acl entries
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use the existing FOREACH_ACL_ENTRY() macro to iterate over POSIX acl
|
||||
entries and remove the custom acl_for_each_entry() macro.
|
||||
|
||||
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/acl.c | 11 +++--------
|
||||
1 file changed, 3 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/acl.c b/fs/bcachefs/acl.c
|
||||
index 87f1be9d4db4..99487727ae64 100644
|
||||
--- a/fs/bcachefs/acl.c
|
||||
+++ b/fs/bcachefs/acl.c
|
||||
@@ -184,11 +184,6 @@ static struct posix_acl *bch2_acl_from_disk(struct btree_trans *trans,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
-#define acl_for_each_entry(acl, acl_e) \
|
||||
- for (acl_e = acl->a_entries; \
|
||||
- acl_e < acl->a_entries + acl->a_count; \
|
||||
- acl_e++)
|
||||
-
|
||||
/*
|
||||
* Convert from in-memory to filesystem representation.
|
||||
*/
|
||||
@@ -199,11 +194,11 @@ bch2_acl_to_xattr(struct btree_trans *trans,
|
||||
{
|
||||
struct bkey_i_xattr *xattr;
|
||||
bch_acl_header *acl_header;
|
||||
- const struct posix_acl_entry *acl_e;
|
||||
+ const struct posix_acl_entry *acl_e, *pe;
|
||||
void *outptr;
|
||||
unsigned nr_short = 0, nr_long = 0, acl_len, u64s;
|
||||
|
||||
- acl_for_each_entry(acl, acl_e) {
|
||||
+ FOREACH_ACL_ENTRY(acl_e, acl, pe) {
|
||||
switch (acl_e->e_tag) {
|
||||
case ACL_USER:
|
||||
case ACL_GROUP:
|
||||
@@ -241,7 +236,7 @@ bch2_acl_to_xattr(struct btree_trans *trans,
|
||||
|
||||
outptr = (void *) acl_header + sizeof(*acl_header);
|
||||
|
||||
- acl_for_each_entry(acl, acl_e) {
|
||||
+ FOREACH_ACL_ENTRY(acl_e, acl, pe) {
|
||||
bch_acl_entry *entry = outptr;
|
||||
|
||||
entry->e_tag = cpu_to_le16(acl_e->e_tag);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From aab94e92a9b24c17443295df539631c0bf2306bb Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 23 Sep 2024 18:11:07 -0400
|
||||
Subject: [PATCH 017/233] bcachefs: add more path idx debug asserts
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
|
||||
index 24406f723283..550db3654f2c 100644
|
||||
--- a/fs/bcachefs/btree_iter.h
|
||||
+++ b/fs/bcachefs/btree_iter.h
|
||||
@@ -23,6 +23,7 @@ static inline void __btree_path_get(struct btree_trans *trans, struct btree_path
|
||||
{
|
||||
unsigned idx = path - trans->paths;
|
||||
|
||||
+ EBUG_ON(idx >= trans->nr_paths);
|
||||
EBUG_ON(!test_bit(idx, trans->paths_allocated));
|
||||
if (unlikely(path->ref == U8_MAX)) {
|
||||
bch2_dump_trans_paths_updates(trans);
|
||||
@@ -36,6 +37,7 @@ static inline void __btree_path_get(struct btree_trans *trans, struct btree_path
|
||||
|
||||
static inline bool __btree_path_put(struct btree_trans *trans, struct btree_path *path, bool intent)
|
||||
{
|
||||
+ EBUG_ON(path - trans->paths >= trans->nr_paths);
|
||||
EBUG_ON(!test_bit(path - trans->paths, trans->paths_allocated));
|
||||
EBUG_ON(!path->ref);
|
||||
EBUG_ON(!path->intent_ref && intent);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,51 +0,0 @@
|
||||
From 31308cdd120cb7df3efd2c90f62c4fc735d7cc43 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 21 Sep 2024 20:21:18 -0400
|
||||
Subject: [PATCH 018/233] bcachefs: bch2_run_explicit_recovery_pass() returns
|
||||
different error when not in recovery
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
if we're not in recovery then there's no way to rewind recovery - give
|
||||
this a different errcode so that any error messages will give us a
|
||||
better idea of what happened.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/errcode.h | 4 +++-
|
||||
fs/bcachefs/recovery_passes.c | 3 +++
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h
|
||||
index e3b0ec7a0f73..40bf1e5775a9 100644
|
||||
--- a/fs/bcachefs/errcode.h
|
||||
+++ b/fs/bcachefs/errcode.h
|
||||
@@ -172,7 +172,9 @@
|
||||
x(BCH_ERR_fsck, fsck_errors_not_fixed) \
|
||||
x(BCH_ERR_fsck, fsck_repair_unimplemented) \
|
||||
x(BCH_ERR_fsck, fsck_repair_impossible) \
|
||||
- x(0, restart_recovery) \
|
||||
+ x(EINVAL, restart_recovery) \
|
||||
+ x(EINVAL, not_in_recovery) \
|
||||
+ x(EINVAL, cannot_rewind_recovery) \
|
||||
x(0, data_update_done) \
|
||||
x(EINVAL, device_state_not_allowed) \
|
||||
x(EINVAL, member_info_missing) \
|
||||
diff --git a/fs/bcachefs/recovery_passes.c b/fs/bcachefs/recovery_passes.c
|
||||
index dff589ddc984..1cc010bf1695 100644
|
||||
--- a/fs/bcachefs/recovery_passes.c
|
||||
+++ b/fs/bcachefs/recovery_passes.c
|
||||
@@ -106,6 +106,9 @@ int bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
if (c->opts.recovery_passes & BIT_ULL(pass))
|
||||
return 0;
|
||||
|
||||
+ if (c->curr_recovery_pass == ARRAY_SIZE(recovery_pass_fns))
|
||||
+ return -BCH_ERR_not_in_recovery;
|
||||
+
|
||||
bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)",
|
||||
bch2_recovery_passes[pass], pass,
|
||||
bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,32 +0,0 @@
|
||||
From f5037ae0441bc26678836db41693086b6eddd2ea Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 21 Sep 2024 23:22:48 -0400
|
||||
Subject: [PATCH 019/233] bcachefs: lru, accounting are alloc btrees
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
They can be regenerated by fsck and don't require a btree node scan,
|
||||
like other alloc btrees.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs_format.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
|
||||
index 6a67df2a2fcd..79a80a78c2d8 100644
|
||||
--- a/fs/bcachefs/bcachefs_format.h
|
||||
+++ b/fs/bcachefs/bcachefs_format.h
|
||||
@@ -1359,6 +1359,8 @@ static inline bool btree_id_is_alloc(enum btree_id id)
|
||||
case BTREE_ID_need_discard:
|
||||
case BTREE_ID_freespace:
|
||||
case BTREE_ID_bucket_gens:
|
||||
+ case BTREE_ID_lru:
|
||||
+ case BTREE_ID_accounting:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,163 +0,0 @@
|
||||
From f5e8d0269ca9ef941bda37f57d0af1dc2ede1546 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 21 Sep 2024 23:27:59 -0400
|
||||
Subject: [PATCH 020/233] bcachefs: Add locking for bch_fs.curr_recovery_pass
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Recovery can rewind in certain situations - when we discover we need to
|
||||
run a pass that doesn't normally run.
|
||||
|
||||
This can happen from another thread for btree node read errors, so we
|
||||
need a bit of locking.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs.h | 1 +
|
||||
fs/bcachefs/recovery_passes.c | 76 ++++++++++++++++++++++++++---------
|
||||
fs/bcachefs/super.c | 1 +
|
||||
3 files changed, 59 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
||||
index 7db81e182c3c..fbd89f91625d 100644
|
||||
--- a/fs/bcachefs/bcachefs.h
|
||||
+++ b/fs/bcachefs/bcachefs.h
|
||||
@@ -1060,6 +1060,7 @@ struct bch_fs {
|
||||
u64 recovery_passes_complete;
|
||||
/* never rewinds version of curr_recovery_pass */
|
||||
enum bch_recovery_pass recovery_pass_done;
|
||||
+ spinlock_t recovery_pass_lock;
|
||||
struct semaphore online_fsck_mutex;
|
||||
|
||||
/* DEBUG JUNK */
|
||||
diff --git a/fs/bcachefs/recovery_passes.c b/fs/bcachefs/recovery_passes.c
|
||||
index 1cc010bf1695..5e7722cc0879 100644
|
||||
--- a/fs/bcachefs/recovery_passes.c
|
||||
+++ b/fs/bcachefs/recovery_passes.c
|
||||
@@ -100,8 +100,8 @@ u64 bch2_recovery_passes_from_stable(u64 v)
|
||||
/*
|
||||
* For when we need to rewind recovery passes and run a pass we skipped:
|
||||
*/
|
||||
-int bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
- enum bch_recovery_pass pass)
|
||||
+static int __bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
+ enum bch_recovery_pass pass)
|
||||
{
|
||||
if (c->opts.recovery_passes & BIT_ULL(pass))
|
||||
return 0;
|
||||
@@ -109,6 +109,13 @@ int bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
if (c->curr_recovery_pass == ARRAY_SIZE(recovery_pass_fns))
|
||||
return -BCH_ERR_not_in_recovery;
|
||||
|
||||
+ if (pass < BCH_RECOVERY_PASS_set_may_go_rw &&
|
||||
+ c->curr_recovery_pass >= BCH_RECOVERY_PASS_set_may_go_rw) {
|
||||
+ bch_info(c, "need recovery pass %s (%u), but already rw",
|
||||
+ bch2_recovery_passes[pass], pass);
|
||||
+ return -BCH_ERR_cannot_rewind_recovery;
|
||||
+ }
|
||||
+
|
||||
bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)",
|
||||
bch2_recovery_passes[pass], pass,
|
||||
bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass);
|
||||
@@ -124,6 +131,16 @@ int bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
}
|
||||
}
|
||||
|
||||
+int bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
+ enum bch_recovery_pass pass)
|
||||
+{
|
||||
+ unsigned long flags;
|
||||
+ spin_lock_irqsave(&c->recovery_pass_lock, flags);
|
||||
+ int ret = __bch2_run_explicit_recovery_pass(c, pass);
|
||||
+ spin_unlock_irqrestore(&c->recovery_pass_lock, flags);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *c,
|
||||
enum bch_recovery_pass pass)
|
||||
{
|
||||
@@ -237,30 +254,51 @@ int bch2_run_recovery_passes(struct bch_fs *c)
|
||||
c->opts.recovery_passes_exclude &= ~BCH_RECOVERY_PASS_set_may_go_rw;
|
||||
|
||||
while (c->curr_recovery_pass < ARRAY_SIZE(recovery_pass_fns)) {
|
||||
+ spin_lock_irq(&c->recovery_pass_lock);
|
||||
+ unsigned pass = c->curr_recovery_pass;
|
||||
+
|
||||
if (c->opts.recovery_pass_last &&
|
||||
- c->curr_recovery_pass > c->opts.recovery_pass_last)
|
||||
+ c->curr_recovery_pass > c->opts.recovery_pass_last) {
|
||||
+ spin_unlock_irq(&c->recovery_pass_lock);
|
||||
break;
|
||||
+ }
|
||||
|
||||
- if (should_run_recovery_pass(c, c->curr_recovery_pass)) {
|
||||
- unsigned pass = c->curr_recovery_pass;
|
||||
-
|
||||
- ret = bch2_run_recovery_pass(c, c->curr_recovery_pass) ?:
|
||||
- bch2_journal_flush(&c->journal);
|
||||
- if (bch2_err_matches(ret, BCH_ERR_restart_recovery) ||
|
||||
- (ret && c->curr_recovery_pass < pass))
|
||||
- continue;
|
||||
- if (ret)
|
||||
- break;
|
||||
-
|
||||
- c->recovery_passes_complete |= BIT_ULL(c->curr_recovery_pass);
|
||||
+ if (!should_run_recovery_pass(c, pass)) {
|
||||
+ c->curr_recovery_pass++;
|
||||
+ c->recovery_pass_done = max(c->recovery_pass_done, pass);
|
||||
+ spin_unlock_irq(&c->recovery_pass_lock);
|
||||
+ continue;
|
||||
+ }
|
||||
+ spin_unlock_irq(&c->recovery_pass_lock);
|
||||
+
|
||||
+ ret = bch2_run_recovery_pass(c, pass) ?:
|
||||
+ bch2_journal_flush(&c->journal);
|
||||
+
|
||||
+ spin_lock_irq(&c->recovery_pass_lock);
|
||||
+ if (c->curr_recovery_pass < pass) {
|
||||
+ /*
|
||||
+ * bch2_run_explicit_recovery_pass() was called: we
|
||||
+ * can't always catch -BCH_ERR_restart_recovery because
|
||||
+ * it may have been called from another thread (btree
|
||||
+ * node read completion)
|
||||
+ */
|
||||
+ spin_unlock_irq(&c->recovery_pass_lock);
|
||||
+ continue;
|
||||
+ } else if (c->curr_recovery_pass == pass) {
|
||||
+ c->curr_recovery_pass++;
|
||||
+ } else {
|
||||
+ BUG();
|
||||
}
|
||||
+ spin_unlock_irq(&c->recovery_pass_lock);
|
||||
|
||||
- c->recovery_pass_done = max(c->recovery_pass_done, c->curr_recovery_pass);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
|
||||
- if (!test_bit(BCH_FS_error, &c->flags))
|
||||
- bch2_clear_recovery_pass_required(c, c->curr_recovery_pass);
|
||||
+ c->recovery_passes_complete |= BIT_ULL(pass);
|
||||
+ c->recovery_pass_done = max(c->recovery_pass_done, pass);
|
||||
|
||||
- c->curr_recovery_pass++;
|
||||
+ if (!test_bit(BCH_FS_error, &c->flags))
|
||||
+ bch2_clear_recovery_pass_required(c, pass);
|
||||
}
|
||||
|
||||
return ret;
|
||||
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
|
||||
index 17442df7326d..d6411324cd3f 100644
|
||||
--- a/fs/bcachefs/super.c
|
||||
+++ b/fs/bcachefs/super.c
|
||||
@@ -766,6 +766,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
|
||||
|
||||
refcount_set(&c->ro_ref, 1);
|
||||
init_waitqueue_head(&c->ro_ref_wait);
|
||||
+ spin_lock_init(&c->recovery_pass_lock);
|
||||
sema_init(&c->online_fsck_mutex, 1);
|
||||
|
||||
init_rwsem(&c->gc_lock);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,160 +0,0 @@
|
||||
From 771bf65862db8911c5368bf47410c629928562e4 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 21 Sep 2024 23:40:01 -0400
|
||||
Subject: [PATCH 021/233] bcachefs: bch2_btree_lost_data() now uses
|
||||
run_explicit_rceovery_pass_persistent()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Also get a bit more fine grained about which passes to run for which
|
||||
btrees.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/recovery.c | 63 +++++++++++++++++++++++------------
|
||||
fs/bcachefs/recovery.h | 2 +-
|
||||
fs/bcachefs/recovery_passes.c | 11 ++++++
|
||||
fs/bcachefs/recovery_passes.h | 1 +
|
||||
4 files changed, 54 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
|
||||
index 3c7f941dde39..b1c83e72c0d8 100644
|
||||
--- a/fs/bcachefs/recovery.c
|
||||
+++ b/fs/bcachefs/recovery.c
|
||||
@@ -34,21 +34,52 @@
|
||||
|
||||
#define QSTR(n) { { { .len = strlen(n) } }, .name = n }
|
||||
|
||||
-void bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree)
|
||||
+int bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree)
|
||||
{
|
||||
- if (btree >= BTREE_ID_NR_MAX)
|
||||
- return;
|
||||
-
|
||||
u64 b = BIT_ULL(btree);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ mutex_lock(&c->sb_lock);
|
||||
|
||||
if (!(c->sb.btrees_lost_data & b)) {
|
||||
bch_err(c, "flagging btree %s lost data", bch2_btree_id_str(btree));
|
||||
-
|
||||
- mutex_lock(&c->sb_lock);
|
||||
bch2_sb_field_get(c->disk_sb.sb, ext)->btrees_lost_data |= cpu_to_le64(b);
|
||||
- bch2_write_super(c);
|
||||
- mutex_unlock(&c->sb_lock);
|
||||
}
|
||||
+
|
||||
+ switch (btree) {
|
||||
+ case BTREE_ID_alloc:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_allocations) ?: ret;
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
|
||||
+ goto out;
|
||||
+ case BTREE_ID_backpointers:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_btree_backpointers) ?: ret;
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_extents_to_backpointers) ?: ret;
|
||||
+ goto out;
|
||||
+ case BTREE_ID_need_discard:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
|
||||
+ goto out;
|
||||
+ case BTREE_ID_freespace:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
|
||||
+ goto out;
|
||||
+ case BTREE_ID_bucket_gens:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
|
||||
+ goto out;
|
||||
+ case BTREE_ID_lru:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
|
||||
+ goto out;
|
||||
+ case BTREE_ID_accounting:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_allocations) ?: ret;
|
||||
+ goto out;
|
||||
+ default:
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_scan_for_btree_nodes) ?: ret;
|
||||
+ ret = bch2_run_explicit_recovery_pass_persistent_locked(c, BCH_RECOVERY_PASS_check_topology) ?: ret;
|
||||
+ goto out;
|
||||
+ }
|
||||
+out:
|
||||
+ bch2_write_super(c);
|
||||
+ mutex_unlock(&c->sb_lock);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/* for -o reconstruct_alloc: */
|
||||
@@ -524,22 +555,10 @@ static int read_btree_roots(struct bch_fs *c)
|
||||
c, btree_root_read_error,
|
||||
"error reading btree root %s l=%u: %s",
|
||||
bch2_btree_id_str(i), r->level, bch2_err_str(ret))) {
|
||||
- if (btree_id_is_alloc(i)) {
|
||||
- c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_allocations);
|
||||
- c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_alloc_info);
|
||||
- c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_lrus);
|
||||
- c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers);
|
||||
- c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_alloc_to_lru_refs);
|
||||
- c->sb.compat &= ~(1ULL << BCH_COMPAT_alloc_info);
|
||||
+ if (btree_id_is_alloc(i))
|
||||
r->error = 0;
|
||||
- } else if (!(c->opts.recovery_passes & BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes))) {
|
||||
- bch_info(c, "will run btree node scan");
|
||||
- c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes);
|
||||
- c->opts.recovery_passes |= BIT_ULL(BCH_RECOVERY_PASS_check_topology);
|
||||
- }
|
||||
|
||||
- ret = 0;
|
||||
- bch2_btree_lost_data(c, i);
|
||||
+ ret = bch2_btree_lost_data(c, i);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/recovery.h b/fs/bcachefs/recovery.h
|
||||
index 4bf818de1f2f..b0d55754b21b 100644
|
||||
--- a/fs/bcachefs/recovery.h
|
||||
+++ b/fs/bcachefs/recovery.h
|
||||
@@ -2,7 +2,7 @@
|
||||
#ifndef _BCACHEFS_RECOVERY_H
|
||||
#define _BCACHEFS_RECOVERY_H
|
||||
|
||||
-void bch2_btree_lost_data(struct bch_fs *, enum btree_id);
|
||||
+int bch2_btree_lost_data(struct bch_fs *, enum btree_id);
|
||||
|
||||
int bch2_journal_replay(struct bch_fs *);
|
||||
|
||||
diff --git a/fs/bcachefs/recovery_passes.c b/fs/bcachefs/recovery_passes.c
|
||||
index 5e7722cc0879..1240c5c19fea 100644
|
||||
--- a/fs/bcachefs/recovery_passes.c
|
||||
+++ b/fs/bcachefs/recovery_passes.c
|
||||
@@ -141,6 +141,17 @@ int bch2_run_explicit_recovery_pass(struct bch_fs *c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int bch2_run_explicit_recovery_pass_persistent_locked(struct bch_fs *c,
|
||||
+ enum bch_recovery_pass pass)
|
||||
+{
|
||||
+ lockdep_assert_held(&c->sb_lock);
|
||||
+
|
||||
+ struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext);
|
||||
+ __set_bit_le64(bch2_recovery_pass_to_stable(pass), ext->recovery_passes_required);
|
||||
+
|
||||
+ return bch2_run_explicit_recovery_pass(c, pass);
|
||||
+}
|
||||
+
|
||||
int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *c,
|
||||
enum bch_recovery_pass pass)
|
||||
{
|
||||
diff --git a/fs/bcachefs/recovery_passes.h b/fs/bcachefs/recovery_passes.h
|
||||
index 99b464e127b8..7d7339c8fa29 100644
|
||||
--- a/fs/bcachefs/recovery_passes.h
|
||||
+++ b/fs/bcachefs/recovery_passes.h
|
||||
@@ -9,6 +9,7 @@ u64 bch2_recovery_passes_from_stable(u64 v);
|
||||
u64 bch2_fsck_recovery_passes(void);
|
||||
|
||||
int bch2_run_explicit_recovery_pass(struct bch_fs *, enum bch_recovery_pass);
|
||||
+int bch2_run_explicit_recovery_pass_persistent_locked(struct bch_fs *, enum bch_recovery_pass);
|
||||
int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *, enum bch_recovery_pass);
|
||||
|
||||
int bch2_run_online_recovery_passes(struct bch_fs *);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,67 +0,0 @@
|
||||
From 703b8d61ec2cef306f5379847adc089069333897 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Wed, 9 Oct 2024 21:26:05 -0400
|
||||
Subject: [PATCH 022/233] bcachefs: improved bkey_val_copy()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Factor out some common code, add typechecking.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.h | 28 +++++++++++++---------------
|
||||
1 file changed, 13 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
|
||||
index 550db3654f2c..dda07a320488 100644
|
||||
--- a/fs/bcachefs/btree_iter.h
|
||||
+++ b/fs/bcachefs/btree_iter.h
|
||||
@@ -594,13 +594,18 @@ static inline struct bkey_s_c bch2_bkey_get_iter(struct btree_trans *trans,
|
||||
bkey_s_c_to_##_type(__bch2_bkey_get_iter(_trans, _iter, \
|
||||
_btree_id, _pos, _flags, KEY_TYPE_##_type))
|
||||
|
||||
+static inline void __bkey_val_copy(void *dst_v, unsigned dst_size, struct bkey_s_c src_k)
|
||||
+{
|
||||
+ unsigned b = min_t(unsigned, dst_size, bkey_val_bytes(src_k.k));
|
||||
+ memcpy(dst_v, src_k.v, b);
|
||||
+ if (unlikely(b < dst_size))
|
||||
+ memset(dst_v + b, 0, dst_size - b);
|
||||
+}
|
||||
+
|
||||
#define bkey_val_copy(_dst_v, _src_k) \
|
||||
do { \
|
||||
- unsigned b = min_t(unsigned, sizeof(*_dst_v), \
|
||||
- bkey_val_bytes(_src_k.k)); \
|
||||
- memcpy(_dst_v, _src_k.v, b); \
|
||||
- if (b < sizeof(*_dst_v)) \
|
||||
- memset((void *) (_dst_v) + b, 0, sizeof(*_dst_v) - b); \
|
||||
+ BUILD_BUG_ON(!__typecheck(*_dst_v, *_src_k.v)); \
|
||||
+ __bkey_val_copy(_dst_v, sizeof(*_dst_v), _src_k.s_c); \
|
||||
} while (0)
|
||||
|
||||
static inline int __bch2_bkey_get_val_typed(struct btree_trans *trans,
|
||||
@@ -609,17 +614,10 @@ static inline int __bch2_bkey_get_val_typed(struct btree_trans *trans,
|
||||
unsigned val_size, void *val)
|
||||
{
|
||||
struct btree_iter iter;
|
||||
- struct bkey_s_c k;
|
||||
- int ret;
|
||||
-
|
||||
- k = __bch2_bkey_get_iter(trans, &iter, btree_id, pos, flags, type);
|
||||
- ret = bkey_err(k);
|
||||
+ struct bkey_s_c k = __bch2_bkey_get_iter(trans, &iter, btree_id, pos, flags, type);
|
||||
+ int ret = bkey_err(k);
|
||||
if (!ret) {
|
||||
- unsigned b = min_t(unsigned, bkey_val_bytes(k.k), val_size);
|
||||
-
|
||||
- memcpy(val, k.v, b);
|
||||
- if (unlikely(b < sizeof(*val)))
|
||||
- memset((void *) val + b, 0, sizeof(*val) - b);
|
||||
+ __bkey_val_copy(val, val_size, k);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
}
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,54 +0,0 @@
|
||||
From 7d6273caeac4a7389272be2c870562308753656a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Wed, 9 Oct 2024 21:51:05 -0400
|
||||
Subject: [PATCH 023/233] bcachefs: Factor out jset_entry_log_msg_bytes()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Needed for improved userspace cmd_list_journal
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs_format.h | 9 +++++++++
|
||||
fs/bcachefs/journal_io.c | 3 +--
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
|
||||
index 79a80a78c2d8..c5e3824d5771 100644
|
||||
--- a/fs/bcachefs/bcachefs_format.h
|
||||
+++ b/fs/bcachefs/bcachefs_format.h
|
||||
@@ -1219,6 +1219,15 @@ struct jset_entry_log {
|
||||
u8 d[];
|
||||
} __packed __aligned(8);
|
||||
|
||||
+static inline unsigned jset_entry_log_msg_bytes(struct jset_entry_log *l)
|
||||
+{
|
||||
+ unsigned b = vstruct_bytes(&l->entry) - offsetof(struct jset_entry_log, d);
|
||||
+
|
||||
+ while (b && !l->d[b - 1])
|
||||
+ --b;
|
||||
+ return b;
|
||||
+}
|
||||
+
|
||||
struct jset_entry_datetime {
|
||||
struct jset_entry entry;
|
||||
__le64 seconds;
|
||||
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
|
||||
index fb35dd336331..7c7595e5369b 100644
|
||||
--- a/fs/bcachefs/journal_io.c
|
||||
+++ b/fs/bcachefs/journal_io.c
|
||||
@@ -738,9 +738,8 @@ static void journal_entry_log_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct jset_entry *entry)
|
||||
{
|
||||
struct jset_entry_log *l = container_of(entry, struct jset_entry_log, entry);
|
||||
- unsigned bytes = vstruct_bytes(entry) - offsetof(struct jset_entry_log, d);
|
||||
|
||||
- prt_printf(out, "%.*s", bytes, l->d);
|
||||
+ prt_printf(out, "%.*s", jset_entry_log_msg_bytes(l), l->d);
|
||||
}
|
||||
|
||||
static int journal_entry_overwrite_validate(struct bch_fs *c,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,78 +0,0 @@
|
||||
From a1fbdad42fc52ff038183644e39785525553e667 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Wed, 9 Oct 2024 21:27:11 -0400
|
||||
Subject: [PATCH 024/233] bcachefs: better error message in
|
||||
check_snapshot_tree()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If we find a snapshot node and it didn't match the snapshot tree, we
|
||||
should print it.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/snapshot.c | 18 +++++++++++++++---
|
||||
1 file changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
|
||||
index feaf2aa0d900..34e01bd8127f 100644
|
||||
--- a/fs/bcachefs/snapshot.c
|
||||
+++ b/fs/bcachefs/snapshot.c
|
||||
@@ -506,7 +506,6 @@ static int bch2_snapshot_tree_master_subvol(struct btree_trans *trans,
|
||||
break;
|
||||
}
|
||||
}
|
||||
-
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (!ret && !found) {
|
||||
@@ -536,6 +535,7 @@ static int check_snapshot_tree(struct btree_trans *trans,
|
||||
struct bch_snapshot s;
|
||||
struct bch_subvolume subvol;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
+ struct btree_iter snapshot_iter = {};
|
||||
u32 root_id;
|
||||
int ret;
|
||||
|
||||
@@ -545,16 +545,27 @@ static int check_snapshot_tree(struct btree_trans *trans,
|
||||
st = bkey_s_c_to_snapshot_tree(k);
|
||||
root_id = le32_to_cpu(st.v->root_snapshot);
|
||||
|
||||
- ret = bch2_snapshot_lookup(trans, root_id, &s);
|
||||
+ struct bkey_s_c_snapshot snapshot_k =
|
||||
+ bch2_bkey_get_iter_typed(trans, &snapshot_iter, BTREE_ID_snapshots,
|
||||
+ POS(0, root_id), 0, snapshot);
|
||||
+ ret = bkey_err(snapshot_k);
|
||||
if (ret && !bch2_err_matches(ret, ENOENT))
|
||||
goto err;
|
||||
|
||||
+ if (!ret)
|
||||
+ bkey_val_copy(&s, snapshot_k);
|
||||
+
|
||||
if (fsck_err_on(ret ||
|
||||
root_id != bch2_snapshot_root(c, root_id) ||
|
||||
st.k->p.offset != le32_to_cpu(s.tree),
|
||||
trans, snapshot_tree_to_missing_snapshot,
|
||||
"snapshot tree points to missing/incorrect snapshot:\n %s",
|
||||
- (bch2_bkey_val_to_text(&buf, c, st.s_c), buf.buf))) {
|
||||
+ (bch2_bkey_val_to_text(&buf, c, st.s_c),
|
||||
+ prt_newline(&buf),
|
||||
+ ret
|
||||
+ ? prt_printf(&buf, "(%s)", bch2_err_str(ret))
|
||||
+ : bch2_bkey_val_to_text(&buf, c, snapshot_k.s_c),
|
||||
+ buf.buf))) {
|
||||
ret = bch2_btree_delete_at(trans, iter, 0);
|
||||
goto err;
|
||||
}
|
||||
@@ -605,6 +616,7 @@ static int check_snapshot_tree(struct btree_trans *trans,
|
||||
}
|
||||
err:
|
||||
fsck_err:
|
||||
+ bch2_trans_iter_exit(trans, &snapshot_iter);
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,657 +0,0 @@
|
||||
From 78cf5d12ae82115f913292e8e4fa35e73161504a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Wed, 9 Oct 2024 23:02:04 -0400
|
||||
Subject: [PATCH 025/233] bcachefs: Avoid bch2_btree_id_str()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Prefer bch2_btree_id_to_text() - it prints out the integer ID when
|
||||
unknown.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/backpointers.c | 24 ++++++++-------
|
||||
fs/bcachefs/bbpos.h | 2 +-
|
||||
fs/bcachefs/btree_cache.c | 37 +++++++++++++++---------
|
||||
fs/bcachefs/btree_cache.h | 3 +-
|
||||
fs/bcachefs/btree_gc.c | 45 +++++++++++++++++------------
|
||||
fs/bcachefs/btree_io.c | 13 +++++----
|
||||
fs/bcachefs/btree_iter.c | 32 ++++++++++----------
|
||||
fs/bcachefs/btree_journal_iter.c | 5 +++-
|
||||
fs/bcachefs/btree_node_scan.c | 10 ++++---
|
||||
fs/bcachefs/btree_update_interior.c | 23 ++++++++-------
|
||||
fs/bcachefs/debug.c | 4 ++-
|
||||
fs/bcachefs/disk_accounting.c | 3 +-
|
||||
fs/bcachefs/journal_io.c | 3 +-
|
||||
fs/bcachefs/recovery.c | 25 +++++++++++-----
|
||||
fs/bcachefs/sysfs.c | 3 +-
|
||||
15 files changed, 140 insertions(+), 92 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c
|
||||
index 654a58132a4d..f323ce4b0b33 100644
|
||||
--- a/fs/bcachefs/backpointers.c
|
||||
+++ b/fs/bcachefs/backpointers.c
|
||||
@@ -81,12 +81,11 @@ int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
void bch2_backpointer_to_text(struct printbuf *out, const struct bch_backpointer *bp)
|
||||
{
|
||||
- prt_printf(out, "btree=%s l=%u offset=%llu:%u len=%u pos=",
|
||||
- bch2_btree_id_str(bp->btree_id),
|
||||
- bp->level,
|
||||
- (u64) (bp->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT),
|
||||
- (u32) bp->bucket_offset & ~(~0U << MAX_EXTENT_COMPRESS_RATIO_SHIFT),
|
||||
- bp->bucket_len);
|
||||
+ bch2_btree_id_level_to_text(out, bp->btree_id, bp->level);
|
||||
+ prt_printf(out, " offset=%llu:%u len=%u pos=",
|
||||
+ (u64) (bp->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT),
|
||||
+ (u32) bp->bucket_offset & ~(~0U << MAX_EXTENT_COMPRESS_RATIO_SHIFT),
|
||||
+ bp->bucket_len);
|
||||
bch2_bpos_to_text(out, bp->pos);
|
||||
}
|
||||
|
||||
@@ -501,9 +500,13 @@ static int check_extent_checksum(struct btree_trans *trans,
|
||||
goto err;
|
||||
|
||||
prt_str(&buf, "extents pointing to same space, but first extent checksum bad:");
|
||||
- prt_printf(&buf, "\n %s ", bch2_btree_id_str(btree));
|
||||
+ prt_printf(&buf, "\n ");
|
||||
+ bch2_btree_id_to_text(&buf, btree);
|
||||
+ prt_str(&buf, " ");
|
||||
bch2_bkey_val_to_text(&buf, c, extent);
|
||||
- prt_printf(&buf, "\n %s ", bch2_btree_id_str(o_btree));
|
||||
+ prt_printf(&buf, "\n ");
|
||||
+ bch2_btree_id_to_text(&buf, o_btree);
|
||||
+ prt_str(&buf, " ");
|
||||
bch2_bkey_val_to_text(&buf, c, extent2);
|
||||
|
||||
struct nonce nonce = extent_nonce(extent.k->bversion, p.crc);
|
||||
@@ -638,8 +641,9 @@ static int check_bp_exists(struct btree_trans *trans,
|
||||
goto err;
|
||||
missing:
|
||||
printbuf_reset(&buf);
|
||||
- prt_printf(&buf, "missing backpointer for btree=%s l=%u ",
|
||||
- bch2_btree_id_str(bp.btree_id), bp.level);
|
||||
+ prt_str(&buf, "missing backpointer for btree=");
|
||||
+ bch2_btree_id_to_text(&buf, bp.btree_id);
|
||||
+ prt_printf(&buf, " l=%u ", bp.level);
|
||||
bch2_bkey_val_to_text(&buf, c, orig_k);
|
||||
prt_printf(&buf, "\n got: ");
|
||||
bch2_bkey_val_to_text(&buf, c, bp_k);
|
||||
diff --git a/fs/bcachefs/bbpos.h b/fs/bcachefs/bbpos.h
|
||||
index be2edced5213..63abe17f35ea 100644
|
||||
--- a/fs/bcachefs/bbpos.h
|
||||
+++ b/fs/bcachefs/bbpos.h
|
||||
@@ -29,7 +29,7 @@ static inline struct bbpos bbpos_successor(struct bbpos pos)
|
||||
|
||||
static inline void bch2_bbpos_to_text(struct printbuf *out, struct bbpos pos)
|
||||
{
|
||||
- prt_str(out, bch2_btree_id_str(pos.btree));
|
||||
+ bch2_btree_id_to_text(out, pos.btree);
|
||||
prt_char(out, ':');
|
||||
bch2_bpos_to_text(out, pos.pos);
|
||||
}
|
||||
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c
|
||||
index 7123019ab3bc..a0a406b0c7bc 100644
|
||||
--- a/fs/bcachefs/btree_cache.c
|
||||
+++ b/fs/bcachefs/btree_cache.c
|
||||
@@ -1004,16 +1004,14 @@ static noinline void btree_bad_header(struct bch_fs *c, struct btree *b)
|
||||
return;
|
||||
|
||||
prt_printf(&buf,
|
||||
- "btree node header doesn't match ptr\n"
|
||||
- "btree %s level %u\n"
|
||||
- "ptr: ",
|
||||
- bch2_btree_id_str(b->c.btree_id), b->c.level);
|
||||
+ "btree node header doesn't match ptr: ");
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_str(&buf, "\nptr: ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
- prt_printf(&buf, "\nheader: btree %s level %llu\n"
|
||||
- "min ",
|
||||
- bch2_btree_id_str(BTREE_NODE_ID(b->data)),
|
||||
- BTREE_NODE_LEVEL(b->data));
|
||||
+ prt_str(&buf, "\nheader: ");
|
||||
+ bch2_btree_id_level_to_text(&buf, BTREE_NODE_ID(b->data), BTREE_NODE_LEVEL(b->data));
|
||||
+ prt_str(&buf, "\nmin ");
|
||||
bch2_bpos_to_text(&buf, b->data->min_key);
|
||||
|
||||
prt_printf(&buf, "\nmax ");
|
||||
@@ -1398,12 +1396,19 @@ void bch2_btree_id_to_text(struct printbuf *out, enum btree_id btree)
|
||||
prt_printf(out, "(unknown btree %u)", btree);
|
||||
}
|
||||
|
||||
+void bch2_btree_id_level_to_text(struct printbuf *out, enum btree_id btree, unsigned level)
|
||||
+{
|
||||
+ prt_str(out, "btree=");
|
||||
+ bch2_btree_id_to_text(out, btree);
|
||||
+ prt_printf(out, " level=%u", level);
|
||||
+}
|
||||
+
|
||||
void bch2_btree_pos_to_text(struct printbuf *out, struct bch_fs *c, const struct btree *b)
|
||||
{
|
||||
- prt_printf(out, "%s level %u/%u\n ",
|
||||
- bch2_btree_id_str(b->c.btree_id),
|
||||
- b->c.level,
|
||||
- bch2_btree_id_root(c, b->c.btree_id)->level);
|
||||
+ bch2_btree_id_to_text(out, b->c.btree_id);
|
||||
+ prt_printf(out, " level %u/%u\n ",
|
||||
+ b->c.level,
|
||||
+ bch2_btree_id_root(c, b->c.btree_id)->level);
|
||||
bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(&b->key));
|
||||
}
|
||||
|
||||
@@ -1478,8 +1483,12 @@ void bch2_btree_cache_to_text(struct printbuf *out, const struct btree_cache *bc
|
||||
prt_printf(out, "cannibalize lock:\t%p\n", bc->alloc_lock);
|
||||
prt_newline(out);
|
||||
|
||||
- for (unsigned i = 0; i < ARRAY_SIZE(bc->nr_by_btree); i++)
|
||||
- prt_btree_cache_line(out, c, bch2_btree_id_str(i), bc->nr_by_btree[i]);
|
||||
+ for (unsigned i = 0; i < ARRAY_SIZE(bc->nr_by_btree); i++) {
|
||||
+ bch2_btree_id_to_text(out, i);
|
||||
+ prt_printf(out, "\t");
|
||||
+ prt_human_readable_u64(out, bc->nr_by_btree[i] * c->opts.btree_node_size);
|
||||
+ prt_printf(out, " (%zu)\n", bc->nr_by_btree[i]);
|
||||
+ }
|
||||
|
||||
prt_newline(out);
|
||||
prt_printf(out, "freed:\t%zu\n", bc->nr_freed);
|
||||
diff --git a/fs/bcachefs/btree_cache.h b/fs/bcachefs/btree_cache.h
|
||||
index 66e86d1a178d..6cfacacb6769 100644
|
||||
--- a/fs/bcachefs/btree_cache.h
|
||||
+++ b/fs/bcachefs/btree_cache.h
|
||||
@@ -138,8 +138,9 @@ static inline struct btree *btree_node_root(struct bch_fs *c, struct btree *b)
|
||||
return bch2_btree_id_root(c, b->c.btree_id)->b;
|
||||
}
|
||||
|
||||
-const char *bch2_btree_id_str(enum btree_id);
|
||||
+const char *bch2_btree_id_str(enum btree_id); /* avoid */
|
||||
void bch2_btree_id_to_text(struct printbuf *, enum btree_id);
|
||||
+void bch2_btree_id_level_to_text(struct printbuf *, enum btree_id, unsigned);
|
||||
|
||||
void bch2_btree_pos_to_text(struct printbuf *, struct bch_fs *, const struct btree *);
|
||||
void bch2_btree_node_to_text(struct printbuf *, struct bch_fs *, const struct btree *);
|
||||
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
|
||||
index 81dcf9e512c0..3c4e66da1ca4 100644
|
||||
--- a/fs/bcachefs/btree_gc.c
|
||||
+++ b/fs/bcachefs/btree_gc.c
|
||||
@@ -56,8 +56,8 @@ void bch2_gc_pos_to_text(struct printbuf *out, struct gc_pos *p)
|
||||
{
|
||||
prt_str(out, bch2_gc_phase_strs[p->phase]);
|
||||
prt_char(out, ' ');
|
||||
- bch2_btree_id_to_text(out, p->btree);
|
||||
- prt_printf(out, " l=%u ", p->level);
|
||||
+ bch2_btree_id_level_to_text(out, p->btree, p->level);
|
||||
+ prt_char(out, ' ');
|
||||
bch2_bpos_to_text(out, p->pos);
|
||||
}
|
||||
|
||||
@@ -209,8 +209,9 @@ static int btree_check_node_boundaries(struct btree_trans *trans, struct btree *
|
||||
if (bpos_eq(expected_start, cur->data->min_key))
|
||||
return 0;
|
||||
|
||||
- prt_printf(&buf, " at btree %s level %u:\n parent: ",
|
||||
- bch2_btree_id_str(b->c.btree_id), b->c.level);
|
||||
+ prt_printf(&buf, " at ");
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_printf(&buf, ":\n parent: ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
if (prev) {
|
||||
@@ -277,8 +278,9 @@ static int btree_repair_node_end(struct btree_trans *trans, struct btree *b,
|
||||
if (bpos_eq(child->key.k.p, b->key.k.p))
|
||||
return 0;
|
||||
|
||||
- prt_printf(&buf, "at btree %s level %u:\n parent: ",
|
||||
- bch2_btree_id_str(b->c.btree_id), b->c.level);
|
||||
+ prt_printf(&buf, " at ");
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_printf(&buf, ":\n parent: ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
prt_str(&buf, "\n child: ");
|
||||
@@ -341,14 +343,14 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
|
||||
ret = PTR_ERR_OR_ZERO(cur);
|
||||
|
||||
printbuf_reset(&buf);
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level - 1);
|
||||
+ prt_char(&buf, ' ');
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur_k.k));
|
||||
|
||||
if (mustfix_fsck_err_on(bch2_err_matches(ret, EIO),
|
||||
trans, btree_node_unreadable,
|
||||
- "Topology repair: unreadable btree node at btree %s level %u:\n"
|
||||
+ "Topology repair: unreadable btree node at\n"
|
||||
" %s",
|
||||
- bch2_btree_id_str(b->c.btree_id),
|
||||
- b->c.level - 1,
|
||||
buf.buf)) {
|
||||
bch2_btree_node_evict(trans, cur_k.k);
|
||||
cur = NULL;
|
||||
@@ -370,7 +372,7 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
|
||||
break;
|
||||
|
||||
if (bch2_btree_node_is_stale(c, cur)) {
|
||||
- bch_info(c, "btree node %s older than nodes found by scanning", buf.buf);
|
||||
+ bch_info(c, "btree node older than nodes found by scanning\n %s", buf.buf);
|
||||
six_unlock_read(&cur->c.lock);
|
||||
bch2_btree_node_evict(trans, cur_k.k);
|
||||
ret = bch2_journal_key_delete(c, b->c.btree_id,
|
||||
@@ -478,14 +480,13 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
|
||||
}
|
||||
|
||||
printbuf_reset(&buf);
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_newline(&buf);
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
if (mustfix_fsck_err_on(!have_child,
|
||||
trans, btree_node_topology_interior_node_empty,
|
||||
- "empty interior btree node at btree %s level %u\n"
|
||||
- " %s",
|
||||
- bch2_btree_id_str(b->c.btree_id),
|
||||
- b->c.level, buf.buf))
|
||||
+ "empty interior btree node at %s", buf.buf))
|
||||
ret = DROP_THIS_NODE;
|
||||
err:
|
||||
fsck_err:
|
||||
@@ -511,6 +512,7 @@ int bch2_check_topology(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct bpos pulled_from_scan = POS_MIN;
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_srcu_unlock(trans);
|
||||
@@ -519,19 +521,21 @@ int bch2_check_topology(struct bch_fs *c)
|
||||
struct btree_root *r = bch2_btree_id_root(c, i);
|
||||
bool reconstructed_root = false;
|
||||
|
||||
+ bch2_btree_id_to_text(&buf, i);
|
||||
+
|
||||
if (r->error) {
|
||||
ret = bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_scan_for_btree_nodes);
|
||||
if (ret)
|
||||
break;
|
||||
reconstruct_root:
|
||||
- bch_info(c, "btree root %s unreadable, must recover from scan", bch2_btree_id_str(i));
|
||||
+ bch_info(c, "btree root %s unreadable, must recover from scan", buf.buf);
|
||||
|
||||
r->alive = false;
|
||||
r->error = 0;
|
||||
|
||||
if (!bch2_btree_has_scanned_nodes(c, i)) {
|
||||
mustfix_fsck_err(trans, btree_root_unreadable_and_scan_found_nothing,
|
||||
- "no nodes found for btree %s, continue?", bch2_btree_id_str(i));
|
||||
+ "no nodes found for btree %s, continue?", buf.buf);
|
||||
bch2_btree_root_alloc_fake_trans(trans, i, 0);
|
||||
} else {
|
||||
bch2_btree_root_alloc_fake_trans(trans, i, 1);
|
||||
@@ -560,13 +564,14 @@ int bch2_check_topology(struct bch_fs *c)
|
||||
if (!reconstructed_root)
|
||||
goto reconstruct_root;
|
||||
|
||||
- bch_err(c, "empty btree root %s", bch2_btree_id_str(i));
|
||||
+ bch_err(c, "empty btree root %s", buf.buf);
|
||||
bch2_btree_root_alloc_fake_trans(trans, i, 0);
|
||||
r->alive = false;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
fsck_err:
|
||||
+ printbuf_exit(&buf);
|
||||
bch2_trans_put(trans);
|
||||
return ret;
|
||||
}
|
||||
@@ -713,6 +718,7 @@ static int bch2_gc_btrees(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
enum btree_id ids[BTREE_ID_NR];
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
@@ -731,10 +737,13 @@ static int bch2_gc_btrees(struct bch_fs *c)
|
||||
if (mustfix_fsck_err_on(bch2_err_matches(ret, EIO),
|
||||
trans, btree_node_read_error,
|
||||
"btree node read error for %s",
|
||||
- bch2_btree_id_str(btree)))
|
||||
+ (printbuf_reset(&buf),
|
||||
+ bch2_btree_id_to_text(&buf, btree),
|
||||
+ buf.buf)))
|
||||
ret = bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_topology);
|
||||
}
|
||||
fsck_err:
|
||||
+ printbuf_exit(&buf);
|
||||
bch2_trans_put(trans);
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c
|
||||
index 839d68802e42..89a42ee81e5c 100644
|
||||
--- a/fs/bcachefs/btree_io.c
|
||||
+++ b/fs/bcachefs/btree_io.c
|
||||
@@ -25,9 +25,8 @@
|
||||
|
||||
static void bch2_btree_node_header_to_text(struct printbuf *out, struct btree_node *bn)
|
||||
{
|
||||
- prt_printf(out, "btree=%s l=%u seq %llux\n",
|
||||
- bch2_btree_id_str(BTREE_NODE_ID(bn)),
|
||||
- (unsigned) BTREE_NODE_LEVEL(bn), bn->keys.seq);
|
||||
+ bch2_btree_id_level_to_text(out, BTREE_NODE_ID(bn), BTREE_NODE_LEVEL(bn));
|
||||
+ prt_printf(out, " seq %llux\n", bn->keys.seq);
|
||||
prt_str(out, "min: ");
|
||||
bch2_bpos_to_text(out, bn->min_key);
|
||||
prt_newline(out);
|
||||
@@ -1343,9 +1342,11 @@ static void btree_node_read_work(struct work_struct *work)
|
||||
!btree_node_read_error(b) &&
|
||||
c->curr_recovery_pass != BCH_RECOVERY_PASS_scan_for_btree_nodes) {
|
||||
printbuf_reset(&buf);
|
||||
- bch2_bpos_to_text(&buf, b->key.k.p);
|
||||
- bch_err_ratelimited(c, "%s: rewriting btree node at btree=%s level=%u %s due to error",
|
||||
- __func__, bch2_btree_id_str(b->c.btree_id), b->c.level, buf.buf);
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_str(&buf, " ");
|
||||
+ bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
+ bch_err_ratelimited(c, "%s: rewriting btree node at due to error\n %s",
|
||||
+ __func__, buf.buf);
|
||||
|
||||
bch2_btree_node_rewrite_async(c, b);
|
||||
}
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index 01152fd5ac57..07bce85dafaf 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -1448,10 +1448,11 @@ void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans)
|
||||
trans_for_each_update(trans, i) {
|
||||
struct bkey_s_c old = { &i->old_k, i->old_v };
|
||||
|
||||
- prt_printf(buf, "update: btree=%s cached=%u %pS\n",
|
||||
- bch2_btree_id_str(i->btree_id),
|
||||
- i->cached,
|
||||
- (void *) i->ip_allocated);
|
||||
+ prt_str(buf, "update: btree=");
|
||||
+ bch2_btree_id_to_text(buf, i->btree_id);
|
||||
+ prt_printf(buf, " cached=%u %pS\n",
|
||||
+ i->cached,
|
||||
+ (void *) i->ip_allocated);
|
||||
|
||||
prt_printf(buf, " old ");
|
||||
bch2_bkey_val_to_text(buf, trans->c, old);
|
||||
@@ -1484,13 +1485,13 @@ static void bch2_btree_path_to_text_short(struct printbuf *out, struct btree_tra
|
||||
{
|
||||
struct btree_path *path = trans->paths + path_idx;
|
||||
|
||||
- prt_printf(out, "path: idx %3u ref %u:%u %c %c %c btree=%s l=%u pos ",
|
||||
+ prt_printf(out, "path: idx %3u ref %u:%u %c %c %c ",
|
||||
path_idx, path->ref, path->intent_ref,
|
||||
path->preserve ? 'P' : ' ',
|
||||
path->should_be_locked ? 'S' : ' ',
|
||||
- path->cached ? 'C' : 'B',
|
||||
- bch2_btree_id_str(path->btree_id),
|
||||
- path->level);
|
||||
+ path->cached ? 'C' : 'B');
|
||||
+ bch2_btree_id_level_to_text(out, path->btree_id, path->level);
|
||||
+ prt_str(out, " pos ");
|
||||
bch2_bpos_to_text(out, path->pos);
|
||||
|
||||
if (!path->cached && btree_node_locked(path, path->level)) {
|
||||
@@ -3336,8 +3337,9 @@ bch2_btree_bkey_cached_common_to_text(struct printbuf *out,
|
||||
pid = owner ? owner->pid : 0;
|
||||
rcu_read_unlock();
|
||||
|
||||
- prt_printf(out, "\t%px %c l=%u %s:", b, b->cached ? 'c' : 'b',
|
||||
- b->level, bch2_btree_id_str(b->btree_id));
|
||||
+ prt_printf(out, "\t%px %c ", b, b->cached ? 'c' : 'b');
|
||||
+ bch2_btree_id_to_text(out, b->btree_id);
|
||||
+ prt_printf(out, " l=%u:", b->level);
|
||||
bch2_bpos_to_text(out, btree_node_pos(b));
|
||||
|
||||
prt_printf(out, "\t locks %u:%u:%u held by pid %u",
|
||||
@@ -3376,11 +3378,11 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
|
||||
if (!path->nodes_locked)
|
||||
continue;
|
||||
|
||||
- prt_printf(out, " path %u %c l=%u %s:",
|
||||
- idx,
|
||||
- path->cached ? 'c' : 'b',
|
||||
- path->level,
|
||||
- bch2_btree_id_str(path->btree_id));
|
||||
+ prt_printf(out, " path %u %c ",
|
||||
+ idx,
|
||||
+ path->cached ? 'c' : 'b');
|
||||
+ bch2_btree_id_to_text(out, path->btree_id);
|
||||
+ prt_printf(out, " l=%u:", path->level);
|
||||
bch2_bpos_to_text(out, path->pos);
|
||||
prt_newline(out);
|
||||
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.c b/fs/bcachefs/btree_journal_iter.c
|
||||
index c1657182c275..924b5e3a4390 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.c
|
||||
+++ b/fs/bcachefs/btree_journal_iter.c
|
||||
@@ -628,8 +628,11 @@ void bch2_journal_keys_dump(struct bch_fs *c)
|
||||
|
||||
darray_for_each(*keys, i) {
|
||||
printbuf_reset(&buf);
|
||||
+ prt_printf(&buf, "btree=");
|
||||
+ bch2_btree_id_to_text(&buf, i->btree_id);
|
||||
+ prt_printf(&buf, " l=%u ", i->level);
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(i->k));
|
||||
- pr_err("%s l=%u %s", bch2_btree_id_str(i->btree_id), i->level, buf.buf);
|
||||
+ pr_err("%s", buf.buf);
|
||||
}
|
||||
printbuf_exit(&buf);
|
||||
}
|
||||
diff --git a/fs/bcachefs/btree_node_scan.c b/fs/bcachefs/btree_node_scan.c
|
||||
index 30131c3bdd97..4b4df31d4b95 100644
|
||||
--- a/fs/bcachefs/btree_node_scan.c
|
||||
+++ b/fs/bcachefs/btree_node_scan.c
|
||||
@@ -22,9 +22,9 @@ struct find_btree_nodes_worker {
|
||||
|
||||
static void found_btree_node_to_text(struct printbuf *out, struct bch_fs *c, const struct found_btree_node *n)
|
||||
{
|
||||
- prt_printf(out, "%s l=%u seq=%u journal_seq=%llu cookie=%llx ",
|
||||
- bch2_btree_id_str(n->btree_id), n->level, n->seq,
|
||||
- n->journal_seq, n->cookie);
|
||||
+ bch2_btree_id_level_to_text(out, n->btree_id, n->level);
|
||||
+ prt_printf(out, " seq=%u journal_seq=%llu cookie=%llx ",
|
||||
+ n->seq, n->journal_seq, n->cookie);
|
||||
bch2_bpos_to_text(out, n->min_key);
|
||||
prt_str(out, "-");
|
||||
bch2_bpos_to_text(out, n->max_key);
|
||||
@@ -499,7 +499,9 @@ int bch2_get_scanned_nodes(struct bch_fs *c, enum btree_id btree,
|
||||
if (c->opts.verbose) {
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
- prt_printf(&buf, "recovering %s l=%u ", bch2_btree_id_str(btree), level);
|
||||
+ prt_str(&buf, "recovery ");
|
||||
+ bch2_btree_id_level_to_text(&buf, btree, level);
|
||||
+ prt_str(&buf, " ");
|
||||
bch2_bpos_to_text(&buf, node_min);
|
||||
prt_str(&buf, " - ");
|
||||
bch2_bpos_to_text(&buf, node_max);
|
||||
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
|
||||
index d596ef93239f..d62de3f79b29 100644
|
||||
--- a/fs/bcachefs/btree_update_interior.c
|
||||
+++ b/fs/bcachefs/btree_update_interior.c
|
||||
@@ -97,9 +97,9 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
bch2_topology_error(c);
|
||||
|
||||
printbuf_reset(&buf);
|
||||
- prt_str(&buf, "end of prev node doesn't match start of next node\n"),
|
||||
- prt_printf(&buf, " in btree %s level %u node ",
|
||||
- bch2_btree_id_str(b->c.btree_id), b->c.level);
|
||||
+ prt_str(&buf, "end of prev node doesn't match start of next node\n in ");
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_str(&buf, " node ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
prt_str(&buf, "\n prev ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(prev.k));
|
||||
@@ -118,9 +118,9 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
bch2_topology_error(c);
|
||||
|
||||
printbuf_reset(&buf);
|
||||
- prt_str(&buf, "empty interior node\n");
|
||||
- prt_printf(&buf, " in btree %s level %u node ",
|
||||
- bch2_btree_id_str(b->c.btree_id), b->c.level);
|
||||
+ prt_str(&buf, "empty interior node\n in ");
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_str(&buf, " node ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
need_fsck_err(trans, btree_node_topology_empty_interior_node, "%s", buf.buf);
|
||||
@@ -129,9 +129,9 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
bch2_topology_error(c);
|
||||
|
||||
printbuf_reset(&buf);
|
||||
- prt_str(&buf, "last child node doesn't end at end of parent node\n");
|
||||
- prt_printf(&buf, " in btree %s level %u node ",
|
||||
- bch2_btree_id_str(b->c.btree_id), b->c.level);
|
||||
+ prt_str(&buf, "last child node doesn't end at end of parent node\n in ");
|
||||
+ bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
|
||||
+ prt_str(&buf, " node ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
prt_str(&buf, "\n last key ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(prev.k));
|
||||
@@ -2575,8 +2575,9 @@ static void bch2_btree_update_to_text(struct printbuf *out, struct btree_update
|
||||
prt_printf(out, "%ps: ", (void *) as->ip_started);
|
||||
bch2_trans_commit_flags_to_text(out, as->flags);
|
||||
|
||||
- prt_printf(out, " btree=%s l=%u-%u mode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n",
|
||||
- bch2_btree_id_str(as->btree_id),
|
||||
+ prt_str(out, " ");
|
||||
+ bch2_btree_id_to_text(out, as->btree_id);
|
||||
+ prt_printf(out, " l=%u-%u mode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n",
|
||||
as->update_level_start,
|
||||
as->update_level_end,
|
||||
bch2_btree_update_modes[as->mode],
|
||||
diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c
|
||||
index 45aec1afdb0e..b5de52a50d10 100644
|
||||
--- a/fs/bcachefs/debug.c
|
||||
+++ b/fs/bcachefs/debug.c
|
||||
@@ -472,7 +472,9 @@ static void bch2_cached_btree_node_to_text(struct printbuf *out, struct bch_fs *
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 32);
|
||||
|
||||
- prt_printf(out, "%px btree=%s l=%u\n", b, bch2_btree_id_str(b->c.btree_id), b->c.level);
|
||||
+ prt_printf(out, "%px ", b);
|
||||
+ bch2_btree_id_level_to_text(out, b->c.btree_id, b->c.level);
|
||||
+ prt_printf(out, "\n");
|
||||
|
||||
printbuf_indent_add(out, 2);
|
||||
|
||||
diff --git a/fs/bcachefs/disk_accounting.c b/fs/bcachefs/disk_accounting.c
|
||||
index 07eb8fa1b026..38b563113cfb 100644
|
||||
--- a/fs/bcachefs/disk_accounting.c
|
||||
+++ b/fs/bcachefs/disk_accounting.c
|
||||
@@ -217,7 +217,8 @@ void bch2_accounting_key_to_text(struct printbuf *out, struct disk_accounting_po
|
||||
prt_printf(out, "id=%u", k->snapshot.id);
|
||||
break;
|
||||
case BCH_DISK_ACCOUNTING_btree:
|
||||
- prt_printf(out, "btree=%s", bch2_btree_id_str(k->btree.id));
|
||||
+ prt_str(out, "btree=");
|
||||
+ bch2_btree_id_to_text(out, k->btree.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
|
||||
index 7c7595e5369b..9bc0caa9d5e4 100644
|
||||
--- a/fs/bcachefs/journal_io.c
|
||||
+++ b/fs/bcachefs/journal_io.c
|
||||
@@ -421,7 +421,8 @@ static void journal_entry_btree_keys_to_text(struct printbuf *out, struct bch_fs
|
||||
bch2_prt_jset_entry_type(out, entry->type);
|
||||
prt_str(out, ": ");
|
||||
}
|
||||
- prt_printf(out, "btree=%s l=%u ", bch2_btree_id_str(entry->btree_id), entry->level);
|
||||
+ bch2_btree_id_level_to_text(out, entry->btree_id, entry->level);
|
||||
+ prt_char(out, ' ');
|
||||
bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(k));
|
||||
first = false;
|
||||
}
|
||||
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
|
||||
index b1c83e72c0d8..0e5a53541ce4 100644
|
||||
--- a/fs/bcachefs/recovery.c
|
||||
+++ b/fs/bcachefs/recovery.c
|
||||
@@ -42,7 +42,10 @@ int bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree)
|
||||
mutex_lock(&c->sb_lock);
|
||||
|
||||
if (!(c->sb.btrees_lost_data & b)) {
|
||||
- bch_err(c, "flagging btree %s lost data", bch2_btree_id_str(btree));
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
+ bch2_btree_id_to_text(&buf, btree);
|
||||
+ bch_err(c, "flagging btree %s lost data", buf.buf);
|
||||
+ printbuf_exit(&buf);
|
||||
bch2_sb_field_get(c->disk_sb.sb, ext)->btrees_lost_data |= cpu_to_le64(b);
|
||||
}
|
||||
|
||||
@@ -385,10 +388,13 @@ int bch2_journal_replay(struct bch_fs *c)
|
||||
? BCH_TRANS_COMMIT_no_journal_res|BCH_WATERMARK_reclaim
|
||||
: 0),
|
||||
bch2_journal_replay_key(trans, k));
|
||||
- bch_err_msg(c, ret, "while replaying key at btree %s level %u:",
|
||||
- bch2_btree_id_str(k->btree_id), k->level);
|
||||
- if (ret)
|
||||
+ if (ret) {
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
+ bch2_btree_id_level_to_text(&buf, k->btree_id, k->level);
|
||||
+ bch_err_msg(c, ret, "while replaying key at %s:", buf.buf);
|
||||
+ printbuf_exit(&buf);
|
||||
goto err;
|
||||
+ }
|
||||
|
||||
BUG_ON(k->btree_id != BTREE_ID_accounting && !k->overwritten);
|
||||
}
|
||||
@@ -536,6 +542,7 @@ static int journal_replay_early(struct bch_fs *c,
|
||||
|
||||
static int read_btree_roots(struct bch_fs *c)
|
||||
{
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
int ret = 0;
|
||||
|
||||
for (unsigned i = 0; i < btree_id_nr_alive(c); i++) {
|
||||
@@ -547,14 +554,17 @@ static int read_btree_roots(struct bch_fs *c)
|
||||
if (btree_id_is_alloc(i) && c->opts.reconstruct_alloc)
|
||||
continue;
|
||||
|
||||
+ printbuf_reset(&buf);
|
||||
+ bch2_btree_id_level_to_text(&buf, i, r->level);
|
||||
+
|
||||
if (mustfix_fsck_err_on((ret = r->error),
|
||||
c, btree_root_bkey_invalid,
|
||||
"invalid btree root %s",
|
||||
- bch2_btree_id_str(i)) ||
|
||||
+ buf.buf) ||
|
||||
mustfix_fsck_err_on((ret = r->error = bch2_btree_root_read(c, i, &r->key, r->level)),
|
||||
c, btree_root_read_error,
|
||||
- "error reading btree root %s l=%u: %s",
|
||||
- bch2_btree_id_str(i), r->level, bch2_err_str(ret))) {
|
||||
+ "error reading btree root %s: %s",
|
||||
+ buf.buf, bch2_err_str(ret))) {
|
||||
if (btree_id_is_alloc(i))
|
||||
r->error = 0;
|
||||
|
||||
@@ -572,6 +582,7 @@ static int read_btree_roots(struct bch_fs *c)
|
||||
}
|
||||
}
|
||||
fsck_err:
|
||||
+ printbuf_exit(&buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
|
||||
index 03e59f86f360..3270bfab9466 100644
|
||||
--- a/fs/bcachefs/sysfs.c
|
||||
+++ b/fs/bcachefs/sysfs.c
|
||||
@@ -302,7 +302,8 @@ static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c
|
||||
|
||||
static void bch2_gc_gens_pos_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
{
|
||||
- prt_printf(out, "%s: ", bch2_btree_id_str(c->gc_gens_btree));
|
||||
+ bch2_btree_id_to_text(out, c->gc_gens_btree);
|
||||
+ prt_printf(out, ": ");
|
||||
bch2_bpos_to_text(out, c->gc_gens_pos);
|
||||
prt_printf(out, "\n");
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,420 +0,0 @@
|
||||
From 09115483e7432d20c72e382662c0dffd603cc6b5 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 1 Sep 2024 14:57:26 -0400
|
||||
Subject: [PATCH 026/233] bcachefs: Refactor new stripe path to reduce
|
||||
dependencies on ec_stripe_head
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We need to add a path for reshaping existing stripes (for e.g. device
|
||||
removal), and this new path won't necessarily use ec_stripe_head.
|
||||
|
||||
Refactor the code to avoid unnecessary references to it for clarity.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/ec.c | 196 +++++++++++++++++++++++++----------------------
|
||||
1 file changed, 104 insertions(+), 92 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
|
||||
index d489a9e28702..6e855fe888c2 100644
|
||||
--- a/fs/bcachefs/ec.c
|
||||
+++ b/fs/bcachefs/ec.c
|
||||
@@ -1716,7 +1716,7 @@ static void ec_stripe_key_init(struct bch_fs *c,
|
||||
set_bkey_val_u64s(&s->k, u64s);
|
||||
}
|
||||
|
||||
-static int ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
|
||||
+static struct ec_stripe_new *ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
|
||||
{
|
||||
struct ec_stripe_new *s;
|
||||
|
||||
@@ -1724,7 +1724,7 @@ static int ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
|
||||
|
||||
s = kzalloc(sizeof(*s), GFP_KERNEL);
|
||||
if (!s)
|
||||
- return -BCH_ERR_ENOMEM_ec_new_stripe_alloc;
|
||||
+ return NULL;
|
||||
|
||||
mutex_init(&s->lock);
|
||||
closure_init(&s->iodone, NULL);
|
||||
@@ -1739,10 +1739,7 @@ static int ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
|
||||
ec_stripe_key_init(c, &s->new_stripe.key,
|
||||
s->nr_data, s->nr_parity,
|
||||
h->blocksize, h->disk_label);
|
||||
-
|
||||
- h->s = s;
|
||||
- h->nr_created++;
|
||||
- return 0;
|
||||
+ return s;
|
||||
}
|
||||
|
||||
static void ec_stripe_head_devs_update(struct bch_fs *c, struct ec_stripe_head *h)
|
||||
@@ -1887,25 +1884,26 @@ __bch2_ec_stripe_head_get(struct btree_trans *trans,
|
||||
return h;
|
||||
}
|
||||
|
||||
-static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_head *h,
|
||||
+static int new_stripe_alloc_buckets(struct btree_trans *trans,
|
||||
+ struct ec_stripe_head *h, struct ec_stripe_new *s,
|
||||
enum bch_watermark watermark, struct closure *cl)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bch_devs_mask devs = h->devs;
|
||||
struct open_bucket *ob;
|
||||
struct open_buckets buckets;
|
||||
- struct bch_stripe *v = &bkey_i_to_stripe(&h->s->new_stripe.key)->v;
|
||||
+ struct bch_stripe *v = &bkey_i_to_stripe(&s->new_stripe.key)->v;
|
||||
unsigned i, j, nr_have_parity = 0, nr_have_data = 0;
|
||||
bool have_cache = true;
|
||||
int ret = 0;
|
||||
|
||||
- BUG_ON(v->nr_blocks != h->s->nr_data + h->s->nr_parity);
|
||||
- BUG_ON(v->nr_redundant != h->s->nr_parity);
|
||||
+ BUG_ON(v->nr_blocks != s->nr_data + s->nr_parity);
|
||||
+ BUG_ON(v->nr_redundant != s->nr_parity);
|
||||
|
||||
/* * We bypass the sector allocator which normally does this: */
|
||||
bitmap_and(devs.d, devs.d, c->rw_devs[BCH_DATA_user].d, BCH_SB_MEMBERS_MAX);
|
||||
|
||||
- for_each_set_bit(i, h->s->blocks_gotten, v->nr_blocks) {
|
||||
+ for_each_set_bit(i, s->blocks_gotten, v->nr_blocks) {
|
||||
/*
|
||||
* Note: we don't yet repair invalid blocks (failed/removed
|
||||
* devices) when reusing stripes - we still need a codepath to
|
||||
@@ -1915,21 +1913,21 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_
|
||||
if (v->ptrs[i].dev != BCH_SB_MEMBER_INVALID)
|
||||
__clear_bit(v->ptrs[i].dev, devs.d);
|
||||
|
||||
- if (i < h->s->nr_data)
|
||||
+ if (i < s->nr_data)
|
||||
nr_have_data++;
|
||||
else
|
||||
nr_have_parity++;
|
||||
}
|
||||
|
||||
- BUG_ON(nr_have_data > h->s->nr_data);
|
||||
- BUG_ON(nr_have_parity > h->s->nr_parity);
|
||||
+ BUG_ON(nr_have_data > s->nr_data);
|
||||
+ BUG_ON(nr_have_parity > s->nr_parity);
|
||||
|
||||
buckets.nr = 0;
|
||||
- if (nr_have_parity < h->s->nr_parity) {
|
||||
+ if (nr_have_parity < s->nr_parity) {
|
||||
ret = bch2_bucket_alloc_set_trans(trans, &buckets,
|
||||
&h->parity_stripe,
|
||||
&devs,
|
||||
- h->s->nr_parity,
|
||||
+ s->nr_parity,
|
||||
&nr_have_parity,
|
||||
&have_cache, 0,
|
||||
BCH_DATA_parity,
|
||||
@@ -1937,14 +1935,14 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_
|
||||
cl);
|
||||
|
||||
open_bucket_for_each(c, &buckets, ob, i) {
|
||||
- j = find_next_zero_bit(h->s->blocks_gotten,
|
||||
- h->s->nr_data + h->s->nr_parity,
|
||||
- h->s->nr_data);
|
||||
- BUG_ON(j >= h->s->nr_data + h->s->nr_parity);
|
||||
+ j = find_next_zero_bit(s->blocks_gotten,
|
||||
+ s->nr_data + s->nr_parity,
|
||||
+ s->nr_data);
|
||||
+ BUG_ON(j >= s->nr_data + s->nr_parity);
|
||||
|
||||
- h->s->blocks[j] = buckets.v[i];
|
||||
+ s->blocks[j] = buckets.v[i];
|
||||
v->ptrs[j] = bch2_ob_ptr(c, ob);
|
||||
- __set_bit(j, h->s->blocks_gotten);
|
||||
+ __set_bit(j, s->blocks_gotten);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
@@ -1952,11 +1950,11 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_
|
||||
}
|
||||
|
||||
buckets.nr = 0;
|
||||
- if (nr_have_data < h->s->nr_data) {
|
||||
+ if (nr_have_data < s->nr_data) {
|
||||
ret = bch2_bucket_alloc_set_trans(trans, &buckets,
|
||||
&h->block_stripe,
|
||||
&devs,
|
||||
- h->s->nr_data,
|
||||
+ s->nr_data,
|
||||
&nr_have_data,
|
||||
&have_cache, 0,
|
||||
BCH_DATA_user,
|
||||
@@ -1964,13 +1962,13 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_
|
||||
cl);
|
||||
|
||||
open_bucket_for_each(c, &buckets, ob, i) {
|
||||
- j = find_next_zero_bit(h->s->blocks_gotten,
|
||||
- h->s->nr_data, 0);
|
||||
- BUG_ON(j >= h->s->nr_data);
|
||||
+ j = find_next_zero_bit(s->blocks_gotten,
|
||||
+ s->nr_data, 0);
|
||||
+ BUG_ON(j >= s->nr_data);
|
||||
|
||||
- h->s->blocks[j] = buckets.v[i];
|
||||
+ s->blocks[j] = buckets.v[i];
|
||||
v->ptrs[j] = bch2_ob_ptr(c, ob);
|
||||
- __set_bit(j, h->s->blocks_gotten);
|
||||
+ __set_bit(j, s->blocks_gotten);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
@@ -2016,73 +2014,78 @@ static s64 get_existing_stripe(struct bch_fs *c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int __bch2_ec_stripe_head_reuse(struct btree_trans *trans, struct ec_stripe_head *h)
|
||||
+static int init_new_stripe_from_existing(struct bch_fs *c, struct ec_stripe_new *s)
|
||||
{
|
||||
- struct bch_fs *c = trans->c;
|
||||
- struct bch_stripe *new_v = &bkey_i_to_stripe(&h->s->new_stripe.key)->v;
|
||||
- struct bch_stripe *existing_v;
|
||||
+ struct bch_stripe *new_v = &bkey_i_to_stripe(&s->new_stripe.key)->v;
|
||||
+ struct bch_stripe *existing_v = &bkey_i_to_stripe(&s->existing_stripe.key)->v;
|
||||
unsigned i;
|
||||
- s64 idx;
|
||||
- int ret;
|
||||
|
||||
- /*
|
||||
- * If we can't allocate a new stripe, and there's no stripes with empty
|
||||
- * blocks for us to reuse, that means we have to wait on copygc:
|
||||
- */
|
||||
- idx = get_existing_stripe(c, h);
|
||||
- if (idx < 0)
|
||||
- return -BCH_ERR_stripe_alloc_blocked;
|
||||
-
|
||||
- ret = get_stripe_key_trans(trans, idx, &h->s->existing_stripe);
|
||||
- bch2_fs_fatal_err_on(ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart), c,
|
||||
- "reading stripe key: %s", bch2_err_str(ret));
|
||||
- if (ret) {
|
||||
- bch2_stripe_close(c, h->s);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- existing_v = &bkey_i_to_stripe(&h->s->existing_stripe.key)->v;
|
||||
-
|
||||
- BUG_ON(existing_v->nr_redundant != h->s->nr_parity);
|
||||
- h->s->nr_data = existing_v->nr_blocks -
|
||||
+ BUG_ON(existing_v->nr_redundant != s->nr_parity);
|
||||
+ s->nr_data = existing_v->nr_blocks -
|
||||
existing_v->nr_redundant;
|
||||
|
||||
- ret = ec_stripe_buf_init(&h->s->existing_stripe, 0, h->blocksize);
|
||||
+ int ret = ec_stripe_buf_init(&s->existing_stripe, 0, le16_to_cpu(existing_v->sectors));
|
||||
if (ret) {
|
||||
- bch2_stripe_close(c, h->s);
|
||||
+ bch2_stripe_close(c, s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
- BUG_ON(h->s->existing_stripe.size != h->blocksize);
|
||||
- BUG_ON(h->s->existing_stripe.size != le16_to_cpu(existing_v->sectors));
|
||||
+ BUG_ON(s->existing_stripe.size != le16_to_cpu(existing_v->sectors));
|
||||
|
||||
/*
|
||||
* Free buckets we initially allocated - they might conflict with
|
||||
* blocks from the stripe we're reusing:
|
||||
*/
|
||||
- for_each_set_bit(i, h->s->blocks_gotten, new_v->nr_blocks) {
|
||||
- bch2_open_bucket_put(c, c->open_buckets + h->s->blocks[i]);
|
||||
- h->s->blocks[i] = 0;
|
||||
+ for_each_set_bit(i, s->blocks_gotten, new_v->nr_blocks) {
|
||||
+ bch2_open_bucket_put(c, c->open_buckets + s->blocks[i]);
|
||||
+ s->blocks[i] = 0;
|
||||
}
|
||||
- memset(h->s->blocks_gotten, 0, sizeof(h->s->blocks_gotten));
|
||||
- memset(h->s->blocks_allocated, 0, sizeof(h->s->blocks_allocated));
|
||||
+ memset(s->blocks_gotten, 0, sizeof(s->blocks_gotten));
|
||||
+ memset(s->blocks_allocated, 0, sizeof(s->blocks_allocated));
|
||||
|
||||
- for (i = 0; i < existing_v->nr_blocks; i++) {
|
||||
+ for (unsigned i = 0; i < existing_v->nr_blocks; i++) {
|
||||
if (stripe_blockcount_get(existing_v, i)) {
|
||||
- __set_bit(i, h->s->blocks_gotten);
|
||||
- __set_bit(i, h->s->blocks_allocated);
|
||||
+ __set_bit(i, s->blocks_gotten);
|
||||
+ __set_bit(i, s->blocks_allocated);
|
||||
}
|
||||
|
||||
- ec_block_io(c, &h->s->existing_stripe, READ, i, &h->s->iodone);
|
||||
+ ec_block_io(c, &s->existing_stripe, READ, i, &s->iodone);
|
||||
}
|
||||
|
||||
- bkey_copy(&h->s->new_stripe.key, &h->s->existing_stripe.key);
|
||||
- h->s->have_existing_stripe = true;
|
||||
+ bkey_copy(&s->new_stripe.key, &s->existing_stripe.key);
|
||||
+ s->have_existing_stripe = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int __bch2_ec_stripe_head_reserve(struct btree_trans *trans, struct ec_stripe_head *h)
|
||||
+static int __bch2_ec_stripe_head_reuse(struct btree_trans *trans, struct ec_stripe_head *h,
|
||||
+ struct ec_stripe_new *s)
|
||||
+{
|
||||
+ struct bch_fs *c = trans->c;
|
||||
+ s64 idx;
|
||||
+ int ret;
|
||||
+
|
||||
+ /*
|
||||
+ * If we can't allocate a new stripe, and there's no stripes with empty
|
||||
+ * blocks for us to reuse, that means we have to wait on copygc:
|
||||
+ */
|
||||
+ idx = get_existing_stripe(c, h);
|
||||
+ if (idx < 0)
|
||||
+ return -BCH_ERR_stripe_alloc_blocked;
|
||||
+
|
||||
+ ret = get_stripe_key_trans(trans, idx, &s->existing_stripe);
|
||||
+ bch2_fs_fatal_err_on(ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart), c,
|
||||
+ "reading stripe key: %s", bch2_err_str(ret));
|
||||
+ if (ret) {
|
||||
+ bch2_stripe_close(c, s);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return init_new_stripe_from_existing(c, s);
|
||||
+}
|
||||
+
|
||||
+static int __bch2_ec_stripe_head_reserve(struct btree_trans *trans, struct ec_stripe_head *h,
|
||||
+ struct ec_stripe_new *s)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_iter iter;
|
||||
@@ -2091,15 +2094,19 @@ static int __bch2_ec_stripe_head_reserve(struct btree_trans *trans, struct ec_st
|
||||
struct bpos start_pos = bpos_max(min_pos, POS(0, c->ec_stripe_hint));
|
||||
int ret;
|
||||
|
||||
- if (!h->s->res.sectors) {
|
||||
- ret = bch2_disk_reservation_get(c, &h->s->res,
|
||||
+ if (!s->res.sectors) {
|
||||
+ ret = bch2_disk_reservation_get(c, &s->res,
|
||||
h->blocksize,
|
||||
- h->s->nr_parity,
|
||||
+ s->nr_parity,
|
||||
BCH_DISK_RESERVATION_NOFAIL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Allocate stripe slot
|
||||
+ * XXX: we're going to need a bitrange btree of free stripes
|
||||
+ */
|
||||
for_each_btree_key_norestart(trans, iter, BTREE_ID_stripes, start_pos,
|
||||
BTREE_ITER_slots|BTREE_ITER_intent, k, ret) {
|
||||
if (bkey_gt(k.k->p, POS(0, U32_MAX))) {
|
||||
@@ -2114,7 +2121,7 @@ static int __bch2_ec_stripe_head_reserve(struct btree_trans *trans, struct ec_st
|
||||
}
|
||||
|
||||
if (bkey_deleted(k.k) &&
|
||||
- bch2_try_open_stripe(c, h->s, k.k->p.offset))
|
||||
+ bch2_try_open_stripe(c, s, k.k->p.offset))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2125,16 +2132,16 @@ static int __bch2_ec_stripe_head_reserve(struct btree_trans *trans, struct ec_st
|
||||
|
||||
ret = ec_stripe_mem_alloc(trans, &iter);
|
||||
if (ret) {
|
||||
- bch2_stripe_close(c, h->s);
|
||||
+ bch2_stripe_close(c, s);
|
||||
goto err;
|
||||
}
|
||||
|
||||
- h->s->new_stripe.key.k.p = iter.pos;
|
||||
+ s->new_stripe.key.k.p = iter.pos;
|
||||
out:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
return ret;
|
||||
err:
|
||||
- bch2_disk_reservation_put(c, &h->s->res);
|
||||
+ bch2_disk_reservation_put(c, &s->res);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2165,22 +2172,27 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
|
||||
return h;
|
||||
|
||||
if (!h->s) {
|
||||
- ret = ec_new_stripe_alloc(c, h);
|
||||
- if (ret) {
|
||||
+ h->s = ec_new_stripe_alloc(c, h);
|
||||
+ if (!h->s) {
|
||||
+ ret = -BCH_ERR_ENOMEM_ec_new_stripe_alloc;
|
||||
bch_err(c, "failed to allocate new stripe");
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ h->nr_created++;
|
||||
}
|
||||
|
||||
- if (h->s->allocated)
|
||||
+ struct ec_stripe_new *s = h->s;
|
||||
+
|
||||
+ if (s->allocated)
|
||||
goto allocated;
|
||||
|
||||
- if (h->s->have_existing_stripe)
|
||||
+ if (s->have_existing_stripe)
|
||||
goto alloc_existing;
|
||||
|
||||
/* First, try to allocate a full stripe: */
|
||||
- ret = new_stripe_alloc_buckets(trans, h, BCH_WATERMARK_stripe, NULL) ?:
|
||||
- __bch2_ec_stripe_head_reserve(trans, h);
|
||||
+ ret = new_stripe_alloc_buckets(trans, h, s, BCH_WATERMARK_stripe, NULL) ?:
|
||||
+ __bch2_ec_stripe_head_reserve(trans, h, s);
|
||||
if (!ret)
|
||||
goto allocate_buf;
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart) ||
|
||||
@@ -2192,15 +2204,15 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
|
||||
* existing stripe:
|
||||
*/
|
||||
while (1) {
|
||||
- ret = __bch2_ec_stripe_head_reuse(trans, h);
|
||||
+ ret = __bch2_ec_stripe_head_reuse(trans, h, s);
|
||||
if (!ret)
|
||||
break;
|
||||
if (waiting || !cl || ret != -BCH_ERR_stripe_alloc_blocked)
|
||||
goto err;
|
||||
|
||||
if (watermark == BCH_WATERMARK_copygc) {
|
||||
- ret = new_stripe_alloc_buckets(trans, h, watermark, NULL) ?:
|
||||
- __bch2_ec_stripe_head_reserve(trans, h);
|
||||
+ ret = new_stripe_alloc_buckets(trans, h, s, watermark, NULL) ?:
|
||||
+ __bch2_ec_stripe_head_reserve(trans, h, s);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto allocate_buf;
|
||||
@@ -2218,19 +2230,19 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
|
||||
* Retry allocating buckets, with the watermark for this
|
||||
* particular write:
|
||||
*/
|
||||
- ret = new_stripe_alloc_buckets(trans, h, watermark, cl);
|
||||
+ ret = new_stripe_alloc_buckets(trans, h, s, watermark, cl);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
allocate_buf:
|
||||
- ret = ec_stripe_buf_init(&h->s->new_stripe, 0, h->blocksize);
|
||||
+ ret = ec_stripe_buf_init(&s->new_stripe, 0, h->blocksize);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
- h->s->allocated = true;
|
||||
+ s->allocated = true;
|
||||
allocated:
|
||||
- BUG_ON(!h->s->idx);
|
||||
- BUG_ON(!h->s->new_stripe.data[0]);
|
||||
+ BUG_ON(!s->idx);
|
||||
+ BUG_ON(!s->new_stripe.data[0]);
|
||||
BUG_ON(trans->restarted);
|
||||
return h;
|
||||
err:
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,41 +0,0 @@
|
||||
From cca1dff8fea3f4ebe8a7f39a109d14a0f136d319 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 11 Oct 2024 22:53:09 -0400
|
||||
Subject: [PATCH 027/233] bcachefs: -o norecovery now bails out of recovery
|
||||
earlier
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
-o norecovery (used by the dump tool) should be doing the absolute
|
||||
minimum amount of work to get the filesystem up and readable; we
|
||||
shouldn't be running check and repair code, or going read-write.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/recovery.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
|
||||
index 0e5a53541ce4..bc2fd174bb32 100644
|
||||
--- a/fs/bcachefs/recovery.c
|
||||
+++ b/fs/bcachefs/recovery.c
|
||||
@@ -690,8 +690,13 @@ int bch2_fs_recovery(struct bch_fs *c)
|
||||
goto err;
|
||||
}
|
||||
|
||||
- if (c->opts.norecovery)
|
||||
- c->opts.recovery_pass_last = BCH_RECOVERY_PASS_journal_replay - 1;
|
||||
+ if (c->opts.norecovery) {
|
||||
+ c->opts.recovery_pass_last = c->opts.recovery_pass_last
|
||||
+ ? min(c->opts.recovery_pass_last, BCH_RECOVERY_PASS_snapshots_read)
|
||||
+ : BCH_RECOVERY_PASS_snapshots_read;
|
||||
+ c->opts.nochanges = true;
|
||||
+ c->opts.read_only = true;
|
||||
+ }
|
||||
|
||||
mutex_lock(&c->sb_lock);
|
||||
struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,112 +0,0 @@
|
||||
From a99869f0b74e8ced83ece54c3f1645363fe8214c Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 11 Oct 2024 22:50:48 -0400
|
||||
Subject: [PATCH 028/233] bcachefs: bch2_journal_meta() takes ref on c->writes
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This part of addressing
|
||||
https://github.com/koverstreet/bcachefs/issues/656
|
||||
|
||||
where we're getting stuck in bch2_journal_meta() in the dump tool.
|
||||
|
||||
We shouldn't be invoking the journal without a ref on c->writes (if
|
||||
we're not RW), and there's no reason for the dump tool to be going
|
||||
read-write.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs.h | 1 +
|
||||
fs/bcachefs/journal.c | 27 +++++++++++++++++----------
|
||||
fs/bcachefs/recovery.c | 4 +---
|
||||
3 files changed, 19 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
||||
index fbd89f91625d..d4d95ef6791f 100644
|
||||
--- a/fs/bcachefs/bcachefs.h
|
||||
+++ b/fs/bcachefs/bcachefs.h
|
||||
@@ -688,6 +688,7 @@ struct btree_trans_buf {
|
||||
((subvol_inum) { BCACHEFS_ROOT_SUBVOL, BCACHEFS_ROOT_INO })
|
||||
|
||||
#define BCH_WRITE_REFS() \
|
||||
+ x(journal) \
|
||||
x(trans) \
|
||||
x(write) \
|
||||
x(promote) \
|
||||
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
|
||||
index 2dc0d60c1745..2cf8f24d50cc 100644
|
||||
--- a/fs/bcachefs/journal.c
|
||||
+++ b/fs/bcachefs/journal.c
|
||||
@@ -831,19 +831,14 @@ bool bch2_journal_noflush_seq(struct journal *j, u64 seq)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int bch2_journal_meta(struct journal *j)
|
||||
+static int __bch2_journal_meta(struct journal *j)
|
||||
{
|
||||
- struct journal_buf *buf;
|
||||
- struct journal_res res;
|
||||
- int ret;
|
||||
-
|
||||
- memset(&res, 0, sizeof(res));
|
||||
-
|
||||
- ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0);
|
||||
+ struct journal_res res = {};
|
||||
+ int ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- buf = j->buf + (res.seq & JOURNAL_BUF_MASK);
|
||||
+ struct journal_buf *buf = j->buf + (res.seq & JOURNAL_BUF_MASK);
|
||||
buf->must_flush = true;
|
||||
|
||||
if (!buf->flush_time) {
|
||||
@@ -856,6 +851,18 @@ int bch2_journal_meta(struct journal *j)
|
||||
return bch2_journal_flush_seq(j, res.seq, TASK_UNINTERRUPTIBLE);
|
||||
}
|
||||
|
||||
+int bch2_journal_meta(struct journal *j)
|
||||
+{
|
||||
+ struct bch_fs *c = container_of(j, struct bch_fs, journal);
|
||||
+
|
||||
+ if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_journal))
|
||||
+ return -EROFS;
|
||||
+
|
||||
+ int ret = __bch2_journal_meta(j);
|
||||
+ bch2_write_ref_put(c, BCH_WRITE_REF_journal);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/* block/unlock the journal: */
|
||||
|
||||
void bch2_journal_unblock(struct journal *j)
|
||||
@@ -1193,7 +1200,7 @@ void bch2_fs_journal_stop(struct journal *j)
|
||||
* Always write a new journal entry, to make sure the clock hands are up
|
||||
* to date (and match the superblock)
|
||||
*/
|
||||
- bch2_journal_meta(j);
|
||||
+ __bch2_journal_meta(j);
|
||||
|
||||
journal_quiesce(j);
|
||||
cancel_delayed_work_sync(&j->write_work);
|
||||
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
|
||||
index bc2fd174bb32..431698189090 100644
|
||||
--- a/fs/bcachefs/recovery.c
|
||||
+++ b/fs/bcachefs/recovery.c
|
||||
@@ -910,11 +910,9 @@ int bch2_fs_recovery(struct bch_fs *c)
|
||||
set_bit(BCH_FS_accounting_replay_done, &c->flags);
|
||||
|
||||
/* fsync if we fixed errors */
|
||||
- if (test_bit(BCH_FS_errors_fixed, &c->flags) &&
|
||||
- bch2_write_ref_tryget(c, BCH_WRITE_REF_fsync)) {
|
||||
+ if (test_bit(BCH_FS_errors_fixed, &c->flags)) {
|
||||
bch2_journal_flush_all_pins(&c->journal);
|
||||
bch2_journal_meta(&c->journal);
|
||||
- bch2_write_ref_put(c, BCH_WRITE_REF_fsync);
|
||||
}
|
||||
|
||||
/* If we fixed errors, verify that fs is actually clean now: */
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,55 +0,0 @@
|
||||
From c4bfe7049c62651c7e03210760529e2fab9a7706 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 12 Oct 2024 14:07:44 -0400
|
||||
Subject: [PATCH 029/233] bcachefs: Fix warning about passing flex array member
|
||||
by value
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
this showed up when building in userspace
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/disk_accounting.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/disk_accounting.c b/fs/bcachefs/disk_accounting.c
|
||||
index 38b563113cfb..55a00018dc8b 100644
|
||||
--- a/fs/bcachefs/disk_accounting.c
|
||||
+++ b/fs/bcachefs/disk_accounting.c
|
||||
@@ -244,10 +244,10 @@ void bch2_accounting_swab(struct bkey_s k)
|
||||
}
|
||||
|
||||
static inline void __accounting_to_replicas(struct bch_replicas_entry_v1 *r,
|
||||
- struct disk_accounting_pos acc)
|
||||
+ struct disk_accounting_pos *acc)
|
||||
{
|
||||
- unsafe_memcpy(r, &acc.replicas,
|
||||
- replicas_entry_bytes(&acc.replicas),
|
||||
+ unsafe_memcpy(r, &acc->replicas,
|
||||
+ replicas_entry_bytes(&acc->replicas),
|
||||
"variable length struct");
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struc
|
||||
|
||||
switch (acc_k.type) {
|
||||
case BCH_DISK_ACCOUNTING_replicas:
|
||||
- __accounting_to_replicas(r, acc_k);
|
||||
+ __accounting_to_replicas(r, &acc_k);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -626,7 +626,7 @@ static int bch2_disk_accounting_validate_late(struct btree_trans *trans,
|
||||
switch (acc.type) {
|
||||
case BCH_DISK_ACCOUNTING_replicas: {
|
||||
struct bch_replicas_padded r;
|
||||
- __accounting_to_replicas(&r.e, acc);
|
||||
+ __accounting_to_replicas(&r.e, &acc);
|
||||
|
||||
for (unsigned i = 0; i < r.e.nr_devs; i++)
|
||||
if (r.e.devs[i] != BCH_SB_MEMBER_INVALID &&
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,117 +0,0 @@
|
||||
From b6a562e6d87918faaacea4999d47ae4e0da2f5f0 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 14 Oct 2024 21:35:44 -0400
|
||||
Subject: [PATCH 030/233] bcachefs: Add block plugging to read paths
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This will help with some of the btree_trans srcu lock hold time warnings
|
||||
that are still turning up; submit_bio() can block for awhile if the
|
||||
device is sufficiently congested.
|
||||
|
||||
It's not a perfect solution since blk_plug bios are submitted when
|
||||
scheduling; we might want a way to disable the "submit on context
|
||||
switch" behaviour, or switch to our own plugging in the future.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs-io-buffered.c | 19 ++++++++++++++++++-
|
||||
fs/bcachefs/fs-io-direct.c | 5 +++++
|
||||
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c
|
||||
index 95972809e76d..0923f38a2fcd 100644
|
||||
--- a/fs/bcachefs/fs-io-buffered.c
|
||||
+++ b/fs/bcachefs/fs-io-buffered.c
|
||||
@@ -248,6 +248,7 @@ void bch2_readahead(struct readahead_control *ractl)
|
||||
struct bch_io_opts opts;
|
||||
struct folio *folio;
|
||||
struct readpages_iter readpages_iter;
|
||||
+ struct blk_plug plug;
|
||||
|
||||
bch2_inode_opts_get(&opts, c, &inode->ei_inode);
|
||||
|
||||
@@ -255,6 +256,16 @@ void bch2_readahead(struct readahead_control *ractl)
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
+ /*
|
||||
+ * Besides being a general performance optimization, plugging helps with
|
||||
+ * avoiding btree transaction srcu warnings - submitting a bio can
|
||||
+ * block, and we don't want todo that with the transaction locked.
|
||||
+ *
|
||||
+ * However, plugged bios are submitted when we schedule; we ideally
|
||||
+ * would have our own scheduler hook to call unlock_long() before
|
||||
+ * scheduling.
|
||||
+ */
|
||||
+ blk_start_plug(&plug);
|
||||
bch2_pagecache_add_get(inode);
|
||||
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
@@ -281,7 +292,7 @@ void bch2_readahead(struct readahead_control *ractl)
|
||||
bch2_trans_put(trans);
|
||||
|
||||
bch2_pagecache_add_put(inode);
|
||||
-
|
||||
+ blk_finish_plug(&plug);
|
||||
darray_exit(&readpages_iter.folios);
|
||||
}
|
||||
|
||||
@@ -296,9 +307,13 @@ int bch2_read_single_folio(struct folio *folio, struct address_space *mapping)
|
||||
struct bch_fs *c = inode->v.i_sb->s_fs_info;
|
||||
struct bch_read_bio *rbio;
|
||||
struct bch_io_opts opts;
|
||||
+ struct blk_plug plug;
|
||||
int ret;
|
||||
DECLARE_COMPLETION_ONSTACK(done);
|
||||
|
||||
+ BUG_ON(folio_test_uptodate(folio));
|
||||
+ BUG_ON(folio_test_dirty(folio));
|
||||
+
|
||||
if (!bch2_folio_create(folio, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -313,7 +328,9 @@ int bch2_read_single_folio(struct folio *folio, struct address_space *mapping)
|
||||
rbio->bio.bi_iter.bi_sector = folio_sector(folio);
|
||||
BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
|
||||
|
||||
+ blk_start_plug(&plug);
|
||||
bch2_trans_run(c, (bchfs_read(trans, rbio, inode_inum(inode), NULL), 0));
|
||||
+ blk_finish_plug(&plug);
|
||||
wait_for_completion(&done);
|
||||
|
||||
ret = blk_status_to_errno(rbio->bio.bi_status);
|
||||
diff --git a/fs/bcachefs/fs-io-direct.c b/fs/bcachefs/fs-io-direct.c
|
||||
index 6d3a05ae5da8..2089c36b5866 100644
|
||||
--- a/fs/bcachefs/fs-io-direct.c
|
||||
+++ b/fs/bcachefs/fs-io-direct.c
|
||||
@@ -70,6 +70,7 @@ static int bch2_direct_IO_read(struct kiocb *req, struct iov_iter *iter)
|
||||
struct bch_io_opts opts;
|
||||
struct dio_read *dio;
|
||||
struct bio *bio;
|
||||
+ struct blk_plug plug;
|
||||
loff_t offset = req->ki_pos;
|
||||
bool sync = is_sync_kiocb(req);
|
||||
size_t shorten;
|
||||
@@ -128,6 +129,8 @@ static int bch2_direct_IO_read(struct kiocb *req, struct iov_iter *iter)
|
||||
*/
|
||||
dio->should_dirty = iter_is_iovec(iter);
|
||||
|
||||
+ blk_start_plug(&plug);
|
||||
+
|
||||
goto start;
|
||||
while (iter->count) {
|
||||
bio = bio_alloc_bioset(NULL,
|
||||
@@ -160,6 +163,8 @@ static int bch2_direct_IO_read(struct kiocb *req, struct iov_iter *iter)
|
||||
bch2_read(c, rbio_init(bio, opts), inode_inum(inode));
|
||||
}
|
||||
|
||||
+ blk_finish_plug(&plug);
|
||||
+
|
||||
iter->count += shorten;
|
||||
|
||||
if (sync) {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,35 +0,0 @@
|
||||
From ce612d0d48ce2143fc0394c7fbf5eb1f5944a25f Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 19:02:44 -0400
|
||||
Subject: [PATCH 031/233] bcachefs: Add version check for
|
||||
bch_btree_ptr_v2.sectors_written validate
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
A user popped up with a very old (0.11) filesystem that needed repair
|
||||
and wasn't recently backed up.
|
||||
|
||||
Reported-by: Manoa <manoa@mail.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 37e3d69bec06..85b98c782e1b 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -203,7 +203,8 @@ int bch2_btree_ptr_v2_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
c, btree_ptr_v2_min_key_bad,
|
||||
"min_key > key");
|
||||
|
||||
- if (flags & BCH_VALIDATE_write)
|
||||
+ if ((flags & BCH_VALIDATE_write) &&
|
||||
+ c->sb.version_min >= bcachefs_metadata_version_btree_ptr_sectors_written)
|
||||
bkey_fsck_err_on(!bp.v->sectors_written,
|
||||
c, btree_ptr_v2_written_0,
|
||||
"sectors_written == 0");
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,41 +0,0 @@
|
||||
From d953b409bc8685f21315799bc3b32448945cc27f Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Date: Sat, 19 Oct 2024 14:25:27 +0200
|
||||
Subject: [PATCH 032/233] bcachefs: Use str_write_read() helper function
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Remove hard-coded strings by using the helper function str_write_read().
|
||||
|
||||
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/journal_io.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
|
||||
index 9bc0caa9d5e4..768a3b950997 100644
|
||||
--- a/fs/bcachefs/journal_io.c
|
||||
+++ b/fs/bcachefs/journal_io.c
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "sb-clean.h"
|
||||
#include "trace.h"
|
||||
|
||||
+#include <linux/string_choices.h>
|
||||
+
|
||||
void bch2_journal_pos_from_member_info_set(struct bch_fs *c)
|
||||
{
|
||||
lockdep_assert_held(&c->sb_lock);
|
||||
@@ -666,7 +668,7 @@ static void journal_entry_clock_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct jset_entry_clock *clock =
|
||||
container_of(entry, struct jset_entry_clock, entry);
|
||||
|
||||
- prt_printf(out, "%s=%llu", clock->rw ? "write" : "read", le64_to_cpu(clock->time));
|
||||
+ prt_printf(out, "%s=%llu", str_write_read(clock->rw), le64_to_cpu(clock->time));
|
||||
}
|
||||
|
||||
static int journal_entry_dev_usage_validate(struct bch_fs *c,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,41 +0,0 @@
|
||||
From dfce49250859cf87c267cf3952dadf8d702ff674 Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 13:20:46 +0200
|
||||
Subject: [PATCH 033/233] bcachefs: Use str_write_read() helper in
|
||||
ec_block_endio()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Remove hard-coded strings by using the helper function str_write_read().
|
||||
|
||||
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/ec.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
|
||||
index 6e855fe888c2..015107e241cc 100644
|
||||
--- a/fs/bcachefs/ec.c
|
||||
+++ b/fs/bcachefs/ec.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "util.h"
|
||||
|
||||
#include <linux/sort.h>
|
||||
+#include <linux/string_choices.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
@@ -732,7 +733,7 @@ static void ec_block_endio(struct bio *bio)
|
||||
? BCH_MEMBER_ERROR_write
|
||||
: BCH_MEMBER_ERROR_read,
|
||||
"erasure coding %s error: %s",
|
||||
- bio_data_dir(bio) ? "write" : "read",
|
||||
+ str_write_read(bio_data_dir(bio)),
|
||||
bch2_blk_status_to_str(bio->bi_status)))
|
||||
clear_bit(ec_bio->idx, ec_bio->buf->valid);
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,41 +0,0 @@
|
||||
From 342a485f4e29ecfdcf979af0b2e609cbdc52701d Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Date: Sat, 26 Oct 2024 12:47:23 +0200
|
||||
Subject: [PATCH 034/233] bcachefs: Use str_write_read() helper in
|
||||
write_super_endio()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Remove hard-coded strings by using the str_write_read() helper function.
|
||||
|
||||
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/super-io.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
|
||||
index 7c71594f6a8b..c83bd3dedb1b 100644
|
||||
--- a/fs/bcachefs/super-io.c
|
||||
+++ b/fs/bcachefs/super-io.c
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <linux/backing-dev.h>
|
||||
#include <linux/sort.h>
|
||||
+#include <linux/string_choices.h>
|
||||
|
||||
static const struct blk_holder_ops bch2_sb_handle_bdev_ops = {
|
||||
};
|
||||
@@ -878,7 +879,7 @@ static void write_super_endio(struct bio *bio)
|
||||
? BCH_MEMBER_ERROR_write
|
||||
: BCH_MEMBER_ERROR_read,
|
||||
"superblock %s error: %s",
|
||||
- bio_data_dir(bio) ? "write" : "read",
|
||||
+ str_write_read(bio_data_dir(bio)),
|
||||
bch2_blk_status_to_str(bio->bi_status)))
|
||||
ca->sb_write_error = 1;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,76 +0,0 @@
|
||||
From caaf27392849abbc6499196fcd114da3f11e4e0f Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Date: Sat, 26 Oct 2024 17:47:04 +0200
|
||||
Subject: [PATCH 035/233] bcachefs: Annotate struct bucket_gens with
|
||||
__counted_by()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add the __counted_by compiler attribute to the flexible array member b
|
||||
to improve access bounds-checking via CONFIG_UBSAN_BOUNDS and
|
||||
CONFIG_FORTIFY_SOURCE.
|
||||
|
||||
Use struct_size() to calculate the number of bytes to be allocated.
|
||||
|
||||
Update bucket_gens->nbuckets and bucket_gens->nbuckets_minus_first when
|
||||
resizing.
|
||||
|
||||
Compile-tested only.
|
||||
|
||||
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/buckets.c | 13 ++++++++-----
|
||||
fs/bcachefs/buckets_types.h | 2 +-
|
||||
2 files changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
|
||||
index ec7d9a59bea9..8bd17667e243 100644
|
||||
--- a/fs/bcachefs/buckets.c
|
||||
+++ b/fs/bcachefs/buckets.c
|
||||
@@ -1266,8 +1266,9 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
|
||||
|
||||
BUG_ON(resize && ca->buckets_nouse);
|
||||
|
||||
- if (!(bucket_gens = kvmalloc(sizeof(struct bucket_gens) + nbuckets,
|
||||
- GFP_KERNEL|__GFP_ZERO))) {
|
||||
+ bucket_gens = kvmalloc(struct_size(bucket_gens, b, nbuckets),
|
||||
+ GFP_KERNEL|__GFP_ZERO);
|
||||
+ if (!bucket_gens) {
|
||||
ret = -BCH_ERR_ENOMEM_bucket_gens;
|
||||
goto err;
|
||||
}
|
||||
@@ -1285,11 +1286,13 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
|
||||
old_bucket_gens = rcu_dereference_protected(ca->bucket_gens, 1);
|
||||
|
||||
if (resize) {
|
||||
- size_t n = min(bucket_gens->nbuckets, old_bucket_gens->nbuckets);
|
||||
-
|
||||
+ bucket_gens->nbuckets = min(bucket_gens->nbuckets,
|
||||
+ old_bucket_gens->nbuckets);
|
||||
+ bucket_gens->nbuckets_minus_first =
|
||||
+ bucket_gens->nbuckets - bucket_gens->first_bucket;
|
||||
memcpy(bucket_gens->b,
|
||||
old_bucket_gens->b,
|
||||
- n);
|
||||
+ bucket_gens->nbuckets);
|
||||
}
|
||||
|
||||
rcu_assign_pointer(ca->bucket_gens, bucket_gens);
|
||||
diff --git a/fs/bcachefs/buckets_types.h b/fs/bcachefs/buckets_types.h
|
||||
index 28bd09a253c8..7174047b8e92 100644
|
||||
--- a/fs/bcachefs/buckets_types.h
|
||||
+++ b/fs/bcachefs/buckets_types.h
|
||||
@@ -24,7 +24,7 @@ struct bucket_gens {
|
||||
u16 first_bucket;
|
||||
size_t nbuckets;
|
||||
size_t nbuckets_minus_first;
|
||||
- u8 b[];
|
||||
+ u8 b[] __counted_by(nbuckets);
|
||||
};
|
||||
|
||||
struct bch_dev_usage {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,103 +0,0 @@
|
||||
From 104688e7ed283a31735c61f4c3f95c339df42f8f Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 01:11:29 -0400
|
||||
Subject: [PATCH 036/233] bcachefs: avoid 'unsigned flags'
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
flags should have actual types, where possible: fix btree_update.h
|
||||
helpers
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_update.h | 24 +++++++++++++++---------
|
||||
1 file changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_update.h b/fs/bcachefs/btree_update.h
|
||||
index 70b3c989fac2..7e71c4d1111d 100644
|
||||
--- a/fs/bcachefs/btree_update.h
|
||||
+++ b/fs/bcachefs/btree_update.h
|
||||
@@ -244,7 +244,8 @@ static inline struct bkey_i *bch2_bkey_make_mut_noupdate(struct btree_trans *tra
|
||||
KEY_TYPE_##_type, sizeof(struct bkey_i_##_type)))
|
||||
|
||||
static inline struct bkey_i *__bch2_bkey_make_mut(struct btree_trans *trans, struct btree_iter *iter,
|
||||
- struct bkey_s_c *k, unsigned flags,
|
||||
+ struct bkey_s_c *k,
|
||||
+ enum btree_iter_update_trigger_flags flags,
|
||||
unsigned type, unsigned min_bytes)
|
||||
{
|
||||
struct bkey_i *mut = __bch2_bkey_make_mut_noupdate(trans, *k, type, min_bytes);
|
||||
@@ -261,8 +262,9 @@ static inline struct bkey_i *__bch2_bkey_make_mut(struct btree_trans *trans, str
|
||||
return mut;
|
||||
}
|
||||
|
||||
-static inline struct bkey_i *bch2_bkey_make_mut(struct btree_trans *trans, struct btree_iter *iter,
|
||||
- struct bkey_s_c *k, unsigned flags)
|
||||
+static inline struct bkey_i *bch2_bkey_make_mut(struct btree_trans *trans,
|
||||
+ struct btree_iter *iter, struct bkey_s_c *k,
|
||||
+ enum btree_iter_update_trigger_flags flags)
|
||||
{
|
||||
return __bch2_bkey_make_mut(trans, iter, k, flags, 0, 0);
|
||||
}
|
||||
@@ -274,7 +276,8 @@ static inline struct bkey_i *bch2_bkey_make_mut(struct btree_trans *trans, struc
|
||||
static inline struct bkey_i *__bch2_bkey_get_mut_noupdate(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
unsigned btree_id, struct bpos pos,
|
||||
- unsigned flags, unsigned type, unsigned min_bytes)
|
||||
+ enum btree_iter_update_trigger_flags flags,
|
||||
+ unsigned type, unsigned min_bytes)
|
||||
{
|
||||
struct bkey_s_c k = __bch2_bkey_get_iter(trans, iter,
|
||||
btree_id, pos, flags|BTREE_ITER_intent, type);
|
||||
@@ -289,7 +292,7 @@ static inline struct bkey_i *__bch2_bkey_get_mut_noupdate(struct btree_trans *tr
|
||||
static inline struct bkey_i *bch2_bkey_get_mut_noupdate(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
unsigned btree_id, struct bpos pos,
|
||||
- unsigned flags)
|
||||
+ enum btree_iter_update_trigger_flags flags)
|
||||
{
|
||||
return __bch2_bkey_get_mut_noupdate(trans, iter, btree_id, pos, flags, 0, 0);
|
||||
}
|
||||
@@ -297,7 +300,8 @@ static inline struct bkey_i *bch2_bkey_get_mut_noupdate(struct btree_trans *tran
|
||||
static inline struct bkey_i *__bch2_bkey_get_mut(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
unsigned btree_id, struct bpos pos,
|
||||
- unsigned flags, unsigned type, unsigned min_bytes)
|
||||
+ enum btree_iter_update_trigger_flags flags,
|
||||
+ unsigned type, unsigned min_bytes)
|
||||
{
|
||||
struct bkey_i *mut = __bch2_bkey_get_mut_noupdate(trans, iter,
|
||||
btree_id, pos, flags|BTREE_ITER_intent, type, min_bytes);
|
||||
@@ -318,7 +322,8 @@ static inline struct bkey_i *__bch2_bkey_get_mut(struct btree_trans *trans,
|
||||
static inline struct bkey_i *bch2_bkey_get_mut_minsize(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
unsigned btree_id, struct bpos pos,
|
||||
- unsigned flags, unsigned min_bytes)
|
||||
+ enum btree_iter_update_trigger_flags flags,
|
||||
+ unsigned min_bytes)
|
||||
{
|
||||
return __bch2_bkey_get_mut(trans, iter, btree_id, pos, flags, 0, min_bytes);
|
||||
}
|
||||
@@ -326,7 +331,7 @@ static inline struct bkey_i *bch2_bkey_get_mut_minsize(struct btree_trans *trans
|
||||
static inline struct bkey_i *bch2_bkey_get_mut(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
unsigned btree_id, struct bpos pos,
|
||||
- unsigned flags)
|
||||
+ enum btree_iter_update_trigger_flags flags)
|
||||
{
|
||||
return __bch2_bkey_get_mut(trans, iter, btree_id, pos, flags, 0, 0);
|
||||
}
|
||||
@@ -337,7 +342,8 @@ static inline struct bkey_i *bch2_bkey_get_mut(struct btree_trans *trans,
|
||||
KEY_TYPE_##_type, sizeof(struct bkey_i_##_type)))
|
||||
|
||||
static inline struct bkey_i *__bch2_bkey_alloc(struct btree_trans *trans, struct btree_iter *iter,
|
||||
- unsigned flags, unsigned type, unsigned val_size)
|
||||
+ enum btree_iter_update_trigger_flags flags,
|
||||
+ unsigned type, unsigned val_size)
|
||||
{
|
||||
struct bkey_i *k = bch2_trans_kmalloc(trans, sizeof(*k) + val_size);
|
||||
int ret;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,75 +0,0 @@
|
||||
From e86231fc642b4d428c941fbd8285ca66873375db Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 01:16:16 -0400
|
||||
Subject: [PATCH 037/233] bcachefs: use bch2_data_update_opts_to_text() in
|
||||
trace_move_extent_fail()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/data_update.c | 33 ++++++++++++++-------------------
|
||||
1 file changed, 14 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c
|
||||
index 8e75a852b358..5ea432bc0052 100644
|
||||
--- a/fs/bcachefs/data_update.c
|
||||
+++ b/fs/bcachefs/data_update.c
|
||||
@@ -110,11 +110,8 @@ static void trace_move_extent_fail2(struct data_update *m,
|
||||
{
|
||||
struct bch_fs *c = m->op.c;
|
||||
struct bkey_s_c old = bkey_i_to_s_c(m->k.k);
|
||||
- const union bch_extent_entry *entry;
|
||||
- struct bch_extent_ptr *ptr;
|
||||
- struct extent_ptr_decoded p;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
- unsigned i, rewrites_found = 0;
|
||||
+ unsigned rewrites_found = 0;
|
||||
|
||||
if (!trace_move_extent_fail_enabled())
|
||||
return;
|
||||
@@ -122,27 +119,25 @@ static void trace_move_extent_fail2(struct data_update *m,
|
||||
prt_str(&buf, msg);
|
||||
|
||||
if (insert) {
|
||||
- i = 0;
|
||||
+ const union bch_extent_entry *entry;
|
||||
+ struct bch_extent_ptr *ptr;
|
||||
+ struct extent_ptr_decoded p;
|
||||
+
|
||||
+ unsigned ptr_bit = 1;
|
||||
bkey_for_each_ptr_decode(old.k, bch2_bkey_ptrs_c(old), p, entry) {
|
||||
- if (((1U << i) & m->data_opts.rewrite_ptrs) &&
|
||||
+ if ((ptr_bit & m->data_opts.rewrite_ptrs) &&
|
||||
(ptr = bch2_extent_has_ptr(old, p, bkey_i_to_s(insert))) &&
|
||||
!ptr->cached)
|
||||
- rewrites_found |= 1U << i;
|
||||
- i++;
|
||||
+ rewrites_found |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
- prt_printf(&buf, "\nrewrite ptrs: %u%u%u%u",
|
||||
- (m->data_opts.rewrite_ptrs & (1 << 0)) != 0,
|
||||
- (m->data_opts.rewrite_ptrs & (1 << 1)) != 0,
|
||||
- (m->data_opts.rewrite_ptrs & (1 << 2)) != 0,
|
||||
- (m->data_opts.rewrite_ptrs & (1 << 3)) != 0);
|
||||
-
|
||||
- prt_printf(&buf, "\nrewrites found: %u%u%u%u",
|
||||
- (rewrites_found & (1 << 0)) != 0,
|
||||
- (rewrites_found & (1 << 1)) != 0,
|
||||
- (rewrites_found & (1 << 2)) != 0,
|
||||
- (rewrites_found & (1 << 3)) != 0);
|
||||
+ prt_str(&buf, "rewrites found:\t");
|
||||
+ bch2_prt_u64_base2(&buf, rewrites_found);
|
||||
+ prt_newline(&buf);
|
||||
+
|
||||
+ bch2_data_update_opts_to_text(&buf, c, &m->op.opts, &m->data_opts);
|
||||
|
||||
prt_str(&buf, "\nold: ");
|
||||
bch2_bkey_val_to_text(&buf, c, old);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,148 +0,0 @@
|
||||
From 7813e014b5c83791825eff8850c42bd9dfe25471 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 01:21:43 -0400
|
||||
Subject: [PATCH 038/233] bcachefs: bch2_io_opts_fixups()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Centralize some io path option fixups - they weren't always being
|
||||
applied correctly:
|
||||
|
||||
- background_compression uses compression if unset
|
||||
- background_target uses foreground_target if unset
|
||||
- nocow disables most fancy io path options
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/data_update.c | 4 ++--
|
||||
fs/bcachefs/extents.c | 2 +-
|
||||
fs/bcachefs/inode.c | 4 ++--
|
||||
fs/bcachefs/opts.c | 5 ++++-
|
||||
fs/bcachefs/opts.h | 12 ++++++++++--
|
||||
fs/bcachefs/rebalance.c | 4 ++--
|
||||
6 files changed, 21 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c
|
||||
index 5ea432bc0052..a176e5439cbf 100644
|
||||
--- a/fs/bcachefs/data_update.c
|
||||
+++ b/fs/bcachefs/data_update.c
|
||||
@@ -535,7 +535,7 @@ void bch2_data_update_opts_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "compression:\t");
|
||||
- bch2_compression_opt_to_text(out, background_compression(*io_opts));
|
||||
+ bch2_compression_opt_to_text(out, io_opts->background_compression);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "opts.replicas:\t");
|
||||
@@ -647,7 +647,7 @@ int bch2_data_update_init(struct btree_trans *trans,
|
||||
BCH_WRITE_DATA_ENCODED|
|
||||
BCH_WRITE_MOVE|
|
||||
m->data_opts.write_flags;
|
||||
- m->op.compression_opt = background_compression(io_opts);
|
||||
+ m->op.compression_opt = io_opts.background_compression;
|
||||
m->op.watermark = m->data_opts.btree_insert_flags & BCH_WATERMARK_MASK;
|
||||
|
||||
unsigned durability_have = 0, durability_removing = 0;
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 85b98c782e1b..45a67daf0d64 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1504,7 +1504,7 @@ int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bkey_i *_k,
|
||||
struct bkey_s k = bkey_i_to_s(_k);
|
||||
struct bch_extent_rebalance *r;
|
||||
unsigned target = opts->background_target;
|
||||
- unsigned compression = background_compression(*opts);
|
||||
+ unsigned compression = opts->background_compression;
|
||||
bool needs_rebalance;
|
||||
|
||||
if (!bkey_extent_is_direct_data(k.k))
|
||||
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
|
||||
index 43653cf050e9..fbdd11802bdf 100644
|
||||
--- a/fs/bcachefs/inode.c
|
||||
+++ b/fs/bcachefs/inode.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "extent_update.h"
|
||||
#include "fs.h"
|
||||
#include "inode.h"
|
||||
+#include "opts.h"
|
||||
#include "str_hash.h"
|
||||
#include "snapshot.h"
|
||||
#include "subvolume.h"
|
||||
@@ -1145,8 +1146,7 @@ void bch2_inode_opts_get(struct bch_io_opts *opts, struct bch_fs *c,
|
||||
BCH_INODE_OPTS()
|
||||
#undef x
|
||||
|
||||
- if (opts->nocow)
|
||||
- opts->compression = opts->background_compression = opts->data_checksum = opts->erasure_code = 0;
|
||||
+ bch2_io_opts_fixups(opts);
|
||||
}
|
||||
|
||||
int bch2_inum_opts_get(struct btree_trans *trans, subvol_inum inum, struct bch_io_opts *opts)
|
||||
diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
|
||||
index 0e2ee262fbd4..1f5843284e9e 100644
|
||||
--- a/fs/bcachefs/opts.c
|
||||
+++ b/fs/bcachefs/opts.c
|
||||
@@ -710,11 +710,14 @@ void bch2_opt_set_sb(struct bch_fs *c, struct bch_dev *ca,
|
||||
|
||||
struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts src)
|
||||
{
|
||||
- return (struct bch_io_opts) {
|
||||
+ struct bch_io_opts opts = {
|
||||
#define x(_name, _bits) ._name = src._name,
|
||||
BCH_INODE_OPTS()
|
||||
#undef x
|
||||
};
|
||||
+
|
||||
+ bch2_io_opts_fixups(&opts);
|
||||
+ return opts;
|
||||
}
|
||||
|
||||
bool bch2_opt_is_inode_opt(enum bch_opt_id id)
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index 23dda014e331..dd27ef556611 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -626,9 +626,17 @@ struct bch_io_opts {
|
||||
#undef x
|
||||
};
|
||||
|
||||
-static inline unsigned background_compression(struct bch_io_opts opts)
|
||||
+static inline void bch2_io_opts_fixups(struct bch_io_opts *opts)
|
||||
{
|
||||
- return opts.background_compression ?: opts.compression;
|
||||
+ if (!opts->background_target)
|
||||
+ opts->background_target = opts->foreground_target;
|
||||
+ if (!opts->background_compression)
|
||||
+ opts->background_compression = opts->compression;
|
||||
+ if (opts->nocow) {
|
||||
+ opts->compression = opts->background_compression = 0;
|
||||
+ opts->data_checksum = 0;
|
||||
+ opts->erasure_code = 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts);
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index cd6647374353..2f93ae8781bb 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -257,12 +257,12 @@ static bool rebalance_pred(struct bch_fs *c, void *arg,
|
||||
|
||||
if (k.k->p.inode) {
|
||||
target = io_opts->background_target;
|
||||
- compression = background_compression(*io_opts);
|
||||
+ compression = io_opts->background_compression;
|
||||
} else {
|
||||
const struct bch_extent_rebalance *r = bch2_bkey_rebalance_opts(k);
|
||||
|
||||
target = r ? r->target : io_opts->background_target;
|
||||
- compression = r ? r->compression : background_compression(*io_opts);
|
||||
+ compression = r ? r->compression : io_opts->background_compression;
|
||||
}
|
||||
|
||||
data_opts->rewrite_ptrs = bch2_bkey_ptrs_need_rebalance(c, k, target, compression);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,167 +0,0 @@
|
||||
From 88c26043ea0b7fb1d68b5e7ca2befc1e3077020b Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 01:32:55 -0400
|
||||
Subject: [PATCH 039/233] bcachefs: small cleanup for extent ptr bitmasks
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/data_update.c | 30 +++++++++++++++---------------
|
||||
fs/bcachefs/extents.c | 12 ++++++------
|
||||
fs/bcachefs/io_read.c | 6 +++---
|
||||
3 files changed, 24 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c
|
||||
index a176e5439cbf..90da57a26962 100644
|
||||
--- a/fs/bcachefs/data_update.c
|
||||
+++ b/fs/bcachefs/data_update.c
|
||||
@@ -189,7 +189,7 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
|
||||
struct bpos next_pos;
|
||||
bool should_check_enospc;
|
||||
s64 i_sectors_delta = 0, disk_sectors_delta = 0;
|
||||
- unsigned rewrites_found = 0, durability, i;
|
||||
+ unsigned rewrites_found = 0, durability, ptr_bit;
|
||||
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
@@ -226,16 +226,16 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
|
||||
*
|
||||
* Fist, drop rewrite_ptrs from @new:
|
||||
*/
|
||||
- i = 0;
|
||||
+ ptr_bit = 1;
|
||||
bkey_for_each_ptr_decode(old.k, bch2_bkey_ptrs_c(old), p, entry_c) {
|
||||
- if (((1U << i) & m->data_opts.rewrite_ptrs) &&
|
||||
+ if ((ptr_bit & m->data_opts.rewrite_ptrs) &&
|
||||
(ptr = bch2_extent_has_ptr(old, p, bkey_i_to_s(insert))) &&
|
||||
!ptr->cached) {
|
||||
bch2_extent_ptr_set_cached(c, &m->op.opts,
|
||||
bkey_i_to_s(insert), ptr);
|
||||
- rewrites_found |= 1U << i;
|
||||
+ rewrites_found |= ptr_bit;
|
||||
}
|
||||
- i++;
|
||||
+ ptr_bit <<= 1;
|
||||
}
|
||||
|
||||
if (m->data_opts.rewrite_ptrs &&
|
||||
@@ -609,7 +609,7 @@ int bch2_data_update_init(struct btree_trans *trans,
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
const union bch_extent_entry *entry;
|
||||
struct extent_ptr_decoded p;
|
||||
- unsigned i, reserve_sectors = k.k->size * data_opts.extra_replicas;
|
||||
+ unsigned reserve_sectors = k.k->size * data_opts.extra_replicas;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
@@ -652,17 +652,17 @@ int bch2_data_update_init(struct btree_trans *trans,
|
||||
|
||||
unsigned durability_have = 0, durability_removing = 0;
|
||||
|
||||
- i = 0;
|
||||
+ unsigned ptr_bit = 1;
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
if (!p.ptr.cached) {
|
||||
rcu_read_lock();
|
||||
- if (BIT(i) & m->data_opts.rewrite_ptrs) {
|
||||
+ if (ptr_bit & m->data_opts.rewrite_ptrs) {
|
||||
if (crc_is_compressed(p.crc))
|
||||
reserve_sectors += k.k->size;
|
||||
|
||||
m->op.nr_replicas += bch2_extent_ptr_desired_durability(c, &p);
|
||||
durability_removing += bch2_extent_ptr_desired_durability(c, &p);
|
||||
- } else if (!(BIT(i) & m->data_opts.kill_ptrs)) {
|
||||
+ } else if (!(ptr_bit & m->data_opts.kill_ptrs)) {
|
||||
bch2_dev_list_add_dev(&m->op.devs_have, p.ptr.dev);
|
||||
durability_have += bch2_extent_ptr_durability(c, &p);
|
||||
}
|
||||
@@ -682,7 +682,7 @@ int bch2_data_update_init(struct btree_trans *trans,
|
||||
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible)
|
||||
m->op.incompressible = true;
|
||||
|
||||
- i++;
|
||||
+ ptr_bit <<= 1;
|
||||
}
|
||||
|
||||
unsigned durability_required = max(0, (int) (io_opts.data_replicas - durability_have));
|
||||
@@ -745,14 +745,14 @@ int bch2_data_update_init(struct btree_trans *trans,
|
||||
void bch2_data_update_opts_normalize(struct bkey_s_c k, struct data_update_opts *opts)
|
||||
{
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
- unsigned i = 0;
|
||||
+ unsigned ptr_bit = 1;
|
||||
|
||||
bkey_for_each_ptr(ptrs, ptr) {
|
||||
- if ((opts->rewrite_ptrs & (1U << i)) && ptr->cached) {
|
||||
- opts->kill_ptrs |= 1U << i;
|
||||
- opts->rewrite_ptrs ^= 1U << i;
|
||||
+ if ((opts->rewrite_ptrs & ptr_bit) && ptr->cached) {
|
||||
+ opts->kill_ptrs |= ptr_bit;
|
||||
+ opts->rewrite_ptrs ^= ptr_bit;
|
||||
}
|
||||
|
||||
- i++;
|
||||
+ ptr_bit <<= 1;
|
||||
}
|
||||
}
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 45a67daf0d64..243cb15b74b3 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1414,7 +1414,7 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
unsigned compression_type = bch2_compression_opt_to_type(compression);
|
||||
const union bch_extent_entry *entry;
|
||||
struct extent_ptr_decoded p;
|
||||
- unsigned i = 0;
|
||||
+ unsigned ptr_bit = 1;
|
||||
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
@@ -1424,18 +1424,18 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
}
|
||||
|
||||
if (!p.ptr.cached && p.crc.compression_type != compression_type)
|
||||
- rewrite_ptrs |= 1U << i;
|
||||
- i++;
|
||||
+ rewrite_ptrs |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
}
|
||||
}
|
||||
incompressible:
|
||||
if (target && bch2_target_accepts_data(c, BCH_DATA_user, target)) {
|
||||
- unsigned i = 0;
|
||||
+ unsigned ptr_bit = 1;
|
||||
|
||||
bkey_for_each_ptr(ptrs, ptr) {
|
||||
if (!ptr->cached && !bch2_dev_in_target(c, ptr->dev, target))
|
||||
- rewrite_ptrs |= 1U << i;
|
||||
- i++;
|
||||
+ rewrite_ptrs |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/io_read.c b/fs/bcachefs/io_read.c
|
||||
index b3b934a87c6d..cbc3cc1f6d03 100644
|
||||
--- a/fs/bcachefs/io_read.c
|
||||
+++ b/fs/bcachefs/io_read.c
|
||||
@@ -231,11 +231,11 @@ static struct promote_op *__promote_alloc(struct btree_trans *trans,
|
||||
update_opts.target = opts.foreground_target;
|
||||
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
- unsigned i = 0;
|
||||
+ unsigned ptr_bit = 1;
|
||||
bkey_for_each_ptr(ptrs, ptr) {
|
||||
if (bch2_dev_io_failures(failed, ptr->dev))
|
||||
- update_opts.rewrite_ptrs |= BIT(i);
|
||||
- i++;
|
||||
+ update_opts.rewrite_ptrs |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,59 +0,0 @@
|
||||
From ef92eb2a63e2a1ae573455c11784519fee7bd70c Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 01:40:19 -0400
|
||||
Subject: [PATCH 040/233] bcachefs: kill bch2_bkey_needs_rebalance()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Dead code
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 17 -----------------
|
||||
fs/bcachefs/extents.h | 1 -
|
||||
2 files changed, 18 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 243cb15b74b3..6ad5ff7c8239 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1442,23 +1442,6 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
return rewrite_ptrs;
|
||||
}
|
||||
|
||||
-bool bch2_bkey_needs_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
-{
|
||||
- const struct bch_extent_rebalance *r = bch2_bkey_rebalance_opts(k);
|
||||
-
|
||||
- /*
|
||||
- * If it's an indirect extent, we don't delete the rebalance entry when
|
||||
- * done so that we know what options were applied - check if it still
|
||||
- * needs work done:
|
||||
- */
|
||||
- if (r &&
|
||||
- k.k->type == KEY_TYPE_reflink_v &&
|
||||
- !bch2_bkey_ptrs_need_rebalance(c, k, r->target, r->compression))
|
||||
- r = NULL;
|
||||
-
|
||||
- return r != NULL;
|
||||
-}
|
||||
-
|
||||
static u64 __bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
unsigned target, unsigned compression)
|
||||
{
|
||||
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
|
||||
index bcffcf60aaaf..9374599b384d 100644
|
||||
--- a/fs/bcachefs/extents.h
|
||||
+++ b/fs/bcachefs/extents.h
|
||||
@@ -713,7 +713,6 @@ void bch2_ptr_swab(struct bkey_s);
|
||||
const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c);
|
||||
unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c,
|
||||
unsigned, unsigned);
|
||||
-bool bch2_bkey_needs_rebalance(struct bch_fs *, struct bkey_s_c);
|
||||
u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *, struct bkey_s_c);
|
||||
|
||||
int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,72 +0,0 @@
|
||||
From 48cc0c6bed2eb17b1bba38273cb257533a83c408 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 02:14:53 -0400
|
||||
Subject: [PATCH 041/233] bcachefs: kill __bch2_bkey_sectors_need_rebalance()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Single caller, fold into bch2_bkey_sectors_need_rebalance()
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 23 ++++++++++-------------
|
||||
1 file changed, 10 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 6ad5ff7c8239..5ec0fec597f7 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1442,16 +1442,19 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
return rewrite_ptrs;
|
||||
}
|
||||
|
||||
-static u64 __bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
- unsigned target, unsigned compression)
|
||||
+u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
{
|
||||
+ const struct bch_extent_rebalance *opts = bch2_bkey_rebalance_opts(k);
|
||||
+ if (!opts)
|
||||
+ return 0;
|
||||
+
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
const union bch_extent_entry *entry;
|
||||
struct extent_ptr_decoded p;
|
||||
u64 sectors = 0;
|
||||
|
||||
- if (compression) {
|
||||
- unsigned compression_type = bch2_compression_opt_to_type(compression);
|
||||
+ if (opts->compression) {
|
||||
+ unsigned compression_type = bch2_compression_opt_to_type(opts->compression);
|
||||
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
@@ -1465,22 +1468,16 @@ static u64 __bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c
|
||||
}
|
||||
}
|
||||
incompressible:
|
||||
- if (target && bch2_target_accepts_data(c, BCH_DATA_user, target)) {
|
||||
+ if (opts->target &&
|
||||
+ bch2_target_accepts_data(c, BCH_DATA_user, opts->target)) {
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
|
||||
- if (!p.ptr.cached && !bch2_dev_in_target(c, p.ptr.dev, target))
|
||||
+ if (!p.ptr.cached && !bch2_dev_in_target(c, p.ptr.dev, opts->target))
|
||||
sectors += p.crc.compressed_size;
|
||||
}
|
||||
|
||||
return sectors;
|
||||
}
|
||||
|
||||
-u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
-{
|
||||
- const struct bch_extent_rebalance *r = bch2_bkey_rebalance_opts(k);
|
||||
-
|
||||
- return r ? __bch2_bkey_sectors_need_rebalance(c, k, r->target, r->compression) : 0;
|
||||
-}
|
||||
-
|
||||
int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bkey_i *_k,
|
||||
struct bch_io_opts *opts)
|
||||
{
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,157 +0,0 @@
|
||||
From 875a3128db4cabe615187b9ca841b85bde923fd9 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 02:21:28 -0400
|
||||
Subject: [PATCH 042/233] bcachefs: rename bch_extent_rebalance fields to match
|
||||
other opts structs
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 36 ++++++++++++++++++------------------
|
||||
fs/bcachefs/extents_format.h | 8 ++++----
|
||||
fs/bcachefs/rebalance.c | 12 ++++++------
|
||||
3 files changed, 28 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 5ec0fec597f7..ee0e86f0becd 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1161,11 +1161,11 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
|
||||
prt_str(out, "rebalance: target ");
|
||||
if (c)
|
||||
- bch2_target_to_text(out, c, r->target);
|
||||
+ bch2_target_to_text(out, c, r->background_target);
|
||||
else
|
||||
- prt_printf(out, "%u", r->target);
|
||||
+ prt_printf(out, "%u", r->background_target);
|
||||
prt_str(out, " compression ");
|
||||
- bch2_compression_opt_to_text(out, r->compression);
|
||||
+ bch2_compression_opt_to_text(out, r->background_compression);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1453,8 +1453,8 @@ u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
struct extent_ptr_decoded p;
|
||||
u64 sectors = 0;
|
||||
|
||||
- if (opts->compression) {
|
||||
- unsigned compression_type = bch2_compression_opt_to_type(opts->compression);
|
||||
+ if (opts->background_compression) {
|
||||
+ unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
@@ -1468,10 +1468,10 @@ u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
}
|
||||
}
|
||||
incompressible:
|
||||
- if (opts->target &&
|
||||
- bch2_target_accepts_data(c, BCH_DATA_user, opts->target)) {
|
||||
+ if (opts->background_target &&
|
||||
+ bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target)) {
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
|
||||
- if (!p.ptr.cached && !bch2_dev_in_target(c, p.ptr.dev, opts->target))
|
||||
+ if (!p.ptr.cached && !bch2_dev_in_target(c, p.ptr.dev, opts->background_target))
|
||||
sectors += p.crc.compressed_size;
|
||||
}
|
||||
|
||||
@@ -1500,14 +1500,14 @@ int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bkey_i *_k,
|
||||
* they're referenced by different inodes with different
|
||||
* options:
|
||||
*/
|
||||
- if (r->target)
|
||||
- target = r->target;
|
||||
- if (r->compression)
|
||||
- compression = r->compression;
|
||||
+ if (r->background_target)
|
||||
+ target = r->background_target;
|
||||
+ if (r->background_compression)
|
||||
+ compression = r->background_compression;
|
||||
}
|
||||
|
||||
- r->target = target;
|
||||
- r->compression = compression;
|
||||
+ r->background_target = target;
|
||||
+ r->background_compression = compression;
|
||||
}
|
||||
|
||||
needs_rebalance = bch2_bkey_ptrs_need_rebalance(c, k.s_c, target, compression);
|
||||
@@ -1515,10 +1515,10 @@ int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bkey_i *_k,
|
||||
if (needs_rebalance && !r) {
|
||||
union bch_extent_entry *new = bkey_val_end(k);
|
||||
|
||||
- new->rebalance.type = 1U << BCH_EXTENT_ENTRY_rebalance;
|
||||
- new->rebalance.compression = compression;
|
||||
- new->rebalance.target = target;
|
||||
- new->rebalance.unused = 0;
|
||||
+ new->rebalance.type = 1U << BCH_EXTENT_ENTRY_rebalance;
|
||||
+ new->rebalance.background_compression = compression;
|
||||
+ new->rebalance.background_target = target;
|
||||
+ new->rebalance.unused = 0;
|
||||
k.k->u64s += extent_entry_u64s(new);
|
||||
} else if (!needs_rebalance && r && k.k->type != KEY_TYPE_reflink_v) {
|
||||
/*
|
||||
diff --git a/fs/bcachefs/extents_format.h b/fs/bcachefs/extents_format.h
|
||||
index 3bd2fdbb0817..2cc3e60f3b12 100644
|
||||
--- a/fs/bcachefs/extents_format.h
|
||||
+++ b/fs/bcachefs/extents_format.h
|
||||
@@ -205,11 +205,11 @@ struct bch_extent_rebalance {
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
__u64 type:6,
|
||||
unused:34,
|
||||
- compression:8, /* enum bch_compression_opt */
|
||||
- target:16;
|
||||
+ background_compression:8, /* enum bch_compression_opt */
|
||||
+ background_target:16;
|
||||
#elif defined (__BIG_ENDIAN_BITFIELD)
|
||||
- __u64 target:16,
|
||||
- compression:8,
|
||||
+ __u64 background_target:16,
|
||||
+ background_compression:8,
|
||||
unused:34,
|
||||
type:6;
|
||||
#endif
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index 2f93ae8781bb..dc70e6feaf79 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -157,8 +157,8 @@ static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans,
|
||||
memset(data_opts, 0, sizeof(*data_opts));
|
||||
|
||||
data_opts->rewrite_ptrs =
|
||||
- bch2_bkey_ptrs_need_rebalance(c, k, r->target, r->compression);
|
||||
- data_opts->target = r->target;
|
||||
+ bch2_bkey_ptrs_need_rebalance(c, k, r->background_target, r->background_compression);
|
||||
+ data_opts->target = r->background_target;
|
||||
data_opts->write_flags |= BCH_WRITE_ONLY_SPECIFIED_DEVS;
|
||||
|
||||
if (!data_opts->rewrite_ptrs) {
|
||||
@@ -179,9 +179,9 @@ static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans,
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
prt_str(&buf, "target=");
|
||||
- bch2_target_to_text(&buf, c, r->target);
|
||||
+ bch2_target_to_text(&buf, c, r->background_target);
|
||||
prt_str(&buf, " compression=");
|
||||
- bch2_compression_opt_to_text(&buf, r->compression);
|
||||
+ bch2_compression_opt_to_text(&buf, r->background_compression);
|
||||
prt_str(&buf, " ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
|
||||
@@ -261,8 +261,8 @@ static bool rebalance_pred(struct bch_fs *c, void *arg,
|
||||
} else {
|
||||
const struct bch_extent_rebalance *r = bch2_bkey_rebalance_opts(k);
|
||||
|
||||
- target = r ? r->target : io_opts->background_target;
|
||||
- compression = r ? r->compression : io_opts->background_compression;
|
||||
+ target = r ? r->background_target : io_opts->background_target;
|
||||
+ compression = r ? r->background_compression : io_opts->background_compression;
|
||||
}
|
||||
|
||||
data_opts->rewrite_ptrs = bch2_bkey_ptrs_need_rebalance(c, k, target, compression);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,205 +0,0 @@
|
||||
From bdad263284332336642784929b9e4bf3887560b8 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 02:28:51 -0400
|
||||
Subject: [PATCH 043/233] bcachefs: io_opts_to_rebalance_opts()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
New helper to simplify bch2_bkey_set_needs_rebalance()
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/data_update.c | 2 +-
|
||||
fs/bcachefs/extents.c | 60 ++++++++++--------------------------
|
||||
fs/bcachefs/extents.h | 3 +-
|
||||
fs/bcachefs/extents_format.h | 5 +++
|
||||
fs/bcachefs/io_misc.c | 2 +-
|
||||
fs/bcachefs/io_write.c | 2 +-
|
||||
fs/bcachefs/opts.h | 13 ++++++++
|
||||
fs/bcachefs/reflink.c | 2 +-
|
||||
8 files changed, 39 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c
|
||||
index 90da57a26962..e4af2ccdf4c8 100644
|
||||
--- a/fs/bcachefs/data_update.c
|
||||
+++ b/fs/bcachefs/data_update.c
|
||||
@@ -357,7 +357,7 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
|
||||
k.k->p, bkey_start_pos(&insert->k)) ?:
|
||||
bch2_insert_snapshot_whiteouts(trans, m->btree_id,
|
||||
k.k->p, insert->k.p) ?:
|
||||
- bch2_bkey_set_needs_rebalance(c, insert, &op->opts) ?:
|
||||
+ bch2_bkey_set_needs_rebalance(c, &op->opts, insert) ?:
|
||||
bch2_trans_update(trans, &iter, insert,
|
||||
BTREE_UPDATE_internal_snapshot_node) ?:
|
||||
bch2_trans_commit(trans, &op->res,
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index ee0e86f0becd..a134aa5a76bb 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1478,55 +1478,27 @@ u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
return sectors;
|
||||
}
|
||||
|
||||
-int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bkey_i *_k,
|
||||
- struct bch_io_opts *opts)
|
||||
+int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
+ struct bkey_i *_k)
|
||||
{
|
||||
- struct bkey_s k = bkey_i_to_s(_k);
|
||||
- struct bch_extent_rebalance *r;
|
||||
- unsigned target = opts->background_target;
|
||||
- unsigned compression = opts->background_compression;
|
||||
- bool needs_rebalance;
|
||||
-
|
||||
- if (!bkey_extent_is_direct_data(k.k))
|
||||
+ if (!bkey_extent_is_direct_data(&_k->k))
|
||||
return 0;
|
||||
|
||||
- /* get existing rebalance entry: */
|
||||
- r = (struct bch_extent_rebalance *) bch2_bkey_rebalance_opts(k.s_c);
|
||||
- if (r) {
|
||||
- if (k.k->type == KEY_TYPE_reflink_v) {
|
||||
- /*
|
||||
- * indirect extents: existing options take precedence,
|
||||
- * so that we don't move extents back and forth if
|
||||
- * they're referenced by different inodes with different
|
||||
- * options:
|
||||
- */
|
||||
- if (r->background_target)
|
||||
- target = r->background_target;
|
||||
- if (r->background_compression)
|
||||
- compression = r->background_compression;
|
||||
+ struct bkey_s k = bkey_i_to_s(_k);
|
||||
+ struct bch_extent_rebalance *old =
|
||||
+ (struct bch_extent_rebalance *) bch2_bkey_rebalance_opts(k.s_c);
|
||||
+
|
||||
+ if (k.k->type == KEY_TYPE_reflink_v ||
|
||||
+ bch2_bkey_ptrs_need_rebalance(c, k.s_c, opts->background_target, opts->background_compression)) {
|
||||
+ if (!old) {
|
||||
+ old = bkey_val_end(k);
|
||||
+ k.k->u64s += sizeof(*old) / sizeof(u64);
|
||||
}
|
||||
|
||||
- r->background_target = target;
|
||||
- r->background_compression = compression;
|
||||
- }
|
||||
-
|
||||
- needs_rebalance = bch2_bkey_ptrs_need_rebalance(c, k.s_c, target, compression);
|
||||
-
|
||||
- if (needs_rebalance && !r) {
|
||||
- union bch_extent_entry *new = bkey_val_end(k);
|
||||
-
|
||||
- new->rebalance.type = 1U << BCH_EXTENT_ENTRY_rebalance;
|
||||
- new->rebalance.background_compression = compression;
|
||||
- new->rebalance.background_target = target;
|
||||
- new->rebalance.unused = 0;
|
||||
- k.k->u64s += extent_entry_u64s(new);
|
||||
- } else if (!needs_rebalance && r && k.k->type != KEY_TYPE_reflink_v) {
|
||||
- /*
|
||||
- * For indirect extents, don't delete the rebalance entry when
|
||||
- * we're finished so that we know we specifically moved it or
|
||||
- * compressed it to its current location/compression type
|
||||
- */
|
||||
- extent_entry_drop(k, (union bch_extent_entry *) r);
|
||||
+ *old = io_opts_to_rebalance_opts(opts);
|
||||
+ } else {
|
||||
+ if (old)
|
||||
+ extent_entry_drop(k, (union bch_extent_entry *) old);
|
||||
}
|
||||
|
||||
return 0;
|
||||
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
|
||||
index 9374599b384d..97af0d6e4319 100644
|
||||
--- a/fs/bcachefs/extents.h
|
||||
+++ b/fs/bcachefs/extents.h
|
||||
@@ -715,8 +715,7 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c,
|
||||
unsigned, unsigned);
|
||||
u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *, struct bkey_s_c);
|
||||
|
||||
-int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *,
|
||||
- struct bch_io_opts *);
|
||||
+int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bch_io_opts *, struct bkey_i *);
|
||||
|
||||
/* Generic extent code: */
|
||||
|
||||
diff --git a/fs/bcachefs/extents_format.h b/fs/bcachefs/extents_format.h
|
||||
index 2cc3e60f3b12..520697f236c0 100644
|
||||
--- a/fs/bcachefs/extents_format.h
|
||||
+++ b/fs/bcachefs/extents_format.h
|
||||
@@ -215,6 +215,11 @@ struct bch_extent_rebalance {
|
||||
#endif
|
||||
};
|
||||
|
||||
+/* subset of BCH_INODE_OPTS */
|
||||
+#define BCH_REBALANCE_OPTS() \
|
||||
+ x(background_compression) \
|
||||
+ x(background_target)
|
||||
+
|
||||
union bch_extent_entry {
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || __BITS_PER_LONG == 64
|
||||
unsigned long type;
|
||||
diff --git a/fs/bcachefs/io_misc.c b/fs/bcachefs/io_misc.c
|
||||
index f283051758d6..e2acf21ac9b0 100644
|
||||
--- a/fs/bcachefs/io_misc.c
|
||||
+++ b/fs/bcachefs/io_misc.c
|
||||
@@ -461,7 +461,7 @@ case LOGGED_OP_FINSERT_shift_extents:
|
||||
|
||||
op->v.pos = cpu_to_le64(insert ? bkey_start_offset(&delete.k) : delete.k.p.offset);
|
||||
|
||||
- ret = bch2_bkey_set_needs_rebalance(c, copy, &opts) ?:
|
||||
+ ret = bch2_bkey_set_needs_rebalance(c, &opts, copy) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_extents, &delete, 0) ?:
|
||||
bch2_btree_insert_trans(trans, BTREE_ID_extents, copy, 0) ?:
|
||||
bch2_logged_op_update(trans, &op->k_i) ?:
|
||||
diff --git a/fs/bcachefs/io_write.c b/fs/bcachefs/io_write.c
|
||||
index 96720adcfee0..f2f69e5e0910 100644
|
||||
--- a/fs/bcachefs/io_write.c
|
||||
+++ b/fs/bcachefs/io_write.c
|
||||
@@ -369,7 +369,7 @@ static int bch2_write_index_default(struct bch_write_op *op)
|
||||
bkey_start_pos(&sk.k->k),
|
||||
BTREE_ITER_slots|BTREE_ITER_intent);
|
||||
|
||||
- ret = bch2_bkey_set_needs_rebalance(c, sk.k, &op->opts) ?:
|
||||
+ ret = bch2_bkey_set_needs_rebalance(c, &op->opts, sk.k) ?:
|
||||
bch2_extent_update(trans, inum, &iter, sk.k,
|
||||
&op->res,
|
||||
op->new_i_size, &op->i_sectors_delta,
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index dd27ef556611..13555bc35f00 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -642,4 +642,17 @@ static inline void bch2_io_opts_fixups(struct bch_io_opts *opts)
|
||||
struct bch_io_opts bch2_opts_to_inode_opts(struct bch_opts);
|
||||
bool bch2_opt_is_inode_opt(enum bch_opt_id);
|
||||
|
||||
+/* rebalance opts: */
|
||||
+
|
||||
+static inline struct bch_extent_rebalance io_opts_to_rebalance_opts(struct bch_io_opts *opts)
|
||||
+{
|
||||
+ return (struct bch_extent_rebalance) {
|
||||
+ .type = BIT(BCH_EXTENT_ENTRY_rebalance),
|
||||
+#define x(_name) \
|
||||
+ ._name = opts->_name,
|
||||
+ BCH_REBALANCE_OPTS()
|
||||
+#undef x
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
#endif /* _BCACHEFS_OPTS_H */
|
||||
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
|
||||
index f457925fa362..8a36ebd9dd9c 100644
|
||||
--- a/fs/bcachefs/reflink.c
|
||||
+++ b/fs/bcachefs/reflink.c
|
||||
@@ -547,7 +547,7 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
min(src_k.k->p.offset - src_want.offset,
|
||||
dst_end.offset - dst_iter.pos.offset));
|
||||
|
||||
- ret = bch2_bkey_set_needs_rebalance(c, new_dst.k, &opts) ?:
|
||||
+ ret = bch2_bkey_set_needs_rebalance(c, &opts, new_dst.k) ?:
|
||||
bch2_extent_update(trans, dst_inum, &dst_iter,
|
||||
new_dst.k, &disk_res,
|
||||
new_i_size, i_sectors_delta,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,60 +0,0 @@
|
||||
From fc23ffb93c5ba25558186bb77216ad0d1baf59b5 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 19 Oct 2024 23:26:11 -0400
|
||||
Subject: [PATCH 044/233] bcachefs: Add bch_io_opts fields for indicating
|
||||
whether the opts came from the inode
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is going to be used in the bch_extent_rebalance improvements, which
|
||||
propagate io_path options into the extent (important for rebalance,
|
||||
which needs something present in the extent for transactionally tagging
|
||||
them in the rebalance_work btree, and also for indirect extents).
|
||||
|
||||
By tracking in bch_extent_rebalance whether the option came from the
|
||||
filesystem or the inode we can correctly handle options being changed on
|
||||
indirect extents.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/inode.c | 8 +++++++-
|
||||
fs/bcachefs/opts.h | 3 +++
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
|
||||
index fbdd11802bdf..5dd9d3edae77 100644
|
||||
--- a/fs/bcachefs/inode.c
|
||||
+++ b/fs/bcachefs/inode.c
|
||||
@@ -1142,7 +1142,13 @@ struct bch_opts bch2_inode_opts_to_opts(struct bch_inode_unpacked *inode)
|
||||
void bch2_inode_opts_get(struct bch_io_opts *opts, struct bch_fs *c,
|
||||
struct bch_inode_unpacked *inode)
|
||||
{
|
||||
-#define x(_name, _bits) opts->_name = inode_opt_get(c, inode, _name);
|
||||
+#define x(_name, _bits) \
|
||||
+ if ((inode)->bi_##_name) { \
|
||||
+ opts->_name = inode->bi_##_name - 1; \
|
||||
+ opts->_name##_from_inode = true; \
|
||||
+ } else { \
|
||||
+ opts->_name = c->opts._name; \
|
||||
+ }
|
||||
BCH_INODE_OPTS()
|
||||
#undef x
|
||||
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index 13555bc35f00..918eb6730117 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -624,6 +624,9 @@ struct bch_io_opts {
|
||||
#define x(_name, _bits) u##_bits _name;
|
||||
BCH_INODE_OPTS()
|
||||
#undef x
|
||||
+#define x(_name, _bits) u64 _name##_from_inode:1;
|
||||
+ BCH_INODE_OPTS()
|
||||
+#undef x
|
||||
};
|
||||
|
||||
static inline void bch2_io_opts_fixups(struct bch_io_opts *opts)
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,194 +0,0 @@
|
||||
From 86066b111be8a1ef502332ab0511d2cf65766bcd Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 24 Oct 2024 01:06:53 -0400
|
||||
Subject: [PATCH 045/233] bcachefs: copygc_enabled, rebalance_enabled now
|
||||
opts.h options
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
They can now be set at mount time
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs.h | 2 --
|
||||
fs/bcachefs/movinggc.c | 4 ++--
|
||||
fs/bcachefs/opts.h | 12 ++++++++++++
|
||||
fs/bcachefs/rebalance.c | 4 ++--
|
||||
fs/bcachefs/rebalance_types.h | 2 --
|
||||
fs/bcachefs/super.c | 3 ---
|
||||
fs/bcachefs/sysfs.c | 31 +++++++------------------------
|
||||
7 files changed, 23 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
||||
index d4d95ef6791f..e1ab67c533f0 100644
|
||||
--- a/fs/bcachefs/bcachefs.h
|
||||
+++ b/fs/bcachefs/bcachefs.h
|
||||
@@ -1096,8 +1096,6 @@ struct bch_fs {
|
||||
u64 counters_on_mount[BCH_COUNTER_NR];
|
||||
u64 __percpu *counters;
|
||||
|
||||
- unsigned copy_gc_enabled:1;
|
||||
-
|
||||
struct bch2_time_stats times[BCH_TIME_STAT_NR];
|
||||
|
||||
struct btree_transaction_stats btree_transaction_stats[BCH_TRANSACTIONS_NR];
|
||||
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
|
||||
index d658be90f737..725292d69fd6 100644
|
||||
--- a/fs/bcachefs/movinggc.c
|
||||
+++ b/fs/bcachefs/movinggc.c
|
||||
@@ -350,9 +350,9 @@ static int bch2_copygc_thread(void *arg)
|
||||
bch2_trans_unlock_long(ctxt.trans);
|
||||
cond_resched();
|
||||
|
||||
- if (!c->copy_gc_enabled) {
|
||||
+ if (!c->opts.copygc_enabled) {
|
||||
move_buckets_wait(&ctxt, buckets, true);
|
||||
- kthread_wait_freezable(c->copy_gc_enabled ||
|
||||
+ kthread_wait_freezable(c->opts.copygc_enabled ||
|
||||
kthread_should_stop());
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index 918eb6730117..e0e23c29c2d6 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -473,6 +473,18 @@ enum fsck_err_opts {
|
||||
BCH2_NO_SB_OPT, true, \
|
||||
NULL, "Enable nocow mode: enables runtime locking in\n"\
|
||||
"data move path needed if nocow will ever be in use\n")\
|
||||
+ x(copygc_enabled, u8, \
|
||||
+ OPT_FS|OPT_MOUNT, \
|
||||
+ OPT_BOOL(), \
|
||||
+ BCH2_NO_SB_OPT, true, \
|
||||
+ NULL, "Enable copygc: disable for debugging, or to\n"\
|
||||
+ "quiet the system when doing performance testing\n")\
|
||||
+ x(rebalance_enabled, u8, \
|
||||
+ OPT_FS|OPT_MOUNT, \
|
||||
+ OPT_BOOL(), \
|
||||
+ BCH2_NO_SB_OPT, true, \
|
||||
+ NULL, "Enable rebalance: disable for debugging, or to\n"\
|
||||
+ "quiet the system when doing performance testing\n")\
|
||||
x(no_data_io, u8, \
|
||||
OPT_MOUNT, \
|
||||
OPT_BOOL(), \
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index dc70e6feaf79..d8cb346ac138 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -338,9 +338,9 @@ static int do_rebalance(struct moving_context *ctxt)
|
||||
BTREE_ITER_all_snapshots);
|
||||
|
||||
while (!bch2_move_ratelimit(ctxt)) {
|
||||
- if (!r->enabled) {
|
||||
+ if (!c->opts.rebalance_enabled) {
|
||||
bch2_moving_ctxt_flush_all(ctxt);
|
||||
- kthread_wait_freezable(r->enabled ||
|
||||
+ kthread_wait_freezable(c->opts.rebalance_enabled ||
|
||||
kthread_should_stop());
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/rebalance_types.h b/fs/bcachefs/rebalance_types.h
|
||||
index 0fffb536c1d0..fe5098c17dfc 100644
|
||||
--- a/fs/bcachefs/rebalance_types.h
|
||||
+++ b/fs/bcachefs/rebalance_types.h
|
||||
@@ -30,8 +30,6 @@ struct bch_fs_rebalance {
|
||||
struct bbpos scan_start;
|
||||
struct bbpos scan_end;
|
||||
struct bch_move_stats scan_stats;
|
||||
-
|
||||
- unsigned enabled:1;
|
||||
};
|
||||
|
||||
#endif /* _BCACHEFS_REBALANCE_TYPES_H */
|
||||
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
|
||||
index d6411324cd3f..7e2431de3a94 100644
|
||||
--- a/fs/bcachefs/super.c
|
||||
+++ b/fs/bcachefs/super.c
|
||||
@@ -810,9 +810,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
|
||||
INIT_LIST_HEAD(&c->vfs_inodes_list);
|
||||
mutex_init(&c->vfs_inodes_lock);
|
||||
|
||||
- c->copy_gc_enabled = 1;
|
||||
- c->rebalance.enabled = 1;
|
||||
-
|
||||
c->journal.flush_write_time = &c->times[BCH_TIME_journal_flush_write];
|
||||
c->journal.noflush_write_time = &c->times[BCH_TIME_journal_noflush_write];
|
||||
c->journal.flush_seq_time = &c->times[BCH_TIME_journal_flush_seq];
|
||||
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
|
||||
index 3270bfab9466..4ab0ccba2ab5 100644
|
||||
--- a/fs/bcachefs/sysfs.c
|
||||
+++ b/fs/bcachefs/sysfs.c
|
||||
@@ -213,10 +213,8 @@ BCH_PERSISTENT_COUNTERS()
|
||||
rw_attribute(discard);
|
||||
rw_attribute(label);
|
||||
|
||||
-rw_attribute(copy_gc_enabled);
|
||||
read_attribute(copy_gc_wait);
|
||||
|
||||
-rw_attribute(rebalance_enabled);
|
||||
sysfs_pd_controller_attribute(rebalance);
|
||||
read_attribute(rebalance_status);
|
||||
|
||||
@@ -340,9 +338,6 @@ SHOW(bch2_fs)
|
||||
if (attr == &sysfs_gc_gens_pos)
|
||||
bch2_gc_gens_pos_to_text(out, c);
|
||||
|
||||
- sysfs_printf(copy_gc_enabled, "%i", c->copy_gc_enabled);
|
||||
-
|
||||
- sysfs_printf(rebalance_enabled, "%i", c->rebalance.enabled);
|
||||
sysfs_pd_controller_show(rebalance, &c->rebalance.pd); /* XXX */
|
||||
|
||||
if (attr == &sysfs_copy_gc_wait)
|
||||
@@ -419,23 +414,6 @@ STORE(bch2_fs)
|
||||
{
|
||||
struct bch_fs *c = container_of(kobj, struct bch_fs, kobj);
|
||||
|
||||
- if (attr == &sysfs_copy_gc_enabled) {
|
||||
- ssize_t ret = strtoul_safe(buf, c->copy_gc_enabled)
|
||||
- ?: (ssize_t) size;
|
||||
-
|
||||
- if (c->copygc_thread)
|
||||
- wake_up_process(c->copygc_thread);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- if (attr == &sysfs_rebalance_enabled) {
|
||||
- ssize_t ret = strtoul_safe(buf, c->rebalance.enabled)
|
||||
- ?: (ssize_t) size;
|
||||
-
|
||||
- rebalance_wakeup(c);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
sysfs_pd_controller_store(rebalance, &c->rebalance.pd);
|
||||
|
||||
/* Debugging: */
|
||||
@@ -611,10 +589,8 @@ struct attribute *bch2_fs_internal_files[] = {
|
||||
|
||||
&sysfs_gc_gens_pos,
|
||||
|
||||
- &sysfs_copy_gc_enabled,
|
||||
&sysfs_copy_gc_wait,
|
||||
|
||||
- &sysfs_rebalance_enabled,
|
||||
sysfs_pd_controller_files(rebalance),
|
||||
|
||||
&sysfs_moving_ctxts,
|
||||
@@ -683,6 +659,13 @@ STORE(bch2_fs_opts_dir)
|
||||
(id == Opt_compression && !c->opts.background_compression)))
|
||||
bch2_set_rebalance_needs_scan(c, 0);
|
||||
|
||||
+ if (v && id == Opt_rebalance_enabled)
|
||||
+ rebalance_wakeup(c);
|
||||
+
|
||||
+ if (v && id == Opt_copygc_enabled &&
|
||||
+ c->copygc_thread)
|
||||
+ wake_up_process(c->copygc_thread);
|
||||
+
|
||||
ret = size;
|
||||
err:
|
||||
bch2_write_ref_put(c, BCH_WRITE_REF_sysfs);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,104 +0,0 @@
|
||||
From e1d67b5d67f83789f0cf57d8c822941a5050a454 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 28 Oct 2024 01:14:53 -0400
|
||||
Subject: [PATCH 046/233] bcachefs: bch2_prt_csum_opt()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
bounds checking helper
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs_format.h | 2 +-
|
||||
fs/bcachefs/checksum.h | 2 +-
|
||||
fs/bcachefs/opts.c | 3 ++-
|
||||
fs/bcachefs/opts.h | 7 ++++---
|
||||
4 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
|
||||
index c5e3824d5771..dc14bfe37e3b 100644
|
||||
--- a/fs/bcachefs/bcachefs_format.h
|
||||
+++ b/fs/bcachefs/bcachefs_format.h
|
||||
@@ -1030,7 +1030,7 @@ static inline _Bool bch2_csum_type_is_encryption(enum bch_csum_type type)
|
||||
x(crc64, 2) \
|
||||
x(xxhash, 3)
|
||||
|
||||
-enum bch_csum_opts {
|
||||
+enum bch_csum_opt {
|
||||
#define x(t, n) BCH_CSUM_OPT_##t = n,
|
||||
BCH_CSUM_OPTS()
|
||||
#undef x
|
||||
diff --git a/fs/bcachefs/checksum.h b/fs/bcachefs/checksum.h
|
||||
index e40499fde9a4..43b9d71f2f2b 100644
|
||||
--- a/fs/bcachefs/checksum.h
|
||||
+++ b/fs/bcachefs/checksum.h
|
||||
@@ -109,7 +109,7 @@ int bch2_enable_encryption(struct bch_fs *, bool);
|
||||
void bch2_fs_encryption_exit(struct bch_fs *);
|
||||
int bch2_fs_encryption_init(struct bch_fs *);
|
||||
|
||||
-static inline enum bch_csum_type bch2_csum_opt_to_type(enum bch_csum_opts type,
|
||||
+static inline enum bch_csum_type bch2_csum_opt_to_type(enum bch_csum_opt type,
|
||||
bool data)
|
||||
{
|
||||
switch (type) {
|
||||
diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
|
||||
index 1f5843284e9e..49c59aec6954 100644
|
||||
--- a/fs/bcachefs/opts.c
|
||||
+++ b/fs/bcachefs/opts.c
|
||||
@@ -48,7 +48,7 @@ static const char * const __bch2_csum_types[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
-const char * const bch2_csum_opts[] = {
|
||||
+const char * const __bch2_csum_opts[] = {
|
||||
BCH_CSUM_OPTS()
|
||||
NULL
|
||||
};
|
||||
@@ -113,6 +113,7 @@ void bch2_prt_##name(struct printbuf *out, type t) \
|
||||
PRT_STR_OPT_BOUNDSCHECKED(jset_entry_type, enum bch_jset_entry_type);
|
||||
PRT_STR_OPT_BOUNDSCHECKED(fs_usage_type, enum bch_fs_usage_type);
|
||||
PRT_STR_OPT_BOUNDSCHECKED(data_type, enum bch_data_type);
|
||||
+PRT_STR_OPT_BOUNDSCHECKED(csum_opt, enum bch_csum_opt);
|
||||
PRT_STR_OPT_BOUNDSCHECKED(csum_type, enum bch_csum_type);
|
||||
PRT_STR_OPT_BOUNDSCHECKED(compression_type, enum bch_compression_type);
|
||||
PRT_STR_OPT_BOUNDSCHECKED(str_hash_type, enum bch_str_hash_type);
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index e0e23c29c2d6..f6dc0628b025 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -16,7 +16,7 @@ extern const char * const bch2_version_upgrade_opts[];
|
||||
extern const char * const bch2_sb_features[];
|
||||
extern const char * const bch2_sb_compat[];
|
||||
extern const char * const __bch2_btree_ids[];
|
||||
-extern const char * const bch2_csum_opts[];
|
||||
+extern const char * const __bch2_csum_opts[];
|
||||
extern const char * const bch2_compression_opts[];
|
||||
extern const char * const __bch2_str_hash_types[];
|
||||
extern const char * const bch2_str_hash_opts[];
|
||||
@@ -27,6 +27,7 @@ extern const char * const bch2_d_types[];
|
||||
void bch2_prt_jset_entry_type(struct printbuf *, enum bch_jset_entry_type);
|
||||
void bch2_prt_fs_usage_type(struct printbuf *, enum bch_fs_usage_type);
|
||||
void bch2_prt_data_type(struct printbuf *, enum bch_data_type);
|
||||
+void bch2_prt_csum_opt(struct printbuf *, enum bch_csum_opt);
|
||||
void bch2_prt_csum_type(struct printbuf *, enum bch_csum_type);
|
||||
void bch2_prt_compression_type(struct printbuf *, enum bch_compression_type);
|
||||
void bch2_prt_str_hash_type(struct printbuf *, enum bch_str_hash_type);
|
||||
@@ -171,12 +172,12 @@ enum fsck_err_opts {
|
||||
"size", "Maximum size of checksummed/compressed extents")\
|
||||
x(metadata_checksum, u8, \
|
||||
OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \
|
||||
- OPT_STR(bch2_csum_opts), \
|
||||
+ OPT_STR(__bch2_csum_opts), \
|
||||
BCH_SB_META_CSUM_TYPE, BCH_CSUM_OPT_crc32c, \
|
||||
NULL, NULL) \
|
||||
x(data_checksum, u8, \
|
||||
OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \
|
||||
- OPT_STR(bch2_csum_opts), \
|
||||
+ OPT_STR(__bch2_csum_opts), \
|
||||
BCH_SB_DATA_CSUM_TYPE, BCH_CSUM_OPT_crc32c, \
|
||||
NULL, NULL) \
|
||||
x(compression, u8, \
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,179 +0,0 @@
|
||||
From a5fe1d1656b8471db2cd0854062977245aadd80a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 19 Oct 2024 21:41:20 -0400
|
||||
Subject: [PATCH 047/233] bcachefs: New bch_extent_rebalance fields
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
- Add more io path options to bch_extent_rebalance
|
||||
- For each option, track whether it came from the filesystem or the
|
||||
inode
|
||||
|
||||
This will be used for improved rebalance support for reflinked data.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 65 ++++++++++++++++++++++++++++++------
|
||||
fs/bcachefs/extents_format.h | 34 +++++++++++++++++--
|
||||
fs/bcachefs/opts.h | 3 +-
|
||||
3 files changed, 87 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index a134aa5a76bb..467ffed0809e 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1121,6 +1121,57 @@ void bch2_extent_crc_unpacked_to_text(struct printbuf *out, struct bch_extent_cr
|
||||
bch2_prt_compression_type(out, crc->compression_type);
|
||||
}
|
||||
|
||||
+static void bch2_extent_rebalance_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
+ const struct bch_extent_rebalance *r)
|
||||
+{
|
||||
+ prt_str(out, "rebalance:");
|
||||
+
|
||||
+ prt_printf(out, " replicas=%u", r->data_replicas);
|
||||
+ if (r->data_replicas_from_inode)
|
||||
+ prt_str(out, " (inode)");
|
||||
+
|
||||
+ prt_str(out, " checksum=");
|
||||
+ bch2_prt_csum_opt(out, r->data_checksum);
|
||||
+ if (r->data_checksum_from_inode)
|
||||
+ prt_str(out, " (inode)");
|
||||
+
|
||||
+ if (r->background_compression || r->background_compression_from_inode) {
|
||||
+ prt_str(out, " background_compression=");
|
||||
+ bch2_compression_opt_to_text(out, r->background_compression);
|
||||
+
|
||||
+ if (r->background_compression_from_inode)
|
||||
+ prt_str(out, " (inode)");
|
||||
+ }
|
||||
+
|
||||
+ if (r->background_target || r->background_target_from_inode) {
|
||||
+ prt_str(out, " background_target=");
|
||||
+ if (c)
|
||||
+ bch2_target_to_text(out, c, r->background_target);
|
||||
+ else
|
||||
+ prt_printf(out, "%u", r->background_target);
|
||||
+
|
||||
+ if (r->background_target_from_inode)
|
||||
+ prt_str(out, " (inode)");
|
||||
+ }
|
||||
+
|
||||
+ if (r->promote_target || r->promote_target_from_inode) {
|
||||
+ prt_str(out, " promote_target=");
|
||||
+ if (c)
|
||||
+ bch2_target_to_text(out, c, r->promote_target);
|
||||
+ else
|
||||
+ prt_printf(out, "%u", r->promote_target);
|
||||
+
|
||||
+ if (r->promote_target_from_inode)
|
||||
+ prt_str(out, " (inode)");
|
||||
+ }
|
||||
+
|
||||
+ if (r->erasure_code || r->erasure_code_from_inode) {
|
||||
+ prt_printf(out, " ec=%u", r->erasure_code);
|
||||
+ if (r->erasure_code_from_inode)
|
||||
+ prt_str(out, " (inode)");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct bkey_s_c k)
|
||||
{
|
||||
@@ -1156,18 +1207,10 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
(u64) ec->idx, ec->block);
|
||||
break;
|
||||
}
|
||||
- case BCH_EXTENT_ENTRY_rebalance: {
|
||||
- const struct bch_extent_rebalance *r = &entry->rebalance;
|
||||
-
|
||||
- prt_str(out, "rebalance: target ");
|
||||
- if (c)
|
||||
- bch2_target_to_text(out, c, r->background_target);
|
||||
- else
|
||||
- prt_printf(out, "%u", r->background_target);
|
||||
- prt_str(out, " compression ");
|
||||
- bch2_compression_opt_to_text(out, r->background_compression);
|
||||
+ case BCH_EXTENT_ENTRY_rebalance:
|
||||
+ bch2_extent_rebalance_to_text(out, c, &entry->rebalance);
|
||||
break;
|
||||
- }
|
||||
+
|
||||
default:
|
||||
prt_printf(out, "(invalid extent entry %.16llx)", *((u64 *) entry));
|
||||
return;
|
||||
diff --git a/fs/bcachefs/extents_format.h b/fs/bcachefs/extents_format.h
|
||||
index 520697f236c0..222eed6b46d8 100644
|
||||
--- a/fs/bcachefs/extents_format.h
|
||||
+++ b/fs/bcachefs/extents_format.h
|
||||
@@ -204,21 +204,49 @@ struct bch_extent_stripe_ptr {
|
||||
struct bch_extent_rebalance {
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
__u64 type:6,
|
||||
- unused:34,
|
||||
+ unused:3,
|
||||
+
|
||||
+ promote_target_from_inode:1,
|
||||
+ erasure_code_from_inode:1,
|
||||
+ data_checksum_from_inode:1,
|
||||
+ background_compression_from_inode:1,
|
||||
+ data_replicas_from_inode:1,
|
||||
+ background_target_from_inode:1,
|
||||
+
|
||||
+ promote_target:16,
|
||||
+ erasure_code:1,
|
||||
+ data_checksum:4,
|
||||
+ data_replicas:4,
|
||||
background_compression:8, /* enum bch_compression_opt */
|
||||
background_target:16;
|
||||
#elif defined (__BIG_ENDIAN_BITFIELD)
|
||||
__u64 background_target:16,
|
||||
background_compression:8,
|
||||
- unused:34,
|
||||
+ data_replicas:4,
|
||||
+ data_checksum:4,
|
||||
+ erasure_code:1,
|
||||
+ promote_target:16,
|
||||
+
|
||||
+ background_target_from_inode:1,
|
||||
+ data_replicas_from_inode:1,
|
||||
+ background_compression_from_inode:1,
|
||||
+ data_checksum_from_inode:1,
|
||||
+ erasure_code_from_inode:1,
|
||||
+ promote_target_from_inode:1,
|
||||
+
|
||||
+ unused:3,
|
||||
type:6;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* subset of BCH_INODE_OPTS */
|
||||
#define BCH_REBALANCE_OPTS() \
|
||||
+ x(data_checksum) \
|
||||
x(background_compression) \
|
||||
- x(background_target)
|
||||
+ x(data_replicas) \
|
||||
+ x(promote_target) \
|
||||
+ x(background_target) \
|
||||
+ x(erasure_code)
|
||||
|
||||
union bch_extent_entry {
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || __BITS_PER_LONG == 64
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index f6dc0628b025..39cdc185fa73 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -665,7 +665,8 @@ static inline struct bch_extent_rebalance io_opts_to_rebalance_opts(struct bch_i
|
||||
return (struct bch_extent_rebalance) {
|
||||
.type = BIT(BCH_EXTENT_ENTRY_rebalance),
|
||||
#define x(_name) \
|
||||
- ._name = opts->_name,
|
||||
+ ._name = opts->_name, \
|
||||
+ ._name##_from_inode = opts->_name##_from_inode,
|
||||
BCH_REBALANCE_OPTS()
|
||||
#undef x
|
||||
};
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,159 +0,0 @@
|
||||
From e2aeaaa5c9eee014aba96c54c6730d016c00ca67 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 20:53:53 -0400
|
||||
Subject: [PATCH 048/233] bcachefs: bch2_write_inode() now checks for changing
|
||||
rebalance options
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Previously, BCHFS_IOC_REINHERIT_ATTRS didn't trigger rebalance scans
|
||||
when changing rebalance options - it had been missed, only the xattr
|
||||
interface triggered them.
|
||||
|
||||
Ideally they'd be done by the transactional trigger, but unpacking the
|
||||
inode to get the options is too heavy to be done in the low level
|
||||
trigger - the inode trigger is run on every extent update, since the
|
||||
bch_inode.bi_journal_seq has to be updated for fsync.
|
||||
|
||||
bch2_write_inode() is a good compromise, it already unpacks and repacks
|
||||
and is not run in any super-fast paths.
|
||||
|
||||
Additionally, creating the new rebalance entry to trigger the scan is
|
||||
now done in the same transaction as the inode update that changed the
|
||||
options.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs.c | 26 +++++++++++++++++++++-----
|
||||
fs/bcachefs/inode.h | 8 ++++++++
|
||||
fs/bcachefs/rebalance.c | 4 ++--
|
||||
fs/bcachefs/rebalance.h | 1 +
|
||||
fs/bcachefs/xattr.c | 7 -------
|
||||
5 files changed, 32 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
|
||||
index 646b74494a3f..e0ffe4648bb8 100644
|
||||
--- a/fs/bcachefs/fs.c
|
||||
+++ b/fs/bcachefs/fs.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "journal.h"
|
||||
#include "keylist.h"
|
||||
#include "quota.h"
|
||||
+#include "rebalance.h"
|
||||
#include "snapshot.h"
|
||||
#include "super.h"
|
||||
#include "xattr.h"
|
||||
@@ -89,10 +90,25 @@ int __must_check bch2_write_inode(struct bch_fs *c,
|
||||
retry:
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
- ret = bch2_inode_peek(trans, &iter, &inode_u, inode_inum(inode),
|
||||
- BTREE_ITER_intent) ?:
|
||||
- (set ? set(trans, inode, &inode_u, p) : 0) ?:
|
||||
- bch2_inode_write(trans, &iter, &inode_u) ?:
|
||||
+ ret = bch2_inode_peek(trans, &iter, &inode_u, inode_inum(inode), BTREE_ITER_intent);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ struct bch_extent_rebalance old_r = bch2_inode_rebalance_opts_get(c, &inode_u);
|
||||
+
|
||||
+ ret = (set ? set(trans, inode, &inode_u, p) : 0);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ struct bch_extent_rebalance new_r = bch2_inode_rebalance_opts_get(c, &inode_u);
|
||||
+
|
||||
+ if (memcmp(&old_r, &new_r, sizeof(new_r))) {
|
||||
+ ret = bch2_set_rebalance_needs_scan_trans(trans, inode_u.bi_inum);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = bch2_inode_write(trans, &iter, &inode_u) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc);
|
||||
|
||||
/*
|
||||
@@ -101,7 +117,7 @@ int __must_check bch2_write_inode(struct bch_fs *c,
|
||||
*/
|
||||
if (!ret)
|
||||
bch2_inode_update_after_write(trans, inode, &inode_u, fields);
|
||||
-
|
||||
+err:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
diff --git a/fs/bcachefs/inode.h b/fs/bcachefs/inode.h
|
||||
index bdeb6be76038..f52336cb298f 100644
|
||||
--- a/fs/bcachefs/inode.h
|
||||
+++ b/fs/bcachefs/inode.h
|
||||
@@ -262,6 +262,14 @@ void bch2_inode_opts_get(struct bch_io_opts *, struct bch_fs *,
|
||||
struct bch_inode_unpacked *);
|
||||
int bch2_inum_opts_get(struct btree_trans*, subvol_inum, struct bch_io_opts *);
|
||||
|
||||
+static inline struct bch_extent_rebalance
|
||||
+bch2_inode_rebalance_opts_get(struct bch_fs *c, struct bch_inode_unpacked *inode)
|
||||
+{
|
||||
+ struct bch_io_opts io_opts;
|
||||
+ bch2_inode_opts_get(&io_opts, c, inode);
|
||||
+ return io_opts_to_rebalance_opts(&io_opts);
|
||||
+}
|
||||
+
|
||||
int bch2_inode_rm_snapshot(struct btree_trans *, u64, u32);
|
||||
int bch2_delete_dead_inodes(struct bch_fs *);
|
||||
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index d8cb346ac138..926b9d5eba45 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -33,7 +33,7 @@ static const char * const bch2_rebalance_state_strs[] = {
|
||||
#undef x
|
||||
};
|
||||
|
||||
-static int __bch2_set_rebalance_needs_scan(struct btree_trans *trans, u64 inum)
|
||||
+int bch2_set_rebalance_needs_scan_trans(struct btree_trans *trans, u64 inum)
|
||||
{
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
@@ -73,7 +73,7 @@ int bch2_set_rebalance_needs_scan(struct bch_fs *c, u64 inum)
|
||||
int ret = bch2_trans_commit_do(c, NULL, NULL,
|
||||
BCH_TRANS_COMMIT_no_enospc|
|
||||
BCH_TRANS_COMMIT_lazy_rw,
|
||||
- __bch2_set_rebalance_needs_scan(trans, inum));
|
||||
+ bch2_set_rebalance_needs_scan_trans(trans, inum));
|
||||
rebalance_wakeup(c);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/fs/bcachefs/rebalance.h b/fs/bcachefs/rebalance.h
|
||||
index 28a52638f16c..791649c04ff5 100644
|
||||
--- a/fs/bcachefs/rebalance.h
|
||||
+++ b/fs/bcachefs/rebalance.h
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "rebalance_types.h"
|
||||
|
||||
+int bch2_set_rebalance_needs_scan_trans(struct btree_trans *, u64);
|
||||
int bch2_set_rebalance_needs_scan(struct bch_fs *, u64 inum);
|
||||
int bch2_set_fs_needs_rebalance(struct bch_fs *);
|
||||
|
||||
diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c
|
||||
index bf3c6bb50495..ed418a747cdd 100644
|
||||
--- a/fs/bcachefs/xattr.c
|
||||
+++ b/fs/bcachefs/xattr.c
|
||||
@@ -565,13 +565,6 @@ static int bch2_xattr_bcachefs_set(const struct xattr_handler *handler,
|
||||
ret = bch2_write_inode(c, inode, inode_opt_set_fn, &s, 0);
|
||||
err:
|
||||
mutex_unlock(&inode->ei_update_lock);
|
||||
-
|
||||
- if (value &&
|
||||
- (opt_id == Opt_background_target ||
|
||||
- opt_id == Opt_background_compression ||
|
||||
- (opt_id == Opt_compression && !inode_opt_get(c, &inode->ei_inode, background_compression))))
|
||||
- bch2_set_rebalance_needs_scan(c, inode->ei_inode.bi_inum);
|
||||
-
|
||||
err_class_exit:
|
||||
return bch2_err_class(ret);
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,247 +0,0 @@
|
||||
From f14488c8cf907f1d69716465c9c8ab11b9ff2261 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 19 Oct 2024 21:41:20 -0400
|
||||
Subject: [PATCH 049/233] bcachefs: get_update_rebalance_opts()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
bch2_move_get_io_opts() now synchronizes options loaded from the
|
||||
filesystem and inode (if present, i.e. not walking the reflink btree
|
||||
directly) with options from the bch_extent_rebalance_entry, updating the
|
||||
extent if necessary.
|
||||
|
||||
Since bch_extent_rebalance tracks where its option came from we can
|
||||
preserve "inode options override filesystem options", even for indirect
|
||||
extents where we don't have access to the inode the options came from.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 17 ++++++++
|
||||
fs/bcachefs/extents.h | 1 +
|
||||
fs/bcachefs/move.c | 94 ++++++++++++++++++++++++++++++-----------
|
||||
fs/bcachefs/move.h | 5 +--
|
||||
fs/bcachefs/rebalance.c | 2 +-
|
||||
5 files changed, 91 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 467ffed0809e..4988056ab4f1 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1521,6 +1521,23 @@ u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
return sectors;
|
||||
}
|
||||
|
||||
+bool bch2_bkey_rebalance_needs_update(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
+ struct bkey_s_c k)
|
||||
+{
|
||||
+ if (!bkey_extent_is_direct_data(k.k))
|
||||
+ return 0;
|
||||
+
|
||||
+ const struct bch_extent_rebalance *old = bch2_bkey_rebalance_opts(k);
|
||||
+
|
||||
+ if (k.k->type == KEY_TYPE_reflink_v ||
|
||||
+ bch2_bkey_ptrs_need_rebalance(c, k, opts->background_target, opts->background_compression)) {
|
||||
+ struct bch_extent_rebalance new = io_opts_to_rebalance_opts(opts);
|
||||
+ return old == NULL || memcmp(old, &new, sizeof(new));
|
||||
+ } else {
|
||||
+ return old != NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
struct bkey_i *_k)
|
||||
{
|
||||
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
|
||||
index 97af0d6e4319..abe7d4b2fc6b 100644
|
||||
--- a/fs/bcachefs/extents.h
|
||||
+++ b/fs/bcachefs/extents.h
|
||||
@@ -715,6 +715,7 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c,
|
||||
unsigned, unsigned);
|
||||
u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *, struct bkey_s_c);
|
||||
|
||||
+bool bch2_bkey_rebalance_needs_update(struct bch_fs *, struct bch_io_opts *, struct bkey_s_c);
|
||||
int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bch_io_opts *, struct bkey_i *);
|
||||
|
||||
/* Generic extent code: */
|
||||
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
|
||||
index 0ef4a86850bb..1003f7fe4f50 100644
|
||||
--- a/fs/bcachefs/move.c
|
||||
+++ b/fs/bcachefs/move.c
|
||||
@@ -379,14 +379,57 @@ int bch2_move_extent(struct moving_context *ctxt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-struct bch_io_opts *bch2_move_get_io_opts(struct btree_trans *trans,
|
||||
+static int get_update_rebalance_opts(struct btree_trans *trans,
|
||||
+ struct bch_io_opts *io_opts,
|
||||
+ struct btree_iter *iter,
|
||||
+ struct bkey_s_c k)
|
||||
+{
|
||||
+ BUG_ON(iter->flags & BTREE_ITER_is_extents);
|
||||
+ BUG_ON(iter->flags & BTREE_ITER_filter_snapshots);
|
||||
+
|
||||
+ const struct bch_extent_rebalance *r = k.k->type == KEY_TYPE_reflink_v
|
||||
+ ? bch2_bkey_rebalance_opts(k) : NULL;
|
||||
+ if (r) {
|
||||
+#define x(_name) \
|
||||
+ if (r->_name##_from_inode) { \
|
||||
+ io_opts->_name = r->_name; \
|
||||
+ io_opts->_name##_from_inode = true; \
|
||||
+ }
|
||||
+ BCH_REBALANCE_OPTS()
|
||||
+#undef x
|
||||
+ }
|
||||
+
|
||||
+ if (!bch2_bkey_rebalance_needs_update(trans->c, io_opts, k))
|
||||
+ return 0;
|
||||
+
|
||||
+ struct bkey_i *n = bch2_trans_kmalloc(trans, bkey_bytes(k.k) + 8);
|
||||
+ int ret = PTR_ERR_OR_ZERO(n);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ bkey_reassemble(n, k);
|
||||
+
|
||||
+ /* On successfull transaction commit, @k was invalidated: */
|
||||
+
|
||||
+ return bch2_bkey_set_needs_rebalance(trans->c, io_opts, n) ?:
|
||||
+ bch2_trans_update(trans, iter, n, BTREE_UPDATE_internal_snapshot_node) ?:
|
||||
+ bch2_trans_commit(trans, NULL, NULL, 0) ?:
|
||||
+ -BCH_ERR_transaction_restart_nested;
|
||||
+}
|
||||
+
|
||||
+static struct bch_io_opts *bch2_move_get_io_opts(struct btree_trans *trans,
|
||||
struct per_snapshot_io_opts *io_opts,
|
||||
+ struct btree_iter *extent_iter,
|
||||
struct bkey_s_c extent_k)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
u32 restart_count = trans->restart_count;
|
||||
+ struct bch_io_opts *opts_ret = &io_opts->fs_io_opts;
|
||||
int ret = 0;
|
||||
|
||||
+ if (extent_k.k->type == KEY_TYPE_reflink_v)
|
||||
+ goto out;
|
||||
+
|
||||
if (io_opts->cur_inum != extent_k.k->p.inode) {
|
||||
io_opts->d.nr = 0;
|
||||
|
||||
@@ -415,43 +458,46 @@ struct bch_io_opts *bch2_move_get_io_opts(struct btree_trans *trans,
|
||||
|
||||
if (extent_k.k->p.snapshot)
|
||||
darray_for_each(io_opts->d, i)
|
||||
- if (bch2_snapshot_is_ancestor(c, extent_k.k->p.snapshot, i->snapshot))
|
||||
- return &i->io_opts;
|
||||
-
|
||||
- return &io_opts->fs_io_opts;
|
||||
+ if (bch2_snapshot_is_ancestor(c, extent_k.k->p.snapshot, i->snapshot)) {
|
||||
+ opts_ret = &i->io_opts;
|
||||
+ break;
|
||||
+ }
|
||||
+out:
|
||||
+ ret = get_update_rebalance_opts(trans, opts_ret, extent_iter, extent_k);
|
||||
+ if (ret)
|
||||
+ return ERR_PTR(ret);
|
||||
+ return opts_ret;
|
||||
}
|
||||
|
||||
int bch2_move_get_io_opts_one(struct btree_trans *trans,
|
||||
struct bch_io_opts *io_opts,
|
||||
+ struct btree_iter *extent_iter,
|
||||
struct bkey_s_c extent_k)
|
||||
{
|
||||
- struct btree_iter iter;
|
||||
- struct bkey_s_c k;
|
||||
- int ret;
|
||||
+ struct bch_fs *c = trans->c;
|
||||
+
|
||||
+ *io_opts = bch2_opts_to_inode_opts(c->opts);
|
||||
|
||||
/* reflink btree? */
|
||||
- if (!extent_k.k->p.inode) {
|
||||
- *io_opts = bch2_opts_to_inode_opts(trans->c->opts);
|
||||
- return 0;
|
||||
- }
|
||||
+ if (!extent_k.k->p.inode)
|
||||
+ goto out;
|
||||
|
||||
- k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
|
||||
+ struct btree_iter inode_iter;
|
||||
+ struct bkey_s_c inode_k = bch2_bkey_get_iter(trans, &inode_iter, BTREE_ID_inodes,
|
||||
SPOS(0, extent_k.k->p.inode, extent_k.k->p.snapshot),
|
||||
BTREE_ITER_cached);
|
||||
- ret = bkey_err(k);
|
||||
+ int ret = bkey_err(inode_k);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
return ret;
|
||||
|
||||
- if (!ret && bkey_is_inode(k.k)) {
|
||||
+ if (!ret && bkey_is_inode(inode_k.k)) {
|
||||
struct bch_inode_unpacked inode;
|
||||
- bch2_inode_unpack(k, &inode);
|
||||
- bch2_inode_opts_get(io_opts, trans->c, &inode);
|
||||
- } else {
|
||||
- *io_opts = bch2_opts_to_inode_opts(trans->c->opts);
|
||||
+ bch2_inode_unpack(inode_k, &inode);
|
||||
+ bch2_inode_opts_get(io_opts, c, &inode);
|
||||
}
|
||||
-
|
||||
- bch2_trans_iter_exit(trans, &iter);
|
||||
- return 0;
|
||||
+ bch2_trans_iter_exit(trans, &inode_iter);
|
||||
+out:
|
||||
+ return get_update_rebalance_opts(trans, io_opts, extent_iter, extent_k);
|
||||
}
|
||||
|
||||
int bch2_move_ratelimit(struct moving_context *ctxt)
|
||||
@@ -552,7 +598,7 @@ static int bch2_move_data_btree(struct moving_context *ctxt,
|
||||
if (!bkey_extent_is_direct_data(k.k))
|
||||
goto next_nondata;
|
||||
|
||||
- io_opts = bch2_move_get_io_opts(trans, &snapshot_io_opts, k);
|
||||
+ io_opts = bch2_move_get_io_opts(trans, &snapshot_io_opts, &iter, k);
|
||||
ret = PTR_ERR_OR_ZERO(io_opts);
|
||||
if (ret)
|
||||
continue;
|
||||
@@ -728,7 +774,7 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
|
||||
bch2_bkey_buf_reassemble(&sk, c, k);
|
||||
k = bkey_i_to_s_c(sk.k);
|
||||
|
||||
- ret = bch2_move_get_io_opts_one(trans, &io_opts, k);
|
||||
+ ret = bch2_move_get_io_opts_one(trans, &io_opts, &iter, k);
|
||||
if (ret) {
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
continue;
|
||||
diff --git a/fs/bcachefs/move.h b/fs/bcachefs/move.h
|
||||
index 9baf3093a678..51e0505a8156 100644
|
||||
--- a/fs/bcachefs/move.h
|
||||
+++ b/fs/bcachefs/move.h
|
||||
@@ -110,9 +110,8 @@ static inline void per_snapshot_io_opts_exit(struct per_snapshot_io_opts *io_opt
|
||||
darray_exit(&io_opts->d);
|
||||
}
|
||||
|
||||
-struct bch_io_opts *bch2_move_get_io_opts(struct btree_trans *,
|
||||
- struct per_snapshot_io_opts *, struct bkey_s_c);
|
||||
-int bch2_move_get_io_opts_one(struct btree_trans *, struct bch_io_opts *, struct bkey_s_c);
|
||||
+int bch2_move_get_io_opts_one(struct btree_trans *, struct bch_io_opts *,
|
||||
+ struct btree_iter *, struct bkey_s_c);
|
||||
|
||||
int bch2_scan_old_btree_nodes(struct bch_fs *, struct bch_move_stats *);
|
||||
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index 926b9d5eba45..e79459a5891d 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -216,7 +216,7 @@ static int do_rebalance_extent(struct moving_context *ctxt,
|
||||
if (ret || !k.k)
|
||||
goto out;
|
||||
|
||||
- ret = bch2_move_get_io_opts_one(trans, &io_opts, k);
|
||||
+ ret = bch2_move_get_io_opts_one(trans, &io_opts, extent_iter, k);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,199 +0,0 @@
|
||||
From 8aa17c262842fedae48ab6b38e63284664971560 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 19 Oct 2024 21:41:20 -0400
|
||||
Subject: [PATCH 050/233] bcachefs: Simplify option logic in rebalance
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Since bch2_move_get_io_opts() now synchronizes io_opts with options from
|
||||
bch_extent_rebalance, delete the ad-hoc logic in rebalance.c that
|
||||
previously did this.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 20 +++++++++---------
|
||||
fs/bcachefs/extents.h | 3 +--
|
||||
fs/bcachefs/rebalance.c | 47 +++++++++++++----------------------------
|
||||
3 files changed, 26 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 4988056ab4f1..bee083d787f2 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1447,14 +1447,15 @@ const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c k)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
- unsigned target, unsigned compression)
|
||||
+unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c,
|
||||
+ struct bch_io_opts *opts,
|
||||
+ struct bkey_s_c k)
|
||||
{
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
unsigned rewrite_ptrs = 0;
|
||||
|
||||
- if (compression) {
|
||||
- unsigned compression_type = bch2_compression_opt_to_type(compression);
|
||||
+ if (opts->background_compression) {
|
||||
+ unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
const union bch_extent_entry *entry;
|
||||
struct extent_ptr_decoded p;
|
||||
unsigned ptr_bit = 1;
|
||||
@@ -1472,11 +1473,12 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
|
||||
}
|
||||
}
|
||||
incompressible:
|
||||
- if (target && bch2_target_accepts_data(c, BCH_DATA_user, target)) {
|
||||
+ if (opts->background_target &&
|
||||
+ bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target)) {
|
||||
unsigned ptr_bit = 1;
|
||||
|
||||
bkey_for_each_ptr(ptrs, ptr) {
|
||||
- if (!ptr->cached && !bch2_dev_in_target(c, ptr->dev, target))
|
||||
+ if (!ptr->cached && !bch2_dev_in_target(c, ptr->dev, opts->background_target))
|
||||
rewrite_ptrs |= ptr_bit;
|
||||
ptr_bit <<= 1;
|
||||
}
|
||||
@@ -1529,8 +1531,7 @@ bool bch2_bkey_rebalance_needs_update(struct bch_fs *c, struct bch_io_opts *opts
|
||||
|
||||
const struct bch_extent_rebalance *old = bch2_bkey_rebalance_opts(k);
|
||||
|
||||
- if (k.k->type == KEY_TYPE_reflink_v ||
|
||||
- bch2_bkey_ptrs_need_rebalance(c, k, opts->background_target, opts->background_compression)) {
|
||||
+ if (k.k->type == KEY_TYPE_reflink_v || bch2_bkey_ptrs_need_rebalance(c, opts, k)) {
|
||||
struct bch_extent_rebalance new = io_opts_to_rebalance_opts(opts);
|
||||
return old == NULL || memcmp(old, &new, sizeof(new));
|
||||
} else {
|
||||
@@ -1548,8 +1549,7 @@ int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
struct bch_extent_rebalance *old =
|
||||
(struct bch_extent_rebalance *) bch2_bkey_rebalance_opts(k.s_c);
|
||||
|
||||
- if (k.k->type == KEY_TYPE_reflink_v ||
|
||||
- bch2_bkey_ptrs_need_rebalance(c, k.s_c, opts->background_target, opts->background_compression)) {
|
||||
+ if (k.k->type == KEY_TYPE_reflink_v || bch2_bkey_ptrs_need_rebalance(c, opts, k.s_c)) {
|
||||
if (!old) {
|
||||
old = bkey_val_end(k);
|
||||
k.k->u64s += sizeof(*old) / sizeof(u64);
|
||||
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
|
||||
index abe7d4b2fc6b..156fbb8e04d5 100644
|
||||
--- a/fs/bcachefs/extents.h
|
||||
+++ b/fs/bcachefs/extents.h
|
||||
@@ -711,8 +711,7 @@ static inline bool bch2_extent_ptr_eq(struct bch_extent_ptr ptr1,
|
||||
void bch2_ptr_swab(struct bkey_s);
|
||||
|
||||
const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c);
|
||||
-unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c,
|
||||
- unsigned, unsigned);
|
||||
+unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bch_io_opts *, struct bkey_s_c);
|
||||
u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *, struct bkey_s_c);
|
||||
|
||||
bool bch2_bkey_rebalance_needs_update(struct bch_fs *, struct bch_io_opts *, struct bkey_s_c);
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index e79459a5891d..3be9c85dd55d 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -121,6 +121,9 @@ static int bch2_bkey_clear_needs_rebalance(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
struct bkey_s_c k)
|
||||
{
|
||||
+ if (!bch2_bkey_rebalance_opts(k))
|
||||
+ return 0;
|
||||
+
|
||||
struct bkey_i *n = bch2_bkey_make_mut(trans, iter, &k, 0);
|
||||
int ret = PTR_ERR_OR_ZERO(n);
|
||||
if (ret)
|
||||
@@ -134,31 +137,27 @@ static int bch2_bkey_clear_needs_rebalance(struct btree_trans *trans,
|
||||
static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans,
|
||||
struct bpos work_pos,
|
||||
struct btree_iter *extent_iter,
|
||||
+ struct bch_io_opts *io_opts,
|
||||
struct data_update_opts *data_opts)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
- struct bkey_s_c k;
|
||||
|
||||
bch2_trans_iter_exit(trans, extent_iter);
|
||||
bch2_trans_iter_init(trans, extent_iter,
|
||||
work_pos.inode ? BTREE_ID_extents : BTREE_ID_reflink,
|
||||
work_pos,
|
||||
BTREE_ITER_all_snapshots);
|
||||
- k = bch2_btree_iter_peek_slot(extent_iter);
|
||||
+ struct bkey_s_c k = bch2_btree_iter_peek_slot(extent_iter);
|
||||
if (bkey_err(k))
|
||||
return k;
|
||||
|
||||
- const struct bch_extent_rebalance *r = k.k ? bch2_bkey_rebalance_opts(k) : NULL;
|
||||
- if (!r) {
|
||||
- /* raced due to btree write buffer, nothing to do */
|
||||
- return bkey_s_c_null;
|
||||
- }
|
||||
+ int ret = bch2_move_get_io_opts_one(trans, io_opts, extent_iter, k);
|
||||
+ if (ret)
|
||||
+ return bkey_s_c_err(ret);
|
||||
|
||||
memset(data_opts, 0, sizeof(*data_opts));
|
||||
-
|
||||
- data_opts->rewrite_ptrs =
|
||||
- bch2_bkey_ptrs_need_rebalance(c, k, r->background_target, r->background_compression);
|
||||
- data_opts->target = r->background_target;
|
||||
+ data_opts->rewrite_ptrs = bch2_bkey_ptrs_need_rebalance(c, io_opts, k);
|
||||
+ data_opts->target = io_opts->background_target;
|
||||
data_opts->write_flags |= BCH_WRITE_ONLY_SPECIFIED_DEVS;
|
||||
|
||||
if (!data_opts->rewrite_ptrs) {
|
||||
@@ -179,9 +178,9 @@ static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans,
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
prt_str(&buf, "target=");
|
||||
- bch2_target_to_text(&buf, c, r->background_target);
|
||||
+ bch2_target_to_text(&buf, c, io_opts->background_target);
|
||||
prt_str(&buf, " compression=");
|
||||
- bch2_compression_opt_to_text(&buf, r->background_compression);
|
||||
+ bch2_compression_opt_to_text(&buf, io_opts->background_compression);
|
||||
prt_str(&buf, " ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
|
||||
@@ -212,14 +211,10 @@ static int do_rebalance_extent(struct moving_context *ctxt,
|
||||
bch2_bkey_buf_init(&sk);
|
||||
|
||||
ret = bkey_err(k = next_rebalance_extent(trans, work_pos,
|
||||
- extent_iter, &data_opts));
|
||||
+ extent_iter, &io_opts, &data_opts));
|
||||
if (ret || !k.k)
|
||||
goto out;
|
||||
|
||||
- ret = bch2_move_get_io_opts_one(trans, &io_opts, extent_iter, k);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
-
|
||||
atomic64_add(k.k->size, &ctxt->stats->sectors_seen);
|
||||
|
||||
/*
|
||||
@@ -253,20 +248,8 @@ static bool rebalance_pred(struct bch_fs *c, void *arg,
|
||||
struct bch_io_opts *io_opts,
|
||||
struct data_update_opts *data_opts)
|
||||
{
|
||||
- unsigned target, compression;
|
||||
-
|
||||
- if (k.k->p.inode) {
|
||||
- target = io_opts->background_target;
|
||||
- compression = io_opts->background_compression;
|
||||
- } else {
|
||||
- const struct bch_extent_rebalance *r = bch2_bkey_rebalance_opts(k);
|
||||
-
|
||||
- target = r ? r->background_target : io_opts->background_target;
|
||||
- compression = r ? r->background_compression : io_opts->background_compression;
|
||||
- }
|
||||
-
|
||||
- data_opts->rewrite_ptrs = bch2_bkey_ptrs_need_rebalance(c, k, target, compression);
|
||||
- data_opts->target = target;
|
||||
+ data_opts->rewrite_ptrs = bch2_bkey_ptrs_need_rebalance(c, io_opts, k);
|
||||
+ data_opts->target = io_opts->background_target;
|
||||
data_opts->write_flags |= BCH_WRITE_ONLY_SPECIFIED_DEVS;
|
||||
return data_opts->rewrite_ptrs != 0;
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,174 +0,0 @@
|
||||
From 9cf36d9f4d281af3dc65f1e819f5ec84613db899 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 26 Oct 2024 01:42:57 -0400
|
||||
Subject: [PATCH 051/233] bcachefs: Improve trace_rebalance_extent
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We now say explicitly which pointers are being moved or compressed
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extents.c | 35 +++--------------------------
|
||||
fs/bcachefs/rebalance.c | 26 +++++++++++++++++-----
|
||||
fs/bcachefs/rebalance.h | 49 +++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 73 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index bee083d787f2..6f9514c19b2f 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "extents.h"
|
||||
#include "inode.h"
|
||||
#include "journal.h"
|
||||
+#include "rebalance.h"
|
||||
#include "replicas.h"
|
||||
#include "super.h"
|
||||
#include "super-io.h"
|
||||
@@ -1452,39 +1453,9 @@ unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c,
|
||||
struct bkey_s_c k)
|
||||
{
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
- unsigned rewrite_ptrs = 0;
|
||||
|
||||
- if (opts->background_compression) {
|
||||
- unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
- const union bch_extent_entry *entry;
|
||||
- struct extent_ptr_decoded p;
|
||||
- unsigned ptr_bit = 1;
|
||||
-
|
||||
- bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
- if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
- p.ptr.unwritten) {
|
||||
- rewrite_ptrs = 0;
|
||||
- goto incompressible;
|
||||
- }
|
||||
-
|
||||
- if (!p.ptr.cached && p.crc.compression_type != compression_type)
|
||||
- rewrite_ptrs |= ptr_bit;
|
||||
- ptr_bit <<= 1;
|
||||
- }
|
||||
- }
|
||||
-incompressible:
|
||||
- if (opts->background_target &&
|
||||
- bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target)) {
|
||||
- unsigned ptr_bit = 1;
|
||||
-
|
||||
- bkey_for_each_ptr(ptrs, ptr) {
|
||||
- if (!ptr->cached && !bch2_dev_in_target(c, ptr->dev, opts->background_target))
|
||||
- rewrite_ptrs |= ptr_bit;
|
||||
- ptr_bit <<= 1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return rewrite_ptrs;
|
||||
+ return bch2_bkey_ptrs_need_compress(c, opts, k, ptrs) |
|
||||
+ bch2_bkey_ptrs_need_move(c, opts, ptrs);
|
||||
}
|
||||
|
||||
u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index 3be9c85dd55d..124da250cbe7 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -177,12 +177,28 @@ static struct bkey_s_c next_rebalance_extent(struct btree_trans *trans,
|
||||
if (trace_rebalance_extent_enabled()) {
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
- prt_str(&buf, "target=");
|
||||
- bch2_target_to_text(&buf, c, io_opts->background_target);
|
||||
- prt_str(&buf, " compression=");
|
||||
- bch2_compression_opt_to_text(&buf, io_opts->background_compression);
|
||||
- prt_str(&buf, " ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
+ prt_newline(&buf);
|
||||
+
|
||||
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
+
|
||||
+ unsigned p = bch2_bkey_ptrs_need_compress(c, io_opts, k, ptrs);
|
||||
+ if (p) {
|
||||
+ prt_str(&buf, "compression=");
|
||||
+ bch2_compression_opt_to_text(&buf, io_opts->background_compression);
|
||||
+ prt_str(&buf, " ");
|
||||
+ bch2_prt_u64_base2(&buf, p);
|
||||
+ prt_newline(&buf);
|
||||
+ }
|
||||
+
|
||||
+ p = bch2_bkey_ptrs_need_move(c, io_opts, ptrs);
|
||||
+ if (p) {
|
||||
+ prt_str(&buf, "move=");
|
||||
+ bch2_target_to_text(&buf, c, io_opts->background_target);
|
||||
+ prt_str(&buf, " ");
|
||||
+ bch2_prt_u64_base2(&buf, p);
|
||||
+ prt_newline(&buf);
|
||||
+ }
|
||||
|
||||
trace_rebalance_extent(c, buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
diff --git a/fs/bcachefs/rebalance.h b/fs/bcachefs/rebalance.h
|
||||
index 791649c04ff5..606c88f49f7f 100644
|
||||
--- a/fs/bcachefs/rebalance.h
|
||||
+++ b/fs/bcachefs/rebalance.h
|
||||
@@ -2,8 +2,57 @@
|
||||
#ifndef _BCACHEFS_REBALANCE_H
|
||||
#define _BCACHEFS_REBALANCE_H
|
||||
|
||||
+#include "compress.h"
|
||||
+#include "disk_groups.h"
|
||||
#include "rebalance_types.h"
|
||||
|
||||
+static inline unsigned bch2_bkey_ptrs_need_compress(struct bch_fs *c,
|
||||
+ struct bch_io_opts *opts,
|
||||
+ struct bkey_s_c k,
|
||||
+ struct bkey_ptrs_c ptrs)
|
||||
+{
|
||||
+ if (!opts->background_compression)
|
||||
+ return 0;
|
||||
+
|
||||
+ unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
+ const union bch_extent_entry *entry;
|
||||
+ struct extent_ptr_decoded p;
|
||||
+ unsigned ptr_bit = 1;
|
||||
+ unsigned rewrite_ptrs = 0;
|
||||
+
|
||||
+ bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
+ if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
+ p.ptr.unwritten)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!p.ptr.cached && p.crc.compression_type != compression_type)
|
||||
+ rewrite_ptrs |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
+ }
|
||||
+
|
||||
+ return rewrite_ptrs;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned bch2_bkey_ptrs_need_move(struct bch_fs *c,
|
||||
+ struct bch_io_opts *opts,
|
||||
+ struct bkey_ptrs_c ptrs)
|
||||
+{
|
||||
+ if (!opts->background_target ||
|
||||
+ !bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target))
|
||||
+ return 0;
|
||||
+
|
||||
+ unsigned ptr_bit = 1;
|
||||
+ unsigned rewrite_ptrs = 0;
|
||||
+
|
||||
+ bkey_for_each_ptr(ptrs, ptr) {
|
||||
+ if (!ptr->cached && !bch2_dev_in_target(c, ptr->dev, opts->background_target))
|
||||
+ rewrite_ptrs |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
+ }
|
||||
+
|
||||
+ return rewrite_ptrs;
|
||||
+}
|
||||
+
|
||||
int bch2_set_rebalance_needs_scan_trans(struct btree_trans *, u64);
|
||||
int bch2_set_rebalance_needs_scan(struct bch_fs *, u64 inum);
|
||||
int bch2_set_fs_needs_rebalance(struct bch_fs *);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,618 +0,0 @@
|
||||
From f6240723f7d66143b5a74b620666795112162b4f Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 28 Oct 2024 23:23:18 -0400
|
||||
Subject: [PATCH 052/233] bcachefs: Move bch_extent_rebalance code to
|
||||
rebalance.c
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/buckets.c | 1 +
|
||||
fs/bcachefs/extents.c | 99 ------------------
|
||||
fs/bcachefs/extents.h | 7 --
|
||||
fs/bcachefs/extents_format.h | 48 +--------
|
||||
fs/bcachefs/move.c | 43 +-------
|
||||
fs/bcachefs/rebalance.c | 186 +++++++++++++++++++++++++++++++++
|
||||
fs/bcachefs/rebalance.h | 52 ++-------
|
||||
fs/bcachefs/rebalance_format.h | 53 ++++++++++
|
||||
8 files changed, 251 insertions(+), 238 deletions(-)
|
||||
create mode 100644 fs/bcachefs/rebalance_format.h
|
||||
|
||||
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
|
||||
index 8bd17667e243..c4123fa4f250 100644
|
||||
--- a/fs/bcachefs/buckets.c
|
||||
+++ b/fs/bcachefs/buckets.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "error.h"
|
||||
#include "inode.h"
|
||||
#include "movinggc.h"
|
||||
+#include "rebalance.h"
|
||||
#include "recovery.h"
|
||||
#include "reflink.h"
|
||||
#include "replicas.h"
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index 6f9514c19b2f..bc7cfdb66687 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1436,105 +1436,6 @@ void bch2_ptr_swab(struct bkey_s k)
|
||||
}
|
||||
}
|
||||
|
||||
-const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c k)
|
||||
-{
|
||||
- struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
- const union bch_extent_entry *entry;
|
||||
-
|
||||
- bkey_extent_entry_for_each(ptrs, entry)
|
||||
- if (__extent_entry_type(entry) == BCH_EXTENT_ENTRY_rebalance)
|
||||
- return &entry->rebalance;
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
-unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c,
|
||||
- struct bch_io_opts *opts,
|
||||
- struct bkey_s_c k)
|
||||
-{
|
||||
- struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
-
|
||||
- return bch2_bkey_ptrs_need_compress(c, opts, k, ptrs) |
|
||||
- bch2_bkey_ptrs_need_move(c, opts, ptrs);
|
||||
-}
|
||||
-
|
||||
-u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
-{
|
||||
- const struct bch_extent_rebalance *opts = bch2_bkey_rebalance_opts(k);
|
||||
- if (!opts)
|
||||
- return 0;
|
||||
-
|
||||
- struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
- const union bch_extent_entry *entry;
|
||||
- struct extent_ptr_decoded p;
|
||||
- u64 sectors = 0;
|
||||
-
|
||||
- if (opts->background_compression) {
|
||||
- unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
-
|
||||
- bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
- if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
- p.ptr.unwritten) {
|
||||
- sectors = 0;
|
||||
- goto incompressible;
|
||||
- }
|
||||
-
|
||||
- if (!p.ptr.cached && p.crc.compression_type != compression_type)
|
||||
- sectors += p.crc.compressed_size;
|
||||
- }
|
||||
- }
|
||||
-incompressible:
|
||||
- if (opts->background_target &&
|
||||
- bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target)) {
|
||||
- bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
|
||||
- if (!p.ptr.cached && !bch2_dev_in_target(c, p.ptr.dev, opts->background_target))
|
||||
- sectors += p.crc.compressed_size;
|
||||
- }
|
||||
-
|
||||
- return sectors;
|
||||
-}
|
||||
-
|
||||
-bool bch2_bkey_rebalance_needs_update(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
- struct bkey_s_c k)
|
||||
-{
|
||||
- if (!bkey_extent_is_direct_data(k.k))
|
||||
- return 0;
|
||||
-
|
||||
- const struct bch_extent_rebalance *old = bch2_bkey_rebalance_opts(k);
|
||||
-
|
||||
- if (k.k->type == KEY_TYPE_reflink_v || bch2_bkey_ptrs_need_rebalance(c, opts, k)) {
|
||||
- struct bch_extent_rebalance new = io_opts_to_rebalance_opts(opts);
|
||||
- return old == NULL || memcmp(old, &new, sizeof(new));
|
||||
- } else {
|
||||
- return old != NULL;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
- struct bkey_i *_k)
|
||||
-{
|
||||
- if (!bkey_extent_is_direct_data(&_k->k))
|
||||
- return 0;
|
||||
-
|
||||
- struct bkey_s k = bkey_i_to_s(_k);
|
||||
- struct bch_extent_rebalance *old =
|
||||
- (struct bch_extent_rebalance *) bch2_bkey_rebalance_opts(k.s_c);
|
||||
-
|
||||
- if (k.k->type == KEY_TYPE_reflink_v || bch2_bkey_ptrs_need_rebalance(c, opts, k.s_c)) {
|
||||
- if (!old) {
|
||||
- old = bkey_val_end(k);
|
||||
- k.k->u64s += sizeof(*old) / sizeof(u64);
|
||||
- }
|
||||
-
|
||||
- *old = io_opts_to_rebalance_opts(opts);
|
||||
- } else {
|
||||
- if (old)
|
||||
- extent_entry_drop(k, (union bch_extent_entry *) old);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/* Generic extent code: */
|
||||
|
||||
int bch2_cut_front_s(struct bpos where, struct bkey_s k)
|
||||
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
|
||||
index 156fbb8e04d5..ba33788fee36 100644
|
||||
--- a/fs/bcachefs/extents.h
|
||||
+++ b/fs/bcachefs/extents.h
|
||||
@@ -710,13 +710,6 @@ static inline bool bch2_extent_ptr_eq(struct bch_extent_ptr ptr1,
|
||||
|
||||
void bch2_ptr_swab(struct bkey_s);
|
||||
|
||||
-const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c);
|
||||
-unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bch_io_opts *, struct bkey_s_c);
|
||||
-u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *, struct bkey_s_c);
|
||||
-
|
||||
-bool bch2_bkey_rebalance_needs_update(struct bch_fs *, struct bch_io_opts *, struct bkey_s_c);
|
||||
-int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bch_io_opts *, struct bkey_i *);
|
||||
-
|
||||
/* Generic extent code: */
|
||||
|
||||
enum bch_extent_overlap {
|
||||
diff --git a/fs/bcachefs/extents_format.h b/fs/bcachefs/extents_format.h
|
||||
index 222eed6b46d8..c198dfc376d6 100644
|
||||
--- a/fs/bcachefs/extents_format.h
|
||||
+++ b/fs/bcachefs/extents_format.h
|
||||
@@ -201,52 +201,8 @@ struct bch_extent_stripe_ptr {
|
||||
#endif
|
||||
};
|
||||
|
||||
-struct bch_extent_rebalance {
|
||||
-#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
- __u64 type:6,
|
||||
- unused:3,
|
||||
-
|
||||
- promote_target_from_inode:1,
|
||||
- erasure_code_from_inode:1,
|
||||
- data_checksum_from_inode:1,
|
||||
- background_compression_from_inode:1,
|
||||
- data_replicas_from_inode:1,
|
||||
- background_target_from_inode:1,
|
||||
-
|
||||
- promote_target:16,
|
||||
- erasure_code:1,
|
||||
- data_checksum:4,
|
||||
- data_replicas:4,
|
||||
- background_compression:8, /* enum bch_compression_opt */
|
||||
- background_target:16;
|
||||
-#elif defined (__BIG_ENDIAN_BITFIELD)
|
||||
- __u64 background_target:16,
|
||||
- background_compression:8,
|
||||
- data_replicas:4,
|
||||
- data_checksum:4,
|
||||
- erasure_code:1,
|
||||
- promote_target:16,
|
||||
-
|
||||
- background_target_from_inode:1,
|
||||
- data_replicas_from_inode:1,
|
||||
- background_compression_from_inode:1,
|
||||
- data_checksum_from_inode:1,
|
||||
- erasure_code_from_inode:1,
|
||||
- promote_target_from_inode:1,
|
||||
-
|
||||
- unused:3,
|
||||
- type:6;
|
||||
-#endif
|
||||
-};
|
||||
-
|
||||
-/* subset of BCH_INODE_OPTS */
|
||||
-#define BCH_REBALANCE_OPTS() \
|
||||
- x(data_checksum) \
|
||||
- x(background_compression) \
|
||||
- x(data_replicas) \
|
||||
- x(promote_target) \
|
||||
- x(background_target) \
|
||||
- x(erasure_code)
|
||||
+/* bch_extent_rebalance: */
|
||||
+#include "rebalance_format.h"
|
||||
|
||||
union bch_extent_entry {
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || __BITS_PER_LONG == 64
|
||||
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
|
||||
index 1003f7fe4f50..d6e68265e039 100644
|
||||
--- a/fs/bcachefs/move.c
|
||||
+++ b/fs/bcachefs/move.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "journal_reclaim.h"
|
||||
#include "keylist.h"
|
||||
#include "move.h"
|
||||
+#include "rebalance.h"
|
||||
#include "replicas.h"
|
||||
#include "snapshot.h"
|
||||
#include "super-io.h"
|
||||
@@ -379,44 +380,6 @@ int bch2_move_extent(struct moving_context *ctxt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int get_update_rebalance_opts(struct btree_trans *trans,
|
||||
- struct bch_io_opts *io_opts,
|
||||
- struct btree_iter *iter,
|
||||
- struct bkey_s_c k)
|
||||
-{
|
||||
- BUG_ON(iter->flags & BTREE_ITER_is_extents);
|
||||
- BUG_ON(iter->flags & BTREE_ITER_filter_snapshots);
|
||||
-
|
||||
- const struct bch_extent_rebalance *r = k.k->type == KEY_TYPE_reflink_v
|
||||
- ? bch2_bkey_rebalance_opts(k) : NULL;
|
||||
- if (r) {
|
||||
-#define x(_name) \
|
||||
- if (r->_name##_from_inode) { \
|
||||
- io_opts->_name = r->_name; \
|
||||
- io_opts->_name##_from_inode = true; \
|
||||
- }
|
||||
- BCH_REBALANCE_OPTS()
|
||||
-#undef x
|
||||
- }
|
||||
-
|
||||
- if (!bch2_bkey_rebalance_needs_update(trans->c, io_opts, k))
|
||||
- return 0;
|
||||
-
|
||||
- struct bkey_i *n = bch2_trans_kmalloc(trans, bkey_bytes(k.k) + 8);
|
||||
- int ret = PTR_ERR_OR_ZERO(n);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- bkey_reassemble(n, k);
|
||||
-
|
||||
- /* On successfull transaction commit, @k was invalidated: */
|
||||
-
|
||||
- return bch2_bkey_set_needs_rebalance(trans->c, io_opts, n) ?:
|
||||
- bch2_trans_update(trans, iter, n, BTREE_UPDATE_internal_snapshot_node) ?:
|
||||
- bch2_trans_commit(trans, NULL, NULL, 0) ?:
|
||||
- -BCH_ERR_transaction_restart_nested;
|
||||
-}
|
||||
-
|
||||
static struct bch_io_opts *bch2_move_get_io_opts(struct btree_trans *trans,
|
||||
struct per_snapshot_io_opts *io_opts,
|
||||
struct btree_iter *extent_iter,
|
||||
@@ -463,7 +426,7 @@ static struct bch_io_opts *bch2_move_get_io_opts(struct btree_trans *trans,
|
||||
break;
|
||||
}
|
||||
out:
|
||||
- ret = get_update_rebalance_opts(trans, opts_ret, extent_iter, extent_k);
|
||||
+ ret = bch2_get_update_rebalance_opts(trans, opts_ret, extent_iter, extent_k);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
return opts_ret;
|
||||
@@ -497,7 +460,7 @@ int bch2_move_get_io_opts_one(struct btree_trans *trans,
|
||||
}
|
||||
bch2_trans_iter_exit(trans, &inode_iter);
|
||||
out:
|
||||
- return get_update_rebalance_opts(trans, io_opts, extent_iter, extent_k);
|
||||
+ return bch2_get_update_rebalance_opts(trans, io_opts, extent_iter, extent_k);
|
||||
}
|
||||
|
||||
int bch2_move_ratelimit(struct moving_context *ctxt)
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index 124da250cbe7..d1b580e76ba4 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -24,6 +24,192 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sched/cputime.h>
|
||||
|
||||
+/* bch_extent_rebalance: */
|
||||
+
|
||||
+static const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c k)
|
||||
+{
|
||||
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
+ const union bch_extent_entry *entry;
|
||||
+
|
||||
+ bkey_extent_entry_for_each(ptrs, entry)
|
||||
+ if (__extent_entry_type(entry) == BCH_EXTENT_ENTRY_rebalance)
|
||||
+ return &entry->rebalance;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned bch2_bkey_ptrs_need_compress(struct bch_fs *c,
|
||||
+ struct bch_io_opts *opts,
|
||||
+ struct bkey_s_c k,
|
||||
+ struct bkey_ptrs_c ptrs)
|
||||
+{
|
||||
+ if (!opts->background_compression)
|
||||
+ return 0;
|
||||
+
|
||||
+ unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
+ const union bch_extent_entry *entry;
|
||||
+ struct extent_ptr_decoded p;
|
||||
+ unsigned ptr_bit = 1;
|
||||
+ unsigned rewrite_ptrs = 0;
|
||||
+
|
||||
+ bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
+ if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
+ p.ptr.unwritten)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!p.ptr.cached && p.crc.compression_type != compression_type)
|
||||
+ rewrite_ptrs |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
+ }
|
||||
+
|
||||
+ return rewrite_ptrs;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned bch2_bkey_ptrs_need_move(struct bch_fs *c,
|
||||
+ struct bch_io_opts *opts,
|
||||
+ struct bkey_ptrs_c ptrs)
|
||||
+{
|
||||
+ if (!opts->background_target ||
|
||||
+ !bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target))
|
||||
+ return 0;
|
||||
+
|
||||
+ unsigned ptr_bit = 1;
|
||||
+ unsigned rewrite_ptrs = 0;
|
||||
+
|
||||
+ bkey_for_each_ptr(ptrs, ptr) {
|
||||
+ if (!ptr->cached && !bch2_dev_in_target(c, ptr->dev, opts->background_target))
|
||||
+ rewrite_ptrs |= ptr_bit;
|
||||
+ ptr_bit <<= 1;
|
||||
+ }
|
||||
+
|
||||
+ return rewrite_ptrs;
|
||||
+}
|
||||
+
|
||||
+static unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *c,
|
||||
+ struct bch_io_opts *opts,
|
||||
+ struct bkey_s_c k)
|
||||
+{
|
||||
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
+
|
||||
+ return bch2_bkey_ptrs_need_compress(c, opts, k, ptrs) |
|
||||
+ bch2_bkey_ptrs_need_move(c, opts, ptrs);
|
||||
+}
|
||||
+
|
||||
+u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
|
||||
+{
|
||||
+ const struct bch_extent_rebalance *opts = bch2_bkey_rebalance_opts(k);
|
||||
+ if (!opts)
|
||||
+ return 0;
|
||||
+
|
||||
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
+ const union bch_extent_entry *entry;
|
||||
+ struct extent_ptr_decoded p;
|
||||
+ u64 sectors = 0;
|
||||
+
|
||||
+ if (opts->background_compression) {
|
||||
+ unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
+
|
||||
+ bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
+ if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
+ p.ptr.unwritten) {
|
||||
+ sectors = 0;
|
||||
+ goto incompressible;
|
||||
+ }
|
||||
+
|
||||
+ if (!p.ptr.cached && p.crc.compression_type != compression_type)
|
||||
+ sectors += p.crc.compressed_size;
|
||||
+ }
|
||||
+ }
|
||||
+incompressible:
|
||||
+ if (opts->background_target &&
|
||||
+ bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target)) {
|
||||
+ bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
|
||||
+ if (!p.ptr.cached && !bch2_dev_in_target(c, p.ptr.dev, opts->background_target))
|
||||
+ sectors += p.crc.compressed_size;
|
||||
+ }
|
||||
+
|
||||
+ return sectors;
|
||||
+}
|
||||
+
|
||||
+static bool bch2_bkey_rebalance_needs_update(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
+ struct bkey_s_c k)
|
||||
+{
|
||||
+ if (!bkey_extent_is_direct_data(k.k))
|
||||
+ return 0;
|
||||
+
|
||||
+ const struct bch_extent_rebalance *old = bch2_bkey_rebalance_opts(k);
|
||||
+
|
||||
+ if (k.k->type == KEY_TYPE_reflink_v || bch2_bkey_ptrs_need_rebalance(c, opts, k)) {
|
||||
+ struct bch_extent_rebalance new = io_opts_to_rebalance_opts(opts);
|
||||
+ return old == NULL || memcmp(old, &new, sizeof(new));
|
||||
+ } else {
|
||||
+ return old != NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bch_io_opts *opts,
|
||||
+ struct bkey_i *_k)
|
||||
+{
|
||||
+ if (!bkey_extent_is_direct_data(&_k->k))
|
||||
+ return 0;
|
||||
+
|
||||
+ struct bkey_s k = bkey_i_to_s(_k);
|
||||
+ struct bch_extent_rebalance *old =
|
||||
+ (struct bch_extent_rebalance *) bch2_bkey_rebalance_opts(k.s_c);
|
||||
+
|
||||
+ if (k.k->type == KEY_TYPE_reflink_v || bch2_bkey_ptrs_need_rebalance(c, opts, k.s_c)) {
|
||||
+ if (!old) {
|
||||
+ old = bkey_val_end(k);
|
||||
+ k.k->u64s += sizeof(*old) / sizeof(u64);
|
||||
+ }
|
||||
+
|
||||
+ *old = io_opts_to_rebalance_opts(opts);
|
||||
+ } else {
|
||||
+ if (old)
|
||||
+ extent_entry_drop(k, (union bch_extent_entry *) old);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int bch2_get_update_rebalance_opts(struct btree_trans *trans,
|
||||
+ struct bch_io_opts *io_opts,
|
||||
+ struct btree_iter *iter,
|
||||
+ struct bkey_s_c k)
|
||||
+{
|
||||
+ BUG_ON(iter->flags & BTREE_ITER_is_extents);
|
||||
+ BUG_ON(iter->flags & BTREE_ITER_filter_snapshots);
|
||||
+
|
||||
+ const struct bch_extent_rebalance *r = k.k->type == KEY_TYPE_reflink_v
|
||||
+ ? bch2_bkey_rebalance_opts(k) : NULL;
|
||||
+ if (r) {
|
||||
+#define x(_name) \
|
||||
+ if (r->_name##_from_inode) { \
|
||||
+ io_opts->_name = r->_name; \
|
||||
+ io_opts->_name##_from_inode = true; \
|
||||
+ }
|
||||
+ BCH_REBALANCE_OPTS()
|
||||
+#undef x
|
||||
+ }
|
||||
+
|
||||
+ if (!bch2_bkey_rebalance_needs_update(trans->c, io_opts, k))
|
||||
+ return 0;
|
||||
+
|
||||
+ struct bkey_i *n = bch2_trans_kmalloc(trans, bkey_bytes(k.k) + 8);
|
||||
+ int ret = PTR_ERR_OR_ZERO(n);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ bkey_reassemble(n, k);
|
||||
+
|
||||
+ /* On successfull transaction commit, @k was invalidated: */
|
||||
+
|
||||
+ return bch2_bkey_set_needs_rebalance(trans->c, io_opts, n) ?:
|
||||
+ bch2_trans_update(trans, iter, n, BTREE_UPDATE_internal_snapshot_node) ?:
|
||||
+ bch2_trans_commit(trans, NULL, NULL, 0) ?:
|
||||
+ -BCH_ERR_transaction_restart_nested;
|
||||
+}
|
||||
+
|
||||
#define REBALANCE_WORK_SCAN_OFFSET (U64_MAX - 1)
|
||||
|
||||
static const char * const bch2_rebalance_state_strs[] = {
|
||||
diff --git a/fs/bcachefs/rebalance.h b/fs/bcachefs/rebalance.h
|
||||
index 606c88f49f7f..0a0821ab895d 100644
|
||||
--- a/fs/bcachefs/rebalance.h
|
||||
+++ b/fs/bcachefs/rebalance.h
|
||||
@@ -6,52 +6,12 @@
|
||||
#include "disk_groups.h"
|
||||
#include "rebalance_types.h"
|
||||
|
||||
-static inline unsigned bch2_bkey_ptrs_need_compress(struct bch_fs *c,
|
||||
- struct bch_io_opts *opts,
|
||||
- struct bkey_s_c k,
|
||||
- struct bkey_ptrs_c ptrs)
|
||||
-{
|
||||
- if (!opts->background_compression)
|
||||
- return 0;
|
||||
-
|
||||
- unsigned compression_type = bch2_compression_opt_to_type(opts->background_compression);
|
||||
- const union bch_extent_entry *entry;
|
||||
- struct extent_ptr_decoded p;
|
||||
- unsigned ptr_bit = 1;
|
||||
- unsigned rewrite_ptrs = 0;
|
||||
-
|
||||
- bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||
- if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
|
||||
- p.ptr.unwritten)
|
||||
- return 0;
|
||||
-
|
||||
- if (!p.ptr.cached && p.crc.compression_type != compression_type)
|
||||
- rewrite_ptrs |= ptr_bit;
|
||||
- ptr_bit <<= 1;
|
||||
- }
|
||||
-
|
||||
- return rewrite_ptrs;
|
||||
-}
|
||||
-
|
||||
-static inline unsigned bch2_bkey_ptrs_need_move(struct bch_fs *c,
|
||||
- struct bch_io_opts *opts,
|
||||
- struct bkey_ptrs_c ptrs)
|
||||
-{
|
||||
- if (!opts->background_target ||
|
||||
- !bch2_target_accepts_data(c, BCH_DATA_user, opts->background_target))
|
||||
- return 0;
|
||||
-
|
||||
- unsigned ptr_bit = 1;
|
||||
- unsigned rewrite_ptrs = 0;
|
||||
-
|
||||
- bkey_for_each_ptr(ptrs, ptr) {
|
||||
- if (!ptr->cached && !bch2_dev_in_target(c, ptr->dev, opts->background_target))
|
||||
- rewrite_ptrs |= ptr_bit;
|
||||
- ptr_bit <<= 1;
|
||||
- }
|
||||
-
|
||||
- return rewrite_ptrs;
|
||||
-}
|
||||
+u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *, struct bkey_s_c);
|
||||
+int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bch_io_opts *, struct bkey_i *);
|
||||
+int bch2_get_update_rebalance_opts(struct btree_trans *,
|
||||
+ struct bch_io_opts *,
|
||||
+ struct btree_iter *,
|
||||
+ struct bkey_s_c);
|
||||
|
||||
int bch2_set_rebalance_needs_scan_trans(struct btree_trans *, u64);
|
||||
int bch2_set_rebalance_needs_scan(struct bch_fs *, u64 inum);
|
||||
diff --git a/fs/bcachefs/rebalance_format.h b/fs/bcachefs/rebalance_format.h
|
||||
new file mode 100644
|
||||
index 000000000000..ff9a1342a22b
|
||||
--- /dev/null
|
||||
+++ b/fs/bcachefs/rebalance_format.h
|
||||
@@ -0,0 +1,53 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef _BCACHEFS_REBALANCE_FORMAT_H
|
||||
+#define _BCACHEFS_REBALANCE_FORMAT_H
|
||||
+
|
||||
+struct bch_extent_rebalance {
|
||||
+#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
+ __u64 type:6,
|
||||
+ unused:3,
|
||||
+
|
||||
+ promote_target_from_inode:1,
|
||||
+ erasure_code_from_inode:1,
|
||||
+ data_checksum_from_inode:1,
|
||||
+ background_compression_from_inode:1,
|
||||
+ data_replicas_from_inode:1,
|
||||
+ background_target_from_inode:1,
|
||||
+
|
||||
+ promote_target:16,
|
||||
+ erasure_code:1,
|
||||
+ data_checksum:4,
|
||||
+ data_replicas:4,
|
||||
+ background_compression:8, /* enum bch_compression_opt */
|
||||
+ background_target:16;
|
||||
+#elif defined (__BIG_ENDIAN_BITFIELD)
|
||||
+ __u64 background_target:16,
|
||||
+ background_compression:8,
|
||||
+ data_replicas:4,
|
||||
+ data_checksum:4,
|
||||
+ erasure_code:1,
|
||||
+ promote_target:16,
|
||||
+
|
||||
+ background_target_from_inode:1,
|
||||
+ data_replicas_from_inode:1,
|
||||
+ background_compression_from_inode:1,
|
||||
+ data_checksum_from_inode:1,
|
||||
+ erasure_code_from_inode:1,
|
||||
+ promote_target_from_inode:1,
|
||||
+
|
||||
+ unused:3,
|
||||
+ type:6;
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+/* subset of BCH_INODE_OPTS */
|
||||
+#define BCH_REBALANCE_OPTS() \
|
||||
+ x(data_checksum) \
|
||||
+ x(background_compression) \
|
||||
+ x(data_replicas) \
|
||||
+ x(promote_target) \
|
||||
+ x(background_target) \
|
||||
+ x(erasure_code)
|
||||
+
|
||||
+#endif /* _BCACHEFS_REBALANCE_FORMAT_H */
|
||||
+
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,46 +0,0 @@
|
||||
From 9e6755da18a187eb1389a205680049587d97c62a Mon Sep 17 00:00:00 2001
|
||||
From: Hongbo Li <lihongbo22@huawei.com>
|
||||
Date: Tue, 29 Oct 2024 20:53:50 +0800
|
||||
Subject: [PATCH 053/233] bcachefs: remove write permission for gc_gens_pos
|
||||
sysfs interface
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The gc_gens_pos is used to show the status of bucket gen gc.
|
||||
There is no need to assign write permissions for this attribute.
|
||||
Here we can use read_attribute helper to define this attribute.
|
||||
|
||||
```
|
||||
[Before]
|
||||
$ ll internal/gc_gens_pos
|
||||
-rw-r--r-- 1 root root 4096 Oct 28 15:27 internal/gc_gens_pos
|
||||
|
||||
[After]
|
||||
$ ll internal/gc_gens_pos
|
||||
-r--r--r-- 1 root root 4096 Oct 28 17:27 internal/gc_gens_pos
|
||||
```
|
||||
|
||||
Fixes: ac516d0e7db7 ("bcachefs: Add the status of bucket gen gc to sysfs")
|
||||
Signed-off-by: Hongbo Li <lihongbo22@huawei.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/sysfs.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
|
||||
index 4ab0ccba2ab5..47ac8d5ab562 100644
|
||||
--- a/fs/bcachefs/sysfs.c
|
||||
+++ b/fs/bcachefs/sysfs.c
|
||||
@@ -146,7 +146,7 @@ write_attribute(trigger_journal_writes);
|
||||
write_attribute(trigger_btree_cache_shrink);
|
||||
write_attribute(trigger_btree_key_cache_shrink);
|
||||
write_attribute(trigger_freelist_wakeup);
|
||||
-rw_attribute(gc_gens_pos);
|
||||
+read_attribute(gc_gens_pos);
|
||||
|
||||
read_attribute(uuid);
|
||||
read_attribute(minor);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,64 +0,0 @@
|
||||
From 3289204eca4e4f1f873ceb5630f855b66373576e Mon Sep 17 00:00:00 2001
|
||||
From: Hongbo Li <lihongbo22@huawei.com>
|
||||
Date: Tue, 29 Oct 2024 20:54:08 +0800
|
||||
Subject: [PATCH 054/233] bcachefs: use attribute define helper for sysfs
|
||||
attribute
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The sysfs attribute definition has been wrapped into macro:
|
||||
rw_attribute, read_attribute and write_attribute, we can
|
||||
use these helpers to uniform the attribute definition.
|
||||
|
||||
Signed-off-by: Hongbo Li <lihongbo22@huawei.com>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/sysfs.c | 10 +++-------
|
||||
1 file changed, 3 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
|
||||
index 47ac8d5ab562..97733c766948 100644
|
||||
--- a/fs/bcachefs/sysfs.c
|
||||
+++ b/fs/bcachefs/sysfs.c
|
||||
@@ -211,6 +211,7 @@ BCH_PERSISTENT_COUNTERS()
|
||||
#undef x
|
||||
|
||||
rw_attribute(discard);
|
||||
+read_attribute(state);
|
||||
rw_attribute(label);
|
||||
|
||||
read_attribute(copy_gc_wait);
|
||||
@@ -235,11 +236,6 @@ write_attribute(perf_test);
|
||||
BCH_TIME_STATS()
|
||||
#undef x
|
||||
|
||||
-static struct attribute sysfs_state_rw = {
|
||||
- .name = "state",
|
||||
- .mode = 0444,
|
||||
-};
|
||||
-
|
||||
static size_t bch2_btree_cache_size(struct bch_fs *c)
|
||||
{
|
||||
struct btree_cache *bc = &c->btree_cache;
|
||||
@@ -774,7 +770,7 @@ SHOW(bch2_dev)
|
||||
prt_char(out, '\n');
|
||||
}
|
||||
|
||||
- if (attr == &sysfs_state_rw) {
|
||||
+ if (attr == &sysfs_state) {
|
||||
prt_string_option(out, bch2_member_states, ca->mi.state);
|
||||
prt_char(out, '\n');
|
||||
}
|
||||
@@ -854,7 +850,7 @@ struct attribute *bch2_dev_files[] = {
|
||||
|
||||
/* settings: */
|
||||
&sysfs_discard,
|
||||
- &sysfs_state_rw,
|
||||
+ &sysfs_state,
|
||||
&sysfs_label,
|
||||
|
||||
&sysfs_has_data,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,80 +0,0 @@
|
||||
From 0877e537bcecaaa8b2a7926a130fab809a83e6da Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 31 Oct 2024 03:35:41 -0400
|
||||
Subject: [PATCH 055/233] bcachefs: Add assert for use of journal replay keys
|
||||
for updates
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The journal replay keys mechanism can only be used for updates in early
|
||||
recovery, when still single threaded.
|
||||
|
||||
Add some asserts to make sure we never accidentally use it elsewhere.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs.h | 6 ++++++
|
||||
fs/bcachefs/btree_trans_commit.c | 2 ++
|
||||
fs/bcachefs/super.c | 5 +++++
|
||||
3 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
||||
index e1ab67c533f0..c59a58b93a92 100644
|
||||
--- a/fs/bcachefs/bcachefs.h
|
||||
+++ b/fs/bcachefs/bcachefs.h
|
||||
@@ -743,6 +743,12 @@ struct bch_fs {
|
||||
#else
|
||||
struct percpu_ref writes;
|
||||
#endif
|
||||
+ /*
|
||||
+ * Certain operations are only allowed in single threaded mode, during
|
||||
+ * recovery, and we want to assert that this is the case:
|
||||
+ */
|
||||
+ struct task_struct *recovery_task;
|
||||
+
|
||||
/*
|
||||
* Analagous to c->writes, for asynchronous ops that don't necessarily
|
||||
* need fs to be read-write
|
||||
diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c
|
||||
index b47f11881fe4..529a5a19ab8a 100644
|
||||
--- a/fs/bcachefs/btree_trans_commit.c
|
||||
+++ b/fs/bcachefs/btree_trans_commit.c
|
||||
@@ -999,6 +999,8 @@ do_bch2_trans_commit_to_journal_replay(struct btree_trans *trans)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
|
||||
+ BUG_ON(current != c->recovery_task);
|
||||
+
|
||||
trans_for_each_update(trans, i) {
|
||||
int ret = bch2_journal_key_insert(c, i->btree_id, i->level, i->k);
|
||||
if (ret)
|
||||
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
|
||||
index 7e2431de3a94..7e0ff17a6dbb 100644
|
||||
--- a/fs/bcachefs/super.c
|
||||
+++ b/fs/bcachefs/super.c
|
||||
@@ -441,6 +441,8 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
|
||||
{
|
||||
int ret;
|
||||
|
||||
+ BUG_ON(!test_bit(BCH_FS_may_go_rw, &c->flags));
|
||||
+
|
||||
if (test_bit(BCH_FS_initial_gc_unfixed, &c->flags)) {
|
||||
bch_err(c, "cannot go rw, unfixed btree errors");
|
||||
return -BCH_ERR_erofs_unfixed_errors;
|
||||
@@ -1031,9 +1033,12 @@ int bch2_fs_start(struct bch_fs *c)
|
||||
bch2_dev_allocator_add(c, ca);
|
||||
bch2_recalc_capacity(c);
|
||||
|
||||
+ c->recovery_task = current;
|
||||
ret = BCH_SB_INITIALIZED(c->disk_sb.sb)
|
||||
? bch2_fs_recovery(c)
|
||||
: bch2_fs_initialize(c);
|
||||
+ c->recovery_task = NULL;
|
||||
+
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,197 +0,0 @@
|
||||
From bf924eff0e7b0dff40eee7d9237e382918022f6a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 31 Oct 2024 03:39:32 -0400
|
||||
Subject: [PATCH 056/233] bcachefs: Kill BCH_TRANS_COMMIT_lazy_rw
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We unconditionally go read-write, if we're going to do so, before
|
||||
journal replay: lazy_rw is obsolete.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_gc.c | 2 +-
|
||||
fs/bcachefs/btree_trans_commit.c | 31 +++++--------------------------
|
||||
fs/bcachefs/btree_update.c | 3 +--
|
||||
fs/bcachefs/btree_update.h | 1 -
|
||||
fs/bcachefs/lru.c | 2 +-
|
||||
fs/bcachefs/rebalance.c | 3 +--
|
||||
fs/bcachefs/snapshot.c | 8 ++++++--
|
||||
fs/bcachefs/subvolume.c | 2 +-
|
||||
fs/bcachefs/super.h | 10 ----------
|
||||
9 files changed, 16 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
|
||||
index 3c4e66da1ca4..833d743dee0c 100644
|
||||
--- a/fs/bcachefs/btree_gc.c
|
||||
+++ b/fs/bcachefs/btree_gc.c
|
||||
@@ -908,7 +908,7 @@ static int bch2_gc_alloc_done(struct bch_fs *c)
|
||||
POS(ca->dev_idx, ca->mi.first_bucket),
|
||||
POS(ca->dev_idx, ca->mi.nbuckets - 1),
|
||||
BTREE_ITER_slots|BTREE_ITER_prefetch, k,
|
||||
- NULL, NULL, BCH_TRANS_COMMIT_lazy_rw,
|
||||
+ NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
|
||||
bch2_alloc_write_key(trans, &iter, ca, k)));
|
||||
if (ret) {
|
||||
bch2_dev_put(ca);
|
||||
diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c
|
||||
index 529a5a19ab8a..3aca746d08f6 100644
|
||||
--- a/fs/bcachefs/btree_trans_commit.c
|
||||
+++ b/fs/bcachefs/btree_trans_commit.c
|
||||
@@ -971,24 +971,6 @@ int bch2_trans_commit_error(struct btree_trans *trans, unsigned flags,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static noinline int
|
||||
-bch2_trans_commit_get_rw_cold(struct btree_trans *trans, unsigned flags)
|
||||
-{
|
||||
- struct bch_fs *c = trans->c;
|
||||
- int ret;
|
||||
-
|
||||
- if (likely(!(flags & BCH_TRANS_COMMIT_lazy_rw)) ||
|
||||
- test_bit(BCH_FS_started, &c->flags))
|
||||
- return -BCH_ERR_erofs_trans_commit;
|
||||
-
|
||||
- ret = drop_locks_do(trans, bch2_fs_read_write_early(c));
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- bch2_write_ref_get(c, BCH_WRITE_REF_trans);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* This is for updates done in the early part of fsck - btree_gc - before we've
|
||||
* gone RW. we only add the new key to the list of keys for journal replay to
|
||||
@@ -1037,16 +1019,13 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
|
||||
if (ret)
|
||||
goto out_reset;
|
||||
|
||||
- if (unlikely(!test_bit(BCH_FS_may_go_rw, &c->flags))) {
|
||||
- ret = do_bch2_trans_commit_to_journal_replay(trans);
|
||||
- goto out_reset;
|
||||
- }
|
||||
-
|
||||
if (!(flags & BCH_TRANS_COMMIT_no_check_rw) &&
|
||||
unlikely(!bch2_write_ref_tryget(c, BCH_WRITE_REF_trans))) {
|
||||
- ret = bch2_trans_commit_get_rw_cold(trans, flags);
|
||||
- if (ret)
|
||||
- goto out_reset;
|
||||
+ if (unlikely(!test_bit(BCH_FS_may_go_rw, &c->flags)))
|
||||
+ ret = do_bch2_trans_commit_to_journal_replay(trans);
|
||||
+ else
|
||||
+ ret = -BCH_ERR_erofs_trans_commit;
|
||||
+ goto out_reset;
|
||||
}
|
||||
|
||||
EBUG_ON(test_bit(BCH_FS_clean_shutdown, &c->flags));
|
||||
diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c
|
||||
index 79a274dcd17b..a9a29fba4902 100644
|
||||
--- a/fs/bcachefs/btree_update.c
|
||||
+++ b/fs/bcachefs/btree_update.c
|
||||
@@ -865,8 +865,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
|
||||
memcpy(l->d, buf.buf, buf.pos);
|
||||
c->journal.early_journal_entries.nr += jset_u64s(u64s);
|
||||
} else {
|
||||
- ret = bch2_trans_commit_do(c, NULL, NULL,
|
||||
- BCH_TRANS_COMMIT_lazy_rw|commit_flags,
|
||||
+ ret = bch2_trans_commit_do(c, NULL, NULL, commit_flags,
|
||||
__bch2_trans_log_msg(trans, &buf, u64s));
|
||||
}
|
||||
err:
|
||||
diff --git a/fs/bcachefs/btree_update.h b/fs/bcachefs/btree_update.h
|
||||
index 7e71c4d1111d..3bc57d43aa83 100644
|
||||
--- a/fs/bcachefs/btree_update.h
|
||||
+++ b/fs/bcachefs/btree_update.h
|
||||
@@ -24,7 +24,6 @@ void bch2_btree_insert_key_leaf(struct btree_trans *, struct btree_path *,
|
||||
#define BCH_TRANS_COMMIT_FLAGS() \
|
||||
x(no_enospc, "don't check for enospc") \
|
||||
x(no_check_rw, "don't attempt to take a ref on c->writes") \
|
||||
- x(lazy_rw, "go read-write if we haven't yet - only for use in recovery") \
|
||||
x(no_journal_res, "don't take a journal reservation, instead " \
|
||||
"pin journal entry referred to by trans->journal_res.seq") \
|
||||
x(journal_reclaim, "operation required for journal reclaim; may return error" \
|
||||
diff --git a/fs/bcachefs/lru.c b/fs/bcachefs/lru.c
|
||||
index 10857eccdeaf..c18242748ca3 100644
|
||||
--- a/fs/bcachefs/lru.c
|
||||
+++ b/fs/bcachefs/lru.c
|
||||
@@ -192,7 +192,7 @@ int bch2_check_lrus(struct bch_fs *c)
|
||||
int ret = bch2_trans_run(c,
|
||||
for_each_btree_key_commit(trans, iter,
|
||||
BTREE_ID_lru, POS_MIN, BTREE_ITER_prefetch, k,
|
||||
- NULL, NULL, BCH_TRANS_COMMIT_no_enospc|BCH_TRANS_COMMIT_lazy_rw,
|
||||
+ NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
|
||||
bch2_check_lru_key(trans, &iter, k, &last_flushed)));
|
||||
|
||||
bch2_bkey_buf_exit(&last_flushed, c);
|
||||
diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
|
||||
index d1b580e76ba4..4adc74cd3f70 100644
|
||||
--- a/fs/bcachefs/rebalance.c
|
||||
+++ b/fs/bcachefs/rebalance.c
|
||||
@@ -257,8 +257,7 @@ int bch2_set_rebalance_needs_scan_trans(struct btree_trans *trans, u64 inum)
|
||||
int bch2_set_rebalance_needs_scan(struct bch_fs *c, u64 inum)
|
||||
{
|
||||
int ret = bch2_trans_commit_do(c, NULL, NULL,
|
||||
- BCH_TRANS_COMMIT_no_enospc|
|
||||
- BCH_TRANS_COMMIT_lazy_rw,
|
||||
+ BCH_TRANS_COMMIT_no_enospc,
|
||||
bch2_set_rebalance_needs_scan_trans(trans, inum));
|
||||
rebalance_wakeup(c);
|
||||
return ret;
|
||||
diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
|
||||
index 34e01bd8127f..6a52090485dc 100644
|
||||
--- a/fs/bcachefs/snapshot.c
|
||||
+++ b/fs/bcachefs/snapshot.c
|
||||
@@ -1733,8 +1733,12 @@ void bch2_delete_dead_snapshots_work(struct work_struct *work)
|
||||
|
||||
void bch2_delete_dead_snapshots_async(struct bch_fs *c)
|
||||
{
|
||||
- if (bch2_write_ref_tryget(c, BCH_WRITE_REF_delete_dead_snapshots) &&
|
||||
- !queue_work(c->write_ref_wq, &c->snapshot_delete_work))
|
||||
+ if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_delete_dead_snapshots))
|
||||
+ return;
|
||||
+
|
||||
+ BUG_ON(!test_bit(BCH_FS_may_go_rw, &c->flags));
|
||||
+
|
||||
+ if (!queue_work(c->write_ref_wq, &c->snapshot_delete_work))
|
||||
bch2_write_ref_put(c, BCH_WRITE_REF_delete_dead_snapshots);
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/subvolume.c b/fs/bcachefs/subvolume.c
|
||||
index 80e5efaff524..cb45ef769c54 100644
|
||||
--- a/fs/bcachefs/subvolume.c
|
||||
+++ b/fs/bcachefs/subvolume.c
|
||||
@@ -675,7 +675,7 @@ static int __bch2_fs_upgrade_for_subvolumes(struct btree_trans *trans)
|
||||
/* set bi_subvol on root inode */
|
||||
int bch2_fs_upgrade_for_subvolumes(struct bch_fs *c)
|
||||
{
|
||||
- int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_lazy_rw,
|
||||
+ int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
|
||||
__bch2_fs_upgrade_for_subvolumes(trans));
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
diff --git a/fs/bcachefs/super.h b/fs/bcachefs/super.h
|
||||
index dada09331d2e..fa6d52216510 100644
|
||||
--- a/fs/bcachefs/super.h
|
||||
+++ b/fs/bcachefs/super.h
|
||||
@@ -34,16 +34,6 @@ void bch2_fs_read_only(struct bch_fs *);
|
||||
int bch2_fs_read_write(struct bch_fs *);
|
||||
int bch2_fs_read_write_early(struct bch_fs *);
|
||||
|
||||
-/*
|
||||
- * Only for use in the recovery/fsck path:
|
||||
- */
|
||||
-static inline void bch2_fs_lazy_rw(struct bch_fs *c)
|
||||
-{
|
||||
- if (!test_bit(BCH_FS_rw, &c->flags) &&
|
||||
- !test_bit(BCH_FS_was_rw, &c->flags))
|
||||
- bch2_fs_read_write_early(c);
|
||||
-}
|
||||
-
|
||||
void __bch2_fs_stop(struct bch_fs *);
|
||||
void bch2_fs_free(struct bch_fs *);
|
||||
void bch2_fs_stop(struct bch_fs *);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,78 +0,0 @@
|
||||
From 657e12389cdd2f954012666fd5a2ea336950bd56 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 31 Oct 2024 00:25:36 -0400
|
||||
Subject: [PATCH 057/233] bcachefs: Improved check_topology() assert
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On interior btree node updates, we always verify that we're not
|
||||
introducing topology errors: child nodes should exactly span the range
|
||||
of the parent node.
|
||||
|
||||
single_device.ktest small_nodes has been popping this assert: change it
|
||||
to give us more information.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_update_interior.c | 27 +++++++++++++++++----------
|
||||
1 file changed, 17 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
|
||||
index d62de3f79b29..865c4724d550 100644
|
||||
--- a/fs/bcachefs/btree_update_interior.c
|
||||
+++ b/fs/bcachefs/btree_update_interior.c
|
||||
@@ -1418,15 +1418,26 @@ bch2_btree_insert_keys_interior(struct btree_update *as,
|
||||
(bkey_cmp_left_packed(b, k, &insert->k.p) >= 0))
|
||||
;
|
||||
|
||||
- while (!bch2_keylist_empty(keys)) {
|
||||
- insert = bch2_keylist_front(keys);
|
||||
+ for (;
|
||||
+ insert != keys->top && bpos_le(insert->k.p, b->key.k.p);
|
||||
+ insert = bkey_next(insert))
|
||||
+ bch2_insert_fixup_btree_ptr(as, trans, path, b, &node_iter, insert);
|
||||
|
||||
- if (bpos_gt(insert->k.p, b->key.k.p))
|
||||
- break;
|
||||
+ if (bch2_btree_node_check_topology(trans, b)) {
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
|
||||
- bch2_insert_fixup_btree_ptr(as, trans, path, b, &node_iter, insert);
|
||||
- bch2_keylist_pop_front(keys);
|
||||
+ for (struct bkey_i *k = keys->keys;
|
||||
+ k != insert;
|
||||
+ k = bkey_next(k)) {
|
||||
+ bch2_bkey_val_to_text(&buf, trans->c, bkey_i_to_s_c(k));
|
||||
+ prt_newline(&buf);
|
||||
+ }
|
||||
+
|
||||
+ panic("%s(): check_topology error: inserted keys\n%s", __func__, buf.buf);
|
||||
}
|
||||
+
|
||||
+ memmove_u64s_down(keys->keys, insert, keys->top_p - insert->_data);
|
||||
+ keys->top_p -= insert->_data - keys->keys_p;
|
||||
}
|
||||
|
||||
static bool key_deleted_in_insert(struct keylist *insert_keys, struct bpos pos)
|
||||
@@ -1575,8 +1586,6 @@ static void btree_split_insert_keys(struct btree_update *as,
|
||||
bch2_btree_node_iter_init(&node_iter, b, &bch2_keylist_front(keys)->k.p);
|
||||
|
||||
bch2_btree_insert_keys_interior(as, trans, path, b, node_iter, keys);
|
||||
-
|
||||
- BUG_ON(bch2_btree_node_check_topology(trans, b));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1827,8 +1836,6 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
|
||||
|
||||
btree_update_updated_node(as, b);
|
||||
bch2_btree_node_unlock_write(trans, path, b);
|
||||
-
|
||||
- BUG_ON(bch2_btree_node_check_topology(trans, b));
|
||||
return 0;
|
||||
split:
|
||||
/*
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,40 +0,0 @@
|
||||
From e17c5f5f191f21665cc9e48cd68d92ef4cc377ef Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 7 Nov 2024 22:00:05 -0500
|
||||
Subject: [PATCH 058/233] bcachefs: Fix unhandled transaction restart in
|
||||
evacuate_bucket()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Generally, releasing a transaction within a transaction restart means an
|
||||
unhandled transaction restart: but this can happen legitimately within
|
||||
the move code, e.g. when bch2_move_ratelimit() tells us to exit before
|
||||
we've retried.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/move.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
|
||||
index d6e68265e039..a6b503278519 100644
|
||||
--- a/fs/bcachefs/move.c
|
||||
+++ b/fs/bcachefs/move.c
|
||||
@@ -197,6 +197,13 @@ void bch2_moving_ctxt_exit(struct moving_context *ctxt)
|
||||
list_del(&ctxt->list);
|
||||
mutex_unlock(&c->moving_context_lock);
|
||||
|
||||
+ /*
|
||||
+ * Generally, releasing a transaction within a transaction restart means
|
||||
+ * an unhandled transaction restart: but this can happen legitimately
|
||||
+ * within the move code, e.g. when bch2_move_ratelimit() tells us to
|
||||
+ * exit before we've retried
|
||||
+ */
|
||||
+ bch2_trans_begin(ctxt->trans);
|
||||
bch2_trans_put(ctxt->trans);
|
||||
memset(ctxt, 0, sizeof(*ctxt));
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 58d33a0a41804c2ab68c85fc61f79e91f4b9f98b Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 14 Oct 2024 23:33:57 -0400
|
||||
Subject: [PATCH 059/233] bcachefs: Assert we're not in a restart in
|
||||
bch2_trans_put()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This always indicates a transaction restart handling bug
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index 07bce85dafaf..98375c66021a 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -3261,6 +3261,9 @@ void bch2_trans_put(struct btree_trans *trans)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
|
||||
+ if (trans->restarted)
|
||||
+ bch2_trans_in_restart_error(trans);
|
||||
+
|
||||
bch2_trans_unlock(trans);
|
||||
|
||||
trans_for_each_update(trans, i)
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,85 +0,0 @@
|
||||
From efaa4e4ea6ceb2cdee4b0dca156e0606bbc98f8d Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 14 Oct 2024 23:52:51 -0400
|
||||
Subject: [PATCH 060/233] bcachefs: Better in_restart error
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We're ramping up on checking transaction restart handling correctness -
|
||||
so, in debug mode we now save a backtrace for where the restart was
|
||||
emitted, which makes it much easier to track down the incorrect
|
||||
handling.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 12 ++++++++++++
|
||||
fs/bcachefs/btree_iter.h | 4 ++++
|
||||
fs/bcachefs/btree_types.h | 3 +++
|
||||
3 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index 98375c66021a..acf70aaf2fd2 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -1427,9 +1427,17 @@ void __noreturn bch2_trans_restart_error(struct btree_trans *trans, u32 restart_
|
||||
|
||||
void __noreturn bch2_trans_in_restart_error(struct btree_trans *trans)
|
||||
{
|
||||
+#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
+ bch2_prt_backtrace(&buf, &trans->last_restarted_trace);
|
||||
+ panic("in transaction restart: %s, last restarted by\n%s",
|
||||
+ bch2_err_str(trans->restarted),
|
||||
+ buf.buf);
|
||||
+#else
|
||||
panic("in transaction restart: %s, last restarted by %pS\n",
|
||||
bch2_err_str(trans->restarted),
|
||||
(void *) trans->last_restarted_ip);
|
||||
+#endif
|
||||
}
|
||||
|
||||
void __noreturn bch2_trans_unlocked_error(struct btree_trans *trans)
|
||||
@@ -3287,6 +3295,10 @@ void bch2_trans_put(struct btree_trans *trans)
|
||||
closure_return_sync(&trans->ref);
|
||||
trans->locking_wait.task = NULL;
|
||||
|
||||
+#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
+ darray_exit(&trans->last_restarted_trace);
|
||||
+#endif
|
||||
+
|
||||
unsigned long *paths_allocated = trans->paths_allocated;
|
||||
trans->paths_allocated = NULL;
|
||||
trans->paths = NULL;
|
||||
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
|
||||
index dda07a320488..36899c6b134e 100644
|
||||
--- a/fs/bcachefs/btree_iter.h
|
||||
+++ b/fs/bcachefs/btree_iter.h
|
||||
@@ -350,6 +350,10 @@ static int btree_trans_restart_ip(struct btree_trans *trans, int err, unsigned l
|
||||
|
||||
trans->restarted = err;
|
||||
trans->last_restarted_ip = ip;
|
||||
+#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
+ darray_exit(&trans->last_restarted_trace);
|
||||
+ bch2_save_backtrace(&trans->last_restarted_trace, current, 0, GFP_NOWAIT);
|
||||
+#endif
|
||||
return -err;
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h
|
||||
index 4568a41fefaf..baab5288ecc9 100644
|
||||
--- a/fs/bcachefs/btree_types.h
|
||||
+++ b/fs/bcachefs/btree_types.h
|
||||
@@ -513,6 +513,9 @@ struct btree_trans {
|
||||
u64 last_begin_time;
|
||||
unsigned long last_begin_ip;
|
||||
unsigned long last_restarted_ip;
|
||||
+#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
+ bch_stacktrace last_restarted_trace;
|
||||
+#endif
|
||||
unsigned long last_unlock_ip;
|
||||
unsigned long srcu_lock_time;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,267 +0,0 @@
|
||||
From e398d6fb0f5aace9f5d181fab0b9dfb7c1025938 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 27 Oct 2024 19:32:40 -0400
|
||||
Subject: [PATCH 061/233] bcachefs:
|
||||
bch2_trans_verify_not_unlocked_or_in_restart()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fold two asserts into one.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 36 ++++++++++++++++-------------
|
||||
fs/bcachefs/btree_iter.h | 20 +++++-----------
|
||||
fs/bcachefs/btree_locking.h | 2 +-
|
||||
fs/bcachefs/btree_trans_commit.c | 9 +++-----
|
||||
fs/bcachefs/btree_update_interior.c | 3 +--
|
||||
fs/bcachefs/btree_update_interior.h | 2 +-
|
||||
6 files changed, 32 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index acf70aaf2fd2..1efc77fc9abf 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -327,7 +327,7 @@ static int bch2_btree_iter_verify_ret(struct btree_iter *iter, struct bkey_s_c k
|
||||
void bch2_assert_pos_locked(struct btree_trans *trans, enum btree_id id,
|
||||
struct bpos pos)
|
||||
{
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
struct btree_path *path;
|
||||
struct trans_for_each_path_inorder_iter iter;
|
||||
@@ -1265,7 +1265,7 @@ __bch2_btree_path_set_pos(struct btree_trans *trans,
|
||||
{
|
||||
int cmp = bpos_cmp(new_pos, trans->paths[path_idx].pos);
|
||||
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
EBUG_ON(!trans->paths[path_idx].ref);
|
||||
|
||||
trace_btree_path_set_pos(trans, trans->paths + path_idx, &new_pos);
|
||||
@@ -1425,7 +1425,7 @@ void __noreturn bch2_trans_restart_error(struct btree_trans *trans, u32 restart_
|
||||
(void *) trans->last_begin_ip);
|
||||
}
|
||||
|
||||
-void __noreturn bch2_trans_in_restart_error(struct btree_trans *trans)
|
||||
+static void __noreturn bch2_trans_in_restart_error(struct btree_trans *trans)
|
||||
{
|
||||
#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
struct printbuf buf = PRINTBUF;
|
||||
@@ -1440,10 +1440,16 @@ void __noreturn bch2_trans_in_restart_error(struct btree_trans *trans)
|
||||
#endif
|
||||
}
|
||||
|
||||
-void __noreturn bch2_trans_unlocked_error(struct btree_trans *trans)
|
||||
+void __noreturn bch2_trans_unlocked_or_in_restart_error(struct btree_trans *trans)
|
||||
{
|
||||
- panic("trans should be locked, unlocked by %pS\n",
|
||||
- (void *) trans->last_unlock_ip);
|
||||
+ if (trans->restarted)
|
||||
+ bch2_trans_in_restart_error(trans);
|
||||
+
|
||||
+ if (!trans->locked)
|
||||
+ panic("trans should be locked, unlocked by %pS\n",
|
||||
+ (void *) trans->last_unlock_ip);
|
||||
+
|
||||
+ BUG();
|
||||
}
|
||||
|
||||
noinline __cold
|
||||
@@ -1724,8 +1730,7 @@ btree_path_idx_t bch2_path_get(struct btree_trans *trans,
|
||||
struct trans_for_each_path_inorder_iter iter;
|
||||
btree_path_idx_t path_pos = 0, path_idx;
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
bch2_trans_verify_locks(trans);
|
||||
|
||||
btree_trans_sort_paths(trans);
|
||||
@@ -1877,7 +1882,7 @@ bch2_btree_iter_traverse(struct btree_iter *iter)
|
||||
struct btree_trans *trans = iter->trans;
|
||||
int ret;
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
iter->path = bch2_btree_path_set_pos(trans, iter->path,
|
||||
btree_iter_search_key(iter),
|
||||
@@ -1952,7 +1957,7 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
|
||||
int ret;
|
||||
|
||||
EBUG_ON(trans->paths[iter->path].cached);
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
bch2_btree_iter_verify(iter);
|
||||
|
||||
ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
|
||||
@@ -2161,8 +2166,7 @@ struct bkey_s_c btree_trans_peek_key_cache(struct btree_iter *iter, struct bpos
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
if ((iter->flags & BTREE_ITER_key_cache_fill) &&
|
||||
bpos_eq(iter->pos, pos))
|
||||
@@ -2302,7 +2306,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
|
||||
struct bpos iter_pos;
|
||||
int ret;
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bkey_eq(end, POS_MAX));
|
||||
|
||||
if (iter->update_path) {
|
||||
@@ -2475,7 +2479,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
|
||||
btree_path_idx_t saved_path = 0;
|
||||
int ret;
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
EBUG_ON(btree_iter_path(trans, iter)->cached ||
|
||||
btree_iter_path(trans, iter)->level);
|
||||
|
||||
@@ -2614,7 +2618,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
bch2_btree_iter_verify(iter);
|
||||
bch2_btree_iter_verify_entry_exit(iter);
|
||||
EBUG_ON(btree_iter_path(trans, iter)->level && (iter->flags & BTREE_ITER_with_key_cache));
|
||||
@@ -3136,7 +3140,7 @@ u32 bch2_trans_begin(struct btree_trans *trans)
|
||||
trans->notrace_relock_fail = false;
|
||||
}
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
return trans->restart_count;
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
|
||||
index 36899c6b134e..6b1c46e95432 100644
|
||||
--- a/fs/bcachefs/btree_iter.h
|
||||
+++ b/fs/bcachefs/btree_iter.h
|
||||
@@ -236,12 +236,12 @@ int __must_check bch2_btree_path_traverse_one(struct btree_trans *,
|
||||
btree_path_idx_t,
|
||||
unsigned, unsigned long);
|
||||
|
||||
-static inline void bch2_trans_verify_not_unlocked(struct btree_trans *);
|
||||
+static inline void bch2_trans_verify_not_unlocked_or_in_restart(struct btree_trans *);
|
||||
|
||||
static inline int __must_check bch2_btree_path_traverse(struct btree_trans *trans,
|
||||
btree_path_idx_t path, unsigned flags)
|
||||
{
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
if (trans->paths[path].uptodate < BTREE_ITER_NEED_RELOCK)
|
||||
return 0;
|
||||
@@ -326,20 +326,12 @@ static inline void bch2_trans_verify_not_restarted(struct btree_trans *trans,
|
||||
bch2_trans_restart_error(trans, restart_count);
|
||||
}
|
||||
|
||||
-void __noreturn bch2_trans_in_restart_error(struct btree_trans *);
|
||||
+void __noreturn bch2_trans_unlocked_or_in_restart_error(struct btree_trans *);
|
||||
|
||||
-static inline void bch2_trans_verify_not_in_restart(struct btree_trans *trans)
|
||||
+static inline void bch2_trans_verify_not_unlocked_or_in_restart(struct btree_trans *trans)
|
||||
{
|
||||
- if (trans->restarted)
|
||||
- bch2_trans_in_restart_error(trans);
|
||||
-}
|
||||
-
|
||||
-void __noreturn bch2_trans_unlocked_error(struct btree_trans *);
|
||||
-
|
||||
-static inline void bch2_trans_verify_not_unlocked(struct btree_trans *trans)
|
||||
-{
|
||||
- if (!trans->locked)
|
||||
- bch2_trans_unlocked_error(trans);
|
||||
+ if (trans->restarted || !trans->locked)
|
||||
+ bch2_trans_unlocked_or_in_restart_error(trans);
|
||||
}
|
||||
|
||||
__always_inline
|
||||
diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h
|
||||
index 7c07f9fa9add..ca4aeefd631e 100644
|
||||
--- a/fs/bcachefs/btree_locking.h
|
||||
+++ b/fs/bcachefs/btree_locking.h
|
||||
@@ -282,7 +282,7 @@ static inline int btree_node_lock(struct btree_trans *trans,
|
||||
int ret = 0;
|
||||
|
||||
EBUG_ON(level >= BTREE_MAX_DEPTH);
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
if (likely(six_trylock_type(&b->lock, type)) ||
|
||||
btree_node_lock_increment(trans, b, level, (enum btree_node_locked_type) type) ||
|
||||
diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c
|
||||
index 3aca746d08f6..cf313477567a 100644
|
||||
--- a/fs/bcachefs/btree_trans_commit.c
|
||||
+++ b/fs/bcachefs/btree_trans_commit.c
|
||||
@@ -619,8 +619,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
|
||||
unsigned u64s = 0;
|
||||
int ret = 0;
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
if (race_fault()) {
|
||||
trace_and_count(c, trans_restart_fault_inject, trans, trace_ip);
|
||||
@@ -1008,8 +1007,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
|
||||
struct bch_fs *c = trans->c;
|
||||
int ret = 0;
|
||||
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
if (!trans->nr_updates &&
|
||||
!trans->journal_entries_u64s)
|
||||
@@ -1070,8 +1068,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
|
||||
}
|
||||
retry:
|
||||
errored_at = NULL;
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
if (likely(!(flags & BCH_TRANS_COMMIT_no_journal_res)))
|
||||
memset(&trans->journal_res, 0, sizeof(trans->journal_res));
|
||||
memset(&trans->fs_usage_delta, 0, sizeof(trans->fs_usage_delta));
|
||||
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
|
||||
index 865c4724d550..c11babe31f54 100644
|
||||
--- a/fs/bcachefs/btree_update_interior.c
|
||||
+++ b/fs/bcachefs/btree_update_interior.c
|
||||
@@ -1960,8 +1960,7 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
|
||||
u64 start_time = local_clock();
|
||||
int ret = 0;
|
||||
|
||||
- bch2_trans_verify_not_in_restart(trans);
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
BUG_ON(!trans->paths[path].should_be_locked);
|
||||
BUG_ON(!btree_node_locked(&trans->paths[path], level));
|
||||
|
||||
diff --git a/fs/bcachefs/btree_update_interior.h b/fs/bcachefs/btree_update_interior.h
|
||||
index 10f400957f21..1c6cf3e2e6a9 100644
|
||||
--- a/fs/bcachefs/btree_update_interior.h
|
||||
+++ b/fs/bcachefs/btree_update_interior.h
|
||||
@@ -159,7 +159,7 @@ static inline int bch2_foreground_maybe_merge(struct btree_trans *trans,
|
||||
unsigned level,
|
||||
unsigned flags)
|
||||
{
|
||||
- bch2_trans_verify_not_unlocked(trans);
|
||||
+ bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
|
||||
return bch2_foreground_maybe_merge_sibling(trans, path, level, flags,
|
||||
btree_prev_sib) ?:
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,56 +0,0 @@
|
||||
From f97b3e7fd8f371eba3ae114eb8eb0dd3c6842771 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 25 Oct 2024 22:31:20 -0400
|
||||
Subject: [PATCH 062/233] bcachefs: Assert that we're not violating key cache
|
||||
coherency rules
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We're not allowed to have a dirty key in the key cache if the key
|
||||
doesn't exist at all in the btree - creation has to bypass the key
|
||||
cache, so that iteration over the btree can check if the key is present
|
||||
in the key cache.
|
||||
|
||||
Things break in subtle ways if cache coherency is broken, so this needs
|
||||
an assert.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_key_cache.c | 13 ++++++++++---
|
||||
1 file changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c
|
||||
index 244610b1d0b5..3bd40ea0fa3d 100644
|
||||
--- a/fs/bcachefs/btree_key_cache.c
|
||||
+++ b/fs/bcachefs/btree_key_cache.c
|
||||
@@ -424,8 +424,15 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
|
||||
!test_bit(JOURNAL_space_low, &c->journal.flags))
|
||||
commit_flags |= BCH_TRANS_COMMIT_no_journal_res;
|
||||
|
||||
- ret = bch2_btree_iter_traverse(&b_iter) ?:
|
||||
- bch2_trans_update(trans, &b_iter, ck->k,
|
||||
+ struct bkey_s_c btree_k = bch2_btree_iter_peek_slot(&b_iter);
|
||||
+ ret = bkey_err(btree_k);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ /* * Check that we're not violating cache coherency rules: */
|
||||
+ BUG_ON(bkey_deleted(btree_k.k));
|
||||
+
|
||||
+ ret = bch2_trans_update(trans, &b_iter, ck->k,
|
||||
BTREE_UPDATE_key_cache_reclaim|
|
||||
BTREE_UPDATE_internal_snapshot_node|
|
||||
BTREE_TRIGGER_norun) ?:
|
||||
@@ -433,7 +440,7 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
|
||||
BCH_TRANS_COMMIT_no_check_rw|
|
||||
BCH_TRANS_COMMIT_no_enospc|
|
||||
commit_flags);
|
||||
-
|
||||
+err:
|
||||
bch2_fs_fatal_err_on(ret &&
|
||||
!bch2_err_matches(ret, BCH_ERR_transaction_restart) &&
|
||||
!bch2_err_matches(ret, BCH_ERR_journal_reclaim_would_deadlock) &&
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,794 +0,0 @@
|
||||
From 95918915a6d31158bbec7a2abd3eeffed4decab3 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 24 Oct 2024 18:39:59 -0400
|
||||
Subject: [PATCH 063/233] bcachefs: Rename btree_iter_peek_upto() ->
|
||||
btree_iter_peek_max()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We'll be introducing btree_iter_peek_prev_min(), so rename for
|
||||
consistency.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_background.c | 6 +++---
|
||||
fs/bcachefs/btree_gc.c | 2 +-
|
||||
fs/bcachefs/btree_iter.c | 10 ++++-----
|
||||
fs/bcachefs/btree_iter.h | 36 ++++++++++++++++----------------
|
||||
fs/bcachefs/btree_journal_iter.c | 4 ++--
|
||||
fs/bcachefs/btree_journal_iter.h | 2 +-
|
||||
fs/bcachefs/btree_update.c | 6 +++---
|
||||
fs/bcachefs/dirent.c | 4 ++--
|
||||
fs/bcachefs/ec.c | 2 +-
|
||||
fs/bcachefs/extent_update.c | 2 +-
|
||||
fs/bcachefs/fs-io-pagecache.c | 2 +-
|
||||
fs/bcachefs/fs-io.c | 8 +++----
|
||||
fs/bcachefs/fs.c | 2 +-
|
||||
fs/bcachefs/fsck.c | 8 +++----
|
||||
fs/bcachefs/inode.c | 6 +++---
|
||||
fs/bcachefs/io_misc.c | 6 +++---
|
||||
fs/bcachefs/io_write.c | 4 ++--
|
||||
fs/bcachefs/movinggc.c | 2 +-
|
||||
fs/bcachefs/reflink.c | 2 +-
|
||||
fs/bcachefs/str_hash.h | 6 +++---
|
||||
fs/bcachefs/subvolume.h | 12 +++++------
|
||||
fs/bcachefs/tests.c | 26 +++++++++++------------
|
||||
fs/bcachefs/xattr.c | 2 +-
|
||||
23 files changed, 80 insertions(+), 80 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
|
||||
index c84a91572a1d..af791f4dab99 100644
|
||||
--- a/fs/bcachefs/alloc_background.c
|
||||
+++ b/fs/bcachefs/alloc_background.c
|
||||
@@ -1045,7 +1045,7 @@ static struct bkey_s_c bch2_get_key_or_hole(struct btree_iter *iter, struct bpos
|
||||
* btree node min/max is a closed interval, upto takes a half
|
||||
* open interval:
|
||||
*/
|
||||
- k = bch2_btree_iter_peek_upto(&iter2, end);
|
||||
+ k = bch2_btree_iter_peek_max(&iter2, end);
|
||||
next = iter2.pos;
|
||||
bch2_trans_iter_exit(iter->trans, &iter2);
|
||||
|
||||
@@ -1886,7 +1886,7 @@ static void bch2_do_discards_work(struct work_struct *work)
|
||||
* successful commit:
|
||||
*/
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter,
|
||||
+ for_each_btree_key_max(trans, iter,
|
||||
BTREE_ID_need_discard,
|
||||
POS(ca->dev_idx, 0),
|
||||
POS(ca->dev_idx, U64_MAX), 0, k,
|
||||
@@ -2101,7 +2101,7 @@ static struct bkey_s_c next_lru_key(struct btree_trans *trans, struct btree_iter
|
||||
{
|
||||
struct bkey_s_c k;
|
||||
again:
|
||||
- k = bch2_btree_iter_peek_upto(iter, lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX));
|
||||
+ k = bch2_btree_iter_peek_max(iter, lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX));
|
||||
if (!k.k && !*wrapped) {
|
||||
bch2_btree_iter_set_pos(iter, lru_pos(ca->dev_idx, 0, 0));
|
||||
*wrapped = true;
|
||||
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
|
||||
index 833d743dee0c..e45cf32a6403 100644
|
||||
--- a/fs/bcachefs/btree_gc.c
|
||||
+++ b/fs/bcachefs/btree_gc.c
|
||||
@@ -904,7 +904,7 @@ static int bch2_gc_alloc_done(struct bch_fs *c)
|
||||
|
||||
for_each_member_device(c, ca) {
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto_commit(trans, iter, BTREE_ID_alloc,
|
||||
+ for_each_btree_key_max_commit(trans, iter, BTREE_ID_alloc,
|
||||
POS(ca->dev_idx, ca->mi.first_bucket),
|
||||
POS(ca->dev_idx, ca->mi.nbuckets - 1),
|
||||
BTREE_ITER_slots|BTREE_ITER_prefetch, k,
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index 1efc77fc9abf..21cadc98bdae 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -2113,7 +2113,7 @@ static struct bkey_i *bch2_btree_journal_peek(struct btree_trans *trans,
|
||||
{
|
||||
struct btree_path *path = btree_iter_path(trans, iter);
|
||||
|
||||
- return bch2_journal_keys_peek_upto(trans->c, iter->btree_id,
|
||||
+ return bch2_journal_keys_peek_max(trans->c, iter->btree_id,
|
||||
path->level,
|
||||
path->pos,
|
||||
end_pos,
|
||||
@@ -2291,14 +2291,14 @@ static struct bkey_s_c __bch2_btree_iter_peek(struct btree_iter *iter, struct bp
|
||||
}
|
||||
|
||||
/**
|
||||
- * bch2_btree_iter_peek_upto() - returns first key greater than or equal to
|
||||
+ * bch2_btree_iter_peek_max() - returns first key greater than or equal to
|
||||
* iterator's current position
|
||||
* @iter: iterator to peek from
|
||||
* @end: search limit: returns keys less than or equal to @end
|
||||
*
|
||||
* Returns: key if found, or an error extractable with bkey_err().
|
||||
*/
|
||||
-struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos end)
|
||||
+struct bkey_s_c bch2_btree_iter_peek_max(struct btree_iter *iter, struct bpos end)
|
||||
{
|
||||
struct btree_trans *trans = iter->trans;
|
||||
struct bpos search_key = btree_iter_search_key(iter);
|
||||
@@ -2682,7 +2682,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
|
||||
struct btree_iter iter2;
|
||||
|
||||
bch2_trans_copy_iter(&iter2, iter);
|
||||
- k = bch2_btree_iter_peek_upto(&iter2, end);
|
||||
+ k = bch2_btree_iter_peek_max(&iter2, end);
|
||||
|
||||
if (k.k && !bkey_err(k)) {
|
||||
swap(iter->key_cache_path, iter2.key_cache_path);
|
||||
@@ -2693,7 +2693,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
|
||||
} else {
|
||||
struct bpos pos = iter->pos;
|
||||
|
||||
- k = bch2_btree_iter_peek_upto(iter, end);
|
||||
+ k = bch2_btree_iter_peek_max(iter, end);
|
||||
if (unlikely(bkey_err(k)))
|
||||
bch2_btree_iter_set_pos(iter, pos);
|
||||
else
|
||||
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
|
||||
index 6b1c46e95432..cd9022ce15a5 100644
|
||||
--- a/fs/bcachefs/btree_iter.h
|
||||
+++ b/fs/bcachefs/btree_iter.h
|
||||
@@ -381,12 +381,12 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *);
|
||||
struct btree *bch2_btree_iter_peek_node_and_restart(struct btree_iter *);
|
||||
struct btree *bch2_btree_iter_next_node(struct btree_iter *);
|
||||
|
||||
-struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *, struct bpos);
|
||||
+struct bkey_s_c bch2_btree_iter_peek_max(struct btree_iter *, struct bpos);
|
||||
struct bkey_s_c bch2_btree_iter_next(struct btree_iter *);
|
||||
|
||||
static inline struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter)
|
||||
{
|
||||
- return bch2_btree_iter_peek_upto(iter, SPOS_MAX);
|
||||
+ return bch2_btree_iter_peek_max(iter, SPOS_MAX);
|
||||
}
|
||||
|
||||
struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *);
|
||||
@@ -672,12 +672,12 @@ static inline struct bkey_s_c bch2_btree_iter_peek_type(struct btree_iter *iter,
|
||||
bch2_btree_iter_peek(iter);
|
||||
}
|
||||
|
||||
-static inline struct bkey_s_c bch2_btree_iter_peek_upto_type(struct btree_iter *iter,
|
||||
+static inline struct bkey_s_c bch2_btree_iter_peek_max_type(struct btree_iter *iter,
|
||||
struct bpos end,
|
||||
unsigned flags)
|
||||
{
|
||||
if (!(flags & BTREE_ITER_slots))
|
||||
- return bch2_btree_iter_peek_upto(iter, end);
|
||||
+ return bch2_btree_iter_peek_max(iter, end);
|
||||
|
||||
if (bkey_gt(iter->pos, end))
|
||||
return bkey_s_c_null;
|
||||
@@ -741,7 +741,7 @@ transaction_restart: \
|
||||
_ret2 ?: trans_was_restarted(_trans, _restart_count); \
|
||||
})
|
||||
|
||||
-#define for_each_btree_key_upto_continue(_trans, _iter, \
|
||||
+#define for_each_btree_key_max_continue(_trans, _iter, \
|
||||
_end, _flags, _k, _do) \
|
||||
({ \
|
||||
struct bkey_s_c _k; \
|
||||
@@ -749,7 +749,7 @@ transaction_restart: \
|
||||
\
|
||||
do { \
|
||||
_ret3 = lockrestart_do(_trans, ({ \
|
||||
- (_k) = bch2_btree_iter_peek_upto_type(&(_iter), \
|
||||
+ (_k) = bch2_btree_iter_peek_max_type(&(_iter), \
|
||||
_end, (_flags)); \
|
||||
if (!(_k).k) \
|
||||
break; \
|
||||
@@ -763,9 +763,9 @@ transaction_restart: \
|
||||
})
|
||||
|
||||
#define for_each_btree_key_continue(_trans, _iter, _flags, _k, _do) \
|
||||
- for_each_btree_key_upto_continue(_trans, _iter, SPOS_MAX, _flags, _k, _do)
|
||||
+ for_each_btree_key_max_continue(_trans, _iter, SPOS_MAX, _flags, _k, _do)
|
||||
|
||||
-#define for_each_btree_key_upto(_trans, _iter, _btree_id, \
|
||||
+#define for_each_btree_key_max(_trans, _iter, _btree_id, \
|
||||
_start, _end, _flags, _k, _do) \
|
||||
({ \
|
||||
bch2_trans_begin(trans); \
|
||||
@@ -774,12 +774,12 @@ transaction_restart: \
|
||||
bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
|
||||
(_start), (_flags)); \
|
||||
\
|
||||
- for_each_btree_key_upto_continue(_trans, _iter, _end, _flags, _k, _do);\
|
||||
+ for_each_btree_key_max_continue(_trans, _iter, _end, _flags, _k, _do);\
|
||||
})
|
||||
|
||||
#define for_each_btree_key(_trans, _iter, _btree_id, \
|
||||
_start, _flags, _k, _do) \
|
||||
- for_each_btree_key_upto(_trans, _iter, _btree_id, _start, \
|
||||
+ for_each_btree_key_max(_trans, _iter, _btree_id, _start, \
|
||||
SPOS_MAX, _flags, _k, _do)
|
||||
|
||||
#define for_each_btree_key_reverse(_trans, _iter, _btree_id, \
|
||||
@@ -823,33 +823,33 @@ transaction_restart: \
|
||||
(_do) ?: bch2_trans_commit(_trans, (_disk_res),\
|
||||
(_journal_seq), (_commit_flags)))
|
||||
|
||||
-#define for_each_btree_key_upto_commit(_trans, _iter, _btree_id, \
|
||||
+#define for_each_btree_key_max_commit(_trans, _iter, _btree_id, \
|
||||
_start, _end, _iter_flags, _k, \
|
||||
_disk_res, _journal_seq, _commit_flags,\
|
||||
_do) \
|
||||
- for_each_btree_key_upto(_trans, _iter, _btree_id, _start, _end, _iter_flags, _k,\
|
||||
+ for_each_btree_key_max(_trans, _iter, _btree_id, _start, _end, _iter_flags, _k,\
|
||||
(_do) ?: bch2_trans_commit(_trans, (_disk_res),\
|
||||
(_journal_seq), (_commit_flags)))
|
||||
|
||||
struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *);
|
||||
|
||||
-#define for_each_btree_key_upto_norestart(_trans, _iter, _btree_id, \
|
||||
+#define for_each_btree_key_max_norestart(_trans, _iter, _btree_id, \
|
||||
_start, _end, _flags, _k, _ret) \
|
||||
for (bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
|
||||
(_start), (_flags)); \
|
||||
- (_k) = bch2_btree_iter_peek_upto_type(&(_iter), _end, _flags),\
|
||||
+ (_k) = bch2_btree_iter_peek_max_type(&(_iter), _end, _flags),\
|
||||
!((_ret) = bkey_err(_k)) && (_k).k; \
|
||||
bch2_btree_iter_advance(&(_iter)))
|
||||
|
||||
-#define for_each_btree_key_upto_continue_norestart(_iter, _end, _flags, _k, _ret)\
|
||||
+#define for_each_btree_key_max_continue_norestart(_iter, _end, _flags, _k, _ret)\
|
||||
for (; \
|
||||
- (_k) = bch2_btree_iter_peek_upto_type(&(_iter), _end, _flags), \
|
||||
+ (_k) = bch2_btree_iter_peek_max_type(&(_iter), _end, _flags), \
|
||||
!((_ret) = bkey_err(_k)) && (_k).k; \
|
||||
bch2_btree_iter_advance(&(_iter)))
|
||||
|
||||
#define for_each_btree_key_norestart(_trans, _iter, _btree_id, \
|
||||
_start, _flags, _k, _ret) \
|
||||
- for_each_btree_key_upto_norestart(_trans, _iter, _btree_id, _start,\
|
||||
+ for_each_btree_key_max_norestart(_trans, _iter, _btree_id, _start,\
|
||||
SPOS_MAX, _flags, _k, _ret)
|
||||
|
||||
#define for_each_btree_key_reverse_norestart(_trans, _iter, _btree_id, \
|
||||
@@ -861,7 +861,7 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *);
|
||||
bch2_btree_iter_rewind(&(_iter)))
|
||||
|
||||
#define for_each_btree_key_continue_norestart(_iter, _flags, _k, _ret) \
|
||||
- for_each_btree_key_upto_continue_norestart(_iter, SPOS_MAX, _flags, _k, _ret)
|
||||
+ for_each_btree_key_max_continue_norestart(_iter, SPOS_MAX, _flags, _k, _ret)
|
||||
|
||||
/*
|
||||
* This should not be used in a fastpath, without first trying _do in
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.c b/fs/bcachefs/btree_journal_iter.c
|
||||
index 924b5e3a4390..c9dee4b4627a 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.c
|
||||
+++ b/fs/bcachefs/btree_journal_iter.c
|
||||
@@ -61,7 +61,7 @@ static size_t bch2_journal_key_search(struct journal_keys *keys,
|
||||
}
|
||||
|
||||
/* Returns first non-overwritten key >= search key: */
|
||||
-struct bkey_i *bch2_journal_keys_peek_upto(struct bch_fs *c, enum btree_id btree_id,
|
||||
+struct bkey_i *bch2_journal_keys_peek_max(struct bch_fs *c, enum btree_id btree_id,
|
||||
unsigned level, struct bpos pos,
|
||||
struct bpos end_pos, size_t *idx)
|
||||
{
|
||||
@@ -112,7 +112,7 @@ struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *c, enum btree_id btree
|
||||
{
|
||||
size_t idx = 0;
|
||||
|
||||
- return bch2_journal_keys_peek_upto(c, btree_id, level, pos, pos, &idx);
|
||||
+ return bch2_journal_keys_peek_max(c, btree_id, level, pos, pos, &idx);
|
||||
}
|
||||
|
||||
static void journal_iter_verify(struct journal_iter *iter)
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.h b/fs/bcachefs/btree_journal_iter.h
|
||||
index 1653de9d609b..754939f604d5 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.h
|
||||
+++ b/fs/bcachefs/btree_journal_iter.h
|
||||
@@ -43,7 +43,7 @@ static inline int journal_key_cmp(const struct journal_key *l, const struct jour
|
||||
return __journal_key_cmp(l->btree_id, l->level, l->k->k.p, r);
|
||||
}
|
||||
|
||||
-struct bkey_i *bch2_journal_keys_peek_upto(struct bch_fs *, enum btree_id,
|
||||
+struct bkey_i *bch2_journal_keys_peek_max(struct bch_fs *, enum btree_id,
|
||||
unsigned, struct bpos, struct bpos, size_t *);
|
||||
struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *, enum btree_id,
|
||||
unsigned, struct bpos);
|
||||
diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c
|
||||
index a9a29fba4902..6afd77c68411 100644
|
||||
--- a/fs/bcachefs/btree_update.c
|
||||
+++ b/fs/bcachefs/btree_update.c
|
||||
@@ -296,7 +296,7 @@ static int bch2_trans_update_extent(struct btree_trans *trans,
|
||||
BTREE_ITER_intent|
|
||||
BTREE_ITER_with_updates|
|
||||
BTREE_ITER_not_extents);
|
||||
- k = bch2_btree_iter_peek_upto(&iter, POS(insert->k.p.inode, U64_MAX));
|
||||
+ k = bch2_btree_iter_peek_max(&iter, POS(insert->k.p.inode, U64_MAX));
|
||||
if ((ret = bkey_err(k)))
|
||||
goto err;
|
||||
if (!k.k)
|
||||
@@ -323,7 +323,7 @@ static int bch2_trans_update_extent(struct btree_trans *trans,
|
||||
goto out;
|
||||
next:
|
||||
bch2_btree_iter_advance(&iter);
|
||||
- k = bch2_btree_iter_peek_upto(&iter, POS(insert->k.p.inode, U64_MAX));
|
||||
+ k = bch2_btree_iter_peek_max(&iter, POS(insert->k.p.inode, U64_MAX));
|
||||
if ((ret = bkey_err(k)))
|
||||
goto err;
|
||||
if (!k.k)
|
||||
@@ -721,7 +721,7 @@ int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id,
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_iter_init(trans, &iter, id, start, BTREE_ITER_intent);
|
||||
- while ((k = bch2_btree_iter_peek_upto(&iter, end)).k) {
|
||||
+ while ((k = bch2_btree_iter_peek_max(&iter, end)).k) {
|
||||
struct disk_reservation disk_res =
|
||||
bch2_disk_reservation_init(trans->c, 0);
|
||||
struct bkey_i delete;
|
||||
diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c
|
||||
index faffc98d5605..4c22f78b0484 100644
|
||||
--- a/fs/bcachefs/dirent.c
|
||||
+++ b/fs/bcachefs/dirent.c
|
||||
@@ -500,7 +500,7 @@ int bch2_empty_dir_snapshot(struct btree_trans *trans, u64 dir, u32 subvol, u32
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
- for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_dirents,
|
||||
+ for_each_btree_key_max_norestart(trans, iter, BTREE_ID_dirents,
|
||||
SPOS(dir, 0, snapshot),
|
||||
POS(dir, U64_MAX), 0, k, ret)
|
||||
if (k.k->type == KEY_TYPE_dirent) {
|
||||
@@ -549,7 +549,7 @@ int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
|
||||
bch2_bkey_buf_init(&sk);
|
||||
|
||||
int ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_in_subvolume_upto(trans, iter, BTREE_ID_dirents,
|
||||
+ for_each_btree_key_in_subvolume_max(trans, iter, BTREE_ID_dirents,
|
||||
POS(inum.inum, ctx->pos),
|
||||
POS(inum.inum, U64_MAX),
|
||||
inum.subvol, 0, k, ({
|
||||
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
|
||||
index 015107e241cc..d6560bccd87c 100644
|
||||
--- a/fs/bcachefs/ec.c
|
||||
+++ b/fs/bcachefs/ec.c
|
||||
@@ -2308,7 +2308,7 @@ static int bch2_invalidate_stripe_to_dev(struct btree_trans *trans, struct bkey_
|
||||
int bch2_dev_remove_stripes(struct bch_fs *c, unsigned dev_idx)
|
||||
{
|
||||
return bch2_trans_run(c,
|
||||
- for_each_btree_key_upto_commit(trans, iter,
|
||||
+ for_each_btree_key_max_commit(trans, iter,
|
||||
BTREE_ID_alloc, POS(dev_idx, 0), POS(dev_idx, U64_MAX),
|
||||
BTREE_ITER_intent, k,
|
||||
NULL, NULL, 0, ({
|
||||
diff --git a/fs/bcachefs/extent_update.c b/fs/bcachefs/extent_update.c
|
||||
index 5f4fecb358da..45c87c019f6b 100644
|
||||
--- a/fs/bcachefs/extent_update.c
|
||||
+++ b/fs/bcachefs/extent_update.c
|
||||
@@ -128,7 +128,7 @@ int bch2_extent_atomic_end(struct btree_trans *trans,
|
||||
|
||||
bch2_trans_copy_iter(©, iter);
|
||||
|
||||
- for_each_btree_key_upto_continue_norestart(copy, insert->k.p, 0, k, ret) {
|
||||
+ for_each_btree_key_max_continue_norestart(copy, insert->k.p, 0, k, ret) {
|
||||
unsigned offset = 0;
|
||||
|
||||
if (bkey_gt(bkey_start_pos(&insert->k), bkey_start_pos(k.k)))
|
||||
diff --git a/fs/bcachefs/fs-io-pagecache.c b/fs/bcachefs/fs-io-pagecache.c
|
||||
index 1d4910ea0f1d..51a499c5a7b6 100644
|
||||
--- a/fs/bcachefs/fs-io-pagecache.c
|
||||
+++ b/fs/bcachefs/fs-io-pagecache.c
|
||||
@@ -199,7 +199,7 @@ int bch2_folio_set(struct bch_fs *c, subvol_inum inum,
|
||||
unsigned folio_idx = 0;
|
||||
|
||||
return bch2_trans_run(c,
|
||||
- for_each_btree_key_in_subvolume_upto(trans, iter, BTREE_ID_extents,
|
||||
+ for_each_btree_key_in_subvolume_max(trans, iter, BTREE_ID_extents,
|
||||
POS(inum.inum, offset),
|
||||
POS(inum.inum, U64_MAX),
|
||||
inum.subvol, BTREE_ITER_slots, k, ({
|
||||
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
|
||||
index 2456c41b215e..0021db191480 100644
|
||||
--- a/fs/bcachefs/fs-io.c
|
||||
+++ b/fs/bcachefs/fs-io.c
|
||||
@@ -222,7 +222,7 @@ static inline int range_has_data(struct bch_fs *c, u32 subvol,
|
||||
struct bpos end)
|
||||
{
|
||||
return bch2_trans_run(c,
|
||||
- for_each_btree_key_in_subvolume_upto(trans, iter, BTREE_ID_extents, start, end,
|
||||
+ for_each_btree_key_in_subvolume_max(trans, iter, BTREE_ID_extents, start, end,
|
||||
subvol, 0, k, ({
|
||||
bkey_extent_is_data(k.k) && !bkey_extent_is_unwritten(k);
|
||||
})));
|
||||
@@ -806,7 +806,7 @@ static int quota_reserve_range(struct bch_inode_info *inode,
|
||||
u64 sectors = end - start;
|
||||
|
||||
int ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_in_subvolume_upto(trans, iter,
|
||||
+ for_each_btree_key_in_subvolume_max(trans, iter,
|
||||
BTREE_ID_extents,
|
||||
POS(inode->v.i_ino, start),
|
||||
POS(inode->v.i_ino, end - 1),
|
||||
@@ -922,7 +922,7 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
|
||||
return -ENXIO;
|
||||
|
||||
int ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_in_subvolume_upto(trans, iter, BTREE_ID_extents,
|
||||
+ for_each_btree_key_in_subvolume_max(trans, iter, BTREE_ID_extents,
|
||||
POS(inode->v.i_ino, offset >> 9),
|
||||
POS(inode->v.i_ino, U64_MAX),
|
||||
inum.subvol, 0, k, ({
|
||||
@@ -958,7 +958,7 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
|
||||
return -ENXIO;
|
||||
|
||||
int ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_in_subvolume_upto(trans, iter, BTREE_ID_extents,
|
||||
+ for_each_btree_key_in_subvolume_max(trans, iter, BTREE_ID_extents,
|
||||
POS(inode->v.i_ino, offset >> 9),
|
||||
POS(inode->v.i_ino, U64_MAX),
|
||||
inum.subvol, BTREE_ITER_slots, k, ({
|
||||
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
|
||||
index e0ffe4648bb8..91fce04272a1 100644
|
||||
--- a/fs/bcachefs/fs.c
|
||||
+++ b/fs/bcachefs/fs.c
|
||||
@@ -1294,7 +1294,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
|
||||
|
||||
bch2_btree_iter_set_snapshot(&iter, snapshot);
|
||||
|
||||
- k = bch2_btree_iter_peek_upto(&iter, end);
|
||||
+ k = bch2_btree_iter_peek_max(&iter, end);
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
continue;
|
||||
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
|
||||
index c96025b8b65d..2229f0dcc860 100644
|
||||
--- a/fs/bcachefs/fsck.c
|
||||
+++ b/fs/bcachefs/fsck.c
|
||||
@@ -73,7 +73,7 @@ static s64 bch2_count_inode_sectors(struct btree_trans *trans, u64 inum,
|
||||
{
|
||||
u64 sectors = 0;
|
||||
|
||||
- int ret = for_each_btree_key_upto(trans, iter, BTREE_ID_extents,
|
||||
+ int ret = for_each_btree_key_max(trans, iter, BTREE_ID_extents,
|
||||
SPOS(inum, 0, snapshot),
|
||||
POS(inum, U64_MAX),
|
||||
0, k, ({
|
||||
@@ -90,7 +90,7 @@ static s64 bch2_count_subdirs(struct btree_trans *trans, u64 inum,
|
||||
{
|
||||
u64 subdirs = 0;
|
||||
|
||||
- int ret = for_each_btree_key_upto(trans, iter, BTREE_ID_dirents,
|
||||
+ int ret = for_each_btree_key_max(trans, iter, BTREE_ID_dirents,
|
||||
SPOS(inum, 0, snapshot),
|
||||
POS(inum, U64_MAX),
|
||||
0, k, ({
|
||||
@@ -1751,7 +1751,7 @@ static int overlapping_extents_found(struct btree_trans *trans,
|
||||
bch2_trans_iter_init(trans, &iter1, btree, pos1,
|
||||
BTREE_ITER_all_snapshots|
|
||||
BTREE_ITER_not_extents);
|
||||
- k1 = bch2_btree_iter_peek_upto(&iter1, POS(pos1.inode, U64_MAX));
|
||||
+ k1 = bch2_btree_iter_peek_max(&iter1, POS(pos1.inode, U64_MAX));
|
||||
ret = bkey_err(k1);
|
||||
if (ret)
|
||||
goto err;
|
||||
@@ -1776,7 +1776,7 @@ static int overlapping_extents_found(struct btree_trans *trans,
|
||||
while (1) {
|
||||
bch2_btree_iter_advance(&iter2);
|
||||
|
||||
- k2 = bch2_btree_iter_peek_upto(&iter2, POS(pos1.inode, U64_MAX));
|
||||
+ k2 = bch2_btree_iter_peek_max(&iter2, POS(pos1.inode, U64_MAX));
|
||||
ret = bkey_err(k2);
|
||||
if (ret)
|
||||
goto err;
|
||||
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
|
||||
index 5dd9d3edae77..5c603ab66be0 100644
|
||||
--- a/fs/bcachefs/inode.c
|
||||
+++ b/fs/bcachefs/inode.c
|
||||
@@ -618,7 +618,7 @@ bch2_bkey_get_iter_snapshot_parent(struct btree_trans *trans, struct btree_iter
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
|
||||
- for_each_btree_key_upto_norestart(trans, *iter, btree,
|
||||
+ for_each_btree_key_max_norestart(trans, *iter, btree,
|
||||
bpos_successor(pos),
|
||||
SPOS(pos.inode, pos.offset, U32_MAX),
|
||||
flags|BTREE_ITER_all_snapshots, k, ret)
|
||||
@@ -653,7 +653,7 @@ int __bch2_inode_has_child_snapshots(struct btree_trans *trans, struct bpos pos)
|
||||
struct bkey_s_c k;
|
||||
int ret = 0;
|
||||
|
||||
- for_each_btree_key_upto_norestart(trans, iter,
|
||||
+ for_each_btree_key_max_norestart(trans, iter,
|
||||
BTREE_ID_inodes, POS(0, pos.offset), bpos_predecessor(pos),
|
||||
BTREE_ITER_all_snapshots|
|
||||
BTREE_ITER_with_updates, k, ret)
|
||||
@@ -967,7 +967,7 @@ static int bch2_inode_delete_keys(struct btree_trans *trans,
|
||||
|
||||
bch2_btree_iter_set_snapshot(&iter, snapshot);
|
||||
|
||||
- k = bch2_btree_iter_peek_upto(&iter, end);
|
||||
+ k = bch2_btree_iter_peek_max(&iter, end);
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
goto err;
|
||||
diff --git a/fs/bcachefs/io_misc.c b/fs/bcachefs/io_misc.c
|
||||
index e2acf21ac9b0..ff661a072000 100644
|
||||
--- a/fs/bcachefs/io_misc.c
|
||||
+++ b/fs/bcachefs/io_misc.c
|
||||
@@ -164,9 +164,9 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
|
||||
bch2_btree_iter_set_snapshot(iter, snapshot);
|
||||
|
||||
/*
|
||||
- * peek_upto() doesn't have ideal semantics for extents:
|
||||
+ * peek_max() doesn't have ideal semantics for extents:
|
||||
*/
|
||||
- k = bch2_btree_iter_peek_upto(iter, end_pos);
|
||||
+ k = bch2_btree_iter_peek_max(iter, end_pos);
|
||||
if (!k.k)
|
||||
break;
|
||||
|
||||
@@ -427,7 +427,7 @@ case LOGGED_OP_FINSERT_shift_extents:
|
||||
|
||||
k = insert
|
||||
? bch2_btree_iter_peek_prev(&iter)
|
||||
- : bch2_btree_iter_peek_upto(&iter, POS(inum.inum, U64_MAX));
|
||||
+ : bch2_btree_iter_peek_max(&iter, POS(inum.inum, U64_MAX));
|
||||
if ((ret = bkey_err(k)))
|
||||
goto btree_err;
|
||||
|
||||
diff --git a/fs/bcachefs/io_write.c b/fs/bcachefs/io_write.c
|
||||
index f2f69e5e0910..f11e11279f01 100644
|
||||
--- a/fs/bcachefs/io_write.c
|
||||
+++ b/fs/bcachefs/io_write.c
|
||||
@@ -164,7 +164,7 @@ int bch2_sum_sector_overwrites(struct btree_trans *trans,
|
||||
|
||||
bch2_trans_copy_iter(&iter, extent_iter);
|
||||
|
||||
- for_each_btree_key_upto_continue_norestart(iter,
|
||||
+ for_each_btree_key_max_continue_norestart(iter,
|
||||
new->k.p, BTREE_ITER_slots, old, ret) {
|
||||
s64 sectors = min(new->k.p.offset, old.k->p.offset) -
|
||||
max(bkey_start_offset(&new->k),
|
||||
@@ -1165,7 +1165,7 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
|
||||
for_each_keylist_key(&op->insert_keys, orig) {
|
||||
- int ret = for_each_btree_key_upto_commit(trans, iter, BTREE_ID_extents,
|
||||
+ int ret = for_each_btree_key_max_commit(trans, iter, BTREE_ID_extents,
|
||||
bkey_start_pos(&orig->k), orig->k.p,
|
||||
BTREE_ITER_intent, k,
|
||||
NULL, NULL, BCH_TRANS_COMMIT_no_enospc, ({
|
||||
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
|
||||
index 725292d69fd6..85c361e78ba5 100644
|
||||
--- a/fs/bcachefs/movinggc.c
|
||||
+++ b/fs/bcachefs/movinggc.c
|
||||
@@ -167,7 +167,7 @@ static int bch2_copygc_get_buckets(struct moving_context *ctxt,
|
||||
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
- ret = for_each_btree_key_upto(trans, iter, BTREE_ID_lru,
|
||||
+ ret = for_each_btree_key_max(trans, iter, BTREE_ID_lru,
|
||||
lru_pos(BCH_LRU_FRAGMENTATION_START, 0, 0),
|
||||
lru_pos(BCH_LRU_FRAGMENTATION_START, U64_MAX, LRU_TIME_MAX),
|
||||
0, k, ({
|
||||
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
|
||||
index 8a36ebd9dd9c..96cf50f4705d 100644
|
||||
--- a/fs/bcachefs/reflink.c
|
||||
+++ b/fs/bcachefs/reflink.c
|
||||
@@ -409,7 +409,7 @@ static struct bkey_s_c get_next_src(struct btree_iter *iter, struct bpos end)
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
- for_each_btree_key_upto_continue_norestart(*iter, end, 0, k, ret) {
|
||||
+ for_each_btree_key_max_continue_norestart(*iter, end, 0, k, ret) {
|
||||
if (bkey_extent_is_unwritten(k))
|
||||
continue;
|
||||
|
||||
diff --git a/fs/bcachefs/str_hash.h b/fs/bcachefs/str_hash.h
|
||||
index ec2b1feea520..00c785055d22 100644
|
||||
--- a/fs/bcachefs/str_hash.h
|
||||
+++ b/fs/bcachefs/str_hash.h
|
||||
@@ -160,7 +160,7 @@ bch2_hash_lookup_in_snapshot(struct btree_trans *trans,
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
- for_each_btree_key_upto_norestart(trans, *iter, desc.btree_id,
|
||||
+ for_each_btree_key_max_norestart(trans, *iter, desc.btree_id,
|
||||
SPOS(inum.inum, desc.hash_key(info, key), snapshot),
|
||||
POS(inum.inum, U64_MAX),
|
||||
BTREE_ITER_slots|flags, k, ret) {
|
||||
@@ -210,7 +210,7 @@ bch2_hash_hole(struct btree_trans *trans,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- for_each_btree_key_upto_norestart(trans, *iter, desc.btree_id,
|
||||
+ for_each_btree_key_max_norestart(trans, *iter, desc.btree_id,
|
||||
SPOS(inum.inum, desc.hash_key(info, key), snapshot),
|
||||
POS(inum.inum, U64_MAX),
|
||||
BTREE_ITER_slots|BTREE_ITER_intent, k, ret)
|
||||
@@ -265,7 +265,7 @@ struct bkey_s_c bch2_hash_set_or_get_in_snapshot(struct btree_trans *trans,
|
||||
bool found = false;
|
||||
int ret;
|
||||
|
||||
- for_each_btree_key_upto_norestart(trans, *iter, desc.btree_id,
|
||||
+ for_each_btree_key_max_norestart(trans, *iter, desc.btree_id,
|
||||
SPOS(insert->k.p.inode,
|
||||
desc.hash_bkey(info, bkey_i_to_s_c(insert)),
|
||||
snapshot),
|
||||
diff --git a/fs/bcachefs/subvolume.h b/fs/bcachefs/subvolume.h
|
||||
index f897d106e142..07b23dc08614 100644
|
||||
--- a/fs/bcachefs/subvolume.h
|
||||
+++ b/fs/bcachefs/subvolume.h
|
||||
@@ -34,7 +34,7 @@ int bch2_subvol_is_ro_trans(struct btree_trans *, u32);
|
||||
int bch2_subvol_is_ro(struct bch_fs *, u32);
|
||||
|
||||
static inline struct bkey_s_c
|
||||
-bch2_btree_iter_peek_in_subvolume_upto_type(struct btree_iter *iter, struct bpos end,
|
||||
+bch2_btree_iter_peek_in_subvolume_max_type(struct btree_iter *iter, struct bpos end,
|
||||
u32 subvolid, unsigned flags)
|
||||
{
|
||||
u32 snapshot;
|
||||
@@ -43,10 +43,10 @@ bch2_btree_iter_peek_in_subvolume_upto_type(struct btree_iter *iter, struct bpos
|
||||
return bkey_s_c_err(ret);
|
||||
|
||||
bch2_btree_iter_set_snapshot(iter, snapshot);
|
||||
- return bch2_btree_iter_peek_upto_type(iter, end, flags);
|
||||
+ return bch2_btree_iter_peek_max_type(iter, end, flags);
|
||||
}
|
||||
|
||||
-#define for_each_btree_key_in_subvolume_upto_continue(_trans, _iter, \
|
||||
+#define for_each_btree_key_in_subvolume_max_continue(_trans, _iter, \
|
||||
_end, _subvolid, _flags, _k, _do) \
|
||||
({ \
|
||||
struct bkey_s_c _k; \
|
||||
@@ -54,7 +54,7 @@ bch2_btree_iter_peek_in_subvolume_upto_type(struct btree_iter *iter, struct bpos
|
||||
\
|
||||
do { \
|
||||
_ret3 = lockrestart_do(_trans, ({ \
|
||||
- (_k) = bch2_btree_iter_peek_in_subvolume_upto_type(&(_iter), \
|
||||
+ (_k) = bch2_btree_iter_peek_in_subvolume_max_type(&(_iter), \
|
||||
_end, _subvolid, (_flags)); \
|
||||
if (!(_k).k) \
|
||||
break; \
|
||||
@@ -67,14 +67,14 @@ bch2_btree_iter_peek_in_subvolume_upto_type(struct btree_iter *iter, struct bpos
|
||||
_ret3; \
|
||||
})
|
||||
|
||||
-#define for_each_btree_key_in_subvolume_upto(_trans, _iter, _btree_id, \
|
||||
+#define for_each_btree_key_in_subvolume_max(_trans, _iter, _btree_id, \
|
||||
_start, _end, _subvolid, _flags, _k, _do) \
|
||||
({ \
|
||||
struct btree_iter _iter; \
|
||||
bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
|
||||
(_start), (_flags)); \
|
||||
\
|
||||
- for_each_btree_key_in_subvolume_upto_continue(_trans, _iter, \
|
||||
+ for_each_btree_key_in_subvolume_max_continue(_trans, _iter, \
|
||||
_end, _subvolid, _flags, _k, _do); \
|
||||
})
|
||||
|
||||
diff --git a/fs/bcachefs/tests.c b/fs/bcachefs/tests.c
|
||||
index fb5c1543e52f..6c6469814637 100644
|
||||
--- a/fs/bcachefs/tests.c
|
||||
+++ b/fs/bcachefs/tests.c
|
||||
@@ -131,7 +131,7 @@ static int test_iterate(struct bch_fs *c, u64 nr)
|
||||
i = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter, BTREE_ID_xattrs,
|
||||
+ for_each_btree_key_max(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(k.k->p.offset != i++);
|
||||
@@ -186,7 +186,7 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
|
||||
i = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter, BTREE_ID_extents,
|
||||
+ for_each_btree_key_max(trans, iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(bkey_start_offset(k.k) != i);
|
||||
@@ -242,7 +242,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
|
||||
i = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter, BTREE_ID_xattrs,
|
||||
+ for_each_btree_key_max(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(k.k->p.offset != i);
|
||||
@@ -259,7 +259,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
|
||||
i = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter, BTREE_ID_xattrs,
|
||||
+ for_each_btree_key_max(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
BTREE_ITER_slots, k, ({
|
||||
if (i >= nr * 2)
|
||||
@@ -302,7 +302,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
|
||||
i = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter, BTREE_ID_extents,
|
||||
+ for_each_btree_key_max(trans, iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k, ({
|
||||
BUG_ON(bkey_start_offset(k.k) != i + 8);
|
||||
@@ -320,7 +320,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
|
||||
i = 0;
|
||||
|
||||
ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter, BTREE_ID_extents,
|
||||
+ for_each_btree_key_max(trans, iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
BTREE_ITER_slots, k, ({
|
||||
if (i == nr)
|
||||
@@ -349,10 +349,10 @@ static int test_peek_end(struct bch_fs *c, u64 nr)
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), 0);
|
||||
|
||||
- lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
+ lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_max(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
- lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
+ lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_max(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
@@ -369,10 +369,10 @@ static int test_peek_end_extents(struct bch_fs *c, u64 nr)
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
|
||||
SPOS(0, 0, U32_MAX), 0);
|
||||
|
||||
- lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
+ lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_max(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
- lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
+ lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_max(&iter, POS(0, U64_MAX))));
|
||||
BUG_ON(k.k);
|
||||
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
@@ -488,7 +488,7 @@ static int test_snapshot_filter(struct bch_fs *c, u32 snapid_lo, u32 snapid_hi)
|
||||
trans = bch2_trans_get(c);
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, snapid_lo), 0);
|
||||
- lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
|
||||
+ lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_max(&iter, POS(0, U64_MAX))));
|
||||
|
||||
BUG_ON(k.k->p.snapshot != U32_MAX);
|
||||
|
||||
@@ -672,7 +672,7 @@ static int __do_delete(struct btree_trans *trans, struct bpos pos)
|
||||
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs, pos,
|
||||
BTREE_ITER_intent);
|
||||
- k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX));
|
||||
+ k = bch2_btree_iter_peek_max(&iter, POS(0, U64_MAX));
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
goto err;
|
||||
@@ -726,7 +726,7 @@ static int seq_insert(struct bch_fs *c, u64 nr)
|
||||
static int seq_lookup(struct bch_fs *c, u64 nr)
|
||||
{
|
||||
return bch2_trans_run(c,
|
||||
- for_each_btree_key_upto(trans, iter, BTREE_ID_xattrs,
|
||||
+ for_each_btree_key_max(trans, iter, BTREE_ID_xattrs,
|
||||
SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
|
||||
0, k,
|
||||
0));
|
||||
diff --git a/fs/bcachefs/xattr.c b/fs/bcachefs/xattr.c
|
||||
index ed418a747cdd..820c1791545a 100644
|
||||
--- a/fs/bcachefs/xattr.c
|
||||
+++ b/fs/bcachefs/xattr.c
|
||||
@@ -309,7 +309,7 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
|
||||
u64 offset = 0, inum = inode->ei_inode.bi_inum;
|
||||
|
||||
int ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_in_subvolume_upto(trans, iter, BTREE_ID_xattrs,
|
||||
+ for_each_btree_key_in_subvolume_max(trans, iter, BTREE_ID_xattrs,
|
||||
POS(inum, offset),
|
||||
POS(inum, U64_MAX),
|
||||
inode->ei_inum.subvol, 0, k, ({
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,206 +0,0 @@
|
||||
From 0ad36d94fec984615bee1a89d402d8ad942b3eab Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 25 Oct 2024 01:48:26 -0400
|
||||
Subject: [PATCH 064/233] bcachefs: Simplify btree_iter_peek() filter_snapshots
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Collapse all the BTREE_ITER_filter_snapshots handling down into a single
|
||||
block; btree iteration is much simpler in the !filter_snapshots case.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 129 +++++++++++++++++++--------------------
|
||||
1 file changed, 62 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index 21cadc98bdae..580fee86a965 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -1855,7 +1855,6 @@ struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *path, struct bkey *
|
||||
return (struct bkey_s_c) { u, NULL };
|
||||
}
|
||||
|
||||
-
|
||||
void bch2_set_btree_iter_dontneed(struct btree_iter *iter)
|
||||
{
|
||||
struct btree_trans *trans = iter->trans;
|
||||
@@ -2212,8 +2211,6 @@ static struct bkey_s_c __bch2_btree_iter_peek(struct btree_iter *iter, struct bp
|
||||
bch2_btree_iter_verify(iter);
|
||||
|
||||
while (1) {
|
||||
- struct btree_path_level *l;
|
||||
-
|
||||
iter->path = bch2_btree_path_set_pos(trans, iter->path, search_key,
|
||||
iter->flags & BTREE_ITER_intent,
|
||||
btree_iter_ip_allocated(iter));
|
||||
@@ -2227,7 +2224,7 @@ static struct bkey_s_c __bch2_btree_iter_peek(struct btree_iter *iter, struct bp
|
||||
}
|
||||
|
||||
struct btree_path *path = btree_iter_path(trans, iter);
|
||||
- l = path_l(path);
|
||||
+ struct btree_path_level *l = path_l(path);
|
||||
|
||||
if (unlikely(!l->b)) {
|
||||
/* No btree nodes at requested level: */
|
||||
@@ -2303,10 +2300,11 @@ struct bkey_s_c bch2_btree_iter_peek_max(struct btree_iter *iter, struct bpos en
|
||||
struct btree_trans *trans = iter->trans;
|
||||
struct bpos search_key = btree_iter_search_key(iter);
|
||||
struct bkey_s_c k;
|
||||
- struct bpos iter_pos;
|
||||
+ struct bpos iter_pos = iter->pos;
|
||||
int ret;
|
||||
|
||||
bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
+ bch2_btree_iter_verify_entry_exit(iter);
|
||||
EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bkey_eq(end, POS_MAX));
|
||||
|
||||
if (iter->update_path) {
|
||||
@@ -2315,8 +2313,6 @@ struct bkey_s_c bch2_btree_iter_peek_max(struct btree_iter *iter, struct bpos en
|
||||
iter->update_path = 0;
|
||||
}
|
||||
|
||||
- bch2_btree_iter_verify_entry_exit(iter);
|
||||
-
|
||||
while (1) {
|
||||
k = __bch2_btree_iter_peek(iter, search_key);
|
||||
if (unlikely(!k.k))
|
||||
@@ -2324,75 +2320,74 @@ struct bkey_s_c bch2_btree_iter_peek_max(struct btree_iter *iter, struct bpos en
|
||||
if (unlikely(bkey_err(k)))
|
||||
goto out_no_locked;
|
||||
|
||||
- /*
|
||||
- * We need to check against @end before FILTER_SNAPSHOTS because
|
||||
- * if we get to a different inode that requested we might be
|
||||
- * seeing keys for a different snapshot tree that will all be
|
||||
- * filtered out.
|
||||
- *
|
||||
- * But we can't do the full check here, because bkey_start_pos()
|
||||
- * isn't monotonically increasing before FILTER_SNAPSHOTS, and
|
||||
- * that's what we check against in extents mode:
|
||||
- */
|
||||
- if (unlikely(!(iter->flags & BTREE_ITER_is_extents)
|
||||
- ? bkey_gt(k.k->p, end)
|
||||
- : k.k->p.inode > end.inode))
|
||||
- goto end;
|
||||
+ if (iter->flags & BTREE_ITER_filter_snapshots) {
|
||||
+ /*
|
||||
+ * We need to check against @end before FILTER_SNAPSHOTS because
|
||||
+ * if we get to a different inode that requested we might be
|
||||
+ * seeing keys for a different snapshot tree that will all be
|
||||
+ * filtered out.
|
||||
+ *
|
||||
+ * But we can't do the full check here, because bkey_start_pos()
|
||||
+ * isn't monotonically increasing before FILTER_SNAPSHOTS, and
|
||||
+ * that's what we check against in extents mode:
|
||||
+ */
|
||||
+ if (unlikely(!(iter->flags & BTREE_ITER_is_extents)
|
||||
+ ? bkey_gt(k.k->p, end)
|
||||
+ : k.k->p.inode > end.inode))
|
||||
+ goto end;
|
||||
+
|
||||
+ if (iter->update_path &&
|
||||
+ !bkey_eq(trans->paths[iter->update_path].pos, k.k->p)) {
|
||||
+ bch2_path_put_nokeep(trans, iter->update_path,
|
||||
+ iter->flags & BTREE_ITER_intent);
|
||||
+ iter->update_path = 0;
|
||||
+ }
|
||||
|
||||
- if (iter->update_path &&
|
||||
- !bkey_eq(trans->paths[iter->update_path].pos, k.k->p)) {
|
||||
- bch2_path_put_nokeep(trans, iter->update_path,
|
||||
- iter->flags & BTREE_ITER_intent);
|
||||
- iter->update_path = 0;
|
||||
- }
|
||||
+ if ((iter->flags & BTREE_ITER_intent) &&
|
||||
+ !(iter->flags & BTREE_ITER_is_extents) &&
|
||||
+ !iter->update_path) {
|
||||
+ struct bpos pos = k.k->p;
|
||||
|
||||
- if ((iter->flags & BTREE_ITER_filter_snapshots) &&
|
||||
- (iter->flags & BTREE_ITER_intent) &&
|
||||
- !(iter->flags & BTREE_ITER_is_extents) &&
|
||||
- !iter->update_path) {
|
||||
- struct bpos pos = k.k->p;
|
||||
+ if (pos.snapshot < iter->snapshot) {
|
||||
+ search_key = bpos_successor(k.k->p);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (pos.snapshot < iter->snapshot) {
|
||||
- search_key = bpos_successor(k.k->p);
|
||||
- continue;
|
||||
- }
|
||||
+ pos.snapshot = iter->snapshot;
|
||||
|
||||
- pos.snapshot = iter->snapshot;
|
||||
+ /*
|
||||
+ * advance, same as on exit for iter->path, but only up
|
||||
+ * to snapshot
|
||||
+ */
|
||||
+ __btree_path_get(trans, trans->paths + iter->path, iter->flags & BTREE_ITER_intent);
|
||||
+ iter->update_path = iter->path;
|
||||
+
|
||||
+ iter->update_path = bch2_btree_path_set_pos(trans,
|
||||
+ iter->update_path, pos,
|
||||
+ iter->flags & BTREE_ITER_intent,
|
||||
+ _THIS_IP_);
|
||||
+ ret = bch2_btree_path_traverse(trans, iter->update_path, iter->flags);
|
||||
+ if (unlikely(ret)) {
|
||||
+ k = bkey_s_c_err(ret);
|
||||
+ goto out_no_locked;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/*
|
||||
- * advance, same as on exit for iter->path, but only up
|
||||
- * to snapshot
|
||||
+ * We can never have a key in a leaf node at POS_MAX, so
|
||||
+ * we don't have to check these successor() calls:
|
||||
*/
|
||||
- __btree_path_get(trans, trans->paths + iter->path, iter->flags & BTREE_ITER_intent);
|
||||
- iter->update_path = iter->path;
|
||||
-
|
||||
- iter->update_path = bch2_btree_path_set_pos(trans,
|
||||
- iter->update_path, pos,
|
||||
- iter->flags & BTREE_ITER_intent,
|
||||
- _THIS_IP_);
|
||||
- ret = bch2_btree_path_traverse(trans, iter->update_path, iter->flags);
|
||||
- if (unlikely(ret)) {
|
||||
- k = bkey_s_c_err(ret);
|
||||
- goto out_no_locked;
|
||||
+ if (!bch2_snapshot_is_ancestor(trans->c,
|
||||
+ iter->snapshot,
|
||||
+ k.k->p.snapshot)) {
|
||||
+ search_key = bpos_successor(k.k->p);
|
||||
+ continue;
|
||||
}
|
||||
- }
|
||||
|
||||
- /*
|
||||
- * We can never have a key in a leaf node at POS_MAX, so
|
||||
- * we don't have to check these successor() calls:
|
||||
- */
|
||||
- if ((iter->flags & BTREE_ITER_filter_snapshots) &&
|
||||
- !bch2_snapshot_is_ancestor(trans->c,
|
||||
- iter->snapshot,
|
||||
- k.k->p.snapshot)) {
|
||||
- search_key = bpos_successor(k.k->p);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (bkey_whiteout(k.k) &&
|
||||
- !(iter->flags & BTREE_ITER_all_snapshots)) {
|
||||
- search_key = bkey_successor(iter, k.k->p);
|
||||
- continue;
|
||||
+ if (bkey_whiteout(k.k)) {
|
||||
+ search_key = bkey_successor(iter, k.k->p);
|
||||
+ continue;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 2cb00966dd7d318400633b66864ceb34dfdcfdc8 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 25 Oct 2024 22:16:19 -0400
|
||||
Subject: [PATCH 065/233] bcachefs: Kill unnecessary iter_rewind() in
|
||||
bkey_get_empty_slot()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_update.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c
|
||||
index 6afd77c68411..f3d7ca3d92b9 100644
|
||||
--- a/fs/bcachefs/btree_update.c
|
||||
+++ b/fs/bcachefs/btree_update.c
|
||||
@@ -588,12 +588,9 @@ struct jset_entry *__bch2_trans_jset_entry_alloc(struct btree_trans *trans, unsi
|
||||
int bch2_bkey_get_empty_slot(struct btree_trans *trans, struct btree_iter *iter,
|
||||
enum btree_id btree, struct bpos end)
|
||||
{
|
||||
- struct bkey_s_c k;
|
||||
- int ret = 0;
|
||||
-
|
||||
bch2_trans_iter_init(trans, iter, btree, POS_MAX, BTREE_ITER_intent);
|
||||
- k = bch2_btree_iter_prev(iter);
|
||||
- ret = bkey_err(k);
|
||||
+ struct bkey_s_c k = bch2_btree_iter_peek_prev(iter);
|
||||
+ int ret = bkey_err(k);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,521 +0,0 @@
|
||||
From 45f667488e390bd9771163eddbcdc304798f32a5 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Wed, 6 Nov 2024 13:13:25 -0500
|
||||
Subject: [PATCH 066/233] bcachefs: Move fsck ioctl code to fsck.c
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
chardev.c and fs-ioctl.c are not organized by subject; let's try to fix
|
||||
this.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/chardev.c | 219 +-----------------------------------------
|
||||
fs/bcachefs/fsck.c | 218 +++++++++++++++++++++++++++++++++++++++++
|
||||
fs/bcachefs/fsck.h | 3 +
|
||||
3 files changed, 222 insertions(+), 218 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c
|
||||
index 2182b555c112..46e9e32105a9 100644
|
||||
--- a/fs/bcachefs/chardev.c
|
||||
+++ b/fs/bcachefs/chardev.c
|
||||
@@ -6,11 +6,11 @@
|
||||
#include "buckets.h"
|
||||
#include "chardev.h"
|
||||
#include "disk_accounting.h"
|
||||
+#include "fsck.h"
|
||||
#include "journal.h"
|
||||
#include "move.h"
|
||||
#include "recovery_passes.h"
|
||||
#include "replicas.h"
|
||||
-#include "super.h"
|
||||
#include "super-io.h"
|
||||
#include "thread_with_file.h"
|
||||
|
||||
@@ -127,130 +127,6 @@ static long bch2_ioctl_incremental(struct bch_ioctl_incremental __user *user_arg
|
||||
}
|
||||
#endif
|
||||
|
||||
-struct fsck_thread {
|
||||
- struct thread_with_stdio thr;
|
||||
- struct bch_fs *c;
|
||||
- struct bch_opts opts;
|
||||
-};
|
||||
-
|
||||
-static void bch2_fsck_thread_exit(struct thread_with_stdio *_thr)
|
||||
-{
|
||||
- struct fsck_thread *thr = container_of(_thr, struct fsck_thread, thr);
|
||||
- kfree(thr);
|
||||
-}
|
||||
-
|
||||
-static int bch2_fsck_offline_thread_fn(struct thread_with_stdio *stdio)
|
||||
-{
|
||||
- struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
|
||||
- struct bch_fs *c = thr->c;
|
||||
-
|
||||
- int ret = PTR_ERR_OR_ZERO(c);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = bch2_fs_start(thr->c);
|
||||
- if (ret)
|
||||
- goto err;
|
||||
-
|
||||
- if (test_bit(BCH_FS_errors_fixed, &c->flags)) {
|
||||
- bch2_stdio_redirect_printf(&stdio->stdio, false, "%s: errors fixed\n", c->name);
|
||||
- ret |= 1;
|
||||
- }
|
||||
- if (test_bit(BCH_FS_error, &c->flags)) {
|
||||
- bch2_stdio_redirect_printf(&stdio->stdio, false, "%s: still has errors\n", c->name);
|
||||
- ret |= 4;
|
||||
- }
|
||||
-err:
|
||||
- bch2_fs_stop(c);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static const struct thread_with_stdio_ops bch2_offline_fsck_ops = {
|
||||
- .exit = bch2_fsck_thread_exit,
|
||||
- .fn = bch2_fsck_offline_thread_fn,
|
||||
-};
|
||||
-
|
||||
-static long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_arg)
|
||||
-{
|
||||
- struct bch_ioctl_fsck_offline arg;
|
||||
- struct fsck_thread *thr = NULL;
|
||||
- darray_str(devs) = {};
|
||||
- long ret = 0;
|
||||
-
|
||||
- if (copy_from_user(&arg, user_arg, sizeof(arg)))
|
||||
- return -EFAULT;
|
||||
-
|
||||
- if (arg.flags)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (!capable(CAP_SYS_ADMIN))
|
||||
- return -EPERM;
|
||||
-
|
||||
- for (size_t i = 0; i < arg.nr_devs; i++) {
|
||||
- u64 dev_u64;
|
||||
- ret = copy_from_user_errcode(&dev_u64, &user_arg->devs[i], sizeof(u64));
|
||||
- if (ret)
|
||||
- goto err;
|
||||
-
|
||||
- char *dev_str = strndup_user((char __user *)(unsigned long) dev_u64, PATH_MAX);
|
||||
- ret = PTR_ERR_OR_ZERO(dev_str);
|
||||
- if (ret)
|
||||
- goto err;
|
||||
-
|
||||
- ret = darray_push(&devs, dev_str);
|
||||
- if (ret) {
|
||||
- kfree(dev_str);
|
||||
- goto err;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- thr = kzalloc(sizeof(*thr), GFP_KERNEL);
|
||||
- if (!thr) {
|
||||
- ret = -ENOMEM;
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- thr->opts = bch2_opts_empty();
|
||||
-
|
||||
- if (arg.opts) {
|
||||
- char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
|
||||
- ret = PTR_ERR_OR_ZERO(optstr) ?:
|
||||
- bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr);
|
||||
- if (!IS_ERR(optstr))
|
||||
- kfree(optstr);
|
||||
-
|
||||
- if (ret)
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- opt_set(thr->opts, stdio, (u64)(unsigned long)&thr->thr.stdio);
|
||||
- opt_set(thr->opts, read_only, 1);
|
||||
- opt_set(thr->opts, ratelimit_errors, 0);
|
||||
-
|
||||
- /* We need request_key() to be called before we punt to kthread: */
|
||||
- opt_set(thr->opts, nostart, true);
|
||||
-
|
||||
- bch2_thread_with_stdio_init(&thr->thr, &bch2_offline_fsck_ops);
|
||||
-
|
||||
- thr->c = bch2_fs_open(devs.data, arg.nr_devs, thr->opts);
|
||||
-
|
||||
- if (!IS_ERR(thr->c) &&
|
||||
- thr->c->opts.errors == BCH_ON_ERROR_panic)
|
||||
- thr->c->opts.errors = BCH_ON_ERROR_ro;
|
||||
-
|
||||
- ret = __bch2_run_thread_with_stdio(&thr->thr);
|
||||
-out:
|
||||
- darray_for_each(devs, i)
|
||||
- kfree(*i);
|
||||
- darray_exit(&devs);
|
||||
- return ret;
|
||||
-err:
|
||||
- if (thr)
|
||||
- bch2_fsck_thread_exit(&thr->thr);
|
||||
- pr_err("ret %s", bch2_err_str(ret));
|
||||
- goto out;
|
||||
-}
|
||||
-
|
||||
static long bch2_global_ioctl(unsigned cmd, void __user *arg)
|
||||
{
|
||||
long ret;
|
||||
@@ -775,99 +651,6 @@ static long bch2_ioctl_disk_resize_journal(struct bch_fs *c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int bch2_fsck_online_thread_fn(struct thread_with_stdio *stdio)
|
||||
-{
|
||||
- struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
|
||||
- struct bch_fs *c = thr->c;
|
||||
-
|
||||
- c->stdio_filter = current;
|
||||
- c->stdio = &thr->thr.stdio;
|
||||
-
|
||||
- /*
|
||||
- * XXX: can we figure out a way to do this without mucking with c->opts?
|
||||
- */
|
||||
- unsigned old_fix_errors = c->opts.fix_errors;
|
||||
- if (opt_defined(thr->opts, fix_errors))
|
||||
- c->opts.fix_errors = thr->opts.fix_errors;
|
||||
- else
|
||||
- c->opts.fix_errors = FSCK_FIX_ask;
|
||||
-
|
||||
- c->opts.fsck = true;
|
||||
- set_bit(BCH_FS_fsck_running, &c->flags);
|
||||
-
|
||||
- c->curr_recovery_pass = BCH_RECOVERY_PASS_check_alloc_info;
|
||||
- int ret = bch2_run_online_recovery_passes(c);
|
||||
-
|
||||
- clear_bit(BCH_FS_fsck_running, &c->flags);
|
||||
- bch_err_fn(c, ret);
|
||||
-
|
||||
- c->stdio = NULL;
|
||||
- c->stdio_filter = NULL;
|
||||
- c->opts.fix_errors = old_fix_errors;
|
||||
-
|
||||
- up(&c->online_fsck_mutex);
|
||||
- bch2_ro_ref_put(c);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static const struct thread_with_stdio_ops bch2_online_fsck_ops = {
|
||||
- .exit = bch2_fsck_thread_exit,
|
||||
- .fn = bch2_fsck_online_thread_fn,
|
||||
-};
|
||||
-
|
||||
-static long bch2_ioctl_fsck_online(struct bch_fs *c,
|
||||
- struct bch_ioctl_fsck_online arg)
|
||||
-{
|
||||
- struct fsck_thread *thr = NULL;
|
||||
- long ret = 0;
|
||||
-
|
||||
- if (arg.flags)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (!capable(CAP_SYS_ADMIN))
|
||||
- return -EPERM;
|
||||
-
|
||||
- if (!bch2_ro_ref_tryget(c))
|
||||
- return -EROFS;
|
||||
-
|
||||
- if (down_trylock(&c->online_fsck_mutex)) {
|
||||
- bch2_ro_ref_put(c);
|
||||
- return -EAGAIN;
|
||||
- }
|
||||
-
|
||||
- thr = kzalloc(sizeof(*thr), GFP_KERNEL);
|
||||
- if (!thr) {
|
||||
- ret = -ENOMEM;
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- thr->c = c;
|
||||
- thr->opts = bch2_opts_empty();
|
||||
-
|
||||
- if (arg.opts) {
|
||||
- char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
|
||||
-
|
||||
- ret = PTR_ERR_OR_ZERO(optstr) ?:
|
||||
- bch2_parse_mount_opts(c, &thr->opts, NULL, optstr);
|
||||
- if (!IS_ERR(optstr))
|
||||
- kfree(optstr);
|
||||
-
|
||||
- if (ret)
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- ret = bch2_run_thread_with_stdio(&thr->thr, &bch2_online_fsck_ops);
|
||||
-err:
|
||||
- if (ret < 0) {
|
||||
- bch_err_fn(c, ret);
|
||||
- if (thr)
|
||||
- bch2_fsck_thread_exit(&thr->thr);
|
||||
- up(&c->online_fsck_mutex);
|
||||
- bch2_ro_ref_put(c);
|
||||
- }
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
#define BCH_IOCTL(_name, _argtype) \
|
||||
do { \
|
||||
_argtype i; \
|
||||
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
|
||||
index 2229f0dcc860..e0335265de3d 100644
|
||||
--- a/fs/bcachefs/fsck.c
|
||||
+++ b/fs/bcachefs/fsck.c
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include "bcachefs.h"
|
||||
+#include "bcachefs_ioctl.h"
|
||||
#include "bkey_buf.h"
|
||||
#include "btree_cache.h"
|
||||
#include "btree_update.h"
|
||||
@@ -16,6 +17,7 @@
|
||||
#include "recovery_passes.h"
|
||||
#include "snapshot.h"
|
||||
#include "super.h"
|
||||
+#include "thread_with_file.h"
|
||||
#include "xattr.h"
|
||||
|
||||
#include <linux/bsearch.h>
|
||||
@@ -3192,3 +3194,219 @@ int bch2_fix_reflink_p(struct bch_fs *c)
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+struct fsck_thread {
|
||||
+ struct thread_with_stdio thr;
|
||||
+ struct bch_fs *c;
|
||||
+ struct bch_opts opts;
|
||||
+};
|
||||
+
|
||||
+static void bch2_fsck_thread_exit(struct thread_with_stdio *_thr)
|
||||
+{
|
||||
+ struct fsck_thread *thr = container_of(_thr, struct fsck_thread, thr);
|
||||
+ kfree(thr);
|
||||
+}
|
||||
+
|
||||
+static int bch2_fsck_offline_thread_fn(struct thread_with_stdio *stdio)
|
||||
+{
|
||||
+ struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
|
||||
+ struct bch_fs *c = thr->c;
|
||||
+
|
||||
+ int ret = PTR_ERR_OR_ZERO(c);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bch2_fs_start(thr->c);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ if (test_bit(BCH_FS_errors_fixed, &c->flags)) {
|
||||
+ bch2_stdio_redirect_printf(&stdio->stdio, false, "%s: errors fixed\n", c->name);
|
||||
+ ret |= 1;
|
||||
+ }
|
||||
+ if (test_bit(BCH_FS_error, &c->flags)) {
|
||||
+ bch2_stdio_redirect_printf(&stdio->stdio, false, "%s: still has errors\n", c->name);
|
||||
+ ret |= 4;
|
||||
+ }
|
||||
+err:
|
||||
+ bch2_fs_stop(c);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct thread_with_stdio_ops bch2_offline_fsck_ops = {
|
||||
+ .exit = bch2_fsck_thread_exit,
|
||||
+ .fn = bch2_fsck_offline_thread_fn,
|
||||
+};
|
||||
+
|
||||
+long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_arg)
|
||||
+{
|
||||
+ struct bch_ioctl_fsck_offline arg;
|
||||
+ struct fsck_thread *thr = NULL;
|
||||
+ darray_str(devs) = {};
|
||||
+ long ret = 0;
|
||||
+
|
||||
+ if (copy_from_user(&arg, user_arg, sizeof(arg)))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ if (arg.flags)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!capable(CAP_SYS_ADMIN))
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ for (size_t i = 0; i < arg.nr_devs; i++) {
|
||||
+ u64 dev_u64;
|
||||
+ ret = copy_from_user_errcode(&dev_u64, &user_arg->devs[i], sizeof(u64));
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ char *dev_str = strndup_user((char __user *)(unsigned long) dev_u64, PATH_MAX);
|
||||
+ ret = PTR_ERR_OR_ZERO(dev_str);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ ret = darray_push(&devs, dev_str);
|
||||
+ if (ret) {
|
||||
+ kfree(dev_str);
|
||||
+ goto err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ thr = kzalloc(sizeof(*thr), GFP_KERNEL);
|
||||
+ if (!thr) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ thr->opts = bch2_opts_empty();
|
||||
+
|
||||
+ if (arg.opts) {
|
||||
+ char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
|
||||
+ ret = PTR_ERR_OR_ZERO(optstr) ?:
|
||||
+ bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr);
|
||||
+ if (!IS_ERR(optstr))
|
||||
+ kfree(optstr);
|
||||
+
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ opt_set(thr->opts, stdio, (u64)(unsigned long)&thr->thr.stdio);
|
||||
+ opt_set(thr->opts, read_only, 1);
|
||||
+ opt_set(thr->opts, ratelimit_errors, 0);
|
||||
+
|
||||
+ /* We need request_key() to be called before we punt to kthread: */
|
||||
+ opt_set(thr->opts, nostart, true);
|
||||
+
|
||||
+ bch2_thread_with_stdio_init(&thr->thr, &bch2_offline_fsck_ops);
|
||||
+
|
||||
+ thr->c = bch2_fs_open(devs.data, arg.nr_devs, thr->opts);
|
||||
+
|
||||
+ if (!IS_ERR(thr->c) &&
|
||||
+ thr->c->opts.errors == BCH_ON_ERROR_panic)
|
||||
+ thr->c->opts.errors = BCH_ON_ERROR_ro;
|
||||
+
|
||||
+ ret = __bch2_run_thread_with_stdio(&thr->thr);
|
||||
+out:
|
||||
+ darray_for_each(devs, i)
|
||||
+ kfree(*i);
|
||||
+ darray_exit(&devs);
|
||||
+ return ret;
|
||||
+err:
|
||||
+ if (thr)
|
||||
+ bch2_fsck_thread_exit(&thr->thr);
|
||||
+ pr_err("ret %s", bch2_err_str(ret));
|
||||
+ goto out;
|
||||
+}
|
||||
+
|
||||
+static int bch2_fsck_online_thread_fn(struct thread_with_stdio *stdio)
|
||||
+{
|
||||
+ struct fsck_thread *thr = container_of(stdio, struct fsck_thread, thr);
|
||||
+ struct bch_fs *c = thr->c;
|
||||
+
|
||||
+ c->stdio_filter = current;
|
||||
+ c->stdio = &thr->thr.stdio;
|
||||
+
|
||||
+ /*
|
||||
+ * XXX: can we figure out a way to do this without mucking with c->opts?
|
||||
+ */
|
||||
+ unsigned old_fix_errors = c->opts.fix_errors;
|
||||
+ if (opt_defined(thr->opts, fix_errors))
|
||||
+ c->opts.fix_errors = thr->opts.fix_errors;
|
||||
+ else
|
||||
+ c->opts.fix_errors = FSCK_FIX_ask;
|
||||
+
|
||||
+ c->opts.fsck = true;
|
||||
+ set_bit(BCH_FS_fsck_running, &c->flags);
|
||||
+
|
||||
+ c->curr_recovery_pass = BCH_RECOVERY_PASS_check_alloc_info;
|
||||
+ int ret = bch2_run_online_recovery_passes(c);
|
||||
+
|
||||
+ clear_bit(BCH_FS_fsck_running, &c->flags);
|
||||
+ bch_err_fn(c, ret);
|
||||
+
|
||||
+ c->stdio = NULL;
|
||||
+ c->stdio_filter = NULL;
|
||||
+ c->opts.fix_errors = old_fix_errors;
|
||||
+
|
||||
+ up(&c->online_fsck_mutex);
|
||||
+ bch2_ro_ref_put(c);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct thread_with_stdio_ops bch2_online_fsck_ops = {
|
||||
+ .exit = bch2_fsck_thread_exit,
|
||||
+ .fn = bch2_fsck_online_thread_fn,
|
||||
+};
|
||||
+
|
||||
+long bch2_ioctl_fsck_online(struct bch_fs *c, struct bch_ioctl_fsck_online arg)
|
||||
+{
|
||||
+ struct fsck_thread *thr = NULL;
|
||||
+ long ret = 0;
|
||||
+
|
||||
+ if (arg.flags)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!capable(CAP_SYS_ADMIN))
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ if (!bch2_ro_ref_tryget(c))
|
||||
+ return -EROFS;
|
||||
+
|
||||
+ if (down_trylock(&c->online_fsck_mutex)) {
|
||||
+ bch2_ro_ref_put(c);
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
+
|
||||
+ thr = kzalloc(sizeof(*thr), GFP_KERNEL);
|
||||
+ if (!thr) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ thr->c = c;
|
||||
+ thr->opts = bch2_opts_empty();
|
||||
+
|
||||
+ if (arg.opts) {
|
||||
+ char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
|
||||
+
|
||||
+ ret = PTR_ERR_OR_ZERO(optstr) ?:
|
||||
+ bch2_parse_mount_opts(c, &thr->opts, NULL, optstr);
|
||||
+ if (!IS_ERR(optstr))
|
||||
+ kfree(optstr);
|
||||
+
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = bch2_run_thread_with_stdio(&thr->thr, &bch2_online_fsck_ops);
|
||||
+err:
|
||||
+ if (ret < 0) {
|
||||
+ bch_err_fn(c, ret);
|
||||
+ if (thr)
|
||||
+ bch2_fsck_thread_exit(&thr->thr);
|
||||
+ up(&c->online_fsck_mutex);
|
||||
+ bch2_ro_ref_put(c);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/fs/bcachefs/fsck.h b/fs/bcachefs/fsck.h
|
||||
index 1cca31011530..4481b40a881d 100644
|
||||
--- a/fs/bcachefs/fsck.h
|
||||
+++ b/fs/bcachefs/fsck.h
|
||||
@@ -14,4 +14,7 @@ int bch2_check_directory_structure(struct bch_fs *);
|
||||
int bch2_check_nlinks(struct bch_fs *);
|
||||
int bch2_fix_reflink_p(struct bch_fs *);
|
||||
|
||||
+long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *);
|
||||
+long bch2_ioctl_fsck_online(struct bch_fs *, struct bch_ioctl_fsck_online);
|
||||
+
|
||||
#endif /* _BCACHEFS_FSCK_H */
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,99 +0,0 @@
|
||||
From 88c2aa59c3f62a04f89a62985f9f0ece694fe066 Mon Sep 17 00:00:00 2001
|
||||
From: Integral <integral@murena.io>
|
||||
Date: Wed, 23 Oct 2024 18:00:33 +0800
|
||||
Subject: [PATCH 067/233] bcachefs: add support for true/false & yes/no in
|
||||
bool-type options
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Here is the patch which uses existing constant table:
|
||||
|
||||
Currently, when using bcachefs-tools to set options, bool-type options
|
||||
can only accept 1 or 0. Add support for accepting true/false and yes/no
|
||||
for these options.
|
||||
|
||||
Signed-off-by: Integral <integral@murena.io>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Acked-by: David Howells <dhowells@redhat.com>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/opts.c | 16 +++++++++-------
|
||||
fs/fs_parser.c | 3 ++-
|
||||
include/linux/fs_parser.h | 2 ++
|
||||
3 files changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
|
||||
index 49c59aec6954..0ba58d74c21f 100644
|
||||
--- a/fs/bcachefs/opts.c
|
||||
+++ b/fs/bcachefs/opts.c
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/kernel.h>
|
||||
+#include <linux/fs_parser.h>
|
||||
|
||||
#include "bcachefs.h"
|
||||
#include "compress.h"
|
||||
@@ -334,17 +335,18 @@ int bch2_opt_parse(struct bch_fs *c,
|
||||
switch (opt->type) {
|
||||
case BCH_OPT_BOOL:
|
||||
if (val) {
|
||||
- ret = kstrtou64(val, 10, res);
|
||||
+ ret = lookup_constant(bool_names, val, -BCH_ERR_option_not_bool);
|
||||
+ if (ret != -BCH_ERR_option_not_bool) {
|
||||
+ *res = ret;
|
||||
+ } else {
|
||||
+ if (err)
|
||||
+ prt_printf(err, "%s: must be bool", opt->attr.name);
|
||||
+ return ret;
|
||||
+ }
|
||||
} else {
|
||||
- ret = 0;
|
||||
*res = 1;
|
||||
}
|
||||
|
||||
- if (ret < 0 || (*res != 0 && *res != 1)) {
|
||||
- if (err)
|
||||
- prt_printf(err, "%s: must be bool", opt->attr.name);
|
||||
- return ret < 0 ? ret : -BCH_ERR_option_not_bool;
|
||||
- }
|
||||
break;
|
||||
case BCH_OPT_UINT:
|
||||
if (!val) {
|
||||
diff --git a/fs/fs_parser.c b/fs/fs_parser.c
|
||||
index 24727ec34e5a..6521e9a9d6ef 100644
|
||||
--- a/fs/fs_parser.c
|
||||
+++ b/fs/fs_parser.c
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <linux/namei.h>
|
||||
#include "internal.h"
|
||||
|
||||
-static const struct constant_table bool_names[] = {
|
||||
+const struct constant_table bool_names[] = {
|
||||
{ "0", false },
|
||||
{ "1", true },
|
||||
{ "false", false },
|
||||
@@ -22,6 +22,7 @@ static const struct constant_table bool_names[] = {
|
||||
{ "yes", true },
|
||||
{ },
|
||||
};
|
||||
+EXPORT_SYMBOL(bool_names);
|
||||
|
||||
static const struct constant_table *
|
||||
__lookup_constant(const struct constant_table *tbl, const char *name)
|
||||
diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h
|
||||
index 6cf713a7e6c6..0974cd33bcba 100644
|
||||
--- a/include/linux/fs_parser.h
|
||||
+++ b/include/linux/fs_parser.h
|
||||
@@ -83,6 +83,8 @@ extern int fs_lookup_param(struct fs_context *fc,
|
||||
|
||||
extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found);
|
||||
|
||||
+extern const struct constant_table bool_names[];
|
||||
+
|
||||
#ifdef CONFIG_VALIDATE_FS_PARSER
|
||||
extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
||||
int low, int high, int special);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 19128c53d438d7435d855625e5abe6a0a929ae63 Mon Sep 17 00:00:00 2001
|
||||
From: Youling Tang <tangyouling@kylinos.cn>
|
||||
Date: Wed, 16 Oct 2024 09:50:26 +0800
|
||||
Subject: [PATCH 068/233] bcachefs: Correct the description of the
|
||||
'--bucket=size' options
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/opts.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index 39cdc185fa73..6b29339ea725 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -501,7 +501,7 @@ enum fsck_err_opts {
|
||||
OPT_DEVICE, \
|
||||
OPT_UINT(0, S64_MAX), \
|
||||
BCH2_NO_SB_OPT, 0, \
|
||||
- "size", "Size of filesystem on device") \
|
||||
+ "size", "Specifies the bucket size; must be greater than the btree node size")\
|
||||
x(durability, u8, \
|
||||
OPT_DEVICE|OPT_SB_FIELD_ONE_BIAS, \
|
||||
OPT_UINT(0, BCH_REPLICAS_MAX), \
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,37 +0,0 @@
|
||||
From a57150fe53c1e85babe43129d047b502b0316765 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Tue, 9 Jul 2024 09:11:33 +0800
|
||||
Subject: [PATCH 069/233] bcachefs: Add support for FS_IOC_GETFSUUID
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use super_set_uuid() to set `sb->s_uuid_len` to avoid returning `-ENOTTY`
|
||||
with sb->s_uuid_len being 0.
|
||||
|
||||
Original patch link:
|
||||
[1]: https://lore.kernel.org/all/20240207025624.1019754-2-kent.overstreet@linux.dev/
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
|
||||
index 91fce04272a1..396a8f677621 100644
|
||||
--- a/fs/bcachefs/fs.c
|
||||
+++ b/fs/bcachefs/fs.c
|
||||
@@ -2216,7 +2216,7 @@ static int bch2_fs_get_tree(struct fs_context *fc)
|
||||
sb->s_time_gran = c->sb.nsec_per_time_unit;
|
||||
sb->s_time_min = div_s64(S64_MIN, c->sb.time_units_per_sec) + 1;
|
||||
sb->s_time_max = div_s64(S64_MAX, c->sb.time_units_per_sec);
|
||||
- sb->s_uuid = c->sb.user_uuid;
|
||||
+ super_set_uuid(sb, c->sb.user_uuid.b, sizeof(c->sb.user_uuid));
|
||||
sb->s_shrink->seeks = 0;
|
||||
c->vfs_sb = sb;
|
||||
strscpy(sb->s_id, c->name, sizeof(sb->s_id));
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,76 +0,0 @@
|
||||
From 797a14eb7da2e1db8b8c768b62035f6567bf4b80 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Tue, 9 Jul 2024 09:11:34 +0800
|
||||
Subject: [PATCH 070/233] bcachefs: Add support for FS_IOC_GETFSSYSFSPATH
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
[TEST]:
|
||||
```
|
||||
$ cat ioctl_getsysfspath.c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd;
|
||||
struct fs_sysfs_path sysfs_path = {};
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <path_to_file_or_directory>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fd = open(argv[1], O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ioctl(fd, FS_IOC_GETFSSYSFSPATH, &sysfs_path) == -1) {
|
||||
perror("ioctl FS_IOC_GETFSSYSFSPATH");
|
||||
close(fd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("FS_IOC_GETFSSYSFSPATH: %s\n", sysfs_path.name);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$ gcc ioctl_getsysfspath.c
|
||||
$ sudo bcachefs format /dev/sda
|
||||
$ sudo mount.bcachefs /dev/sda /mnt
|
||||
$ sudo ./a.out /mnt
|
||||
FS_IOC_GETFSSYSFSPATH: bcachefs/c380b4ab-fbb6-41d2-b805-7a89cae9cadb
|
||||
```
|
||||
|
||||
Original patch link:
|
||||
[1]: https://lore.kernel.org/all/20240207025624.1019754-8-kent.overstreet@linux.dev/
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Youling Tang <youling.tang@linux.dev>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
|
||||
index 396a8f677621..7a269dbcf44b 100644
|
||||
--- a/fs/bcachefs/fs.c
|
||||
+++ b/fs/bcachefs/fs.c
|
||||
@@ -2217,6 +2217,7 @@ static int bch2_fs_get_tree(struct fs_context *fc)
|
||||
sb->s_time_min = div_s64(S64_MIN, c->sb.time_units_per_sec) + 1;
|
||||
sb->s_time_max = div_s64(S64_MAX, c->sb.time_units_per_sec);
|
||||
super_set_uuid(sb, c->sb.user_uuid.b, sizeof(c->sb.user_uuid));
|
||||
+ super_set_sysfs_name_uuid(sb);
|
||||
sb->s_shrink->seeks = 0;
|
||||
c->vfs_sb = sb;
|
||||
strscpy(sb->s_id, c->name, sizeof(sb->s_id));
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,62 +0,0 @@
|
||||
From 0fe251fd827271cb8d40490db395ca9c58a21509 Mon Sep 17 00:00:00 2001
|
||||
From: Youling Tang <tangyouling@kylinos.cn>
|
||||
Date: Tue, 24 Sep 2024 10:53:50 +0800
|
||||
Subject: [PATCH 071/233] bcachefs: Removes NULL pointer checks for
|
||||
__filemap_get_folio return values
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
__filemap_get_folio the return value cannot be NULL, so unnecessary checks
|
||||
are removed.
|
||||
|
||||
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs-io-buffered.c | 2 +-
|
||||
fs/bcachefs/fs-io-pagecache.c | 2 +-
|
||||
fs/bcachefs/fs-io.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c
|
||||
index 0923f38a2fcd..b853cecd3c1b 100644
|
||||
--- a/fs/bcachefs/fs-io-buffered.c
|
||||
+++ b/fs/bcachefs/fs-io-buffered.c
|
||||
@@ -686,7 +686,7 @@ int bch2_write_begin(struct file *file, struct address_space *mapping,
|
||||
folio = __filemap_get_folio(mapping, pos >> PAGE_SHIFT,
|
||||
FGP_WRITEBEGIN | fgf_set_order(len),
|
||||
mapping_gfp_mask(mapping));
|
||||
- if (IS_ERR_OR_NULL(folio))
|
||||
+ if (IS_ERR(folio))
|
||||
goto err_unlock;
|
||||
|
||||
offset = pos - folio_pos(folio);
|
||||
diff --git a/fs/bcachefs/fs-io-pagecache.c b/fs/bcachefs/fs-io-pagecache.c
|
||||
index 51a499c5a7b6..e072900e6a5b 100644
|
||||
--- a/fs/bcachefs/fs-io-pagecache.c
|
||||
+++ b/fs/bcachefs/fs-io-pagecache.c
|
||||
@@ -29,7 +29,7 @@ int bch2_filemap_get_contig_folios_d(struct address_space *mapping,
|
||||
break;
|
||||
|
||||
f = __filemap_get_folio(mapping, pos >> PAGE_SHIFT, fgp_flags, gfp);
|
||||
- if (IS_ERR_OR_NULL(f))
|
||||
+ if (IS_ERR(f))
|
||||
break;
|
||||
|
||||
BUG_ON(fs->nr && folio_pos(f) != pos);
|
||||
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
|
||||
index 0021db191480..c6fdfec51082 100644
|
||||
--- a/fs/bcachefs/fs-io.c
|
||||
+++ b/fs/bcachefs/fs-io.c
|
||||
@@ -256,7 +256,7 @@ static int __bch2_truncate_folio(struct bch_inode_info *inode,
|
||||
|
||||
folio = __filemap_get_folio(mapping, index,
|
||||
FGP_LOCK|FGP_CREAT, GFP_KERNEL);
|
||||
- if (IS_ERR_OR_NULL(folio)) {
|
||||
+ if (IS_ERR(folio)) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,34 +0,0 @@
|
||||
From db6b114bd5c8426f9efa74209e987f3ff2a7bf5f Mon Sep 17 00:00:00 2001
|
||||
From: Youling Tang <tangyouling@kylinos.cn>
|
||||
Date: Fri, 27 Sep 2024 16:40:42 +0800
|
||||
Subject: [PATCH 072/233] bcachefs: Remove redundant initialization in
|
||||
bch2_vfs_inode_init()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
`inode->v.i_ino` has been initialized to `inum.inum`. If `inum.inum` and
|
||||
`bi->bi_inum` are not equal, BUG_ON() is triggered in
|
||||
bch2_inode_update_after_write().
|
||||
|
||||
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
|
||||
index 7a269dbcf44b..f852dbf30aa2 100644
|
||||
--- a/fs/bcachefs/fs.c
|
||||
+++ b/fs/bcachefs/fs.c
|
||||
@@ -1752,7 +1752,6 @@ static void bch2_vfs_inode_init(struct btree_trans *trans,
|
||||
bch2_inode_update_after_write(trans, inode, bi, ~0);
|
||||
|
||||
inode->v.i_blocks = bi->bi_sectors;
|
||||
- inode->v.i_ino = bi->bi_inum;
|
||||
inode->v.i_rdev = bi->bi_dev;
|
||||
inode->v.i_generation = bi->bi_generation;
|
||||
inode->v.i_size = bi->bi_size;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,44 +0,0 @@
|
||||
From c03828056d84e06f5687d296a2808b3ee5e4dfce Mon Sep 17 00:00:00 2001
|
||||
From: Youling Tang <tangyouling@kylinos.cn>
|
||||
Date: Wed, 16 Oct 2024 09:49:11 +0800
|
||||
Subject: [PATCH 073/233] bcachefs: Simplify code in bch2_dev_alloc()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
- Remove unnecessary variable 'ret'.
|
||||
- Remove unnecessary bch2_dev_free() operations.
|
||||
|
||||
Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/super.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
|
||||
index 7e0ff17a6dbb..ab678231afd4 100644
|
||||
--- a/fs/bcachefs/super.c
|
||||
+++ b/fs/bcachefs/super.c
|
||||
@@ -1369,7 +1369,6 @@ static int bch2_dev_alloc(struct bch_fs *c, unsigned dev_idx)
|
||||
{
|
||||
struct bch_member member = bch2_sb_member_get(c->disk_sb.sb, dev_idx);
|
||||
struct bch_dev *ca = NULL;
|
||||
- int ret = 0;
|
||||
|
||||
if (bch2_fs_init_fault("dev_alloc"))
|
||||
goto err;
|
||||
@@ -1381,10 +1380,8 @@ static int bch2_dev_alloc(struct bch_fs *c, unsigned dev_idx)
|
||||
ca->fs = c;
|
||||
|
||||
bch2_dev_attach(c, ca, dev_idx);
|
||||
- return ret;
|
||||
+ return 0;
|
||||
err:
|
||||
- if (ca)
|
||||
- bch2_dev_free(ca);
|
||||
return -BCH_ERR_ENOMEM_dev_alloc;
|
||||
}
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,79 +0,0 @@
|
||||
From 53f02a6929c291960b8d44540a7085940b82366d Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 7 Nov 2024 19:15:38 -0500
|
||||
Subject: [PATCH 074/233] bcachefs: Don't use page allocator for
|
||||
sb_read_scratch
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Kill another unnecessary dependency on PAGE_SIZE
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/super-io.c | 7 ++++---
|
||||
fs/bcachefs/super-io.h | 2 ++
|
||||
fs/bcachefs/super.c | 4 ++--
|
||||
3 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
|
||||
index c83bd3dedb1b..4c29f8215d54 100644
|
||||
--- a/fs/bcachefs/super-io.c
|
||||
+++ b/fs/bcachefs/super-io.c
|
||||
@@ -892,14 +892,15 @@ static void read_back_super(struct bch_fs *c, struct bch_dev *ca)
|
||||
struct bch_sb *sb = ca->disk_sb.sb;
|
||||
struct bio *bio = ca->disk_sb.bio;
|
||||
|
||||
+ memset(ca->sb_read_scratch, 0, BCH_SB_READ_SCRATCH_BUF_SIZE);
|
||||
+
|
||||
bio_reset(bio, ca->disk_sb.bdev, REQ_OP_READ|REQ_SYNC|REQ_META);
|
||||
bio->bi_iter.bi_sector = le64_to_cpu(sb->layout.sb_offset[0]);
|
||||
bio->bi_end_io = write_super_endio;
|
||||
bio->bi_private = ca;
|
||||
- bch2_bio_map(bio, ca->sb_read_scratch, PAGE_SIZE);
|
||||
+ bch2_bio_map(bio, ca->sb_read_scratch, BCH_SB_READ_SCRATCH_BUF_SIZE);
|
||||
|
||||
- this_cpu_add(ca->io_done->sectors[READ][BCH_DATA_sb],
|
||||
- bio_sectors(bio));
|
||||
+ this_cpu_add(ca->io_done->sectors[READ][BCH_DATA_sb], bio_sectors(bio));
|
||||
|
||||
percpu_ref_get(&ca->io_ref);
|
||||
closure_bio_submit(bio, &c->sb_write);
|
||||
diff --git a/fs/bcachefs/super-io.h b/fs/bcachefs/super-io.h
|
||||
index fadd364e2802..90e7b176cdd0 100644
|
||||
--- a/fs/bcachefs/super-io.h
|
||||
+++ b/fs/bcachefs/super-io.h
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
+#define BCH_SB_READ_SCRATCH_BUF_SIZE 4096
|
||||
+
|
||||
static inline bool bch2_version_compatible(u16 version)
|
||||
{
|
||||
return BCH_VERSION_MAJOR(version) <= BCH_VERSION_MAJOR(bcachefs_metadata_version_current) &&
|
||||
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
|
||||
index ab678231afd4..6ab93db52eca 100644
|
||||
--- a/fs/bcachefs/super.c
|
||||
+++ b/fs/bcachefs/super.c
|
||||
@@ -1201,7 +1201,7 @@ static void bch2_dev_free(struct bch_dev *ca)
|
||||
|
||||
free_percpu(ca->io_done);
|
||||
bch2_dev_buckets_free(ca);
|
||||
- free_page((unsigned long) ca->sb_read_scratch);
|
||||
+ kfree(ca->sb_read_scratch);
|
||||
|
||||
bch2_time_stats_quantiles_exit(&ca->io_latency[WRITE]);
|
||||
bch2_time_stats_quantiles_exit(&ca->io_latency[READ]);
|
||||
@@ -1340,7 +1340,7 @@ static struct bch_dev *__bch2_dev_alloc(struct bch_fs *c,
|
||||
|
||||
if (percpu_ref_init(&ca->io_ref, bch2_dev_io_ref_complete,
|
||||
PERCPU_REF_INIT_DEAD, GFP_KERNEL) ||
|
||||
- !(ca->sb_read_scratch = (void *) __get_free_page(GFP_KERNEL)) ||
|
||||
+ !(ca->sb_read_scratch = kmalloc(BCH_SB_READ_SCRATCH_BUF_SIZE, GFP_KERNEL)) ||
|
||||
bch2_dev_buckets_alloc(c, ca) ||
|
||||
!(ca->io_done = alloc_percpu(*ca->io_done)))
|
||||
goto err;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,29 +0,0 @@
|
||||
From a0678f9c859bf25e60a535e65aff5864ccf66eb2 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 7 Nov 2024 21:50:00 -0500
|
||||
Subject: [PATCH 075/233] bcachefs: Fix shutdown message
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/super.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
|
||||
index 6ab93db52eca..37eee352fa21 100644
|
||||
--- a/fs/bcachefs/super.c
|
||||
+++ b/fs/bcachefs/super.c
|
||||
@@ -290,7 +290,7 @@ static void __bch2_fs_read_only(struct bch_fs *c)
|
||||
|
||||
bch2_fs_journal_stop(&c->journal);
|
||||
|
||||
- bch_info(c, "%sshutdown complete, journal seq %llu",
|
||||
+ bch_info(c, "%sclean shutdown complete, journal seq %llu",
|
||||
test_bit(BCH_FS_clean_shutdown, &c->flags) ? "" : "un",
|
||||
c->journal.seq_ondisk);
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,47 +0,0 @@
|
||||
From 2228901e43af2add536866df466a21117faef0b0 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Tue, 12 Nov 2024 03:53:30 -0500
|
||||
Subject: [PATCH 076/233] bcachefs: delete dead code
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/error.h | 20 --------------------
|
||||
1 file changed, 20 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h
|
||||
index 6551ada926b6..81af0b8ddb52 100644
|
||||
--- a/fs/bcachefs/error.h
|
||||
+++ b/fs/bcachefs/error.h
|
||||
@@ -54,26 +54,6 @@ int bch2_topology_error(struct bch_fs *);
|
||||
_ret; \
|
||||
})
|
||||
|
||||
-/*
|
||||
- * Later we might want to mark only the particular device inconsistent, not the
|
||||
- * entire filesystem:
|
||||
- */
|
||||
-
|
||||
-#define bch2_dev_inconsistent(ca, ...) \
|
||||
-do { \
|
||||
- bch_err(ca, __VA_ARGS__); \
|
||||
- bch2_inconsistent_error((ca)->fs); \
|
||||
-} while (0)
|
||||
-
|
||||
-#define bch2_dev_inconsistent_on(cond, ca, ...) \
|
||||
-({ \
|
||||
- bool _ret = unlikely(!!(cond)); \
|
||||
- \
|
||||
- if (_ret) \
|
||||
- bch2_dev_inconsistent(ca, __VA_ARGS__); \
|
||||
- _ret; \
|
||||
-})
|
||||
-
|
||||
/*
|
||||
* When a transaction update discovers or is causing a fs inconsistency, it's
|
||||
* helpful to also dump the pending updates:
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,230 +0,0 @@
|
||||
From 7fda5f15087a016cc2ef2d449bcba4e4b9b795ce Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 26 Oct 2024 23:35:03 -0400
|
||||
Subject: [PATCH 077/233] bcachefs: bch2_btree_bit_mod_iter()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
factor out a new helper, make it handle extents bitset btrees
|
||||
(freespace).
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_background.c | 57 ++++++----------------------------
|
||||
fs/bcachefs/btree_update.c | 37 +++++++++++-----------
|
||||
fs/bcachefs/btree_update.h | 3 +-
|
||||
3 files changed, 29 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
|
||||
index af791f4dab99..a1bd75a44d79 100644
|
||||
--- a/fs/bcachefs/alloc_background.c
|
||||
+++ b/fs/bcachefs/alloc_background.c
|
||||
@@ -671,44 +671,31 @@ static int bch2_bucket_do_index(struct btree_trans *trans,
|
||||
bool set)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
- struct btree_iter iter;
|
||||
- struct bkey_s_c old;
|
||||
- struct bkey_i *k;
|
||||
enum btree_id btree;
|
||||
+ struct bpos pos;
|
||||
enum bch_bkey_type old_type = !set ? KEY_TYPE_set : KEY_TYPE_deleted;
|
||||
- enum bch_bkey_type new_type = set ? KEY_TYPE_set : KEY_TYPE_deleted;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
- int ret;
|
||||
|
||||
if (a->data_type != BCH_DATA_free &&
|
||||
a->data_type != BCH_DATA_need_discard)
|
||||
return 0;
|
||||
|
||||
- k = bch2_trans_kmalloc_nomemzero(trans, sizeof(*k));
|
||||
- if (IS_ERR(k))
|
||||
- return PTR_ERR(k);
|
||||
-
|
||||
- bkey_init(&k->k);
|
||||
- k->k.type = new_type;
|
||||
-
|
||||
switch (a->data_type) {
|
||||
case BCH_DATA_free:
|
||||
btree = BTREE_ID_freespace;
|
||||
- k->k.p = alloc_freespace_pos(alloc_k.k->p, *a);
|
||||
- bch2_key_resize(&k->k, 1);
|
||||
+ pos = alloc_freespace_pos(alloc_k.k->p, *a);
|
||||
break;
|
||||
case BCH_DATA_need_discard:
|
||||
btree = BTREE_ID_need_discard;
|
||||
- k->k.p = alloc_k.k->p;
|
||||
+ pos = alloc_k.k->p;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
- old = bch2_bkey_get_iter(trans, &iter, btree,
|
||||
- bkey_start_pos(&k->k),
|
||||
- BTREE_ITER_intent);
|
||||
- ret = bkey_err(old);
|
||||
+ struct btree_iter iter;
|
||||
+ struct bkey_s_c old = bch2_bkey_get_iter(trans, &iter, btree, pos, BTREE_ITER_intent);
|
||||
+ int ret = bkey_err(old);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -728,7 +715,7 @@ static int bch2_bucket_do_index(struct btree_trans *trans,
|
||||
goto err;
|
||||
}
|
||||
|
||||
- ret = bch2_trans_update(trans, &iter, k, 0);
|
||||
+ ret = bch2_btree_bit_mod_iter(trans, &iter, set);
|
||||
err:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
printbuf_exit(&buf);
|
||||
@@ -1163,18 +1150,7 @@ int bch2_check_alloc_key(struct btree_trans *trans,
|
||||
bch2_bkey_types[k.k->type],
|
||||
bch2_bkey_types[discard_key_type],
|
||||
(bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
|
||||
- struct bkey_i *update =
|
||||
- bch2_trans_kmalloc(trans, sizeof(*update));
|
||||
-
|
||||
- ret = PTR_ERR_OR_ZERO(update);
|
||||
- if (ret)
|
||||
- goto err;
|
||||
-
|
||||
- bkey_init(&update->k);
|
||||
- update->k.type = discard_key_type;
|
||||
- update->k.p = discard_iter->pos;
|
||||
-
|
||||
- ret = bch2_trans_update(trans, discard_iter, update, 0);
|
||||
+ ret = bch2_btree_bit_mod_iter(trans, discard_iter, !!discard_key_type);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
@@ -1194,19 +1170,7 @@ int bch2_check_alloc_key(struct btree_trans *trans,
|
||||
bch2_bkey_types[freespace_key_type],
|
||||
(printbuf_reset(&buf),
|
||||
bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
|
||||
- struct bkey_i *update =
|
||||
- bch2_trans_kmalloc(trans, sizeof(*update));
|
||||
-
|
||||
- ret = PTR_ERR_OR_ZERO(update);
|
||||
- if (ret)
|
||||
- goto err;
|
||||
-
|
||||
- bkey_init(&update->k);
|
||||
- update->k.type = freespace_key_type;
|
||||
- update->k.p = freespace_iter->pos;
|
||||
- bch2_key_resize(&update->k, 1);
|
||||
-
|
||||
- ret = bch2_trans_update(trans, freespace_iter, update, 0);
|
||||
+ ret = bch2_btree_bit_mod_iter(trans, freespace_iter, !!freespace_key_type);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
@@ -1420,8 +1384,7 @@ static noinline_for_stack int bch2_check_discard_freespace_key(struct btree_tran
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
delete:
|
||||
- ret = bch2_btree_delete_extent_at(trans, iter,
|
||||
- iter->btree_id == BTREE_ID_freespace ? 1 : 0, 0) ?:
|
||||
+ ret = bch2_btree_bit_mod_iter(trans, iter, false) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
BCH_TRANS_COMMIT_no_enospc);
|
||||
goto out;
|
||||
diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c
|
||||
index f3d7ca3d92b9..06fd5aa62296 100644
|
||||
--- a/fs/bcachefs/btree_update.c
|
||||
+++ b/fs/bcachefs/btree_update.c
|
||||
@@ -669,27 +669,19 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id, struct bkey_i *k,
|
||||
bch2_btree_insert_trans(trans, id, k, iter_flags));
|
||||
}
|
||||
|
||||
-int bch2_btree_delete_extent_at(struct btree_trans *trans, struct btree_iter *iter,
|
||||
- unsigned len, unsigned update_flags)
|
||||
+int bch2_btree_delete_at(struct btree_trans *trans,
|
||||
+ struct btree_iter *iter, unsigned update_flags)
|
||||
{
|
||||
- struct bkey_i *k;
|
||||
-
|
||||
- k = bch2_trans_kmalloc(trans, sizeof(*k));
|
||||
- if (IS_ERR(k))
|
||||
- return PTR_ERR(k);
|
||||
+ struct bkey_i *k = bch2_trans_kmalloc(trans, sizeof(*k));
|
||||
+ int ret = PTR_ERR_OR_ZERO(k);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
bkey_init(&k->k);
|
||||
k->k.p = iter->pos;
|
||||
- bch2_key_resize(&k->k, len);
|
||||
return bch2_trans_update(trans, iter, k, update_flags);
|
||||
}
|
||||
|
||||
-int bch2_btree_delete_at(struct btree_trans *trans,
|
||||
- struct btree_iter *iter, unsigned update_flags)
|
||||
-{
|
||||
- return bch2_btree_delete_extent_at(trans, iter, 0, update_flags);
|
||||
-}
|
||||
-
|
||||
int bch2_btree_delete(struct btree_trans *trans,
|
||||
enum btree_id btree, struct bpos pos,
|
||||
unsigned update_flags)
|
||||
@@ -791,8 +783,7 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int bch2_btree_bit_mod(struct btree_trans *trans, enum btree_id btree,
|
||||
- struct bpos pos, bool set)
|
||||
+int bch2_btree_bit_mod_iter(struct btree_trans *trans, struct btree_iter *iter, bool set)
|
||||
{
|
||||
struct bkey_i *k = bch2_trans_kmalloc(trans, sizeof(*k));
|
||||
int ret = PTR_ERR_OR_ZERO(k);
|
||||
@@ -801,13 +792,21 @@ int bch2_btree_bit_mod(struct btree_trans *trans, enum btree_id btree,
|
||||
|
||||
bkey_init(&k->k);
|
||||
k->k.type = set ? KEY_TYPE_set : KEY_TYPE_deleted;
|
||||
- k->k.p = pos;
|
||||
+ k->k.p = iter->pos;
|
||||
+ if (iter->flags & BTREE_ITER_is_extents)
|
||||
+ bch2_key_resize(&k->k, 1);
|
||||
+
|
||||
+ return bch2_trans_update(trans, iter, k, 0);
|
||||
+}
|
||||
|
||||
+int bch2_btree_bit_mod(struct btree_trans *trans, enum btree_id btree,
|
||||
+ struct bpos pos, bool set)
|
||||
+{
|
||||
struct btree_iter iter;
|
||||
bch2_trans_iter_init(trans, &iter, btree, pos, BTREE_ITER_intent);
|
||||
|
||||
- ret = bch2_btree_iter_traverse(&iter) ?:
|
||||
- bch2_trans_update(trans, &iter, k, 0);
|
||||
+ int ret = bch2_btree_iter_traverse(&iter) ?:
|
||||
+ bch2_btree_bit_mod_iter(trans, &iter, set);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/fs/bcachefs/btree_update.h b/fs/bcachefs/btree_update.h
|
||||
index 3bc57d43aa83..58df20194306 100644
|
||||
--- a/fs/bcachefs/btree_update.h
|
||||
+++ b/fs/bcachefs/btree_update.h
|
||||
@@ -46,8 +46,6 @@ enum bch_trans_commit_flags {
|
||||
|
||||
void bch2_trans_commit_flags_to_text(struct printbuf *, enum bch_trans_commit_flags);
|
||||
|
||||
-int bch2_btree_delete_extent_at(struct btree_trans *, struct btree_iter *,
|
||||
- unsigned, unsigned);
|
||||
int bch2_btree_delete_at(struct btree_trans *, struct btree_iter *, unsigned);
|
||||
int bch2_btree_delete(struct btree_trans *, enum btree_id, struct bpos, unsigned);
|
||||
|
||||
@@ -65,6 +63,7 @@ int bch2_btree_delete_range_trans(struct btree_trans *, enum btree_id,
|
||||
int bch2_btree_delete_range(struct bch_fs *, enum btree_id,
|
||||
struct bpos, struct bpos, unsigned, u64 *);
|
||||
|
||||
+int bch2_btree_bit_mod_iter(struct btree_trans *, struct btree_iter *, bool);
|
||||
int bch2_btree_bit_mod(struct btree_trans *, enum btree_id, struct bpos, bool);
|
||||
int bch2_btree_bit_mod_buffered(struct btree_trans *, enum btree_id, struct bpos, bool);
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,59 +0,0 @@
|
||||
From 7ad0ba0e1849e010a7be3e90f6588b4460a469e4 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 26 Oct 2024 22:52:06 -0400
|
||||
Subject: [PATCH 078/233] bcachefs: Delete dead code from
|
||||
bch2_discard_one_bucket()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
alloc key validation ensures that if a bucket is in need_discard state
|
||||
the sector counts are all zero - we don't have to check for that.
|
||||
|
||||
The NEED_INC_GEN check appears to be dead code, as well: we only see
|
||||
buckets in the need_discard btree, and it's an error if they aren't in
|
||||
the need_discard state.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_background.c | 16 ----------------
|
||||
1 file changed, 16 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
|
||||
index a1bd75a44d79..38df36f8e70a 100644
|
||||
--- a/fs/bcachefs/alloc_background.c
|
||||
+++ b/fs/bcachefs/alloc_background.c
|
||||
@@ -1756,22 +1756,7 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
- if (bch2_bucket_sectors_total(a->v)) {
|
||||
- if (bch2_trans_inconsistent_on(c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_info,
|
||||
- trans, "attempting to discard bucket with dirty data\n%s",
|
||||
- (bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
|
||||
- ret = -EIO;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
if (a->v.data_type != BCH_DATA_need_discard) {
|
||||
- if (data_type_is_empty(a->v.data_type) &&
|
||||
- BCH_ALLOC_V4_NEED_INC_GEN(&a->v)) {
|
||||
- a->v.gen++;
|
||||
- SET_BCH_ALLOC_V4_NEED_INC_GEN(&a->v, false);
|
||||
- goto write;
|
||||
- }
|
||||
-
|
||||
if (bch2_trans_inconsistent_on(c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_info,
|
||||
trans, "bucket incorrectly set in need_discard btree\n"
|
||||
"%s",
|
||||
@@ -1814,7 +1799,6 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
|
||||
}
|
||||
|
||||
SET_BCH_ALLOC_V4_NEED_DISCARD(&a->v, false);
|
||||
-write:
|
||||
alloc_data_type_set(&a->v, a->v.data_type);
|
||||
|
||||
ret = bch2_trans_update(trans, &iter, &a->k_i, 0) ?:
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From d6ad842cf77fe209875d699d3b2d64b764d5edd2 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Tue, 29 Oct 2024 01:17:08 -0400
|
||||
Subject: [PATCH 079/233] bcachefs: lru errors are expected when reconstructing
|
||||
alloc
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/recovery.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
|
||||
index 431698189090..7086a7226989 100644
|
||||
--- a/fs/bcachefs/recovery.c
|
||||
+++ b/fs/bcachefs/recovery.c
|
||||
@@ -113,6 +113,8 @@ static void bch2_reconstruct_alloc(struct bch_fs *c)
|
||||
__set_bit_le64(BCH_FSCK_ERR_fs_usage_persistent_reserved_wrong, ext->errors_silent);
|
||||
__set_bit_le64(BCH_FSCK_ERR_fs_usage_replicas_wrong, ext->errors_silent);
|
||||
|
||||
+ __set_bit_le64(BCH_FSCK_ERR_alloc_key_to_missing_lru_entry, ext->errors_silent);
|
||||
+
|
||||
__set_bit_le64(BCH_FSCK_ERR_alloc_key_data_type_wrong, ext->errors_silent);
|
||||
__set_bit_le64(BCH_FSCK_ERR_alloc_key_gen_wrong, ext->errors_silent);
|
||||
__set_bit_le64(BCH_FSCK_ERR_alloc_key_dirty_sectors_wrong, ext->errors_silent);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,280 +0,0 @@
|
||||
From 4a370320dcb4ea925e38a852baf85724baf9711a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 28 Oct 2024 21:27:23 -0400
|
||||
Subject: [PATCH 080/233] bcachefs: Kill FSCK_NEED_FSCK
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If we find an error that indicates that we need to run fsck, we can
|
||||
specify that directly with run_explicit_recovery_pass().
|
||||
|
||||
These are now log_fsck_err() calls: we're just logging in the superblock
|
||||
that an error occurred - and possibly doing an emergency shutdown,
|
||||
depending on policy.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_update_interior.c | 18 ++++++------------
|
||||
fs/bcachefs/buckets.c | 29 +++++++++++++++++------------
|
||||
fs/bcachefs/error.c | 21 +++++++++++++--------
|
||||
fs/bcachefs/error.h | 12 ++++++------
|
||||
fs/bcachefs/sb-errors_format.h | 5 ++---
|
||||
5 files changed, 44 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
|
||||
index c11babe31f54..faa2816e02a0 100644
|
||||
--- a/fs/bcachefs/btree_update_interior.c
|
||||
+++ b/fs/bcachefs/btree_update_interior.c
|
||||
@@ -62,7 +62,7 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
if (!bpos_eq(b->data->min_key, POS_MIN)) {
|
||||
printbuf_reset(&buf);
|
||||
bch2_bpos_to_text(&buf, b->data->min_key);
|
||||
- need_fsck_err(trans, btree_root_bad_min_key,
|
||||
+ log_fsck_err(trans, btree_root_bad_min_key,
|
||||
"btree root with incorrect min_key: %s", buf.buf);
|
||||
goto topology_repair;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
if (!bpos_eq(b->data->max_key, SPOS_MAX)) {
|
||||
printbuf_reset(&buf);
|
||||
bch2_bpos_to_text(&buf, b->data->max_key);
|
||||
- need_fsck_err(trans, btree_root_bad_max_key,
|
||||
+ log_fsck_err(trans, btree_root_bad_max_key,
|
||||
"btree root with incorrect max_key: %s", buf.buf);
|
||||
goto topology_repair;
|
||||
}
|
||||
@@ -106,7 +106,7 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
prt_str(&buf, "\n next ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
|
||||
- need_fsck_err(trans, btree_node_topology_bad_min_key, "%s", buf.buf);
|
||||
+ log_fsck_err(trans, btree_node_topology_bad_min_key, "%s", buf.buf);
|
||||
goto topology_repair;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
prt_str(&buf, " node ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
- need_fsck_err(trans, btree_node_topology_empty_interior_node, "%s", buf.buf);
|
||||
+ log_fsck_err(trans, btree_node_topology_empty_interior_node, "%s", buf.buf);
|
||||
goto topology_repair;
|
||||
} else if (!bpos_eq(prev.k->k.p, b->key.k.p)) {
|
||||
bch2_topology_error(c);
|
||||
@@ -136,7 +136,7 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
prt_str(&buf, "\n last key ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(prev.k));
|
||||
|
||||
- need_fsck_err(trans, btree_node_topology_bad_max_key, "%s", buf.buf);
|
||||
+ log_fsck_err(trans, btree_node_topology_bad_max_key, "%s", buf.buf);
|
||||
goto topology_repair;
|
||||
}
|
||||
out:
|
||||
@@ -146,13 +146,7 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
topology_repair:
|
||||
- if ((c->opts.recovery_passes & BIT_ULL(BCH_RECOVERY_PASS_check_topology)) &&
|
||||
- c->curr_recovery_pass > BCH_RECOVERY_PASS_check_topology) {
|
||||
- bch2_inconsistent_error(c);
|
||||
- ret = -BCH_ERR_btree_need_topology_repair;
|
||||
- } else {
|
||||
- ret = bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_topology);
|
||||
- }
|
||||
+ ret = bch2_topology_error(c);
|
||||
goto out;
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
|
||||
index c4123fa4f250..5b42f0a7b0cb 100644
|
||||
--- a/fs/bcachefs/buckets.c
|
||||
+++ b/fs/bcachefs/buckets.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "movinggc.h"
|
||||
#include "rebalance.h"
|
||||
#include "recovery.h"
|
||||
+#include "recovery_passes.h"
|
||||
#include "reflink.h"
|
||||
#include "replicas.h"
|
||||
#include "subvolume.h"
|
||||
@@ -402,8 +403,8 @@ int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
|
||||
BUG_ON(!sectors);
|
||||
|
||||
if (gen_after(ptr->gen, b_gen)) {
|
||||
- bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
|
||||
- ptr_gen_newer_than_bucket_gen,
|
||||
+ bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
+ log_fsck_err(trans, ptr_gen_newer_than_bucket_gen,
|
||||
"bucket %u:%zu gen %u data type %s: ptr gen %u newer than bucket gen\n"
|
||||
"while marking %s",
|
||||
ptr->dev, bucket_nr, b_gen,
|
||||
@@ -416,8 +417,8 @@ int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
|
||||
}
|
||||
|
||||
if (gen_cmp(b_gen, ptr->gen) > BUCKET_GC_GEN_MAX) {
|
||||
- bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
|
||||
- ptr_too_stale,
|
||||
+ bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
+ log_fsck_err(trans, ptr_too_stale,
|
||||
"bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
|
||||
"while marking %s",
|
||||
ptr->dev, bucket_nr, b_gen,
|
||||
@@ -436,8 +437,8 @@ int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
|
||||
}
|
||||
|
||||
if (b_gen != ptr->gen) {
|
||||
- bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
|
||||
- stale_dirty_ptr,
|
||||
+ bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
+ log_fsck_err(trans, stale_dirty_ptr,
|
||||
"bucket %u:%zu gen %u (mem gen %u) data type %s: stale dirty ptr (gen %u)\n"
|
||||
"while marking %s",
|
||||
ptr->dev, bucket_nr, b_gen,
|
||||
@@ -452,8 +453,8 @@ int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
|
||||
}
|
||||
|
||||
if (bucket_data_type_mismatch(bucket_data_type, ptr_data_type)) {
|
||||
- bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
|
||||
- ptr_bucket_data_type_mismatch,
|
||||
+ bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
+ log_fsck_err(trans, ptr_bucket_data_type_mismatch,
|
||||
"bucket %u:%zu gen %u different types of data in same bucket: %s, %s\n"
|
||||
"while marking %s",
|
||||
ptr->dev, bucket_nr, b_gen,
|
||||
@@ -467,8 +468,8 @@ int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
|
||||
}
|
||||
|
||||
if ((u64) *bucket_sectors + sectors > U32_MAX) {
|
||||
- bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
|
||||
- bucket_sector_count_overflow,
|
||||
+ bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
+ log_fsck_err(trans, bucket_sector_count_overflow,
|
||||
"bucket %u:%zu gen %u data type %s sector count overflow: %u + %lli > U32_MAX\n"
|
||||
"while marking %s",
|
||||
ptr->dev, bucket_nr, b_gen,
|
||||
@@ -486,7 +487,9 @@ int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
err:
|
||||
+fsck_err:
|
||||
bch2_dump_trans_updates(trans);
|
||||
+ bch2_inconsistent_error(c);
|
||||
ret = -BCH_ERR_bucket_ref_update;
|
||||
goto out;
|
||||
}
|
||||
@@ -952,6 +955,7 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
|
||||
enum bch_data_type type,
|
||||
unsigned sectors)
|
||||
{
|
||||
+ struct bch_fs *c = trans->c;
|
||||
struct btree_iter iter;
|
||||
int ret = 0;
|
||||
|
||||
@@ -961,8 +965,8 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
|
||||
return PTR_ERR(a);
|
||||
|
||||
if (a->v.data_type && type && a->v.data_type != type) {
|
||||
- bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
|
||||
- bucket_metadata_type_mismatch,
|
||||
+ bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations);
|
||||
+ log_fsck_err(trans, bucket_metadata_type_mismatch,
|
||||
"bucket %llu:%llu gen %u different types of data in same bucket: %s, %s\n"
|
||||
"while marking %s",
|
||||
iter.pos.inode, iter.pos.offset, a->v.gen,
|
||||
@@ -980,6 +984,7 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
|
||||
ret = bch2_trans_update(trans, &iter, &a->k_i, 0);
|
||||
}
|
||||
err:
|
||||
+fsck_err:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c
|
||||
index b679def8fb98..22b0fa405a39 100644
|
||||
--- a/fs/bcachefs/error.c
|
||||
+++ b/fs/bcachefs/error.c
|
||||
@@ -385,9 +385,7 @@ int __bch2_fsck_err(struct bch_fs *c,
|
||||
prt_str(out, ", not ");
|
||||
prt_actioning(out, action);
|
||||
}
|
||||
- } else if (flags & FSCK_NEED_FSCK) {
|
||||
- prt_str(out, " (run fsck to correct)");
|
||||
- } else {
|
||||
+ } else if (!(flags & FSCK_CAN_IGNORE)) {
|
||||
prt_str(out, " (repair unimplemented)");
|
||||
}
|
||||
|
||||
@@ -424,11 +422,18 @@ int __bch2_fsck_err(struct bch_fs *c,
|
||||
if (inconsistent)
|
||||
bch2_inconsistent_error(c);
|
||||
|
||||
- if (ret == -BCH_ERR_fsck_fix) {
|
||||
- set_bit(BCH_FS_errors_fixed, &c->flags);
|
||||
- } else {
|
||||
- set_bit(BCH_FS_errors_not_fixed, &c->flags);
|
||||
- set_bit(BCH_FS_error, &c->flags);
|
||||
+ /*
|
||||
+ * We don't yet track whether the filesystem currently has errors, for
|
||||
+ * log_fsck_err()s: that would require us to track for every error type
|
||||
+ * which recovery pass corrects it, to get the fsck exit status correct:
|
||||
+ */
|
||||
+ if (flags & FSCK_CAN_FIX) {
|
||||
+ if (ret == -BCH_ERR_fsck_fix) {
|
||||
+ set_bit(BCH_FS_errors_fixed, &c->flags);
|
||||
+ } else {
|
||||
+ set_bit(BCH_FS_errors_not_fixed, &c->flags);
|
||||
+ set_bit(BCH_FS_error, &c->flags);
|
||||
+ }
|
||||
}
|
||||
err:
|
||||
if (action != action_orig)
|
||||
diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h
|
||||
index 81af0b8ddb52..24c41a9994df 100644
|
||||
--- a/fs/bcachefs/error.h
|
||||
+++ b/fs/bcachefs/error.h
|
||||
@@ -129,12 +129,6 @@ void bch2_flush_fsck_errs(struct bch_fs *);
|
||||
(unlikely(cond) ? __fsck_err(c, _flags, _err_type, __VA_ARGS__) : false);\
|
||||
})
|
||||
|
||||
-#define need_fsck_err_on(cond, c, _err_type, ...) \
|
||||
- __fsck_err_on(cond, c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, _err_type, __VA_ARGS__)
|
||||
-
|
||||
-#define need_fsck_err(c, _err_type, ...) \
|
||||
- __fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, _err_type, __VA_ARGS__)
|
||||
-
|
||||
#define mustfix_fsck_err(c, _err_type, ...) \
|
||||
__fsck_err(c, FSCK_CAN_FIX, _err_type, __VA_ARGS__)
|
||||
|
||||
@@ -147,6 +141,12 @@ void bch2_flush_fsck_errs(struct bch_fs *);
|
||||
#define fsck_err_on(cond, c, _err_type, ...) \
|
||||
__fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__)
|
||||
|
||||
+#define log_fsck_err(c, _err_type, ...) \
|
||||
+ __fsck_err(c, FSCK_CAN_IGNORE, _err_type, __VA_ARGS__)
|
||||
+
|
||||
+#define log_fsck_err_on(cond, c, _err_type, ...) \
|
||||
+ __fsck_err_on(cond, c, FSCK_CAN_IGNORE, _err_type, __VA_ARGS__)
|
||||
+
|
||||
enum bch_validate_flags;
|
||||
__printf(5, 6)
|
||||
int __bch2_bkey_fsck_err(struct bch_fs *,
|
||||
diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h
|
||||
index 9feb6739f77a..f2b38493356d 100644
|
||||
--- a/fs/bcachefs/sb-errors_format.h
|
||||
+++ b/fs/bcachefs/sb-errors_format.h
|
||||
@@ -5,9 +5,8 @@
|
||||
enum bch_fsck_flags {
|
||||
FSCK_CAN_FIX = 1 << 0,
|
||||
FSCK_CAN_IGNORE = 1 << 1,
|
||||
- FSCK_NEED_FSCK = 1 << 2,
|
||||
- FSCK_NO_RATELIMIT = 1 << 3,
|
||||
- FSCK_AUTOFIX = 1 << 4,
|
||||
+ FSCK_NO_RATELIMIT = 1 << 2,
|
||||
+ FSCK_AUTOFIX = 1 << 3,
|
||||
};
|
||||
|
||||
#define BCH_SB_ERRS() \
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,230 +0,0 @@
|
||||
From b36ff5dc0842ed3c4aa202107da727cc74b59cd0 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Mon, 28 Oct 2024 23:43:16 -0400
|
||||
Subject: [PATCH 081/233] bcachefs: Reserve 8 bits in bch_reflink_p
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Better repair for reflink pointers, as well as propagating new inode
|
||||
options to indirect extents, are going to require a few extra bits
|
||||
bch_reflink_p: so claim a few from the high end of the destination
|
||||
index.
|
||||
|
||||
Also add some missing bounds checking.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/extent_update.c | 2 +-
|
||||
fs/bcachefs/extents.c | 2 +-
|
||||
fs/bcachefs/io_read.c | 14 ++++-------
|
||||
fs/bcachefs/reflink.c | 45 +++++++++++++++++++++++++-----------
|
||||
fs/bcachefs/reflink_format.h | 4 +++-
|
||||
5 files changed, 41 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/extent_update.c b/fs/bcachefs/extent_update.c
|
||||
index 45c87c019f6b..6aac579a692a 100644
|
||||
--- a/fs/bcachefs/extent_update.c
|
||||
+++ b/fs/bcachefs/extent_update.c
|
||||
@@ -64,7 +64,7 @@ static int count_iters_for_insert(struct btree_trans *trans,
|
||||
break;
|
||||
case KEY_TYPE_reflink_p: {
|
||||
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
|
||||
- u64 idx = le64_to_cpu(p.v->idx);
|
||||
+ u64 idx = REFLINK_P_IDX(p.v);
|
||||
unsigned sectors = bpos_min(*end, p.k->p).offset -
|
||||
bkey_start_offset(p.k);
|
||||
struct btree_iter iter;
|
||||
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
|
||||
index bc7cfdb66687..98bb680b3860 100644
|
||||
--- a/fs/bcachefs/extents.c
|
||||
+++ b/fs/bcachefs/extents.c
|
||||
@@ -1495,7 +1495,7 @@ int bch2_cut_front_s(struct bpos where, struct bkey_s k)
|
||||
case KEY_TYPE_reflink_p: {
|
||||
struct bkey_s_reflink_p p = bkey_s_to_reflink_p(k);
|
||||
|
||||
- le64_add_cpu(&p.v->idx, sub);
|
||||
+ SET_REFLINK_P_IDX(p.v, REFLINK_P_IDX(p.v) + sub);
|
||||
break;
|
||||
}
|
||||
case KEY_TYPE_inline_data:
|
||||
diff --git a/fs/bcachefs/io_read.c b/fs/bcachefs/io_read.c
|
||||
index cbc3cc1f6d03..c700a95df89e 100644
|
||||
--- a/fs/bcachefs/io_read.c
|
||||
+++ b/fs/bcachefs/io_read.c
|
||||
@@ -754,17 +754,13 @@ int __bch2_read_indirect_extent(struct btree_trans *trans,
|
||||
unsigned *offset_into_extent,
|
||||
struct bkey_buf *orig_k)
|
||||
{
|
||||
- struct btree_iter iter;
|
||||
- struct bkey_s_c k;
|
||||
- u64 reflink_offset;
|
||||
- int ret;
|
||||
+ struct bkey_i_reflink_p *p = bkey_i_to_reflink_p(orig_k->k);
|
||||
+ u64 reflink_offset = REFLINK_P_IDX(&p->v) + *offset_into_extent;
|
||||
|
||||
- reflink_offset = le64_to_cpu(bkey_i_to_reflink_p(orig_k->k)->v.idx) +
|
||||
- *offset_into_extent;
|
||||
-
|
||||
- k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_reflink,
|
||||
+ struct btree_iter iter;
|
||||
+ struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_reflink,
|
||||
POS(0, reflink_offset), 0);
|
||||
- ret = bkey_err(k);
|
||||
+ int ret = bkey_err(k);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
|
||||
index 96cf50f4705d..addaf5f74624 100644
|
||||
--- a/fs/bcachefs/reflink.c
|
||||
+++ b/fs/bcachefs/reflink.c
|
||||
@@ -35,10 +35,10 @@ int bch2_reflink_p_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
|
||||
int ret = 0;
|
||||
|
||||
- bkey_fsck_err_on(le64_to_cpu(p.v->idx) < le32_to_cpu(p.v->front_pad),
|
||||
+ bkey_fsck_err_on(REFLINK_P_IDX(p.v) < le32_to_cpu(p.v->front_pad),
|
||||
c, reflink_p_front_pad_bad,
|
||||
"idx < front_pad (%llu < %u)",
|
||||
- le64_to_cpu(p.v->idx), le32_to_cpu(p.v->front_pad));
|
||||
+ REFLINK_P_IDX(p.v), le32_to_cpu(p.v->front_pad));
|
||||
fsck_err:
|
||||
return ret;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ void bch2_reflink_p_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
|
||||
|
||||
prt_printf(out, "idx %llu front_pad %u back_pad %u",
|
||||
- le64_to_cpu(p.v->idx),
|
||||
+ REFLINK_P_IDX(p.v),
|
||||
le32_to_cpu(p.v->front_pad),
|
||||
le32_to_cpu(p.v->back_pad));
|
||||
}
|
||||
@@ -65,7 +65,7 @@ bool bch2_reflink_p_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r
|
||||
*/
|
||||
return false;
|
||||
|
||||
- if (le64_to_cpu(l.v->idx) + l.k->size != le64_to_cpu(r.v->idx))
|
||||
+ if (REFLINK_P_IDX(l.v) + l.k->size != REFLINK_P_IDX(r.v))
|
||||
return false;
|
||||
|
||||
bch2_key_resize(l.k, l.k->size + r.k->size);
|
||||
@@ -115,12 +115,12 @@ static int trans_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
u64 pad;
|
||||
|
||||
pad = max_t(s64, le32_to_cpu(v->front_pad),
|
||||
- le64_to_cpu(v->idx) - bkey_start_offset(&k->k));
|
||||
+ REFLINK_P_IDX(v) - bkey_start_offset(&k->k));
|
||||
BUG_ON(pad > U32_MAX);
|
||||
v->front_pad = cpu_to_le32(pad);
|
||||
|
||||
pad = max_t(s64, le32_to_cpu(v->back_pad),
|
||||
- k->k.p.offset - p.k->size - le64_to_cpu(v->idx));
|
||||
+ k->k.p.offset - p.k->size - REFLINK_P_IDX(v));
|
||||
BUG_ON(pad > U32_MAX);
|
||||
v->back_pad = cpu_to_le32(pad);
|
||||
}
|
||||
@@ -147,8 +147,8 @@ static s64 gc_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
struct bch_fs *c = trans->c;
|
||||
struct reflink_gc *r;
|
||||
int add = !(flags & BTREE_TRIGGER_overwrite) ? 1 : -1;
|
||||
- u64 start = le64_to_cpu(p.v->idx);
|
||||
- u64 end = le64_to_cpu(p.v->idx) + p.k->size;
|
||||
+ u64 start = REFLINK_P_IDX(p.v);
|
||||
+ u64 end = start + p.k->size;
|
||||
u64 next_idx = end + le32_to_cpu(p.v->back_pad);
|
||||
s64 ret = 0;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
@@ -210,8 +210,8 @@ static int __trigger_reflink_p(struct btree_trans *trans,
|
||||
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
|
||||
int ret = 0;
|
||||
|
||||
- u64 idx = le64_to_cpu(p.v->idx) - le32_to_cpu(p.v->front_pad);
|
||||
- u64 end = le64_to_cpu(p.v->idx) + p.k->size + le32_to_cpu(p.v->back_pad);
|
||||
+ u64 idx = REFLINK_P_IDX(p.v) - le32_to_cpu(p.v->front_pad);
|
||||
+ u64 end = REFLINK_P_IDX(p.v) + p.k->size + le32_to_cpu(p.v->back_pad);
|
||||
|
||||
if (flags & BTREE_TRIGGER_transactional) {
|
||||
while (idx < end && !ret)
|
||||
@@ -258,7 +258,16 @@ int bch2_trigger_reflink_p(struct btree_trans *trans,
|
||||
int bch2_reflink_v_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
enum bch_validate_flags flags)
|
||||
{
|
||||
- return bch2_bkey_ptrs_validate(c, k, flags);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ bkey_fsck_err_on(bkey_gt(k.k->p, POS(0, REFLINK_P_IDX_MAX)),
|
||||
+ c, reflink_v_pos_bad,
|
||||
+ "indirect extent above maximum position 0:%llu",
|
||||
+ REFLINK_P_IDX_MAX);
|
||||
+
|
||||
+ ret = bch2_bkey_ptrs_validate(c, k, flags);
|
||||
+fsck_err:
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
void bch2_reflink_v_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
@@ -358,6 +367,14 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
+ /*
|
||||
+ * XXX: we're assuming that 56 bits will be enough for the life of the
|
||||
+ * filesystem: we need to implement wraparound, with a cursor in the
|
||||
+ * logged ops btree:
|
||||
+ */
|
||||
+ if (bkey_ge(reflink_iter.pos, POS(0, REFLINK_P_IDX_MAX - orig->k.size)))
|
||||
+ return -ENOSPC;
|
||||
+
|
||||
r_v = bch2_trans_kmalloc(trans, sizeof(__le64) + bkey_bytes(&orig->k));
|
||||
ret = PTR_ERR_OR_ZERO(r_v);
|
||||
if (ret)
|
||||
@@ -394,7 +411,7 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
|
||||
memset(&r_p->v, 0, sizeof(r_p->v));
|
||||
#endif
|
||||
|
||||
- r_p->v.idx = cpu_to_le64(bkey_start_offset(&r_v->k));
|
||||
+ SET_REFLINK_P_IDX(&r_p->v, bkey_start_offset(&r_v->k));
|
||||
|
||||
ret = bch2_trans_update(trans, extent_iter, &r_p->k_i,
|
||||
BTREE_UPDATE_internal_snapshot_node);
|
||||
@@ -533,11 +550,11 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
struct bkey_i_reflink_p *dst_p =
|
||||
bkey_reflink_p_init(new_dst.k);
|
||||
|
||||
- u64 offset = le64_to_cpu(src_p.v->idx) +
|
||||
+ u64 offset = REFLINK_P_IDX(src_p.v) +
|
||||
(src_want.offset -
|
||||
bkey_start_offset(src_k.k));
|
||||
|
||||
- dst_p->v.idx = cpu_to_le64(offset);
|
||||
+ SET_REFLINK_P_IDX(&dst_p->v, offset);
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
diff --git a/fs/bcachefs/reflink_format.h b/fs/bcachefs/reflink_format.h
|
||||
index 6772eebb1fc6..0d8de13b9ddf 100644
|
||||
--- a/fs/bcachefs/reflink_format.h
|
||||
+++ b/fs/bcachefs/reflink_format.h
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
struct bch_reflink_p {
|
||||
struct bch_val v;
|
||||
- __le64 idx;
|
||||
+ __le64 idx_flags;
|
||||
/*
|
||||
* A reflink pointer might point to an indirect extent which is then
|
||||
* later split (by copygc or rebalance). If we only pointed to part of
|
||||
@@ -17,6 +17,8 @@ struct bch_reflink_p {
|
||||
__le32 back_pad;
|
||||
} __packed __aligned(8);
|
||||
|
||||
+LE64_BITMASK(REFLINK_P_IDX, struct bch_reflink_p, idx_flags, 0, 56);
|
||||
+
|
||||
struct bch_reflink_v {
|
||||
struct bch_val v;
|
||||
__le64 refcount;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,383 +0,0 @@
|
||||
From 6cf666ffb5694d38860eb3f46d773825487e7f7e Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 31 Oct 2024 01:25:09 -0400
|
||||
Subject: [PATCH 082/233] bcachefs: Reorganize reflink.c a bit
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_gc.c | 92 ------------------
|
||||
fs/bcachefs/reflink.c | 214 ++++++++++++++++++++++++++++++-----------
|
||||
fs/bcachefs/reflink.h | 3 +
|
||||
3 files changed, 160 insertions(+), 149 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
|
||||
index e45cf32a6403..2e8cfc4d3265 100644
|
||||
--- a/fs/bcachefs/btree_gc.c
|
||||
+++ b/fs/bcachefs/btree_gc.c
|
||||
@@ -937,98 +937,6 @@ static int bch2_gc_alloc_start(struct bch_fs *c)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int bch2_gc_write_reflink_key(struct btree_trans *trans,
|
||||
- struct btree_iter *iter,
|
||||
- struct bkey_s_c k,
|
||||
- size_t *idx)
|
||||
-{
|
||||
- struct bch_fs *c = trans->c;
|
||||
- const __le64 *refcount = bkey_refcount_c(k);
|
||||
- struct printbuf buf = PRINTBUF;
|
||||
- struct reflink_gc *r;
|
||||
- int ret = 0;
|
||||
-
|
||||
- if (!refcount)
|
||||
- return 0;
|
||||
-
|
||||
- while ((r = genradix_ptr(&c->reflink_gc_table, *idx)) &&
|
||||
- r->offset < k.k->p.offset)
|
||||
- ++*idx;
|
||||
-
|
||||
- if (!r ||
|
||||
- r->offset != k.k->p.offset ||
|
||||
- r->size != k.k->size) {
|
||||
- bch_err(c, "unexpected inconsistency walking reflink table at gc finish");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (fsck_err_on(r->refcount != le64_to_cpu(*refcount),
|
||||
- trans, reflink_v_refcount_wrong,
|
||||
- "reflink key has wrong refcount:\n"
|
||||
- " %s\n"
|
||||
- " should be %u",
|
||||
- (bch2_bkey_val_to_text(&buf, c, k), buf.buf),
|
||||
- r->refcount)) {
|
||||
- struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, k);
|
||||
- ret = PTR_ERR_OR_ZERO(new);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
-
|
||||
- if (!r->refcount)
|
||||
- new->k.type = KEY_TYPE_deleted;
|
||||
- else
|
||||
- *bkey_refcount(bkey_i_to_s(new)) = cpu_to_le64(r->refcount);
|
||||
- ret = bch2_trans_update(trans, iter, new, 0);
|
||||
- }
|
||||
-out:
|
||||
-fsck_err:
|
||||
- printbuf_exit(&buf);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int bch2_gc_reflink_done(struct bch_fs *c)
|
||||
-{
|
||||
- size_t idx = 0;
|
||||
-
|
||||
- int ret = bch2_trans_run(c,
|
||||
- for_each_btree_key_commit(trans, iter,
|
||||
- BTREE_ID_reflink, POS_MIN,
|
||||
- BTREE_ITER_prefetch, k,
|
||||
- NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
|
||||
- bch2_gc_write_reflink_key(trans, &iter, k, &idx)));
|
||||
- c->reflink_gc_nr = 0;
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int bch2_gc_reflink_start(struct bch_fs *c)
|
||||
-{
|
||||
- c->reflink_gc_nr = 0;
|
||||
-
|
||||
- int ret = bch2_trans_run(c,
|
||||
- for_each_btree_key(trans, iter, BTREE_ID_reflink, POS_MIN,
|
||||
- BTREE_ITER_prefetch, k, ({
|
||||
- const __le64 *refcount = bkey_refcount_c(k);
|
||||
-
|
||||
- if (!refcount)
|
||||
- continue;
|
||||
-
|
||||
- struct reflink_gc *r = genradix_ptr_alloc(&c->reflink_gc_table,
|
||||
- c->reflink_gc_nr++, GFP_KERNEL);
|
||||
- if (!r) {
|
||||
- ret = -BCH_ERR_ENOMEM_gc_reflink_start;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- r->offset = k.k->p.offset;
|
||||
- r->size = k.k->size;
|
||||
- r->refcount = 0;
|
||||
- 0;
|
||||
- })));
|
||||
-
|
||||
- bch_err_fn(c, ret);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static int bch2_gc_write_stripes_key(struct btree_trans *trans,
|
||||
struct btree_iter *iter,
|
||||
struct bkey_s_c k)
|
||||
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
|
||||
index addaf5f74624..36fb1e9473ff 100644
|
||||
--- a/fs/bcachefs/reflink.c
|
||||
+++ b/fs/bcachefs/reflink.c
|
||||
@@ -72,6 +72,66 @@ bool bch2_reflink_p_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r
|
||||
return true;
|
||||
}
|
||||
|
||||
+/* indirect extents */
|
||||
+
|
||||
+int bch2_reflink_v_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
+ enum bch_validate_flags flags)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ bkey_fsck_err_on(bkey_gt(k.k->p, POS(0, REFLINK_P_IDX_MAX)),
|
||||
+ c, reflink_v_pos_bad,
|
||||
+ "indirect extent above maximum position 0:%llu",
|
||||
+ REFLINK_P_IDX_MAX);
|
||||
+
|
||||
+ ret = bch2_bkey_ptrs_validate(c, k, flags);
|
||||
+fsck_err:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void bch2_reflink_v_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
+ struct bkey_s_c k)
|
||||
+{
|
||||
+ struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k);
|
||||
+
|
||||
+ prt_printf(out, "refcount: %llu ", le64_to_cpu(r.v->refcount));
|
||||
+
|
||||
+ bch2_bkey_ptrs_to_text(out, c, k);
|
||||
+}
|
||||
+
|
||||
+#if 0
|
||||
+Currently disabled, needs to be debugged:
|
||||
+
|
||||
+bool bch2_reflink_v_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r)
|
||||
+{
|
||||
+ struct bkey_s_reflink_v l = bkey_s_to_reflink_v(_l);
|
||||
+ struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(_r);
|
||||
+
|
||||
+ return l.v->refcount == r.v->refcount && bch2_extent_merge(c, _l, _r);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+/* indirect inline data */
|
||||
+
|
||||
+int bch2_indirect_inline_data_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
+ enum bch_validate_flags flags)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void bch2_indirect_inline_data_to_text(struct printbuf *out,
|
||||
+ struct bch_fs *c, struct bkey_s_c k)
|
||||
+{
|
||||
+ struct bkey_s_c_indirect_inline_data d = bkey_s_c_to_indirect_inline_data(k);
|
||||
+ unsigned datalen = bkey_inline_data_bytes(k.k);
|
||||
+
|
||||
+ prt_printf(out, "refcount %llu datalen %u: %*phN",
|
||||
+ le64_to_cpu(d.v->refcount), datalen,
|
||||
+ min(datalen, 32U), d.v->data);
|
||||
+}
|
||||
+
|
||||
+/* reflink pointer trigger */
|
||||
+
|
||||
static int trans_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
struct bkey_s_c_reflink_p p, u64 *idx,
|
||||
enum btree_iter_update_trigger_flags flags)
|
||||
@@ -253,44 +313,7 @@ int bch2_trigger_reflink_p(struct btree_trans *trans,
|
||||
return trigger_run_overwrite_then_insert(__trigger_reflink_p, trans, btree_id, level, old, new, flags);
|
||||
}
|
||||
|
||||
-/* indirect extents */
|
||||
-
|
||||
-int bch2_reflink_v_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
- enum bch_validate_flags flags)
|
||||
-{
|
||||
- int ret = 0;
|
||||
-
|
||||
- bkey_fsck_err_on(bkey_gt(k.k->p, POS(0, REFLINK_P_IDX_MAX)),
|
||||
- c, reflink_v_pos_bad,
|
||||
- "indirect extent above maximum position 0:%llu",
|
||||
- REFLINK_P_IDX_MAX);
|
||||
-
|
||||
- ret = bch2_bkey_ptrs_validate(c, k, flags);
|
||||
-fsck_err:
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-void bch2_reflink_v_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
- struct bkey_s_c k)
|
||||
-{
|
||||
- struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k);
|
||||
-
|
||||
- prt_printf(out, "refcount: %llu ", le64_to_cpu(r.v->refcount));
|
||||
-
|
||||
- bch2_bkey_ptrs_to_text(out, c, k);
|
||||
-}
|
||||
-
|
||||
-#if 0
|
||||
-Currently disabled, needs to be debugged:
|
||||
-
|
||||
-bool bch2_reflink_v_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r)
|
||||
-{
|
||||
- struct bkey_s_reflink_v l = bkey_s_to_reflink_v(_l);
|
||||
- struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(_r);
|
||||
-
|
||||
- return l.v->refcount == r.v->refcount && bch2_extent_merge(c, _l, _r);
|
||||
-}
|
||||
-#endif
|
||||
+/* indirect extent trigger */
|
||||
|
||||
static inline void
|
||||
check_indirect_extent_deleting(struct bkey_s new,
|
||||
@@ -316,25 +339,6 @@ int bch2_trigger_reflink_v(struct btree_trans *trans,
|
||||
return bch2_trigger_extent(trans, btree_id, level, old, new, flags);
|
||||
}
|
||||
|
||||
-/* indirect inline data */
|
||||
-
|
||||
-int bch2_indirect_inline_data_validate(struct bch_fs *c, struct bkey_s_c k,
|
||||
- enum bch_validate_flags flags)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-void bch2_indirect_inline_data_to_text(struct printbuf *out,
|
||||
- struct bch_fs *c, struct bkey_s_c k)
|
||||
-{
|
||||
- struct bkey_s_c_indirect_inline_data d = bkey_s_c_to_indirect_inline_data(k);
|
||||
- unsigned datalen = bkey_inline_data_bytes(k.k);
|
||||
-
|
||||
- prt_printf(out, "refcount %llu datalen %u: %*phN",
|
||||
- le64_to_cpu(d.v->refcount), datalen,
|
||||
- min(datalen, 32U), d.v->data);
|
||||
-}
|
||||
-
|
||||
int bch2_trigger_indirect_inline_data(struct btree_trans *trans,
|
||||
enum btree_id btree_id, unsigned level,
|
||||
struct bkey_s_c old, struct bkey_s new,
|
||||
@@ -345,6 +349,8 @@ int bch2_trigger_indirect_inline_data(struct btree_trans *trans,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* create */
|
||||
+
|
||||
static int bch2_make_extent_indirect(struct btree_trans *trans,
|
||||
struct btree_iter *extent_iter,
|
||||
struct bkey_i *orig)
|
||||
@@ -608,3 +614,97 @@ s64 bch2_remap_range(struct bch_fs *c,
|
||||
|
||||
return dst_done ?: ret ?: ret2;
|
||||
}
|
||||
+
|
||||
+/* fsck */
|
||||
+
|
||||
+static int bch2_gc_write_reflink_key(struct btree_trans *trans,
|
||||
+ struct btree_iter *iter,
|
||||
+ struct bkey_s_c k,
|
||||
+ size_t *idx)
|
||||
+{
|
||||
+ struct bch_fs *c = trans->c;
|
||||
+ const __le64 *refcount = bkey_refcount_c(k);
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
+ struct reflink_gc *r;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!refcount)
|
||||
+ return 0;
|
||||
+
|
||||
+ while ((r = genradix_ptr(&c->reflink_gc_table, *idx)) &&
|
||||
+ r->offset < k.k->p.offset)
|
||||
+ ++*idx;
|
||||
+
|
||||
+ if (!r ||
|
||||
+ r->offset != k.k->p.offset ||
|
||||
+ r->size != k.k->size) {
|
||||
+ bch_err(c, "unexpected inconsistency walking reflink table at gc finish");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (fsck_err_on(r->refcount != le64_to_cpu(*refcount),
|
||||
+ trans, reflink_v_refcount_wrong,
|
||||
+ "reflink key has wrong refcount:\n"
|
||||
+ " %s\n"
|
||||
+ " should be %u",
|
||||
+ (bch2_bkey_val_to_text(&buf, c, k), buf.buf),
|
||||
+ r->refcount)) {
|
||||
+ struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, k);
|
||||
+ ret = PTR_ERR_OR_ZERO(new);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!r->refcount)
|
||||
+ new->k.type = KEY_TYPE_deleted;
|
||||
+ else
|
||||
+ *bkey_refcount(bkey_i_to_s(new)) = cpu_to_le64(r->refcount);
|
||||
+ ret = bch2_trans_update(trans, iter, new, 0);
|
||||
+ }
|
||||
+out:
|
||||
+fsck_err:
|
||||
+ printbuf_exit(&buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int bch2_gc_reflink_done(struct bch_fs *c)
|
||||
+{
|
||||
+ size_t idx = 0;
|
||||
+
|
||||
+ int ret = bch2_trans_run(c,
|
||||
+ for_each_btree_key_commit(trans, iter,
|
||||
+ BTREE_ID_reflink, POS_MIN,
|
||||
+ BTREE_ITER_prefetch, k,
|
||||
+ NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
|
||||
+ bch2_gc_write_reflink_key(trans, &iter, k, &idx)));
|
||||
+ c->reflink_gc_nr = 0;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int bch2_gc_reflink_start(struct bch_fs *c)
|
||||
+{
|
||||
+ c->reflink_gc_nr = 0;
|
||||
+
|
||||
+ int ret = bch2_trans_run(c,
|
||||
+ for_each_btree_key(trans, iter, BTREE_ID_reflink, POS_MIN,
|
||||
+ BTREE_ITER_prefetch, k, ({
|
||||
+ const __le64 *refcount = bkey_refcount_c(k);
|
||||
+
|
||||
+ if (!refcount)
|
||||
+ continue;
|
||||
+
|
||||
+ struct reflink_gc *r = genradix_ptr_alloc(&c->reflink_gc_table,
|
||||
+ c->reflink_gc_nr++, GFP_KERNEL);
|
||||
+ if (!r) {
|
||||
+ ret = -BCH_ERR_ENOMEM_gc_reflink_start;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ r->offset = k.k->p.offset;
|
||||
+ r->size = k.k->size;
|
||||
+ r->refcount = 0;
|
||||
+ 0;
|
||||
+ })));
|
||||
+
|
||||
+ bch_err_fn(c, ret);
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/fs/bcachefs/reflink.h b/fs/bcachefs/reflink.h
|
||||
index 51afe11d8ed6..6ec3a9ea6bb4 100644
|
||||
--- a/fs/bcachefs/reflink.h
|
||||
+++ b/fs/bcachefs/reflink.h
|
||||
@@ -76,4 +76,7 @@ static inline __le64 *bkey_refcount(struct bkey_s k)
|
||||
s64 bch2_remap_range(struct bch_fs *, subvol_inum, u64,
|
||||
subvol_inum, u64, u64, u64, s64 *);
|
||||
|
||||
+int bch2_gc_reflink_done(struct bch_fs *);
|
||||
+int bch2_gc_reflink_start(struct bch_fs *);
|
||||
+
|
||||
#endif /* _BCACHEFS_REFLINK_H */
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,585 +0,0 @@
|
||||
From df4270ccd3907ff2fc8ba3cba6328a229a5bd203 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 20 Oct 2024 20:27:44 -0400
|
||||
Subject: [PATCH 083/233] bcachefs: Don't delete reflink pointers to missing
|
||||
indirect extents
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
To avoid tragic loss in the event of transient errors (i.e., a btree
|
||||
node topology error that was later corrected by btree node scan), we
|
||||
can't delete reflink pointers to correct errors.
|
||||
|
||||
This adds a new error bit to bch_reflink_p, indicating that it is known
|
||||
to point to a missing indirect extent, and the error has already been
|
||||
reported.
|
||||
|
||||
Indirect extent lookups now use bch2_lookup_indirect_extent(), which on
|
||||
error reports it as a fsck_err() and sets the error bit, and clears it
|
||||
if necessary on succesful lookup.
|
||||
|
||||
This also gets rid of the bch2_inconsistent_error() call in
|
||||
__bch2_read_indirect_extent, and in the reflink_p trigger: part of the
|
||||
online self healing project.
|
||||
|
||||
An on disk format change isn't necessary here: setting the error bit
|
||||
will be interpreted by older versions as pointing to a different index,
|
||||
which will also be missing - which is fine.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/fs-io-buffered.c | 5 +-
|
||||
fs/bcachefs/fs.c | 8 +-
|
||||
fs/bcachefs/io_read.c | 45 +------
|
||||
fs/bcachefs/io_read.h | 28 +++-
|
||||
fs/bcachefs/reflink.c | 241 +++++++++++++++++++++++++++--------
|
||||
fs/bcachefs/reflink.h | 4 +
|
||||
fs/bcachefs/reflink_format.h | 1 +
|
||||
7 files changed, 222 insertions(+), 110 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c
|
||||
index b853cecd3c1b..d55e215e8aa6 100644
|
||||
--- a/fs/bcachefs/fs-io-buffered.c
|
||||
+++ b/fs/bcachefs/fs-io-buffered.c
|
||||
@@ -164,7 +164,8 @@ static void bchfs_read(struct btree_trans *trans,
|
||||
BTREE_ITER_slots);
|
||||
while (1) {
|
||||
struct bkey_s_c k;
|
||||
- unsigned bytes, sectors, offset_into_extent;
|
||||
+ unsigned bytes, sectors;
|
||||
+ s64 offset_into_extent;
|
||||
enum btree_id data_btree = BTREE_ID_extents;
|
||||
|
||||
bch2_trans_begin(trans);
|
||||
@@ -197,7 +198,7 @@ static void bchfs_read(struct btree_trans *trans,
|
||||
|
||||
k = bkey_i_to_s_c(sk.k);
|
||||
|
||||
- sectors = min(sectors, k.k->size - offset_into_extent);
|
||||
+ sectors = min_t(unsigned, sectors, k.k->size - offset_into_extent);
|
||||
|
||||
if (readpages_iter) {
|
||||
ret = readpage_bio_extend(trans, readpages_iter, &rbio->bio, sectors,
|
||||
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
|
||||
index f852dbf30aa2..50d323fca001 100644
|
||||
--- a/fs/bcachefs/fs.c
|
||||
+++ b/fs/bcachefs/fs.c
|
||||
@@ -1261,7 +1261,6 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_buf cur, prev;
|
||||
- unsigned offset_into_extent, sectors;
|
||||
bool have_extent = false;
|
||||
int ret = 0;
|
||||
|
||||
@@ -1308,9 +1307,8 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
|
||||
continue;
|
||||
}
|
||||
|
||||
- offset_into_extent = iter.pos.offset -
|
||||
- bkey_start_offset(k.k);
|
||||
- sectors = k.k->size - offset_into_extent;
|
||||
+ s64 offset_into_extent = iter.pos.offset - bkey_start_offset(k.k);
|
||||
+ unsigned sectors = k.k->size - offset_into_extent;
|
||||
|
||||
bch2_bkey_buf_reassemble(&cur, c, k);
|
||||
|
||||
@@ -1322,7 +1320,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
|
||||
k = bkey_i_to_s_c(cur.k);
|
||||
bch2_bkey_buf_realloc(&prev, c, k.k->u64s);
|
||||
|
||||
- sectors = min(sectors, k.k->size - offset_into_extent);
|
||||
+ sectors = min_t(unsigned, sectors, k.k->size - offset_into_extent);
|
||||
|
||||
bch2_cut_front(POS(k.k->p.inode,
|
||||
bkey_start_offset(k.k) +
|
||||
diff --git a/fs/bcachefs/io_read.c b/fs/bcachefs/io_read.c
|
||||
index c700a95df89e..eb8d12fd6398 100644
|
||||
--- a/fs/bcachefs/io_read.c
|
||||
+++ b/fs/bcachefs/io_read.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "io_read.h"
|
||||
#include "io_misc.h"
|
||||
#include "io_write.h"
|
||||
+#include "reflink.h"
|
||||
#include "subvolume.h"
|
||||
#include "trace.h"
|
||||
|
||||
@@ -750,41 +751,6 @@ static void bch2_read_endio(struct bio *bio)
|
||||
bch2_rbio_punt(rbio, __bch2_read_endio, context, wq);
|
||||
}
|
||||
|
||||
-int __bch2_read_indirect_extent(struct btree_trans *trans,
|
||||
- unsigned *offset_into_extent,
|
||||
- struct bkey_buf *orig_k)
|
||||
-{
|
||||
- struct bkey_i_reflink_p *p = bkey_i_to_reflink_p(orig_k->k);
|
||||
- u64 reflink_offset = REFLINK_P_IDX(&p->v) + *offset_into_extent;
|
||||
-
|
||||
- struct btree_iter iter;
|
||||
- struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_reflink,
|
||||
- POS(0, reflink_offset), 0);
|
||||
- int ret = bkey_err(k);
|
||||
- if (ret)
|
||||
- goto err;
|
||||
-
|
||||
- if (k.k->type != KEY_TYPE_reflink_v &&
|
||||
- k.k->type != KEY_TYPE_indirect_inline_data) {
|
||||
- bch_err_inum_offset_ratelimited(trans->c,
|
||||
- orig_k->k->k.p.inode,
|
||||
- orig_k->k->k.p.offset << 9,
|
||||
- "%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 = -BCH_ERR_missing_indirect_extent;
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- *offset_into_extent = iter.pos.offset - bkey_start_offset(k.k);
|
||||
- bch2_bkey_buf_reassemble(orig_k, trans->c, k);
|
||||
-err:
|
||||
- bch2_trans_iter_exit(trans, &iter);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static noinline void read_from_stale_dirty_pointer(struct btree_trans *trans,
|
||||
struct bch_dev *ca,
|
||||
struct bkey_s_c k,
|
||||
@@ -1160,7 +1126,6 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
|
||||
BTREE_ITER_slots);
|
||||
|
||||
while (1) {
|
||||
- unsigned bytes, sectors, offset_into_extent;
|
||||
enum btree_id data_btree = BTREE_ID_extents;
|
||||
|
||||
bch2_trans_begin(trans);
|
||||
@@ -1180,9 +1145,9 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
- offset_into_extent = iter.pos.offset -
|
||||
+ s64 offset_into_extent = iter.pos.offset -
|
||||
bkey_start_offset(k.k);
|
||||
- sectors = k.k->size - offset_into_extent;
|
||||
+ unsigned sectors = k.k->size - offset_into_extent;
|
||||
|
||||
bch2_bkey_buf_reassemble(&sk, c, k);
|
||||
|
||||
@@ -1197,9 +1162,9 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
|
||||
* With indirect extents, the amount of data to read is the min
|
||||
* of the original extent and the indirect extent:
|
||||
*/
|
||||
- sectors = min(sectors, k.k->size - offset_into_extent);
|
||||
+ sectors = min_t(unsigned, sectors, k.k->size - offset_into_extent);
|
||||
|
||||
- bytes = min(sectors, bvec_iter_sectors(bvec_iter)) << 9;
|
||||
+ unsigned bytes = min(sectors, bvec_iter_sectors(bvec_iter)) << 9;
|
||||
swap(bvec_iter.bi_size, bytes);
|
||||
|
||||
if (bvec_iter.bi_size == bytes)
|
||||
diff --git a/fs/bcachefs/io_read.h b/fs/bcachefs/io_read.h
|
||||
index d9c18bb7d403..a82e8a94ccb6 100644
|
||||
--- a/fs/bcachefs/io_read.h
|
||||
+++ b/fs/bcachefs/io_read.h
|
||||
@@ -3,6 +3,7 @@
|
||||
#define _BCACHEFS_IO_READ_H
|
||||
|
||||
#include "bkey_buf.h"
|
||||
+#include "reflink.h"
|
||||
|
||||
struct bch_read_bio {
|
||||
struct bch_fs *c;
|
||||
@@ -79,19 +80,32 @@ struct bch_devs_mask;
|
||||
struct cache_promote_op;
|
||||
struct extent_ptr_decoded;
|
||||
|
||||
-int __bch2_read_indirect_extent(struct btree_trans *, unsigned *,
|
||||
- struct bkey_buf *);
|
||||
-
|
||||
static inline int bch2_read_indirect_extent(struct btree_trans *trans,
|
||||
enum btree_id *data_btree,
|
||||
- unsigned *offset_into_extent,
|
||||
- struct bkey_buf *k)
|
||||
+ s64 *offset_into_extent,
|
||||
+ struct bkey_buf *extent)
|
||||
{
|
||||
- if (k->k->k.type != KEY_TYPE_reflink_p)
|
||||
+ if (extent->k->k.type != KEY_TYPE_reflink_p)
|
||||
return 0;
|
||||
|
||||
*data_btree = BTREE_ID_reflink;
|
||||
- return __bch2_read_indirect_extent(trans, offset_into_extent, k);
|
||||
+ struct btree_iter iter;
|
||||
+ struct bkey_s_c k = bch2_lookup_indirect_extent(trans, &iter,
|
||||
+ offset_into_extent,
|
||||
+ bkey_i_to_s_c_reflink_p(extent->k),
|
||||
+ true, 0);
|
||||
+ int ret = bkey_err(k);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (bkey_deleted(k.k)) {
|
||||
+ bch2_trans_iter_exit(trans, &iter);
|
||||
+ return -BCH_ERR_missing_indirect_extent;
|
||||
+ }
|
||||
+
|
||||
+ bch2_bkey_buf_reassemble(extent, trans->c, k);
|
||||
+ bch2_trans_iter_exit(trans, &iter);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
enum bch_read_flags {
|
||||
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
|
||||
index 36fb1e9473ff..38db5a011702 100644
|
||||
--- a/fs/bcachefs/reflink.c
|
||||
+++ b/fs/bcachefs/reflink.c
|
||||
@@ -15,6 +15,17 @@
|
||||
|
||||
#include <linux/sched/signal.h>
|
||||
|
||||
+static inline bool bkey_extent_is_reflink_data(const struct bkey *k)
|
||||
+{
|
||||
+ switch (k->type) {
|
||||
+ case KEY_TYPE_reflink_v:
|
||||
+ case KEY_TYPE_indirect_inline_data:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static inline unsigned bkey_type_to_indirect(const struct bkey *k)
|
||||
{
|
||||
switch (k->type) {
|
||||
@@ -68,6 +79,9 @@ bool bch2_reflink_p_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r
|
||||
if (REFLINK_P_IDX(l.v) + l.k->size != REFLINK_P_IDX(r.v))
|
||||
return false;
|
||||
|
||||
+ if (REFLINK_P_ERROR(l.v) != REFLINK_P_ERROR(r.v))
|
||||
+ return false;
|
||||
+
|
||||
bch2_key_resize(l.k, l.k->size + r.k->size);
|
||||
return true;
|
||||
}
|
||||
@@ -130,6 +144,144 @@ void bch2_indirect_inline_data_to_text(struct printbuf *out,
|
||||
min(datalen, 32U), d.v->data);
|
||||
}
|
||||
|
||||
+/* lookup */
|
||||
+
|
||||
+static int bch2_indirect_extent_not_missing(struct btree_trans *trans, struct bkey_s_c_reflink_p p,
|
||||
+ bool should_commit)
|
||||
+{
|
||||
+ struct bkey_i_reflink_p *new = bch2_bkey_make_mut_noupdate_typed(trans, p.s_c, reflink_p);
|
||||
+ int ret = PTR_ERR_OR_ZERO(new);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ SET_REFLINK_P_ERROR(&new->v, false);
|
||||
+ ret = bch2_btree_insert_trans(trans, BTREE_ID_extents, &new->k_i, BTREE_TRIGGER_norun);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!should_commit)
|
||||
+ return 0;
|
||||
+
|
||||
+ return bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc) ?:
|
||||
+ -BCH_ERR_transaction_restart_nested;
|
||||
+}
|
||||
+
|
||||
+static int bch2_indirect_extent_missing_error(struct btree_trans *trans,
|
||||
+ struct bkey_s_c_reflink_p p,
|
||||
+ u64 missing_start, u64 missing_end,
|
||||
+ bool should_commit)
|
||||
+{
|
||||
+ if (REFLINK_P_ERROR(p.v))
|
||||
+ return -BCH_ERR_missing_indirect_extent;
|
||||
+
|
||||
+ struct bch_fs *c = trans->c;
|
||||
+ u64 live_start = REFLINK_P_IDX(p.v);
|
||||
+ u64 live_end = REFLINK_P_IDX(p.v) + p.k->size;
|
||||
+ u64 refd_start = live_start - le32_to_cpu(p.v->front_pad);
|
||||
+ u64 refd_end = live_end + le32_to_cpu(p.v->back_pad);
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ BUG_ON(missing_start < refd_start);
|
||||
+ BUG_ON(missing_end > refd_end);
|
||||
+
|
||||
+ if (fsck_err(trans, reflink_p_to_missing_reflink_v,
|
||||
+ "pointer to missing indirect extent\n"
|
||||
+ " %s\n"
|
||||
+ " missing range %llu-%llu",
|
||||
+ (bch2_bkey_val_to_text(&buf, c, p.s_c), buf.buf),
|
||||
+ missing_start, missing_end)) {
|
||||
+ struct bkey_i_reflink_p *new = bch2_bkey_make_mut_noupdate_typed(trans, p.s_c, reflink_p);
|
||||
+ ret = PTR_ERR_OR_ZERO(new);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ /*
|
||||
+ * Is the missing range not actually needed?
|
||||
+ *
|
||||
+ * p.v->idx refers to the data that we actually want, but if the
|
||||
+ * indirect extent we point to was bigger, front_pad and back_pad
|
||||
+ * indicate the range we took a reference on.
|
||||
+ */
|
||||
+
|
||||
+ if (missing_end <= live_start) {
|
||||
+ new->v.front_pad = cpu_to_le32(live_start - missing_end);
|
||||
+ } else if (missing_start >= live_end) {
|
||||
+ new->v.back_pad = cpu_to_le32(missing_start - live_end);
|
||||
+ } else {
|
||||
+ struct bpos new_start = bkey_start_pos(&new->k);
|
||||
+ struct bpos new_end = new->k.p;
|
||||
+
|
||||
+ if (missing_start > live_start)
|
||||
+ new_start.offset += missing_start - live_start;
|
||||
+ if (missing_end < live_end)
|
||||
+ new_end.offset -= live_end - missing_end;
|
||||
+
|
||||
+ bch2_cut_front(new_start, &new->k_i);
|
||||
+ bch2_cut_back(new_end, &new->k_i);
|
||||
+
|
||||
+ SET_REFLINK_P_ERROR(&new->v, true);
|
||||
+ }
|
||||
+
|
||||
+ ret = bch2_btree_insert_trans(trans, BTREE_ID_extents, &new->k_i, BTREE_TRIGGER_norun);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ if (should_commit)
|
||||
+ ret = bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc) ?:
|
||||
+ -BCH_ERR_transaction_restart_nested;
|
||||
+ }
|
||||
+err:
|
||||
+fsck_err:
|
||||
+ printbuf_exit(&buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This is used from the read path, which doesn't expect to have to do a
|
||||
+ * transaction commit, and from triggers, which should not be doing a commit:
|
||||
+ */
|
||||
+struct bkey_s_c bch2_lookup_indirect_extent(struct btree_trans *trans,
|
||||
+ struct btree_iter *iter,
|
||||
+ s64 *offset_into_extent,
|
||||
+ struct bkey_s_c_reflink_p p,
|
||||
+ bool should_commit,
|
||||
+ unsigned iter_flags)
|
||||
+{
|
||||
+ BUG_ON(*offset_into_extent < -((s64) le32_to_cpu(p.v->front_pad)));
|
||||
+ BUG_ON(*offset_into_extent >= p.k->size + le32_to_cpu(p.v->back_pad));
|
||||
+
|
||||
+ u64 reflink_offset = REFLINK_P_IDX(p.v) + *offset_into_extent;
|
||||
+
|
||||
+ struct bkey_s_c k = bch2_bkey_get_iter(trans, iter, BTREE_ID_reflink,
|
||||
+ POS(0, reflink_offset), iter_flags);
|
||||
+ if (bkey_err(k))
|
||||
+ return k;
|
||||
+
|
||||
+ if (unlikely(!bkey_extent_is_reflink_data(k.k))) {
|
||||
+ bch2_trans_iter_exit(trans, iter);
|
||||
+
|
||||
+ unsigned size = min((u64) k.k->size,
|
||||
+ REFLINK_P_IDX(p.v) + p.k->size + le32_to_cpu(p.v->back_pad) -
|
||||
+ reflink_offset);
|
||||
+ bch2_key_resize(&iter->k, size);
|
||||
+
|
||||
+ int ret = bch2_indirect_extent_missing_error(trans, p, reflink_offset,
|
||||
+ k.k->p.offset, should_commit);
|
||||
+ if (ret)
|
||||
+ return bkey_s_c_err(ret);
|
||||
+ } else if (unlikely(REFLINK_P_ERROR(p.v))) {
|
||||
+ bch2_trans_iter_exit(trans, iter);
|
||||
+
|
||||
+ int ret = bch2_indirect_extent_not_missing(trans, p, should_commit);
|
||||
+ if (ret)
|
||||
+ return bkey_s_c_err(ret);
|
||||
+ }
|
||||
+
|
||||
+ *offset_into_extent = reflink_offset - bkey_start_offset(k.k);
|
||||
+ return k;
|
||||
+}
|
||||
+
|
||||
/* reflink pointer trigger */
|
||||
|
||||
static int trans_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
@@ -137,37 +289,37 @@ static int trans_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
enum btree_iter_update_trigger_flags flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
- struct btree_iter iter;
|
||||
- struct bkey_i *k;
|
||||
- __le64 *refcount;
|
||||
- int add = !(flags & BTREE_TRIGGER_overwrite) ? 1 : -1;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
- int ret;
|
||||
|
||||
- k = bch2_bkey_get_mut_noupdate(trans, &iter,
|
||||
- BTREE_ID_reflink, POS(0, *idx),
|
||||
- BTREE_ITER_with_updates);
|
||||
- ret = PTR_ERR_OR_ZERO(k);
|
||||
+ s64 offset_into_extent = *idx - REFLINK_P_IDX(p.v);
|
||||
+ struct btree_iter iter;
|
||||
+ struct bkey_s_c k = bch2_lookup_indirect_extent(trans, &iter, &offset_into_extent, p, false,
|
||||
+ BTREE_ITER_intent|
|
||||
+ BTREE_ITER_with_updates);
|
||||
+ int ret = bkey_err(k);
|
||||
if (ret)
|
||||
- goto err;
|
||||
+ return ret;
|
||||
|
||||
- refcount = bkey_refcount(bkey_i_to_s(k));
|
||||
- if (!refcount) {
|
||||
- bch2_bkey_val_to_text(&buf, c, p.s_c);
|
||||
- bch2_trans_inconsistent(trans,
|
||||
- "nonexistent indirect extent at %llu while marking\n %s",
|
||||
- *idx, buf.buf);
|
||||
- ret = -EIO;
|
||||
- goto err;
|
||||
+ if (bkey_deleted(k.k)) {
|
||||
+ if (!(flags & BTREE_TRIGGER_overwrite))
|
||||
+ ret = -BCH_ERR_missing_indirect_extent;
|
||||
+ goto next;
|
||||
}
|
||||
|
||||
+ struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, k);
|
||||
+ ret = PTR_ERR_OR_ZERO(new);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ __le64 *refcount = bkey_refcount(bkey_i_to_s(new));
|
||||
if (!*refcount && (flags & BTREE_TRIGGER_overwrite)) {
|
||||
bch2_bkey_val_to_text(&buf, c, p.s_c);
|
||||
- bch2_trans_inconsistent(trans,
|
||||
- "indirect extent refcount underflow at %llu while marking\n %s",
|
||||
- *idx, buf.buf);
|
||||
- ret = -EIO;
|
||||
- goto err;
|
||||
+ prt_printf(&buf, "\n ");
|
||||
+ bch2_bkey_val_to_text(&buf, c, k);
|
||||
+ log_fsck_err(trans, reflink_refcount_underflow,
|
||||
+ "indirect extent refcount underflow while marking\n %s",
|
||||
+ buf.buf);
|
||||
+ goto next;
|
||||
}
|
||||
|
||||
if (flags & BTREE_TRIGGER_insert) {
|
||||
@@ -175,25 +327,26 @@ static int trans_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
u64 pad;
|
||||
|
||||
pad = max_t(s64, le32_to_cpu(v->front_pad),
|
||||
- REFLINK_P_IDX(v) - bkey_start_offset(&k->k));
|
||||
+ REFLINK_P_IDX(v) - bkey_start_offset(&new->k));
|
||||
BUG_ON(pad > U32_MAX);
|
||||
v->front_pad = cpu_to_le32(pad);
|
||||
|
||||
pad = max_t(s64, le32_to_cpu(v->back_pad),
|
||||
- k->k.p.offset - p.k->size - REFLINK_P_IDX(v));
|
||||
+ new->k.p.offset - p.k->size - REFLINK_P_IDX(v));
|
||||
BUG_ON(pad > U32_MAX);
|
||||
v->back_pad = cpu_to_le32(pad);
|
||||
}
|
||||
|
||||
- le64_add_cpu(refcount, add);
|
||||
+ le64_add_cpu(refcount, !(flags & BTREE_TRIGGER_overwrite) ? 1 : -1);
|
||||
|
||||
bch2_btree_iter_set_pos_to_extent_start(&iter);
|
||||
- ret = bch2_trans_update(trans, &iter, k, 0);
|
||||
+ ret = bch2_trans_update(trans, &iter, new, 0);
|
||||
if (ret)
|
||||
goto err;
|
||||
-
|
||||
- *idx = k->k.p.offset;
|
||||
+next:
|
||||
+ *idx = k.k->p.offset;
|
||||
err:
|
||||
+fsck_err:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
@@ -207,9 +360,7 @@ static s64 gc_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
struct bch_fs *c = trans->c;
|
||||
struct reflink_gc *r;
|
||||
int add = !(flags & BTREE_TRIGGER_overwrite) ? 1 : -1;
|
||||
- u64 start = REFLINK_P_IDX(p.v);
|
||||
- u64 end = start + p.k->size;
|
||||
- u64 next_idx = end + le32_to_cpu(p.v->back_pad);
|
||||
+ u64 next_idx = REFLINK_P_IDX(p.v) + p.k->size + le32_to_cpu(p.v->back_pad);
|
||||
s64 ret = 0;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
@@ -228,36 +379,14 @@ static s64 gc_trigger_reflink_p_segment(struct btree_trans *trans,
|
||||
*idx = r->offset;
|
||||
return 0;
|
||||
not_found:
|
||||
- BUG_ON(!(flags & BTREE_TRIGGER_check_repair));
|
||||
-
|
||||
- if (fsck_err(trans, reflink_p_to_missing_reflink_v,
|
||||
- "pointer to missing indirect extent\n"
|
||||
- " %s\n"
|
||||
- " missing range %llu-%llu",
|
||||
- (bch2_bkey_val_to_text(&buf, c, p.s_c), buf.buf),
|
||||
- *idx, next_idx)) {
|
||||
- struct bkey_i *update = bch2_bkey_make_mut_noupdate(trans, p.s_c);
|
||||
- ret = PTR_ERR_OR_ZERO(update);
|
||||
+ if (flags & BTREE_TRIGGER_check_repair) {
|
||||
+ ret = bch2_indirect_extent_missing_error(trans, p, *idx, next_idx, false);
|
||||
if (ret)
|
||||
goto err;
|
||||
-
|
||||
- if (next_idx <= start) {
|
||||
- bkey_i_to_reflink_p(update)->v.front_pad = cpu_to_le32(start - next_idx);
|
||||
- } else if (*idx >= end) {
|
||||
- bkey_i_to_reflink_p(update)->v.back_pad = cpu_to_le32(*idx - end);
|
||||
- } else {
|
||||
- bkey_error_init(update);
|
||||
- update->k.p = p.k->p;
|
||||
- update->k.size = p.k->size;
|
||||
- set_bkey_val_u64s(&update->k, 0);
|
||||
- }
|
||||
-
|
||||
- ret = bch2_btree_insert_trans(trans, BTREE_ID_extents, update, BTREE_TRIGGER_norun);
|
||||
}
|
||||
|
||||
*idx = next_idx;
|
||||
err:
|
||||
-fsck_err:
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/fs/bcachefs/reflink.h b/fs/bcachefs/reflink.h
|
||||
index 6ec3a9ea6bb4..b61a4bdd8e82 100644
|
||||
--- a/fs/bcachefs/reflink.h
|
||||
+++ b/fs/bcachefs/reflink.h
|
||||
@@ -73,6 +73,10 @@ static inline __le64 *bkey_refcount(struct bkey_s k)
|
||||
}
|
||||
}
|
||||
|
||||
+struct bkey_s_c bch2_lookup_indirect_extent(struct btree_trans *, struct btree_iter *,
|
||||
+ s64 *, struct bkey_s_c_reflink_p,
|
||||
+ bool, unsigned);
|
||||
+
|
||||
s64 bch2_remap_range(struct bch_fs *, subvol_inum, u64,
|
||||
subvol_inum, u64, u64, u64, s64 *);
|
||||
|
||||
diff --git a/fs/bcachefs/reflink_format.h b/fs/bcachefs/reflink_format.h
|
||||
index 0d8de13b9ddf..53502627b2c5 100644
|
||||
--- a/fs/bcachefs/reflink_format.h
|
||||
+++ b/fs/bcachefs/reflink_format.h
|
||||
@@ -18,6 +18,7 @@ struct bch_reflink_p {
|
||||
} __packed __aligned(8);
|
||||
|
||||
LE64_BITMASK(REFLINK_P_IDX, struct bch_reflink_p, idx_flags, 0, 56);
|
||||
+LE64_BITMASK(REFLINK_P_ERROR, struct bch_reflink_p, idx_flags, 56, 57);
|
||||
|
||||
struct bch_reflink_v {
|
||||
struct bch_val v;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 3de116ce179b69eb2d92498a0872e5ab786cf4ef Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 27 Oct 2024 00:05:54 -0400
|
||||
Subject: [PATCH 084/233] bcachefs: kill inconsistent err in
|
||||
invalidate_one_bucket()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Change it to a normal fsck_err() - meaning it'll get repaired at runtime
|
||||
when that's flipped on.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_background.c | 28 ++++++----------------------
|
||||
1 file changed, 6 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
|
||||
index 38df36f8e70a..72ba7354adac 100644
|
||||
--- a/fs/bcachefs/alloc_background.c
|
||||
+++ b/fs/bcachefs/alloc_background.c
|
||||
@@ -1977,8 +1977,11 @@ static int invalidate_one_bucket(struct btree_trans *trans,
|
||||
return 1;
|
||||
|
||||
if (!bch2_dev_bucket_exists(c, bucket)) {
|
||||
- prt_str(&buf, "lru entry points to invalid bucket");
|
||||
- goto err;
|
||||
+ if (fsck_err(trans, lru_entry_to_invalid_bucket,
|
||||
+ "lru key points to nonexistent device:bucket %llu:%llu",
|
||||
+ bucket.inode, bucket.offset))
|
||||
+ return bch2_btree_bit_mod_buffered(trans, BTREE_ID_lru, lru_iter->pos, false);
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (bch2_bucket_is_open_safe(c, bucket.inode, bucket.offset))
|
||||
@@ -2019,28 +2022,9 @@ static int invalidate_one_bucket(struct btree_trans *trans,
|
||||
trace_and_count(c, bucket_invalidate, c, bucket.inode, bucket.offset, cached_sectors);
|
||||
--*nr_to_invalidate;
|
||||
out:
|
||||
+fsck_err:
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
-err:
|
||||
- prt_str(&buf, "\n lru key: ");
|
||||
- bch2_bkey_val_to_text(&buf, c, lru_k);
|
||||
-
|
||||
- prt_str(&buf, "\n lru entry: ");
|
||||
- bch2_lru_pos_to_text(&buf, lru_iter->pos);
|
||||
-
|
||||
- prt_str(&buf, "\n alloc key: ");
|
||||
- if (!a)
|
||||
- bch2_bpos_to_text(&buf, bucket);
|
||||
- else
|
||||
- bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&a->k_i));
|
||||
-
|
||||
- bch_err(c, "%s", buf.buf);
|
||||
- if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_lrus) {
|
||||
- bch2_inconsistent_error(c);
|
||||
- ret = -EINVAL;
|
||||
- }
|
||||
-
|
||||
- goto out;
|
||||
}
|
||||
|
||||
static struct bkey_s_c next_lru_key(struct btree_trans *trans, struct btree_iter *iter,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,159 +0,0 @@
|
||||
From ecadaf9ae3c9d091cd04c6998341db98bdf683ce Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 27 Oct 2024 20:47:03 -0400
|
||||
Subject: [PATCH 085/233] bcachefs: rework bch2_bucket_alloc_freelist()
|
||||
freelist iteration
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Prep work for converting try_alloc_bucket() to use
|
||||
bch2_check_discard_freespace_key().
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_foreground.c | 59 ++++++++++++++++++----------------
|
||||
1 file changed, 32 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
|
||||
index 372178c8d416..645d8a269142 100644
|
||||
--- a/fs/bcachefs/alloc_foreground.c
|
||||
+++ b/fs/bcachefs/alloc_foreground.c
|
||||
@@ -276,9 +276,9 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *
|
||||
}
|
||||
|
||||
static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bch_dev *ca,
|
||||
- enum bch_watermark watermark, u64 free_entry,
|
||||
+ enum bch_watermark watermark,
|
||||
struct bucket_alloc_state *s,
|
||||
- struct bkey_s_c freespace_k,
|
||||
+ struct btree_iter *freespace_iter,
|
||||
struct closure *cl)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
@@ -287,8 +287,8 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
struct open_bucket *ob;
|
||||
struct bch_alloc_v4 a_convert;
|
||||
const struct bch_alloc_v4 *a;
|
||||
- u64 b = free_entry & ~(~0ULL << 56);
|
||||
- unsigned genbits = free_entry >> 56;
|
||||
+ u64 b = freespace_iter->pos.offset & ~(~0ULL << 56);
|
||||
+ unsigned genbits = freespace_iter->pos.offset >> 56;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
int ret;
|
||||
|
||||
@@ -296,7 +296,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
prt_printf(&buf, "freespace btree has bucket outside allowed range %u-%llu\n"
|
||||
" freespace key ",
|
||||
ca->mi.first_bucket, ca->mi.nbuckets);
|
||||
- bch2_bkey_val_to_text(&buf, c, freespace_k);
|
||||
+ bch2_bkey_to_text(&buf, &freespace_iter->k);
|
||||
bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
ob = ERR_PTR(-EIO);
|
||||
goto err;
|
||||
@@ -321,7 +321,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
|
||||
prt_printf(&buf, "non free bucket in freespace btree\n"
|
||||
" freespace key ");
|
||||
- bch2_bkey_val_to_text(&buf, c, freespace_k);
|
||||
+ bch2_bkey_to_text(&buf, &freespace_iter->k);
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
@@ -334,7 +334,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
prt_printf(&buf, "bucket in freespace btree with wrong genbits (got %u should be %llu)\n"
|
||||
" freespace key ",
|
||||
genbits, alloc_freespace_genbits(*a) >> 56);
|
||||
- bch2_bkey_val_to_text(&buf, c, freespace_k);
|
||||
+ bch2_bkey_to_text(&buf, &freespace_iter->k);
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
@@ -492,17 +492,20 @@ static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans,
|
||||
|
||||
BUG_ON(ca->new_fs_bucket_idx);
|
||||
again:
|
||||
- for_each_btree_key_norestart(trans, iter, BTREE_ID_freespace,
|
||||
- POS(ca->dev_idx, alloc_cursor), 0, k, ret) {
|
||||
- if (k.k->p.inode != ca->dev_idx)
|
||||
- break;
|
||||
+ for_each_btree_key_max_norestart(trans, iter, BTREE_ID_freespace,
|
||||
+ POS(ca->dev_idx, alloc_cursor),
|
||||
+ POS(ca->dev_idx, U64_MAX),
|
||||
+ 0, k, ret) {
|
||||
+ /*
|
||||
+ * peek normally dosen't trim extents - they can span iter.pos,
|
||||
+ * which is not what we want here:
|
||||
+ */
|
||||
+ iter.k.size = iter.k.p.offset - iter.pos.offset;
|
||||
|
||||
- for (alloc_cursor = max(alloc_cursor, bkey_start_offset(k.k));
|
||||
- alloc_cursor < k.k->p.offset;
|
||||
- alloc_cursor++) {
|
||||
+ while (iter.k.size) {
|
||||
s->buckets_seen++;
|
||||
|
||||
- u64 bucket = alloc_cursor & ~(~0ULL << 56);
|
||||
+ u64 bucket = iter.pos.offset & ~(~0ULL << 56);
|
||||
if (s->btree_bitmap != BTREE_BITMAP_ANY &&
|
||||
s->btree_bitmap != bch2_dev_btree_bitmap_marked_sectors(ca,
|
||||
bucket_to_sector(ca, bucket), ca->mi.bucket_size)) {
|
||||
@@ -511,32 +514,36 @@ static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans,
|
||||
goto fail;
|
||||
|
||||
bucket = sector_to_bucket(ca,
|
||||
- round_up(bucket_to_sector(ca, bucket) + 1,
|
||||
+ round_up(bucket_to_sector(ca, bucket + 1),
|
||||
1ULL << ca->mi.btree_bitmap_shift));
|
||||
- u64 genbits = alloc_cursor >> 56;
|
||||
- alloc_cursor = bucket | (genbits << 56);
|
||||
+ alloc_cursor = bucket|(iter.pos.offset & (~0ULL << 56));
|
||||
|
||||
- if (alloc_cursor > k.k->p.offset)
|
||||
- bch2_btree_iter_set_pos(&iter, POS(ca->dev_idx, alloc_cursor));
|
||||
+ bch2_btree_iter_set_pos(&iter, POS(ca->dev_idx, alloc_cursor));
|
||||
s->skipped_mi_btree_bitmap++;
|
||||
- continue;
|
||||
+ goto next;
|
||||
}
|
||||
|
||||
- ob = try_alloc_bucket(trans, ca, watermark,
|
||||
- alloc_cursor, s, k, cl);
|
||||
+ ob = try_alloc_bucket(trans, ca, watermark, s, &iter, cl);
|
||||
if (ob) {
|
||||
+ if (!IS_ERR(ob))
|
||||
+ *dev_alloc_cursor = iter.pos.offset;
|
||||
bch2_set_btree_iter_dontneed(&iter);
|
||||
break;
|
||||
}
|
||||
- }
|
||||
|
||||
+ iter.k.size--;
|
||||
+ iter.pos.offset++;
|
||||
+ }
|
||||
+next:
|
||||
if (ob || ret)
|
||||
break;
|
||||
}
|
||||
fail:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
- if (!ob && ret)
|
||||
+ BUG_ON(ob && ret);
|
||||
+
|
||||
+ if (ret)
|
||||
ob = ERR_PTR(ret);
|
||||
|
||||
if (!ob && alloc_start > ca->mi.first_bucket) {
|
||||
@@ -544,8 +551,6 @@ static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans,
|
||||
goto again;
|
||||
}
|
||||
|
||||
- *dev_alloc_cursor = alloc_cursor;
|
||||
-
|
||||
return ob;
|
||||
}
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,307 +0,0 @@
|
||||
From c51b6019074d107e2c60b23dc23e5c7886a27a4e Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 27 Oct 2024 00:40:43 -0400
|
||||
Subject: [PATCH 086/233] bcachefs: try_alloc_bucket() now uses
|
||||
bch2_check_discard_freespace_key()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
check_discard_freespace_key() was doing all the same checks as
|
||||
try_alloc_bucket(), but with repair.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_background.c | 80 ++++++++++++++++-------------
|
||||
fs/bcachefs/alloc_background.h | 2 +
|
||||
fs/bcachefs/alloc_foreground.c | 93 ++++++----------------------------
|
||||
3 files changed, 62 insertions(+), 113 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
|
||||
index 72ba7354adac..1f42dd208957 100644
|
||||
--- a/fs/bcachefs/alloc_background.c
|
||||
+++ b/fs/bcachefs/alloc_background.c
|
||||
@@ -1332,51 +1332,53 @@ int bch2_check_alloc_hole_bucket_gens(struct btree_trans *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static noinline_for_stack int bch2_check_discard_freespace_key(struct btree_trans *trans,
|
||||
- struct btree_iter *iter)
|
||||
+int bch2_check_discard_freespace_key(struct btree_trans *trans, struct btree_iter *iter, u8 *gen)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
- struct btree_iter alloc_iter;
|
||||
- struct bkey_s_c alloc_k;
|
||||
- struct bch_alloc_v4 a_convert;
|
||||
- const struct bch_alloc_v4 *a;
|
||||
- u64 genbits;
|
||||
- struct bpos pos;
|
||||
enum bch_data_type state = iter->btree_id == BTREE_ID_need_discard
|
||||
? BCH_DATA_need_discard
|
||||
: BCH_DATA_free;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
- int ret;
|
||||
|
||||
- pos = iter->pos;
|
||||
- pos.offset &= ~(~0ULL << 56);
|
||||
- genbits = iter->pos.offset & (~0ULL << 56);
|
||||
+ struct bpos bucket = iter->pos;
|
||||
+ bucket.offset &= ~(~0ULL << 56);
|
||||
+ u64 genbits = iter->pos.offset & (~0ULL << 56);
|
||||
|
||||
- alloc_k = bch2_bkey_get_iter(trans, &alloc_iter, BTREE_ID_alloc, pos, 0);
|
||||
- ret = bkey_err(alloc_k);
|
||||
+ struct btree_iter alloc_iter;
|
||||
+ struct bkey_s_c alloc_k = bch2_bkey_get_iter(trans, &alloc_iter, BTREE_ID_alloc, bucket, BTREE_ITER_cached);
|
||||
+ int ret = bkey_err(alloc_k);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (fsck_err_on(!bch2_dev_bucket_exists(c, pos),
|
||||
- trans, need_discard_freespace_key_to_invalid_dev_bucket,
|
||||
- "entry in %s btree for nonexistant dev:bucket %llu:%llu",
|
||||
- bch2_btree_id_str(iter->btree_id), pos.inode, pos.offset))
|
||||
- goto delete;
|
||||
+ if (!bch2_dev_bucket_exists(c, bucket)) {
|
||||
+ if (fsck_err(trans, need_discard_freespace_key_to_invalid_dev_bucket,
|
||||
+ "entry in %s btree for nonexistant dev:bucket %llu:%llu",
|
||||
+ bch2_btree_id_str(iter->btree_id), bucket.inode, bucket.offset))
|
||||
+ goto delete;
|
||||
+ ret = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- a = bch2_alloc_to_v4(alloc_k, &a_convert);
|
||||
+ struct bch_alloc_v4 a_convert;
|
||||
+ const struct bch_alloc_v4 *a = bch2_alloc_to_v4(alloc_k, &a_convert);
|
||||
+
|
||||
+ if (a->data_type != state ||
|
||||
+ (state == BCH_DATA_free &&
|
||||
+ genbits != alloc_freespace_genbits(*a))) {
|
||||
+ if (fsck_err(trans, need_discard_freespace_key_bad,
|
||||
+ "%s\n incorrectly set at %s:%llu:%llu:0 (free %u, genbits %llu should be %llu)",
|
||||
+ (bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf),
|
||||
+ bch2_btree_id_str(iter->btree_id),
|
||||
+ iter->pos.inode,
|
||||
+ iter->pos.offset,
|
||||
+ a->data_type == state,
|
||||
+ genbits >> 56, alloc_freespace_genbits(*a) >> 56))
|
||||
+ goto delete;
|
||||
+ ret = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- if (fsck_err_on(a->data_type != state ||
|
||||
- (state == BCH_DATA_free &&
|
||||
- genbits != alloc_freespace_genbits(*a)),
|
||||
- trans, need_discard_freespace_key_bad,
|
||||
- "%s\n incorrectly set at %s:%llu:%llu:0 (free %u, genbits %llu should be %llu)",
|
||||
- (bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf),
|
||||
- bch2_btree_id_str(iter->btree_id),
|
||||
- iter->pos.inode,
|
||||
- iter->pos.offset,
|
||||
- a->data_type == state,
|
||||
- genbits >> 56, alloc_freespace_genbits(*a) >> 56))
|
||||
- goto delete;
|
||||
+ *gen = a->gen;
|
||||
out:
|
||||
fsck_err:
|
||||
bch2_set_btree_iter_dontneed(&alloc_iter);
|
||||
@@ -1386,10 +1388,18 @@ static noinline_for_stack int bch2_check_discard_freespace_key(struct btree_tran
|
||||
delete:
|
||||
ret = bch2_btree_bit_mod_iter(trans, iter, false) ?:
|
||||
bch2_trans_commit(trans, NULL, NULL,
|
||||
- BCH_TRANS_COMMIT_no_enospc);
|
||||
+ BCH_TRANS_COMMIT_no_enospc) ?:
|
||||
+ 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
+static int bch2_check_discard_freespace_key_fsck(struct btree_trans *trans, struct btree_iter *iter)
|
||||
+{
|
||||
+ u8 gen;
|
||||
+ int ret = bch2_check_discard_freespace_key(trans, iter, &gen);
|
||||
+ return ret < 0 ? ret : 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* We've already checked that generation numbers in the bucket_gens btree are
|
||||
* valid for buckets that exist; this just checks for keys for nonexistent
|
||||
@@ -1544,7 +1554,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
|
||||
ret = for_each_btree_key(trans, iter,
|
||||
BTREE_ID_need_discard, POS_MIN,
|
||||
BTREE_ITER_prefetch, k,
|
||||
- bch2_check_discard_freespace_key(trans, &iter));
|
||||
+ bch2_check_discard_freespace_key_fsck(trans, &iter));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@@ -1557,7 +1567,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
|
||||
break;
|
||||
|
||||
ret = bkey_err(k) ?:
|
||||
- bch2_check_discard_freespace_key(trans, &iter);
|
||||
+ bch2_check_discard_freespace_key_fsck(trans, &iter);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
|
||||
ret = 0;
|
||||
continue;
|
||||
diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h
|
||||
index 163a67b97a40..57723a37abb8 100644
|
||||
--- a/fs/bcachefs/alloc_background.h
|
||||
+++ b/fs/bcachefs/alloc_background.h
|
||||
@@ -307,6 +307,8 @@ int bch2_alloc_key_to_dev_counters(struct btree_trans *, struct bch_dev *,
|
||||
int bch2_trigger_alloc(struct btree_trans *, enum btree_id, unsigned,
|
||||
struct bkey_s_c, struct bkey_s,
|
||||
enum btree_iter_update_trigger_flags);
|
||||
+
|
||||
+int bch2_check_discard_freespace_key(struct btree_trans *, struct btree_iter *, u8 *);
|
||||
int bch2_check_alloc_info(struct bch_fs *);
|
||||
int bch2_check_alloc_to_lru_refs(struct bch_fs *);
|
||||
void bch2_dev_do_discards(struct bch_dev *);
|
||||
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
|
||||
index 645d8a269142..955ea6ae868f 100644
|
||||
--- a/fs/bcachefs/alloc_foreground.c
|
||||
+++ b/fs/bcachefs/alloc_foreground.c
|
||||
@@ -207,9 +207,8 @@ static inline unsigned open_buckets_reserved(enum bch_watermark watermark)
|
||||
}
|
||||
|
||||
static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *ca,
|
||||
- u64 bucket,
|
||||
+ u64 bucket, u8 gen,
|
||||
enum bch_watermark watermark,
|
||||
- const struct bch_alloc_v4 *a,
|
||||
struct bucket_alloc_state *s,
|
||||
struct closure *cl)
|
||||
{
|
||||
@@ -261,7 +260,7 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *
|
||||
ob->valid = true;
|
||||
ob->sectors_free = ca->mi.bucket_size;
|
||||
ob->dev = ca->dev_idx;
|
||||
- ob->gen = a->gen;
|
||||
+ ob->gen = gen;
|
||||
ob->bucket = bucket;
|
||||
spin_unlock(&ob->lock);
|
||||
|
||||
@@ -282,98 +281,36 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
struct closure *cl)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
- struct btree_iter iter = { NULL };
|
||||
- struct bkey_s_c k;
|
||||
- struct open_bucket *ob;
|
||||
- struct bch_alloc_v4 a_convert;
|
||||
- const struct bch_alloc_v4 *a;
|
||||
u64 b = freespace_iter->pos.offset & ~(~0ULL << 56);
|
||||
- unsigned genbits = freespace_iter->pos.offset >> 56;
|
||||
- struct printbuf buf = PRINTBUF;
|
||||
- int ret;
|
||||
-
|
||||
- if (b < ca->mi.first_bucket || b >= ca->mi.nbuckets) {
|
||||
- prt_printf(&buf, "freespace btree has bucket outside allowed range %u-%llu\n"
|
||||
- " freespace key ",
|
||||
- ca->mi.first_bucket, ca->mi.nbuckets);
|
||||
- bch2_bkey_to_text(&buf, &freespace_iter->k);
|
||||
- bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
- ob = ERR_PTR(-EIO);
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- k = bch2_bkey_get_iter(trans, &iter,
|
||||
- BTREE_ID_alloc, POS(ca->dev_idx, b),
|
||||
- BTREE_ITER_cached);
|
||||
- ret = bkey_err(k);
|
||||
- if (ret) {
|
||||
- ob = ERR_PTR(ret);
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- a = bch2_alloc_to_v4(k, &a_convert);
|
||||
-
|
||||
- if (a->data_type != BCH_DATA_free) {
|
||||
- if (c->curr_recovery_pass <= BCH_RECOVERY_PASS_check_alloc_info) {
|
||||
- ob = NULL;
|
||||
- goto err;
|
||||
- }
|
||||
+ u8 gen;
|
||||
|
||||
- prt_printf(&buf, "non free bucket in freespace btree\n"
|
||||
- " freespace key ");
|
||||
- bch2_bkey_to_text(&buf, &freespace_iter->k);
|
||||
- prt_printf(&buf, "\n ");
|
||||
- bch2_bkey_val_to_text(&buf, c, k);
|
||||
- bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
- ob = ERR_PTR(-EIO);
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- if (genbits != (alloc_freespace_genbits(*a) >> 56) &&
|
||||
- c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_info) {
|
||||
- prt_printf(&buf, "bucket in freespace btree with wrong genbits (got %u should be %llu)\n"
|
||||
- " freespace key ",
|
||||
- genbits, alloc_freespace_genbits(*a) >> 56);
|
||||
- bch2_bkey_to_text(&buf, &freespace_iter->k);
|
||||
- prt_printf(&buf, "\n ");
|
||||
- bch2_bkey_val_to_text(&buf, c, k);
|
||||
- bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
- ob = ERR_PTR(-EIO);
|
||||
- goto err;
|
||||
- }
|
||||
+ int ret = bch2_check_discard_freespace_key(trans, freespace_iter, &gen);
|
||||
+ if (ret < 0)
|
||||
+ return ERR_PTR(ret);
|
||||
+ if (ret)
|
||||
+ return NULL;
|
||||
|
||||
- if (c->curr_recovery_pass <= BCH_RECOVERY_PASS_check_extents_to_backpointers) {
|
||||
+ if (unlikely(c->curr_recovery_pass <= BCH_RECOVERY_PASS_check_extents_to_backpointers)) {
|
||||
struct bch_backpointer bp;
|
||||
struct bpos bp_pos = POS_MIN;
|
||||
|
||||
ret = bch2_get_next_backpointer(trans, ca, POS(ca->dev_idx, b), -1,
|
||||
&bp_pos, &bp,
|
||||
BTREE_ITER_nopreserve);
|
||||
- if (ret) {
|
||||
- ob = ERR_PTR(ret);
|
||||
- goto err;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ return ERR_PTR(ret);
|
||||
|
||||
if (!bkey_eq(bp_pos, POS_MAX)) {
|
||||
/*
|
||||
* Bucket may have data in it - we don't call
|
||||
- * bc2h_trans_inconnsistent() because fsck hasn't
|
||||
+ * bch2_trans_inconsistent() because fsck hasn't
|
||||
* finished yet
|
||||
*/
|
||||
- ob = NULL;
|
||||
- goto err;
|
||||
+ return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- ob = __try_alloc_bucket(c, ca, b, watermark, a, s, cl);
|
||||
- if (!ob)
|
||||
- bch2_set_btree_iter_dontneed(&iter);
|
||||
-err:
|
||||
- if (iter.path)
|
||||
- bch2_set_btree_iter_dontneed(&iter);
|
||||
- bch2_trans_iter_exit(trans, &iter);
|
||||
- printbuf_exit(&buf);
|
||||
- return ob;
|
||||
+ return __try_alloc_bucket(c, ca, b, gen, watermark, s, cl);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -452,7 +389,7 @@ bch2_bucket_alloc_early(struct btree_trans *trans,
|
||||
|
||||
s->buckets_seen++;
|
||||
|
||||
- ob = __try_alloc_bucket(trans->c, ca, k.k->p.offset, watermark, a, s, cl);
|
||||
+ ob = __try_alloc_bucket(trans->c, ca, k.k->p.offset, a->gen, watermark, s, cl);
|
||||
next:
|
||||
bch2_set_btree_iter_dontneed(&citer);
|
||||
bch2_trans_iter_exit(trans, &citer);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,207 +0,0 @@
|
||||
From cbc079bcff7d5eb38f54f3e7d378100d919e028a Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 26 Oct 2024 22:21:20 -0400
|
||||
Subject: [PATCH 087/233] bcachefs: bch2_bucket_do_index(): inconsistent_err ->
|
||||
fsck_err
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Factor out a common helper, need_discard_or_freespace_err(), which is
|
||||
now used by both fsck and the runtime checks, and can repair.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_background.c | 83 ++++++++++++++++++----------------
|
||||
fs/bcachefs/error.c | 7 +--
|
||||
fs/bcachefs/error.h | 6 ++-
|
||||
3 files changed, 51 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
|
||||
index 1f42dd208957..0c044201787f 100644
|
||||
--- a/fs/bcachefs/alloc_background.c
|
||||
+++ b/fs/bcachefs/alloc_background.c
|
||||
@@ -664,17 +664,44 @@ int bch2_alloc_read(struct bch_fs *c)
|
||||
|
||||
/* Free space/discard btree: */
|
||||
|
||||
+static int __need_discard_or_freespace_err(struct btree_trans *trans,
|
||||
+ struct bkey_s_c alloc_k,
|
||||
+ bool set, bool discard, bool repair)
|
||||
+{
|
||||
+ struct bch_fs *c = trans->c;
|
||||
+ enum bch_fsck_flags flags = FSCK_CAN_IGNORE|(repair ? FSCK_CAN_FIX : 0);
|
||||
+ enum bch_sb_error_id err_id = discard
|
||||
+ ? BCH_FSCK_ERR_need_discard_key_wrong
|
||||
+ : BCH_FSCK_ERR_freespace_key_wrong;
|
||||
+ enum btree_id btree = discard ? BTREE_ID_need_discard : BTREE_ID_freespace;
|
||||
+ struct printbuf buf = PRINTBUF;
|
||||
+
|
||||
+ bch2_bkey_val_to_text(&buf, c, alloc_k);
|
||||
+
|
||||
+ int ret = __bch2_fsck_err(NULL, trans, flags, err_id,
|
||||
+ "bucket incorrectly %sset in %s btree\n"
|
||||
+ " %s",
|
||||
+ set ? "" : "un",
|
||||
+ bch2_btree_id_str(btree),
|
||||
+ buf.buf);
|
||||
+ printbuf_exit(&buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#define need_discard_or_freespace_err(...) \
|
||||
+ fsck_err_wrap(__need_discard_or_freespace_err(__VA_ARGS__))
|
||||
+
|
||||
+#define need_discard_or_freespace_err_on(cond, ...) \
|
||||
+ (unlikely(cond) ? need_discard_or_freespace_err(__VA_ARGS__) : false)
|
||||
+
|
||||
static int bch2_bucket_do_index(struct btree_trans *trans,
|
||||
struct bch_dev *ca,
|
||||
struct bkey_s_c alloc_k,
|
||||
const struct bch_alloc_v4 *a,
|
||||
bool set)
|
||||
{
|
||||
- struct bch_fs *c = trans->c;
|
||||
enum btree_id btree;
|
||||
struct bpos pos;
|
||||
- enum bch_bkey_type old_type = !set ? KEY_TYPE_set : KEY_TYPE_deleted;
|
||||
- struct printbuf buf = PRINTBUF;
|
||||
|
||||
if (a->data_type != BCH_DATA_free &&
|
||||
a->data_type != BCH_DATA_need_discard)
|
||||
@@ -699,26 +726,14 @@ static int bch2_bucket_do_index(struct btree_trans *trans,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (ca->mi.freespace_initialized &&
|
||||
- c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_info &&
|
||||
- bch2_trans_inconsistent_on(old.k->type != old_type, trans,
|
||||
- "incorrect key when %s %s:%llu:%llu:0 (got %s should be %s)\n"
|
||||
- " for %s",
|
||||
- set ? "setting" : "clearing",
|
||||
- bch2_btree_id_str(btree),
|
||||
- iter.pos.inode,
|
||||
- iter.pos.offset,
|
||||
- bch2_bkey_types[old.k->type],
|
||||
- bch2_bkey_types[old_type],
|
||||
- (bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
|
||||
- ret = -EIO;
|
||||
- goto err;
|
||||
- }
|
||||
+ need_discard_or_freespace_err_on(ca->mi.freespace_initialized &&
|
||||
+ !old.k->type != set,
|
||||
+ trans, alloc_k, set,
|
||||
+ btree == BTREE_ID_need_discard, false);
|
||||
|
||||
ret = bch2_btree_bit_mod_iter(trans, &iter, set);
|
||||
-err:
|
||||
+fsck_err:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
- printbuf_exit(&buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1116,7 +1131,6 @@ int bch2_check_alloc_key(struct btree_trans *trans,
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bch_alloc_v4 a_convert;
|
||||
const struct bch_alloc_v4 *a;
|
||||
- unsigned discard_key_type, freespace_key_type;
|
||||
unsigned gens_offset;
|
||||
struct bkey_s_c k;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
@@ -1136,41 +1150,30 @@ int bch2_check_alloc_key(struct btree_trans *trans,
|
||||
|
||||
a = bch2_alloc_to_v4(alloc_k, &a_convert);
|
||||
|
||||
- discard_key_type = a->data_type == BCH_DATA_need_discard ? KEY_TYPE_set : 0;
|
||||
bch2_btree_iter_set_pos(discard_iter, alloc_k.k->p);
|
||||
k = bch2_btree_iter_peek_slot(discard_iter);
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
- if (fsck_err_on(k.k->type != discard_key_type,
|
||||
- trans, need_discard_key_wrong,
|
||||
- "incorrect key in need_discard btree (got %s should be %s)\n"
|
||||
- " %s",
|
||||
- bch2_bkey_types[k.k->type],
|
||||
- bch2_bkey_types[discard_key_type],
|
||||
- (bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
|
||||
- ret = bch2_btree_bit_mod_iter(trans, discard_iter, !!discard_key_type);
|
||||
+ bool is_discarded = a->data_type == BCH_DATA_need_discard;
|
||||
+ if (need_discard_or_freespace_err_on(!!k.k->type != is_discarded,
|
||||
+ trans, alloc_k, !is_discarded, true, true)) {
|
||||
+ ret = bch2_btree_bit_mod_iter(trans, discard_iter, is_discarded);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
- freespace_key_type = a->data_type == BCH_DATA_free ? KEY_TYPE_set : 0;
|
||||
bch2_btree_iter_set_pos(freespace_iter, alloc_freespace_pos(alloc_k.k->p, *a));
|
||||
k = bch2_btree_iter_peek_slot(freespace_iter);
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
- if (fsck_err_on(k.k->type != freespace_key_type,
|
||||
- trans, freespace_key_wrong,
|
||||
- "incorrect key in freespace btree (got %s should be %s)\n"
|
||||
- " %s",
|
||||
- bch2_bkey_types[k.k->type],
|
||||
- bch2_bkey_types[freespace_key_type],
|
||||
- (printbuf_reset(&buf),
|
||||
- bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) {
|
||||
- ret = bch2_btree_bit_mod_iter(trans, freespace_iter, !!freespace_key_type);
|
||||
+ bool is_free = a->data_type == BCH_DATA_free;
|
||||
+ if (need_discard_or_freespace_err_on(!!k.k->type != is_free,
|
||||
+ trans, alloc_k, !is_free, false, true)) {
|
||||
+ ret = bch2_btree_bit_mod_iter(trans, freespace_iter, is_free);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c
|
||||
index 22b0fa405a39..2960baa023f6 100644
|
||||
--- a/fs/bcachefs/error.c
|
||||
+++ b/fs/bcachefs/error.c
|
||||
@@ -256,9 +256,10 @@ int __bch2_fsck_err(struct bch_fs *c,
|
||||
!trans &&
|
||||
bch2_current_has_btree_trans(c));
|
||||
|
||||
- if ((flags & FSCK_CAN_FIX) &&
|
||||
- test_bit(err, c->sb.errors_silent))
|
||||
- return -BCH_ERR_fsck_fix;
|
||||
+ if (test_bit(err, c->sb.errors_silent))
|
||||
+ return flags & FSCK_CAN_FIX
|
||||
+ ? -BCH_ERR_fsck_fix
|
||||
+ : -BCH_ERR_fsck_ignore;
|
||||
|
||||
bch2_sb_error_count(c, err);
|
||||
|
||||
diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h
|
||||
index 24c41a9994df..8327a3461535 100644
|
||||
--- a/fs/bcachefs/error.h
|
||||
+++ b/fs/bcachefs/error.h
|
||||
@@ -103,9 +103,9 @@ int __bch2_fsck_err(struct bch_fs *, struct btree_trans *,
|
||||
|
||||
void bch2_flush_fsck_errs(struct bch_fs *);
|
||||
|
||||
-#define __fsck_err(c, _flags, _err_type, ...) \
|
||||
+#define fsck_err_wrap(_do) \
|
||||
({ \
|
||||
- int _ret = bch2_fsck_err(c, _flags, _err_type, __VA_ARGS__); \
|
||||
+ int _ret = _do; \
|
||||
if (_ret != -BCH_ERR_fsck_fix && \
|
||||
_ret != -BCH_ERR_fsck_ignore) { \
|
||||
ret = _ret; \
|
||||
@@ -115,6 +115,8 @@ void bch2_flush_fsck_errs(struct bch_fs *);
|
||||
_ret == -BCH_ERR_fsck_fix; \
|
||||
})
|
||||
|
||||
+#define __fsck_err(...) fsck_err_wrap(bch2_fsck_err(__VA_ARGS__))
|
||||
+
|
||||
/* These macros return true if error should be fixed: */
|
||||
|
||||
/* XXX: mark in superblock that filesystem contains errors, if we ignore: */
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,67 +0,0 @@
|
||||
From a7df326af032869e31b0d2a7e3c03190caf3e381 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 26 Oct 2024 23:25:17 -0400
|
||||
Subject: [PATCH 088/233] bcachefs: discard_one_bucket() now uses
|
||||
need_discard_or_freespace_err()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
More conversion of inconsistent errors to fsck errors.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_background.c | 24 +++++++++++++++---------
|
||||
1 file changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
|
||||
index 0c044201787f..e90561b6def6 100644
|
||||
--- a/fs/bcachefs/alloc_background.c
|
||||
+++ b/fs/bcachefs/alloc_background.c
|
||||
@@ -1770,11 +1770,13 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
|
||||
goto out;
|
||||
|
||||
if (a->v.data_type != BCH_DATA_need_discard) {
|
||||
- if (bch2_trans_inconsistent_on(c->curr_recovery_pass > BCH_RECOVERY_PASS_check_alloc_info,
|
||||
- trans, "bucket incorrectly set in need_discard btree\n"
|
||||
- "%s",
|
||||
- (bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
|
||||
- ret = -EIO;
|
||||
+ if (need_discard_or_freespace_err(trans, k, true, true, true)) {
|
||||
+ ret = bch2_btree_bit_mod_iter(trans, need_discard_iter, false);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+ goto commit;
|
||||
+ }
|
||||
+
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1814,16 +1816,20 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
|
||||
SET_BCH_ALLOC_V4_NEED_DISCARD(&a->v, false);
|
||||
alloc_data_type_set(&a->v, a->v.data_type);
|
||||
|
||||
- ret = bch2_trans_update(trans, &iter, &a->k_i, 0) ?:
|
||||
- bch2_trans_commit(trans, NULL, NULL,
|
||||
- BCH_WATERMARK_btree|
|
||||
- BCH_TRANS_COMMIT_no_enospc);
|
||||
+ ret = bch2_trans_update(trans, &iter, &a->k_i, 0);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+commit:
|
||||
+ ret = bch2_trans_commit(trans, NULL, NULL,
|
||||
+ BCH_WATERMARK_btree|
|
||||
+ BCH_TRANS_COMMIT_no_enospc);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
count_event(c, bucket_discard);
|
||||
s->discarded++;
|
||||
out:
|
||||
+fsck_err:
|
||||
if (discard_locked)
|
||||
discard_in_flight_remove(ca, iter.pos.offset);
|
||||
s->seen++;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,508 +0,0 @@
|
||||
From 632bcf38651efbbf9507cf35ae63d6ac291dca24 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 24 Oct 2024 22:12:37 -0400
|
||||
Subject: [PATCH 089/233] bcachefs: Implement bch2_btree_iter_prev_min()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
A user contributed a filessytem dump, where the dump was actually
|
||||
corrupted (due to being taken while the filesystem was online), but
|
||||
which exposed an interesting bug in fsck - reconstruct_inode().
|
||||
|
||||
When itearting in BTREE_ITER_filter_snapshots mode, it's required to
|
||||
give an end position for the iteration and it can't span inode numbers;
|
||||
continuing into the next inode might mean we start seeing keys from a
|
||||
different snapshot tree, that the is_ancestor() checks always filter,
|
||||
thus we're never able to return a key and stop iterating.
|
||||
|
||||
Backwards iteration never implemented the end position because nothing
|
||||
else needed it - except for reconstuct_inode().
|
||||
|
||||
Additionally, backwards iteration is now able to overlay keys from the
|
||||
journal, which will be useful if we ever decide to start doing journal
|
||||
replay in the background.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 256 +++++++++++++++++++++----------
|
||||
fs/bcachefs/btree_iter.h | 8 +-
|
||||
fs/bcachefs/btree_journal_iter.c | 46 ++++++
|
||||
fs/bcachefs/btree_journal_iter.h | 2 +
|
||||
fs/bcachefs/errcode.h | 1 -
|
||||
fs/bcachefs/fsck.c | 4 +-
|
||||
fs/bcachefs/io_misc.c | 2 +-
|
||||
7 files changed, 234 insertions(+), 85 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index 580fee86a965..d66d773a37b4 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -270,8 +270,10 @@ static void bch2_btree_iter_verify_entry_exit(struct btree_iter *iter)
|
||||
BUG_ON(!(iter->flags & BTREE_ITER_all_snapshots) &&
|
||||
iter->pos.snapshot != iter->snapshot);
|
||||
|
||||
- BUG_ON(bkey_lt(iter->pos, bkey_start_pos(&iter->k)) ||
|
||||
- bkey_gt(iter->pos, iter->k.p));
|
||||
+ BUG_ON(iter->flags & BTREE_ITER_all_snapshots ? !bpos_eq(iter->pos, iter->k.p) :
|
||||
+ !(iter->flags & BTREE_ITER_is_extents) ? !bkey_eq(iter->pos, iter->k.p) :
|
||||
+ (bkey_lt(iter->pos, bkey_start_pos(&iter->k)) ||
|
||||
+ bkey_gt(iter->pos, iter->k.p)));
|
||||
}
|
||||
|
||||
static int bch2_btree_iter_verify_ret(struct btree_iter *iter, struct bkey_s_c k)
|
||||
@@ -2152,6 +2154,37 @@ struct bkey_s_c btree_trans_peek_journal(struct btree_trans *trans,
|
||||
return k;
|
||||
}
|
||||
|
||||
+static struct bkey_i *bch2_btree_journal_peek_prev(struct btree_trans *trans,
|
||||
+ struct btree_iter *iter,
|
||||
+ struct bpos end_pos)
|
||||
+{
|
||||
+ struct btree_path *path = btree_iter_path(trans, iter);
|
||||
+
|
||||
+ return bch2_journal_keys_peek_prev_min(trans->c, iter->btree_id,
|
||||
+ path->level,
|
||||
+ path->pos,
|
||||
+ end_pos,
|
||||
+ &iter->journal_idx);
|
||||
+}
|
||||
+
|
||||
+static noinline
|
||||
+struct bkey_s_c btree_trans_peek_prev_journal(struct btree_trans *trans,
|
||||
+ struct btree_iter *iter,
|
||||
+ struct bkey_s_c k)
|
||||
+{
|
||||
+ struct btree_path *path = btree_iter_path(trans, iter);
|
||||
+ struct bkey_i *next_journal =
|
||||
+ bch2_btree_journal_peek_prev(trans, iter,
|
||||
+ k.k ? k.k->p : path_l(path)->b->key.k.p);
|
||||
+
|
||||
+ if (next_journal) {
|
||||
+ iter->k = next_journal->k;
|
||||
+ k = bkey_i_to_s_c(next_journal);
|
||||
+ }
|
||||
+
|
||||
+ return k;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Checks btree key cache for key at iter->pos and returns it if present, or
|
||||
* bkey_s_c_null:
|
||||
@@ -2457,127 +2490,187 @@ struct bkey_s_c bch2_btree_iter_next(struct btree_iter *iter)
|
||||
return bch2_btree_iter_peek(iter);
|
||||
}
|
||||
|
||||
+static struct bkey_s_c __bch2_btree_iter_peek_prev(struct btree_iter *iter, struct bpos search_key)
|
||||
+{
|
||||
+ struct btree_trans *trans = iter->trans;
|
||||
+ struct bkey_s_c k, k2;
|
||||
+
|
||||
+ bch2_btree_iter_verify(iter);
|
||||
+
|
||||
+ while (1) {
|
||||
+ iter->path = bch2_btree_path_set_pos(trans, iter->path, search_key,
|
||||
+ iter->flags & BTREE_ITER_intent,
|
||||
+ btree_iter_ip_allocated(iter));
|
||||
+
|
||||
+ int ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
|
||||
+ if (unlikely(ret)) {
|
||||
+ /* ensure that iter->k is consistent with iter->pos: */
|
||||
+ bch2_btree_iter_set_pos(iter, iter->pos);
|
||||
+ k = bkey_s_c_err(ret);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ struct btree_path *path = btree_iter_path(trans, iter);
|
||||
+ struct btree_path_level *l = path_l(path);
|
||||
+
|
||||
+ if (unlikely(!l->b)) {
|
||||
+ /* No btree nodes at requested level: */
|
||||
+ bch2_btree_iter_set_pos(iter, SPOS_MAX);
|
||||
+ k = bkey_s_c_null;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ btree_path_set_should_be_locked(trans, path);
|
||||
+
|
||||
+ k = btree_path_level_peek_all(trans->c, l, &iter->k);
|
||||
+ if (!k.k || bpos_gt(k.k->p, search_key)) {
|
||||
+ k = btree_path_level_prev(trans, path, l, &iter->k);
|
||||
+
|
||||
+ BUG_ON(k.k && bpos_gt(k.k->p, search_key));
|
||||
+ }
|
||||
+
|
||||
+ if (unlikely(iter->flags & BTREE_ITER_with_key_cache) &&
|
||||
+ k.k &&
|
||||
+ (k2 = btree_trans_peek_key_cache(iter, k.k->p)).k) {
|
||||
+ k = k2;
|
||||
+ if (bkey_err(k2)) {
|
||||
+ bch2_btree_iter_set_pos(iter, iter->pos);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (unlikely(iter->flags & BTREE_ITER_with_journal))
|
||||
+ k = btree_trans_peek_prev_journal(trans, iter, k);
|
||||
+
|
||||
+ if (unlikely((iter->flags & BTREE_ITER_with_updates) &&
|
||||
+ trans->nr_updates))
|
||||
+ bch2_btree_trans_peek_prev_updates(trans, iter, &k);
|
||||
+
|
||||
+ if (likely(k.k && !bkey_deleted(k.k))) {
|
||||
+ break;
|
||||
+ } else if (k.k) {
|
||||
+ search_key = bpos_predecessor(k.k->p);
|
||||
+ } else if (likely(!bpos_eq(path->l[0].b->data->min_key, POS_MIN))) {
|
||||
+ /* Advance to previous leaf node: */
|
||||
+ search_key = bpos_predecessor(path->l[0].b->data->min_key);
|
||||
+ } else {
|
||||
+ /* Start of btree: */
|
||||
+ bch2_btree_iter_set_pos(iter, POS_MIN);
|
||||
+ k = bkey_s_c_null;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ bch2_btree_iter_verify(iter);
|
||||
+ return k;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
- * bch2_btree_iter_peek_prev() - returns first key less than or equal to
|
||||
+ * bch2_btree_iter_peek_prev_min() - returns first key less than or equal to
|
||||
* iterator's current position
|
||||
* @iter: iterator to peek from
|
||||
+ * @end: search limit: returns keys greater than or equal to @end
|
||||
*
|
||||
* Returns: key if found, or an error extractable with bkey_err().
|
||||
*/
|
||||
-struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
|
||||
+struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_iter *iter, struct bpos end)
|
||||
{
|
||||
struct btree_trans *trans = iter->trans;
|
||||
struct bpos search_key = iter->pos;
|
||||
struct bkey_s_c k;
|
||||
- struct bkey saved_k;
|
||||
- const struct bch_val *saved_v;
|
||||
btree_path_idx_t saved_path = 0;
|
||||
- int ret;
|
||||
|
||||
bch2_trans_verify_not_unlocked_or_in_restart(trans);
|
||||
- EBUG_ON(btree_iter_path(trans, iter)->cached ||
|
||||
- btree_iter_path(trans, iter)->level);
|
||||
-
|
||||
- if (iter->flags & BTREE_ITER_with_journal)
|
||||
- return bkey_s_c_err(-BCH_ERR_btree_iter_with_journal_not_supported);
|
||||
-
|
||||
- bch2_btree_iter_verify(iter);
|
||||
bch2_btree_iter_verify_entry_exit(iter);
|
||||
+ EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bpos_eq(end, POS_MIN));
|
||||
|
||||
if (iter->flags & BTREE_ITER_filter_snapshots)
|
||||
search_key.snapshot = U32_MAX;
|
||||
|
||||
while (1) {
|
||||
- iter->path = bch2_btree_path_set_pos(trans, iter->path, search_key,
|
||||
- iter->flags & BTREE_ITER_intent,
|
||||
- btree_iter_ip_allocated(iter));
|
||||
-
|
||||
- ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
|
||||
- if (unlikely(ret)) {
|
||||
- /* ensure that iter->k is consistent with iter->pos: */
|
||||
- bch2_btree_iter_set_pos(iter, iter->pos);
|
||||
- k = bkey_s_c_err(ret);
|
||||
+ k = __bch2_btree_iter_peek_prev(iter, search_key);
|
||||
+ if (unlikely(!k.k))
|
||||
+ goto end;
|
||||
+ if (unlikely(bkey_err(k)))
|
||||
goto out_no_locked;
|
||||
- }
|
||||
-
|
||||
- struct btree_path *path = btree_iter_path(trans, iter);
|
||||
|
||||
- k = btree_path_level_peek(trans, path, &path->l[0], &iter->k);
|
||||
- if (!k.k ||
|
||||
- ((iter->flags & BTREE_ITER_is_extents)
|
||||
- ? bpos_ge(bkey_start_pos(k.k), search_key)
|
||||
- : bpos_gt(k.k->p, search_key)))
|
||||
- k = btree_path_level_prev(trans, path, &path->l[0], &iter->k);
|
||||
+ if (iter->flags & BTREE_ITER_filter_snapshots) {
|
||||
+ struct btree_path *s = saved_path ? trans->paths + saved_path : NULL;
|
||||
+ if (s && bpos_lt(k.k->p, SPOS(s->pos.inode, s->pos.offset, iter->snapshot))) {
|
||||
+ /*
|
||||
+ * If we have a saved candidate, and we're past
|
||||
+ * the last possible snapshot overwrite, return
|
||||
+ * it:
|
||||
+ */
|
||||
+ bch2_path_put_nokeep(trans, iter->path,
|
||||
+ iter->flags & BTREE_ITER_intent);
|
||||
+ iter->path = saved_path;
|
||||
+ saved_path = 0;
|
||||
+ k = bch2_btree_path_peek_slot(btree_iter_path(trans, iter), &iter->k);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (unlikely((iter->flags & BTREE_ITER_with_updates) &&
|
||||
- trans->nr_updates))
|
||||
- bch2_btree_trans_peek_prev_updates(trans, iter, &k);
|
||||
+ /*
|
||||
+ * We need to check against @end before FILTER_SNAPSHOTS because
|
||||
+ * if we get to a different inode that requested we might be
|
||||
+ * seeing keys for a different snapshot tree that will all be
|
||||
+ * filtered out.
|
||||
+ */
|
||||
+ if (unlikely(bkey_lt(k.k->p, end)))
|
||||
+ goto end;
|
||||
|
||||
- if (likely(k.k)) {
|
||||
- if (iter->flags & BTREE_ITER_filter_snapshots) {
|
||||
- if (k.k->p.snapshot == iter->snapshot)
|
||||
- goto got_key;
|
||||
+ if (!bch2_snapshot_is_ancestor(trans->c, iter->snapshot, k.k->p.snapshot)) {
|
||||
+ search_key = bpos_predecessor(k.k->p);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
+ if (k.k->p.snapshot != iter->snapshot) {
|
||||
/*
|
||||
- * If we have a saved candidate, and we're no
|
||||
- * longer at the same _key_ (not pos), return
|
||||
- * that candidate
|
||||
+ * Have a key visible in iter->snapshot, but
|
||||
+ * might have overwrites: - save it and keep
|
||||
+ * searching. Unless it's a whiteout - then drop
|
||||
+ * our previous saved candidate:
|
||||
*/
|
||||
- if (saved_path && !bkey_eq(k.k->p, saved_k.p)) {
|
||||
- bch2_path_put_nokeep(trans, iter->path,
|
||||
- iter->flags & BTREE_ITER_intent);
|
||||
- iter->path = saved_path;
|
||||
+ if (saved_path) {
|
||||
+ bch2_path_put_nokeep(trans, saved_path,
|
||||
+ iter->flags & BTREE_ITER_intent);
|
||||
saved_path = 0;
|
||||
- iter->k = saved_k;
|
||||
- k.v = saved_v;
|
||||
- goto got_key;
|
||||
}
|
||||
|
||||
- if (bch2_snapshot_is_ancestor(trans->c,
|
||||
- iter->snapshot,
|
||||
- k.k->p.snapshot)) {
|
||||
- if (saved_path)
|
||||
- bch2_path_put_nokeep(trans, saved_path,
|
||||
- iter->flags & BTREE_ITER_intent);
|
||||
+ if (!bkey_whiteout(k.k)) {
|
||||
saved_path = btree_path_clone(trans, iter->path,
|
||||
iter->flags & BTREE_ITER_intent,
|
||||
_THIS_IP_);
|
||||
- path = btree_iter_path(trans, iter);
|
||||
- trace_btree_path_save_pos(trans, path, trans->paths + saved_path);
|
||||
- saved_k = *k.k;
|
||||
- saved_v = k.v;
|
||||
+ trace_btree_path_save_pos(trans,
|
||||
+ trans->paths + iter->path,
|
||||
+ trans->paths + saved_path);
|
||||
}
|
||||
|
||||
search_key = bpos_predecessor(k.k->p);
|
||||
continue;
|
||||
}
|
||||
-got_key:
|
||||
- if (bkey_whiteout(k.k) &&
|
||||
- !(iter->flags & BTREE_ITER_all_snapshots)) {
|
||||
+
|
||||
+ if (bkey_whiteout(k.k)) {
|
||||
search_key = bkey_predecessor(iter, k.k->p);
|
||||
- if (iter->flags & BTREE_ITER_filter_snapshots)
|
||||
- search_key.snapshot = U32_MAX;
|
||||
+ search_key.snapshot = U32_MAX;
|
||||
continue;
|
||||
}
|
||||
-
|
||||
- btree_path_set_should_be_locked(trans, path);
|
||||
- break;
|
||||
- } else if (likely(!bpos_eq(path->l[0].b->data->min_key, POS_MIN))) {
|
||||
- /* Advance to previous leaf node: */
|
||||
- search_key = bpos_predecessor(path->l[0].b->data->min_key);
|
||||
- } else {
|
||||
- /* Start of btree: */
|
||||
- bch2_btree_iter_set_pos(iter, POS_MIN);
|
||||
- k = bkey_s_c_null;
|
||||
- goto out_no_locked;
|
||||
}
|
||||
- }
|
||||
|
||||
- EBUG_ON(bkey_gt(bkey_start_pos(k.k), iter->pos));
|
||||
+ EBUG_ON(iter->flags & BTREE_ITER_all_snapshots ? bpos_gt(k.k->p, iter->pos) :
|
||||
+ iter->flags & BTREE_ITER_is_extents ? bkey_ge(bkey_start_pos(k.k), iter->pos) :
|
||||
+ bkey_gt(k.k->p, iter->pos));
|
||||
+
|
||||
+ if (unlikely(iter->flags & BTREE_ITER_all_snapshots ? bpos_lt(k.k->p, end) :
|
||||
+ iter->flags & BTREE_ITER_is_extents ? bkey_le(k.k->p, end) :
|
||||
+ bkey_lt(k.k->p, end)))
|
||||
+ goto end;
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
/* Extents can straddle iter->pos: */
|
||||
- if (bkey_lt(k.k->p, iter->pos))
|
||||
- iter->pos = k.k->p;
|
||||
+ iter->pos = bpos_min(iter->pos, k.k->p);;
|
||||
|
||||
if (iter->flags & BTREE_ITER_filter_snapshots)
|
||||
iter->pos.snapshot = iter->snapshot;
|
||||
@@ -2587,8 +2680,11 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
|
||||
|
||||
bch2_btree_iter_verify_entry_exit(iter);
|
||||
bch2_btree_iter_verify(iter);
|
||||
-
|
||||
return k;
|
||||
+end:
|
||||
+ bch2_btree_iter_set_pos(iter, end);
|
||||
+ k = bkey_s_c_null;
|
||||
+ goto out_no_locked;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
|
||||
index cd9022ce15a5..3477fc8c0396 100644
|
||||
--- a/fs/bcachefs/btree_iter.h
|
||||
+++ b/fs/bcachefs/btree_iter.h
|
||||
@@ -389,7 +389,13 @@ static inline struct bkey_s_c bch2_btree_iter_peek(struct btree_iter *iter)
|
||||
return bch2_btree_iter_peek_max(iter, SPOS_MAX);
|
||||
}
|
||||
|
||||
-struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *);
|
||||
+struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_iter *, struct bpos);
|
||||
+
|
||||
+static inline struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
|
||||
+{
|
||||
+ return bch2_btree_iter_peek_prev_min(iter, POS_MIN);
|
||||
+}
|
||||
+
|
||||
struct bkey_s_c bch2_btree_iter_prev(struct btree_iter *);
|
||||
|
||||
struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *);
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.c b/fs/bcachefs/btree_journal_iter.c
|
||||
index c9dee4b4627a..c44889ef9817 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.c
|
||||
+++ b/fs/bcachefs/btree_journal_iter.c
|
||||
@@ -107,6 +107,52 @@ struct bkey_i *bch2_journal_keys_peek_max(struct bch_fs *c, enum btree_id btree_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+struct bkey_i *bch2_journal_keys_peek_prev_min(struct bch_fs *c, enum btree_id btree_id,
|
||||
+ unsigned level, struct bpos pos,
|
||||
+ struct bpos end_pos, size_t *idx)
|
||||
+{
|
||||
+ struct journal_keys *keys = &c->journal_keys;
|
||||
+ unsigned iters = 0;
|
||||
+ struct journal_key *k;
|
||||
+
|
||||
+ BUG_ON(*idx > keys->nr);
|
||||
+search:
|
||||
+ if (!*idx)
|
||||
+ *idx = __bch2_journal_key_search(keys, btree_id, level, pos);
|
||||
+
|
||||
+ while (*idx &&
|
||||
+ __journal_key_cmp(btree_id, level, end_pos, idx_to_key(keys, *idx - 1)) <= 0) {
|
||||
+ (*idx)++;
|
||||
+ iters++;
|
||||
+ if (iters == 10) {
|
||||
+ *idx = 0;
|
||||
+ goto search;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while ((k = *idx < keys->nr ? idx_to_key(keys, *idx) : NULL)) {
|
||||
+ if (__journal_key_cmp(btree_id, level, end_pos, k) > 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (k->overwritten) {
|
||||
+ --(*idx);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (__journal_key_cmp(btree_id, level, pos, k) >= 0)
|
||||
+ return k->k;
|
||||
+
|
||||
+ --(*idx);
|
||||
+ iters++;
|
||||
+ if (iters == 10) {
|
||||
+ *idx = 0;
|
||||
+ goto search;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *c, enum btree_id btree_id,
|
||||
unsigned level, struct bpos pos)
|
||||
{
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.h b/fs/bcachefs/btree_journal_iter.h
|
||||
index 754939f604d5..fa8c4f82c9c7 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.h
|
||||
+++ b/fs/bcachefs/btree_journal_iter.h
|
||||
@@ -45,6 +45,8 @@ static inline int journal_key_cmp(const struct journal_key *l, const struct jour
|
||||
|
||||
struct bkey_i *bch2_journal_keys_peek_max(struct bch_fs *, enum btree_id,
|
||||
unsigned, struct bpos, struct bpos, size_t *);
|
||||
+struct bkey_i *bch2_journal_keys_peek_prev_min(struct bch_fs *, enum btree_id,
|
||||
+ unsigned, struct bpos, struct bpos, size_t *);
|
||||
struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *, enum btree_id,
|
||||
unsigned, struct bpos);
|
||||
|
||||
diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h
|
||||
index 40bf1e5775a9..18c995d41203 100644
|
||||
--- a/fs/bcachefs/errcode.h
|
||||
+++ b/fs/bcachefs/errcode.h
|
||||
@@ -193,7 +193,6 @@
|
||||
x(EINVAL, opt_parse_error) \
|
||||
x(EINVAL, remove_with_metadata_missing_unimplemented)\
|
||||
x(EINVAL, remove_would_lose_data) \
|
||||
- x(EINVAL, btree_iter_with_journal_not_supported) \
|
||||
x(EROFS, erofs_trans_commit) \
|
||||
x(EROFS, erofs_no_writes) \
|
||||
x(EROFS, erofs_journal_err) \
|
||||
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
|
||||
index e0335265de3d..e10abd2e6c69 100644
|
||||
--- a/fs/bcachefs/fsck.c
|
||||
+++ b/fs/bcachefs/fsck.c
|
||||
@@ -620,7 +620,7 @@ static int reconstruct_inode(struct btree_trans *trans, enum btree_id btree, u32
|
||||
struct btree_iter iter = {};
|
||||
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_extents, SPOS(inum, U64_MAX, snapshot), 0);
|
||||
- struct bkey_s_c k = bch2_btree_iter_peek_prev(&iter);
|
||||
+ struct bkey_s_c k = bch2_btree_iter_peek_prev_min(&iter, POS(inum, 0));
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
int ret = bkey_err(k);
|
||||
if (ret)
|
||||
@@ -1649,7 +1649,7 @@ static int check_i_sectors_notnested(struct btree_trans *trans, struct inode_wal
|
||||
if (i->count != count2) {
|
||||
bch_err_ratelimited(c, "fsck counted i_sectors wrong for inode %llu:%u: got %llu should be %llu",
|
||||
w->last_pos.inode, i->snapshot, i->count, count2);
|
||||
- return -BCH_ERR_internal_fsck_err;
|
||||
+ i->count = count2;
|
||||
}
|
||||
|
||||
if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_i_sectors_dirty),
|
||||
diff --git a/fs/bcachefs/io_misc.c b/fs/bcachefs/io_misc.c
|
||||
index ff661a072000..524e31e7411b 100644
|
||||
--- a/fs/bcachefs/io_misc.c
|
||||
+++ b/fs/bcachefs/io_misc.c
|
||||
@@ -426,7 +426,7 @@ case LOGGED_OP_FINSERT_shift_extents:
|
||||
bch2_btree_iter_set_pos(&iter, SPOS(inum.inum, pos, snapshot));
|
||||
|
||||
k = insert
|
||||
- ? bch2_btree_iter_peek_prev(&iter)
|
||||
+ ? bch2_btree_iter_peek_prev_min(&iter, POS(inum.inum, 0))
|
||||
: bch2_btree_iter_peek_max(&iter, POS(inum.inum, U64_MAX));
|
||||
if ((ret = bkey_err(k)))
|
||||
goto btree_err;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,64 +0,0 @@
|
||||
From 3140d0052a47723243dbd8f5a1f49ebb5eda2e9e Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 25 Oct 2024 20:41:06 -0400
|
||||
Subject: [PATCH 090/233] bcachefs: peek_prev_min(): Search forwards for
|
||||
extents, snapshots
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
With extents and snapshots, for slightly different reasons, we may have
|
||||
to search forwards to find a key that compares equal to iter->pos (i.e.
|
||||
a key that peek_prev() should return, as it returns keys <= iter->pos).
|
||||
|
||||
peek_slot() does this, and is an easy way to fix this case.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 23 ++++++++++++++++++++---
|
||||
1 file changed, 20 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index d66d773a37b4..ed74f0655d98 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -2575,6 +2575,26 @@ static struct bkey_s_c __bch2_btree_iter_peek_prev(struct btree_iter *iter, stru
|
||||
*/
|
||||
struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_iter *iter, struct bpos end)
|
||||
{
|
||||
+ if ((iter->flags & (BTREE_ITER_is_extents|BTREE_ITER_filter_snapshots)) &&
|
||||
+ !bkey_eq(iter->pos, POS_MAX)) {
|
||||
+ /*
|
||||
+ * bkey_start_pos(), for extents, is not monotonically
|
||||
+ * increasing until after filtering for snapshots:
|
||||
+ *
|
||||
+ * Thus, for extents we need to search forward until we find a
|
||||
+ * real visible extents - easiest to just use peek_slot() (which
|
||||
+ * internally uses peek() for extents)
|
||||
+ */
|
||||
+ struct bkey_s_c k = bch2_btree_iter_peek_slot(iter);
|
||||
+ if (bkey_err(k))
|
||||
+ return k;
|
||||
+
|
||||
+ if (!bkey_deleted(k.k) &&
|
||||
+ (!(iter->flags & BTREE_ITER_is_extents) ||
|
||||
+ bkey_lt(bkey_start_pos(k.k), iter->pos)))
|
||||
+ return k;
|
||||
+ }
|
||||
+
|
||||
struct btree_trans *trans = iter->trans;
|
||||
struct bpos search_key = iter->pos;
|
||||
struct bkey_s_c k;
|
||||
@@ -2584,9 +2604,6 @@ struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_iter *iter, struct bp
|
||||
bch2_btree_iter_verify_entry_exit(iter);
|
||||
EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bpos_eq(end, POS_MIN));
|
||||
|
||||
- if (iter->flags & BTREE_ITER_filter_snapshots)
|
||||
- search_key.snapshot = U32_MAX;
|
||||
-
|
||||
while (1) {
|
||||
k = __bch2_btree_iter_peek_prev(iter, search_key);
|
||||
if (unlikely(!k.k))
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,56 +0,0 @@
|
||||
From 59fad23c7abcecc8d4022e76050295c2f37c1bfb Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 14 Nov 2024 21:28:40 -0500
|
||||
Subject: [PATCH 091/233] bcachefs: Delete backpointers check in
|
||||
try_alloc_bucket()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
try_alloc_bucket() has a "safety" check, which avoids allocating a
|
||||
bucket if there's any backpointers present.
|
||||
|
||||
But backpointers are not the source of truth for live data in a bucket,
|
||||
the bucket sector counts are; this check was fairly useless, and we're
|
||||
also deferring backpointers checks from fsck to runtime in the near
|
||||
future.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/alloc_foreground.c | 20 --------------------
|
||||
1 file changed, 20 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/alloc_foreground.c b/fs/bcachefs/alloc_foreground.c
|
||||
index 955ea6ae868f..6d665b720f72 100644
|
||||
--- a/fs/bcachefs/alloc_foreground.c
|
||||
+++ b/fs/bcachefs/alloc_foreground.c
|
||||
@@ -290,26 +290,6 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
- if (unlikely(c->curr_recovery_pass <= BCH_RECOVERY_PASS_check_extents_to_backpointers)) {
|
||||
- struct bch_backpointer bp;
|
||||
- struct bpos bp_pos = POS_MIN;
|
||||
-
|
||||
- ret = bch2_get_next_backpointer(trans, ca, POS(ca->dev_idx, b), -1,
|
||||
- &bp_pos, &bp,
|
||||
- BTREE_ITER_nopreserve);
|
||||
- if (ret)
|
||||
- return ERR_PTR(ret);
|
||||
-
|
||||
- if (!bkey_eq(bp_pos, POS_MAX)) {
|
||||
- /*
|
||||
- * Bucket may have data in it - we don't call
|
||||
- * bch2_trans_inconsistent() because fsck hasn't
|
||||
- * finished yet
|
||||
- */
|
||||
- return NULL;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
return __try_alloc_bucket(c, ca, b, gen, watermark, s, cl);
|
||||
}
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,494 +0,0 @@
|
||||
From 7fdfb0cbea34b8dcc319be4b4898d89350a7f40f Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 14 Nov 2024 21:53:38 -0500
|
||||
Subject: [PATCH 092/233] bcachefs: Kill bch2_get_next_backpointer()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Since for quite some time backpointers have only been stored in the
|
||||
backpointers btree, not alloc keys (an aborted experiment, support for
|
||||
which has been removed) - we can replace get_next_backpointer() with
|
||||
simple btree iteration.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/backpointers.c | 125 +++++++++++--------------------------
|
||||
fs/bcachefs/backpointers.h | 11 ++--
|
||||
fs/bcachefs/ec.c | 41 +++++-------
|
||||
fs/bcachefs/move.c | 41 ++++++------
|
||||
4 files changed, 75 insertions(+), 143 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c
|
||||
index f323ce4b0b33..a9ffbea277bd 100644
|
||||
--- a/fs/bcachefs/backpointers.c
|
||||
+++ b/fs/bcachefs/backpointers.c
|
||||
@@ -215,59 +215,9 @@ int bch2_bucket_backpointer_mod_nowritebuffer(struct btree_trans *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Find the next backpointer >= *bp_offset:
|
||||
- */
|
||||
-int bch2_get_next_backpointer(struct btree_trans *trans,
|
||||
- struct bch_dev *ca,
|
||||
- struct bpos bucket, int gen,
|
||||
- struct bpos *bp_pos,
|
||||
- struct bch_backpointer *bp,
|
||||
- unsigned iter_flags)
|
||||
-{
|
||||
- struct bpos bp_end_pos = bucket_pos_to_bp(ca, bpos_nosnap_successor(bucket), 0);
|
||||
- struct btree_iter alloc_iter = { NULL }, bp_iter = { NULL };
|
||||
- struct bkey_s_c k;
|
||||
- int ret = 0;
|
||||
-
|
||||
- if (bpos_ge(*bp_pos, bp_end_pos))
|
||||
- goto done;
|
||||
-
|
||||
- if (gen >= 0) {
|
||||
- k = bch2_bkey_get_iter(trans, &alloc_iter, BTREE_ID_alloc,
|
||||
- bucket, BTREE_ITER_cached|iter_flags);
|
||||
- ret = bkey_err(k);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
-
|
||||
- if (k.k->type != KEY_TYPE_alloc_v4 ||
|
||||
- bkey_s_c_to_alloc_v4(k).v->gen != gen)
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- *bp_pos = bpos_max(*bp_pos, bucket_pos_to_bp(ca, bucket, 0));
|
||||
-
|
||||
- for_each_btree_key_norestart(trans, bp_iter, BTREE_ID_backpointers,
|
||||
- *bp_pos, iter_flags, k, ret) {
|
||||
- if (bpos_ge(k.k->p, bp_end_pos))
|
||||
- break;
|
||||
-
|
||||
- *bp_pos = k.k->p;
|
||||
- *bp = *bkey_s_c_to_backpointer(k).v;
|
||||
- goto out;
|
||||
- }
|
||||
-done:
|
||||
- *bp_pos = SPOS_MAX;
|
||||
-out:
|
||||
- bch2_trans_iter_exit(trans, &bp_iter);
|
||||
- bch2_trans_iter_exit(trans, &alloc_iter);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void backpointer_not_found(struct btree_trans *trans,
|
||||
- struct bpos bp_pos,
|
||||
- struct bch_backpointer bp,
|
||||
- struct bkey_s_c k)
|
||||
+static void backpointer_target_not_found(struct btree_trans *trans,
|
||||
+ struct bkey_s_c_backpointer bp,
|
||||
+ struct bkey_s_c target_k)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
@@ -281,22 +231,22 @@ static void backpointer_not_found(struct btree_trans *trans,
|
||||
return;
|
||||
|
||||
struct bpos bucket;
|
||||
- if (!bp_pos_to_bucket_nodev(c, bp_pos, &bucket))
|
||||
+ if (!bp_pos_to_bucket_nodev(c, bp.k->p, &bucket))
|
||||
return;
|
||||
|
||||
prt_printf(&buf, "backpointer doesn't match %s it points to:\n ",
|
||||
- bp.level ? "btree node" : "extent");
|
||||
+ bp.v->level ? "btree node" : "extent");
|
||||
prt_printf(&buf, "bucket: ");
|
||||
bch2_bpos_to_text(&buf, bucket);
|
||||
prt_printf(&buf, "\n ");
|
||||
|
||||
prt_printf(&buf, "backpointer pos: ");
|
||||
- bch2_bpos_to_text(&buf, bp_pos);
|
||||
+ bch2_bpos_to_text(&buf, bp.k->p);
|
||||
prt_printf(&buf, "\n ");
|
||||
|
||||
- bch2_backpointer_to_text(&buf, &bp);
|
||||
+ bch2_backpointer_to_text(&buf, bp.v);
|
||||
prt_printf(&buf, "\n ");
|
||||
- bch2_bkey_val_to_text(&buf, c, k);
|
||||
+ bch2_bkey_val_to_text(&buf, c, target_k);
|
||||
if (c->curr_recovery_pass >= BCH_RECOVERY_PASS_check_extents_to_backpointers)
|
||||
bch_err_ratelimited(c, "%s", buf.buf);
|
||||
else
|
||||
@@ -306,21 +256,20 @@ static void backpointer_not_found(struct btree_trans *trans,
|
||||
}
|
||||
|
||||
struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans,
|
||||
+ struct bkey_s_c_backpointer bp,
|
||||
struct btree_iter *iter,
|
||||
- struct bpos bp_pos,
|
||||
- struct bch_backpointer bp,
|
||||
unsigned iter_flags)
|
||||
{
|
||||
- if (likely(!bp.level)) {
|
||||
+ if (likely(!bp.v->level)) {
|
||||
struct bch_fs *c = trans->c;
|
||||
|
||||
struct bpos bucket;
|
||||
- if (!bp_pos_to_bucket_nodev(c, bp_pos, &bucket))
|
||||
+ if (!bp_pos_to_bucket_nodev(c, bp.k->p, &bucket))
|
||||
return bkey_s_c_err(-EIO);
|
||||
|
||||
bch2_trans_node_iter_init(trans, iter,
|
||||
- bp.btree_id,
|
||||
- bp.pos,
|
||||
+ bp.v->btree_id,
|
||||
+ bp.v->pos,
|
||||
0, 0,
|
||||
iter_flags);
|
||||
struct bkey_s_c k = bch2_btree_iter_peek_slot(iter);
|
||||
@@ -329,14 +278,15 @@ struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans,
|
||||
return k;
|
||||
}
|
||||
|
||||
- if (k.k && extent_matches_bp(c, bp.btree_id, bp.level, k, bucket, bp))
|
||||
+ if (k.k &&
|
||||
+ extent_matches_bp(c, bp.v->btree_id, bp.v->level, k, bucket, *bp.v))
|
||||
return k;
|
||||
|
||||
bch2_trans_iter_exit(trans, iter);
|
||||
- backpointer_not_found(trans, bp_pos, bp, k);
|
||||
+ backpointer_target_not_found(trans, bp, k);
|
||||
return bkey_s_c_null;
|
||||
} else {
|
||||
- struct btree *b = bch2_backpointer_get_node(trans, iter, bp_pos, bp);
|
||||
+ struct btree *b = bch2_backpointer_get_node(trans, bp, iter);
|
||||
|
||||
if (IS_ERR_OR_NULL(b)) {
|
||||
bch2_trans_iter_exit(trans, iter);
|
||||
@@ -347,39 +297,38 @@ struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans,
|
||||
}
|
||||
|
||||
struct btree *bch2_backpointer_get_node(struct btree_trans *trans,
|
||||
- struct btree_iter *iter,
|
||||
- struct bpos bp_pos,
|
||||
- struct bch_backpointer bp)
|
||||
+ struct bkey_s_c_backpointer bp,
|
||||
+ struct btree_iter *iter)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
|
||||
- BUG_ON(!bp.level);
|
||||
+ BUG_ON(!bp.v->level);
|
||||
|
||||
struct bpos bucket;
|
||||
- if (!bp_pos_to_bucket_nodev(c, bp_pos, &bucket))
|
||||
+ if (!bp_pos_to_bucket_nodev(c, bp.k->p, &bucket))
|
||||
return ERR_PTR(-EIO);
|
||||
|
||||
bch2_trans_node_iter_init(trans, iter,
|
||||
- bp.btree_id,
|
||||
- bp.pos,
|
||||
+ bp.v->btree_id,
|
||||
+ bp.v->pos,
|
||||
0,
|
||||
- bp.level - 1,
|
||||
+ bp.v->level - 1,
|
||||
0);
|
||||
struct btree *b = bch2_btree_iter_peek_node(iter);
|
||||
if (IS_ERR_OR_NULL(b))
|
||||
goto err;
|
||||
|
||||
- BUG_ON(b->c.level != bp.level - 1);
|
||||
+ BUG_ON(b->c.level != bp.v->level - 1);
|
||||
|
||||
- if (extent_matches_bp(c, bp.btree_id, bp.level,
|
||||
+ if (extent_matches_bp(c, bp.v->btree_id, bp.v->level,
|
||||
bkey_i_to_s_c(&b->key),
|
||||
- bucket, bp))
|
||||
+ bucket, *bp.v))
|
||||
return b;
|
||||
|
||||
if (btree_node_will_make_reachable(b)) {
|
||||
b = ERR_PTR(-BCH_ERR_backpointer_to_overwritten_btree_node);
|
||||
} else {
|
||||
- backpointer_not_found(trans, bp_pos, bp, bkey_i_to_s_c(&b->key));
|
||||
+ backpointer_target_not_found(trans, bp, bkey_i_to_s_c(&b->key));
|
||||
b = NULL;
|
||||
}
|
||||
err:
|
||||
@@ -581,10 +530,10 @@ static int check_bp_exists(struct btree_trans *trans,
|
||||
if (bp_k.k->type != KEY_TYPE_backpointer)
|
||||
goto missing;
|
||||
|
||||
- struct bch_backpointer other_bp = *bkey_s_c_to_backpointer(bp_k).v;
|
||||
+ struct bkey_s_c_backpointer other_bp = bkey_s_c_to_backpointer(bp_k);
|
||||
|
||||
struct bkey_s_c other_extent =
|
||||
- bch2_backpointer_get_key(trans, &other_extent_iter, bp_k.k->p, other_bp, 0);
|
||||
+ bch2_backpointer_get_key(trans, other_bp, &other_extent_iter, 0);
|
||||
ret = bkey_err(other_extent);
|
||||
if (ret == -BCH_ERR_backpointer_to_overwritten_btree_node)
|
||||
ret = 0;
|
||||
@@ -603,7 +552,7 @@ static int check_bp_exists(struct btree_trans *trans,
|
||||
bch_err(c, "%s", buf.buf);
|
||||
|
||||
if (other_extent.k->size <= orig_k.k->size) {
|
||||
- ret = drop_dev_and_update(trans, other_bp.btree_id, other_extent, bucket.inode);
|
||||
+ ret = drop_dev_and_update(trans, other_bp.v->btree_id, other_extent, bucket.inode);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto out;
|
||||
@@ -615,7 +564,7 @@ static int check_bp_exists(struct btree_trans *trans,
|
||||
}
|
||||
}
|
||||
|
||||
- ret = check_extent_checksum(trans, other_bp.btree_id, other_extent, bp.btree_id, orig_k, bucket.inode);
|
||||
+ ret = check_extent_checksum(trans, other_bp.v->btree_id, other_extent, bp.btree_id, orig_k, bucket.inode);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (ret) {
|
||||
@@ -623,7 +572,7 @@ static int check_bp_exists(struct btree_trans *trans,
|
||||
goto missing;
|
||||
}
|
||||
|
||||
- ret = check_extent_checksum(trans, bp.btree_id, orig_k, other_bp.btree_id, other_extent, bucket.inode);
|
||||
+ ret = check_extent_checksum(trans, bp.btree_id, orig_k, other_bp.v->btree_id, other_extent, bucket.inode);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (ret) {
|
||||
@@ -964,18 +913,16 @@ static int check_one_backpointer(struct btree_trans *trans,
|
||||
|
||||
struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(bp_k);
|
||||
struct bch_fs *c = trans->c;
|
||||
- struct btree_iter iter;
|
||||
struct bbpos pos = bp_to_bbpos(*bp.v);
|
||||
- struct bkey_s_c k;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
- int ret;
|
||||
|
||||
if (bbpos_cmp(pos, start) < 0 ||
|
||||
bbpos_cmp(pos, end) > 0)
|
||||
return 0;
|
||||
|
||||
- k = bch2_backpointer_get_key(trans, &iter, bp.k->p, *bp.v, 0);
|
||||
- ret = bkey_err(k);
|
||||
+ struct btree_iter iter;
|
||||
+ struct bkey_s_c k = bch2_backpointer_get_key(trans, bp, &iter, 0);
|
||||
+ int ret = bkey_err(k);
|
||||
if (ret == -BCH_ERR_backpointer_to_overwritten_btree_node)
|
||||
return 0;
|
||||
if (ret)
|
||||
diff --git a/fs/bcachefs/backpointers.h b/fs/bcachefs/backpointers.h
|
||||
index 3b29fdf519dd..74c96aee713e 100644
|
||||
--- a/fs/bcachefs/backpointers.h
|
||||
+++ b/fs/bcachefs/backpointers.h
|
||||
@@ -165,13 +165,10 @@ static inline void bch2_extent_ptr_to_bp(struct bch_fs *c, struct bch_dev *ca,
|
||||
__bch2_extent_ptr_to_bp(c, ca, btree_id, level, k, p, entry, bucket_pos, bp, sectors);
|
||||
}
|
||||
|
||||
-int bch2_get_next_backpointer(struct btree_trans *, struct bch_dev *ca, struct bpos, int,
|
||||
- struct bpos *, struct bch_backpointer *, unsigned);
|
||||
-struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *, struct btree_iter *,
|
||||
- struct bpos, struct bch_backpointer,
|
||||
- unsigned);
|
||||
-struct btree *bch2_backpointer_get_node(struct btree_trans *, struct btree_iter *,
|
||||
- struct bpos, struct bch_backpointer);
|
||||
+struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *, struct bkey_s_c_backpointer,
|
||||
+ struct btree_iter *, unsigned);
|
||||
+struct btree *bch2_backpointer_get_node(struct btree_trans *, struct bkey_s_c_backpointer,
|
||||
+ struct btree_iter *);
|
||||
|
||||
int bch2_check_btree_backpointers(struct bch_fs *);
|
||||
int bch2_check_extents_to_backpointers(struct bch_fs *);
|
||||
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
|
||||
index d6560bccd87c..aa8ada4f0ec0 100644
|
||||
--- a/fs/bcachefs/ec.c
|
||||
+++ b/fs/bcachefs/ec.c
|
||||
@@ -1276,11 +1276,10 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
|
||||
struct bch_dev *ca,
|
||||
struct bpos bucket, u8 gen,
|
||||
struct ec_stripe_buf *s,
|
||||
- struct bpos *bp_pos)
|
||||
+ struct bkey_s_c_backpointer bp)
|
||||
{
|
||||
struct bch_stripe *v = &bkey_i_to_stripe(&s->key)->v;
|
||||
struct bch_fs *c = trans->c;
|
||||
- struct bch_backpointer bp;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
const struct bch_extent_ptr *ptr_c;
|
||||
@@ -1289,33 +1288,26 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
|
||||
struct bkey_i *n;
|
||||
int ret, dev, block;
|
||||
|
||||
- ret = bch2_get_next_backpointer(trans, ca, bucket, gen,
|
||||
- bp_pos, &bp, BTREE_ITER_cached);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- if (bpos_eq(*bp_pos, SPOS_MAX))
|
||||
- return 0;
|
||||
-
|
||||
- if (bp.level) {
|
||||
+ if (bp.v->level) {
|
||||
struct printbuf buf = PRINTBUF;
|
||||
struct btree_iter node_iter;
|
||||
struct btree *b;
|
||||
|
||||
- b = bch2_backpointer_get_node(trans, &node_iter, *bp_pos, bp);
|
||||
+ b = bch2_backpointer_get_node(trans, bp, &node_iter);
|
||||
bch2_trans_iter_exit(trans, &node_iter);
|
||||
|
||||
if (!b)
|
||||
return 0;
|
||||
|
||||
prt_printf(&buf, "found btree node in erasure coded bucket: b=%px\n", b);
|
||||
- bch2_backpointer_to_text(&buf, &bp);
|
||||
+ bch2_backpointer_to_text(&buf, bp.v);
|
||||
|
||||
bch2_fs_inconsistent(c, "%s", buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
- k = bch2_backpointer_get_key(trans, &iter, *bp_pos, bp, BTREE_ITER_intent);
|
||||
+ k = bch2_backpointer_get_key(trans, bp, &iter, BTREE_ITER_intent);
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1374,7 +1366,6 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bch_stripe *v = &bkey_i_to_stripe(&s->key)->v;
|
||||
struct bch_extent_ptr ptr = v->ptrs[block];
|
||||
- struct bpos bp_pos = POS_MIN;
|
||||
int ret = 0;
|
||||
|
||||
struct bch_dev *ca = bch2_dev_tryget(c, ptr.dev);
|
||||
@@ -1383,18 +1374,20 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
|
||||
|
||||
struct bpos bucket_pos = PTR_BUCKET_POS(ca, &ptr);
|
||||
|
||||
- while (1) {
|
||||
- ret = commit_do(trans, NULL, NULL,
|
||||
- BCH_TRANS_COMMIT_no_check_rw|
|
||||
- BCH_TRANS_COMMIT_no_enospc,
|
||||
- ec_stripe_update_extent(trans, ca, bucket_pos, ptr.gen, s, &bp_pos));
|
||||
- if (ret)
|
||||
- break;
|
||||
- if (bkey_eq(bp_pos, POS_MAX))
|
||||
+ ret = for_each_btree_key_commit(trans, bp_iter, BTREE_ID_backpointers,
|
||||
+ bucket_pos_to_bp(ca, bucket_pos, 0), 0, bp_k,
|
||||
+ NULL, NULL,
|
||||
+ BCH_TRANS_COMMIT_no_check_rw|
|
||||
+ BCH_TRANS_COMMIT_no_enospc, ({
|
||||
+ if (bkey_ge(bp_k.k->p, bucket_pos_to_bp(ca, bpos_nosnap_successor(bucket_pos), 0)))
|
||||
break;
|
||||
|
||||
- bp_pos = bpos_nosnap_successor(bp_pos);
|
||||
- }
|
||||
+ if (bp_k.k->type != KEY_TYPE_backpointer)
|
||||
+ continue;
|
||||
+
|
||||
+ ec_stripe_update_extent(trans, ca, bucket_pos, ptr.gen, s,
|
||||
+ bkey_s_c_to_backpointer(bp_k));
|
||||
+ }));
|
||||
|
||||
bch2_dev_put(ca);
|
||||
return ret;
|
||||
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
|
||||
index a6b503278519..88ab9d7e1a1b 100644
|
||||
--- a/fs/bcachefs/move.c
|
||||
+++ b/fs/bcachefs/move.c
|
||||
@@ -670,16 +670,12 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
|
||||
struct bch_fs *c = trans->c;
|
||||
bool is_kthread = current->flags & PF_KTHREAD;
|
||||
struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
|
||||
- struct btree_iter iter;
|
||||
+ struct btree_iter iter = {}, bp_iter = {};
|
||||
struct bkey_buf sk;
|
||||
- struct bch_backpointer bp;
|
||||
- struct bch_alloc_v4 a_convert;
|
||||
- const struct bch_alloc_v4 *a;
|
||||
struct bkey_s_c k;
|
||||
struct data_update_opts data_opts;
|
||||
unsigned dirty_sectors, bucket_size;
|
||||
u64 fragmentation;
|
||||
- struct bpos bp_pos = POS_MIN;
|
||||
int ret = 0;
|
||||
|
||||
struct bch_dev *ca = bch2_dev_tryget(c, bucket.inode);
|
||||
@@ -695,21 +691,13 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
|
||||
*/
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
- bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
|
||||
- bucket, BTREE_ITER_cached);
|
||||
- ret = lockrestart_do(trans,
|
||||
- bkey_err(k = bch2_btree_iter_peek_slot(&iter)));
|
||||
- bch2_trans_iter_exit(trans, &iter);
|
||||
+ bch2_trans_iter_init(trans, &bp_iter, BTREE_ID_backpointers,
|
||||
+ bucket_pos_to_bp(ca, bucket, 0), 0);
|
||||
|
||||
bch_err_msg(c, ret, "looking up alloc key");
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
- a = bch2_alloc_to_v4(k, &a_convert);
|
||||
- dirty_sectors = bch2_bucket_sectors_dirty(*a);
|
||||
- bucket_size = ca->mi.bucket_size;
|
||||
- fragmentation = alloc_lru_idx_fragmentation(*a, ca);
|
||||
-
|
||||
ret = bch2_btree_write_buffer_tryflush(trans);
|
||||
bch_err_msg(c, ret, "flushing btree write buffer");
|
||||
if (ret)
|
||||
@@ -721,18 +709,24 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
|
||||
|
||||
bch2_trans_begin(trans);
|
||||
|
||||
- ret = bch2_get_next_backpointer(trans, ca, bucket, gen,
|
||||
- &bp_pos, &bp,
|
||||
- BTREE_ITER_cached);
|
||||
+ k = bch2_btree_iter_peek(&bp_iter);
|
||||
+ ret = bkey_err(k);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
continue;
|
||||
if (ret)
|
||||
goto err;
|
||||
- if (bkey_eq(bp_pos, POS_MAX))
|
||||
+
|
||||
+ if (!k.k ||
|
||||
+ bkey_ge(k.k->p, bucket_pos_to_bp(ca, bpos_nosnap_successor(bucket), 0)))
|
||||
break;
|
||||
|
||||
- if (!bp.level) {
|
||||
- k = bch2_backpointer_get_key(trans, &iter, bp_pos, bp, 0);
|
||||
+ if (k.k->type != KEY_TYPE_backpointer)
|
||||
+ goto next;
|
||||
+
|
||||
+ struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
|
||||
+
|
||||
+ if (!bp.v->level) {
|
||||
+ k = bch2_backpointer_get_key(trans, bp, &iter, 0);
|
||||
ret = bkey_err(k);
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
|
||||
continue;
|
||||
@@ -785,7 +779,7 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
|
||||
} else {
|
||||
struct btree *b;
|
||||
|
||||
- b = bch2_backpointer_get_node(trans, &iter, bp_pos, bp);
|
||||
+ b = bch2_backpointer_get_node(trans, bp, &iter);
|
||||
ret = PTR_ERR_OR_ZERO(b);
|
||||
if (ret == -BCH_ERR_backpointer_to_overwritten_btree_node)
|
||||
continue;
|
||||
@@ -814,11 +808,12 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
|
||||
}
|
||||
}
|
||||
next:
|
||||
- bp_pos = bpos_nosnap_successor(bp_pos);
|
||||
+ bch2_btree_iter_advance(&bp_iter);
|
||||
}
|
||||
|
||||
trace_evacuate_bucket(c, &bucket, dirty_sectors, bucket_size, fragmentation, ret);
|
||||
err:
|
||||
+ bch2_trans_iter_exit(trans, &bp_iter);
|
||||
bch2_dev_put(ca);
|
||||
bch2_bkey_buf_exit(&sk, c);
|
||||
return ret;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,31 +0,0 @@
|
||||
From d5b149f3108a40e2bc88e8fcd9bc5d70096fa6c3 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 17 Nov 2024 03:31:01 -0500
|
||||
Subject: [PATCH 093/233] bcachefs: add missing BTREE_ITER_intent
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
this fixes excessive transaction restarts due to trans_commit having to
|
||||
upgrade
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/io_write.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/fs/bcachefs/io_write.c b/fs/bcachefs/io_write.c
|
||||
index f11e11279f01..f97ebb30f6c0 100644
|
||||
--- a/fs/bcachefs/io_write.c
|
||||
+++ b/fs/bcachefs/io_write.c
|
||||
@@ -216,6 +216,7 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
|
||||
SPOS(0,
|
||||
extent_iter->pos.inode,
|
||||
extent_iter->snapshot),
|
||||
+ BTREE_ITER_intent|
|
||||
BTREE_ITER_cached);
|
||||
int ret = bkey_err(k);
|
||||
if (unlikely(ret))
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,93 +0,0 @@
|
||||
From 3c0fc088af9edef54fb6fb410f928df0268a7f63 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 16 Nov 2024 21:03:53 -0500
|
||||
Subject: [PATCH 094/233] bcachefs: compression workspaces should be indexed by
|
||||
opt, not type
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
type includes lz4 and lz4_old, which do not get different compression
|
||||
workspaces, and incompressible, a fake type - BCH_COMPRESSION_OPTS() is
|
||||
the correct enum to use.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs.h | 2 +-
|
||||
fs/bcachefs/compress.c | 19 +++++++++++--------
|
||||
2 files changed, 12 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
||||
index c59a58b93a92..60ad547c52a8 100644
|
||||
--- a/fs/bcachefs/bcachefs.h
|
||||
+++ b/fs/bcachefs/bcachefs.h
|
||||
@@ -982,7 +982,7 @@ struct bch_fs {
|
||||
struct rhashtable promote_table;
|
||||
|
||||
mempool_t compression_bounce[2];
|
||||
- mempool_t compress_workspace[BCH_COMPRESSION_TYPE_NR];
|
||||
+ mempool_t compress_workspace[BCH_COMPRESSION_OPT_NR];
|
||||
mempool_t decompress_workspace;
|
||||
size_t zstd_workspace_size;
|
||||
|
||||
diff --git a/fs/bcachefs/compress.c b/fs/bcachefs/compress.c
|
||||
index 1410365a8891..4f541a195c84 100644
|
||||
--- a/fs/bcachefs/compress.c
|
||||
+++ b/fs/bcachefs/compress.c
|
||||
@@ -394,8 +394,11 @@ static unsigned __bio_compress(struct bch_fs *c,
|
||||
unsigned pad;
|
||||
int ret = 0;
|
||||
|
||||
- BUG_ON(compression_type >= BCH_COMPRESSION_TYPE_NR);
|
||||
- BUG_ON(!mempool_initialized(&c->compress_workspace[compression_type]));
|
||||
+ /* bch2_compression_decode catches unknown compression types: */
|
||||
+ BUG_ON(compression.type >= BCH_COMPRESSION_OPT_NR);
|
||||
+
|
||||
+ mempool_t *workspace_pool = &c->compress_workspace[compression.type];
|
||||
+ BUG_ON(!mempool_initialized(workspace_pool));
|
||||
|
||||
/* If it's only one block, don't bother trying to compress: */
|
||||
if (src->bi_iter.bi_size <= c->opts.block_size)
|
||||
@@ -404,7 +407,7 @@ static unsigned __bio_compress(struct bch_fs *c,
|
||||
dst_data = bio_map_or_bounce(c, dst, WRITE);
|
||||
src_data = bio_map_or_bounce(c, src, READ);
|
||||
|
||||
- workspace = mempool_alloc(&c->compress_workspace[compression_type], GFP_NOFS);
|
||||
+ workspace = mempool_alloc(workspace_pool, GFP_NOFS);
|
||||
|
||||
*src_len = src->bi_iter.bi_size;
|
||||
*dst_len = dst->bi_iter.bi_size;
|
||||
@@ -447,7 +450,7 @@ static unsigned __bio_compress(struct bch_fs *c,
|
||||
*src_len = round_down(*src_len, block_bytes(c));
|
||||
}
|
||||
|
||||
- mempool_free(workspace, &c->compress_workspace[compression_type]);
|
||||
+ mempool_free(workspace, workspace_pool);
|
||||
|
||||
if (ret)
|
||||
goto err;
|
||||
@@ -576,17 +579,17 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
|
||||
|
||||
struct {
|
||||
unsigned feature;
|
||||
- enum bch_compression_type type;
|
||||
+ enum bch_compression_opts type;
|
||||
size_t compress_workspace;
|
||||
size_t decompress_workspace;
|
||||
} compression_types[] = {
|
||||
- { BCH_FEATURE_lz4, BCH_COMPRESSION_TYPE_lz4,
|
||||
+ { BCH_FEATURE_lz4, BCH_COMPRESSION_OPT_lz4,
|
||||
max_t(size_t, LZ4_MEM_COMPRESS, LZ4HC_MEM_COMPRESS),
|
||||
0 },
|
||||
- { BCH_FEATURE_gzip, BCH_COMPRESSION_TYPE_gzip,
|
||||
+ { BCH_FEATURE_gzip, BCH_COMPRESSION_OPT_gzip,
|
||||
zlib_deflate_workspacesize(MAX_WBITS, DEF_MEM_LEVEL),
|
||||
zlib_inflate_workspacesize(), },
|
||||
- { BCH_FEATURE_zstd, BCH_COMPRESSION_TYPE_zstd,
|
||||
+ { BCH_FEATURE_zstd, BCH_COMPRESSION_OPT_zstd,
|
||||
c->zstd_workspace_size,
|
||||
zstd_dctx_workspace_bound() },
|
||||
}, *i;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,181 +0,0 @@
|
||||
From 3a1897837a020cf57b2fa9ceb69f488762e89255 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Fri, 15 Nov 2024 00:52:20 -0500
|
||||
Subject: [PATCH 095/233] bcachefs: Don't use a shared decompress workspace
|
||||
mempool
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
gzip and zstd require different decompress workspace sizes, and if we
|
||||
start with one and then start using the other at runtime we may not get
|
||||
the correct size
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/bcachefs.h | 1 -
|
||||
fs/bcachefs/compress.c | 52 +++++++++++++++++++++++++-----------------
|
||||
fs/bcachefs/errcode.h | 1 -
|
||||
3 files changed, 31 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
|
||||
index 60ad547c52a8..7a947d43d504 100644
|
||||
--- a/fs/bcachefs/bcachefs.h
|
||||
+++ b/fs/bcachefs/bcachefs.h
|
||||
@@ -983,7 +983,6 @@ struct bch_fs {
|
||||
|
||||
mempool_t compression_bounce[2];
|
||||
mempool_t compress_workspace[BCH_COMPRESSION_OPT_NR];
|
||||
- mempool_t decompress_workspace;
|
||||
size_t zstd_workspace_size;
|
||||
|
||||
struct crypto_shash *sha256;
|
||||
diff --git a/fs/bcachefs/compress.c b/fs/bcachefs/compress.c
|
||||
index 4f541a195c84..2813e4556f0d 100644
|
||||
--- a/fs/bcachefs/compress.c
|
||||
+++ b/fs/bcachefs/compress.c
|
||||
@@ -9,6 +9,24 @@
|
||||
#include <linux/zlib.h>
|
||||
#include <linux/zstd.h>
|
||||
|
||||
+static inline enum bch_compression_opts bch2_compression_type_to_opt(enum bch_compression_type type)
|
||||
+{
|
||||
+ switch (type) {
|
||||
+ case BCH_COMPRESSION_TYPE_none:
|
||||
+ case BCH_COMPRESSION_TYPE_incompressible:
|
||||
+ return BCH_COMPRESSION_OPT_none;
|
||||
+ case BCH_COMPRESSION_TYPE_lz4_old:
|
||||
+ case BCH_COMPRESSION_TYPE_lz4:
|
||||
+ return BCH_COMPRESSION_OPT_lz4;
|
||||
+ case BCH_COMPRESSION_TYPE_gzip:
|
||||
+ return BCH_COMPRESSION_OPT_gzip;
|
||||
+ case BCH_COMPRESSION_TYPE_zstd:
|
||||
+ return BCH_COMPRESSION_OPT_zstd;
|
||||
+ default:
|
||||
+ BUG();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Bounce buffer: */
|
||||
struct bbuf {
|
||||
void *b;
|
||||
@@ -158,6 +176,10 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
|
||||
void *workspace;
|
||||
int ret;
|
||||
|
||||
+ enum bch_compression_opts opt = bch2_compression_type_to_opt(crc.compression_type);
|
||||
+ mempool_t *workspace_pool = &c->compress_workspace[opt];
|
||||
+ BUG_ON(!mempool_initialized(workspace_pool));
|
||||
+
|
||||
src_data = bio_map_or_bounce(c, src, READ);
|
||||
|
||||
switch (crc.compression_type) {
|
||||
@@ -176,13 +198,13 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
|
||||
.avail_out = dst_len,
|
||||
};
|
||||
|
||||
- workspace = mempool_alloc(&c->decompress_workspace, GFP_NOFS);
|
||||
+ workspace = mempool_alloc(workspace_pool, GFP_NOFS);
|
||||
|
||||
zlib_set_workspace(&strm, workspace);
|
||||
zlib_inflateInit2(&strm, -MAX_WBITS);
|
||||
ret = zlib_inflate(&strm, Z_FINISH);
|
||||
|
||||
- mempool_free(workspace, &c->decompress_workspace);
|
||||
+ mempool_free(workspace, workspace_pool);
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
goto err;
|
||||
@@ -195,14 +217,14 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
|
||||
if (real_src_len > src_len - 4)
|
||||
goto err;
|
||||
|
||||
- workspace = mempool_alloc(&c->decompress_workspace, GFP_NOFS);
|
||||
+ workspace = mempool_alloc(workspace_pool, GFP_NOFS);
|
||||
ctx = zstd_init_dctx(workspace, zstd_dctx_workspace_bound());
|
||||
|
||||
ret = zstd_decompress_dctx(ctx,
|
||||
dst_data, dst_len,
|
||||
src_data.b + 4, real_src_len);
|
||||
|
||||
- mempool_free(workspace, &c->decompress_workspace);
|
||||
+ mempool_free(workspace, workspace_pool);
|
||||
|
||||
if (ret != dst_len)
|
||||
goto err;
|
||||
@@ -562,7 +584,6 @@ void bch2_fs_compress_exit(struct bch_fs *c)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
- mempool_exit(&c->decompress_workspace);
|
||||
for (i = 0; i < ARRAY_SIZE(c->compress_workspace); i++)
|
||||
mempool_exit(&c->compress_workspace[i]);
|
||||
mempool_exit(&c->compression_bounce[WRITE]);
|
||||
@@ -571,7 +592,6 @@ void bch2_fs_compress_exit(struct bch_fs *c)
|
||||
|
||||
static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
|
||||
{
|
||||
- size_t decompress_workspace_size = 0;
|
||||
ZSTD_parameters params = zstd_get_params(zstd_max_clevel(),
|
||||
c->opts.encoded_extent_max);
|
||||
|
||||
@@ -581,17 +601,15 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
|
||||
unsigned feature;
|
||||
enum bch_compression_opts type;
|
||||
size_t compress_workspace;
|
||||
- size_t decompress_workspace;
|
||||
} compression_types[] = {
|
||||
{ BCH_FEATURE_lz4, BCH_COMPRESSION_OPT_lz4,
|
||||
- max_t(size_t, LZ4_MEM_COMPRESS, LZ4HC_MEM_COMPRESS),
|
||||
- 0 },
|
||||
+ max_t(size_t, LZ4_MEM_COMPRESS, LZ4HC_MEM_COMPRESS) },
|
||||
{ BCH_FEATURE_gzip, BCH_COMPRESSION_OPT_gzip,
|
||||
- zlib_deflate_workspacesize(MAX_WBITS, DEF_MEM_LEVEL),
|
||||
- zlib_inflate_workspacesize(), },
|
||||
+ max(zlib_deflate_workspacesize(MAX_WBITS, DEF_MEM_LEVEL),
|
||||
+ zlib_inflate_workspacesize()) },
|
||||
{ BCH_FEATURE_zstd, BCH_COMPRESSION_OPT_zstd,
|
||||
- c->zstd_workspace_size,
|
||||
- zstd_dctx_workspace_bound() },
|
||||
+ max(c->zstd_workspace_size,
|
||||
+ zstd_dctx_workspace_bound()) },
|
||||
}, *i;
|
||||
bool have_compressed = false;
|
||||
|
||||
@@ -616,9 +634,6 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
|
||||
for (i = compression_types;
|
||||
i < compression_types + ARRAY_SIZE(compression_types);
|
||||
i++) {
|
||||
- decompress_workspace_size =
|
||||
- max(decompress_workspace_size, i->decompress_workspace);
|
||||
-
|
||||
if (!(features & (1 << i->feature)))
|
||||
continue;
|
||||
|
||||
@@ -631,11 +646,6 @@ static int __bch2_fs_compress_init(struct bch_fs *c, u64 features)
|
||||
return -BCH_ERR_ENOMEM_compression_workspace_init;
|
||||
}
|
||||
|
||||
- if (!mempool_initialized(&c->decompress_workspace) &&
|
||||
- mempool_init_kvmalloc_pool(&c->decompress_workspace,
|
||||
- 1, decompress_workspace_size))
|
||||
- return -BCH_ERR_ENOMEM_decompression_workspace_init;
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h
|
||||
index 18c995d41203..3affdafc2c04 100644
|
||||
--- a/fs/bcachefs/errcode.h
|
||||
+++ b/fs/bcachefs/errcode.h
|
||||
@@ -54,7 +54,6 @@
|
||||
x(ENOMEM, ENOMEM_compression_bounce_read_init) \
|
||||
x(ENOMEM, ENOMEM_compression_bounce_write_init) \
|
||||
x(ENOMEM, ENOMEM_compression_workspace_init) \
|
||||
- x(ENOMEM, ENOMEM_decompression_workspace_init) \
|
||||
x(ENOMEM, ENOMEM_bucket_gens) \
|
||||
x(ENOMEM, ENOMEM_buckets_nouse) \
|
||||
x(ENOMEM, ENOMEM_usage_init) \
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,146 +0,0 @@
|
||||
From b287adb628223810c78703e6bcad624944dde679 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Thu, 14 Nov 2024 23:03:40 -0500
|
||||
Subject: [PATCH 096/233] bcachefs: Don't BUG_ON() when superblock feature
|
||||
wasn't set for compressed data
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We don't allocate the mempools for compression/decompression unless we
|
||||
need them - but that means there's an inconsistency to check for.
|
||||
|
||||
Reported-by: syzbot+cb3fbcfb417448cfd278@syzkaller.appspotmail.com
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/compress.c | 29 +++++++++++++++++++++++++++--
|
||||
fs/bcachefs/errcode.h | 1 +
|
||||
fs/bcachefs/opts.c | 2 +-
|
||||
fs/bcachefs/opts.h | 1 +
|
||||
fs/bcachefs/sb-errors_format.h | 4 +++-
|
||||
5 files changed, 33 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/compress.c b/fs/bcachefs/compress.c
|
||||
index 2813e4556f0d..f99ff1819597 100644
|
||||
--- a/fs/bcachefs/compress.c
|
||||
+++ b/fs/bcachefs/compress.c
|
||||
@@ -2,7 +2,9 @@
|
||||
#include "bcachefs.h"
|
||||
#include "checksum.h"
|
||||
#include "compress.h"
|
||||
+#include "error.h"
|
||||
#include "extents.h"
|
||||
+#include "opts.h"
|
||||
#include "super-io.h"
|
||||
|
||||
#include <linux/lz4.h>
|
||||
@@ -178,7 +180,16 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
|
||||
|
||||
enum bch_compression_opts opt = bch2_compression_type_to_opt(crc.compression_type);
|
||||
mempool_t *workspace_pool = &c->compress_workspace[opt];
|
||||
- BUG_ON(!mempool_initialized(workspace_pool));
|
||||
+ if (unlikely(!mempool_initialized(workspace_pool))) {
|
||||
+ if (fsck_err(c, compression_type_not_marked_in_sb,
|
||||
+ "compression type %s set but not marked in superblock",
|
||||
+ __bch2_compression_types[crc.compression_type]))
|
||||
+ ret = bch2_check_set_has_compressed_data(c, opt);
|
||||
+ else
|
||||
+ ret = -BCH_ERR_compression_workspace_not_initialized;
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
src_data = bio_map_or_bounce(c, src, READ);
|
||||
|
||||
@@ -234,6 +245,7 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
|
||||
BUG();
|
||||
}
|
||||
ret = 0;
|
||||
+fsck_err:
|
||||
out:
|
||||
bio_unmap_or_unbounce(c, src_data);
|
||||
return ret;
|
||||
@@ -420,7 +432,17 @@ static unsigned __bio_compress(struct bch_fs *c,
|
||||
BUG_ON(compression.type >= BCH_COMPRESSION_OPT_NR);
|
||||
|
||||
mempool_t *workspace_pool = &c->compress_workspace[compression.type];
|
||||
- BUG_ON(!mempool_initialized(workspace_pool));
|
||||
+ if (unlikely(!mempool_initialized(workspace_pool))) {
|
||||
+ if (fsck_err(c, compression_opt_not_marked_in_sb,
|
||||
+ "compression opt %s set but not marked in superblock",
|
||||
+ bch2_compression_opts[compression.type])) {
|
||||
+ ret = bch2_check_set_has_compressed_data(c, compression.type);
|
||||
+ if (ret) /* memory allocation failure, don't compress */
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* If it's only one block, don't bother trying to compress: */
|
||||
if (src->bi_iter.bi_size <= c->opts.block_size)
|
||||
@@ -502,6 +524,9 @@ static unsigned __bio_compress(struct bch_fs *c,
|
||||
err:
|
||||
ret = BCH_COMPRESSION_TYPE_incompressible;
|
||||
goto out;
|
||||
+fsck_err:
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
unsigned bch2_bio_compress(struct bch_fs *c,
|
||||
diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h
|
||||
index 3affdafc2c04..2dda7f962e5b 100644
|
||||
--- a/fs/bcachefs/errcode.h
|
||||
+++ b/fs/bcachefs/errcode.h
|
||||
@@ -54,6 +54,7 @@
|
||||
x(ENOMEM, ENOMEM_compression_bounce_read_init) \
|
||||
x(ENOMEM, ENOMEM_compression_bounce_write_init) \
|
||||
x(ENOMEM, ENOMEM_compression_workspace_init) \
|
||||
+ x(EIO, compression_workspace_not_initialized) \
|
||||
x(ENOMEM, ENOMEM_bucket_gens) \
|
||||
x(ENOMEM, ENOMEM_buckets_nouse) \
|
||||
x(ENOMEM, ENOMEM_usage_init) \
|
||||
diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
|
||||
index 0ba58d74c21f..6772faf385a5 100644
|
||||
--- a/fs/bcachefs/opts.c
|
||||
+++ b/fs/bcachefs/opts.c
|
||||
@@ -54,7 +54,7 @@ const char * const __bch2_csum_opts[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
-static const char * const __bch2_compression_types[] = {
|
||||
+const char * const __bch2_compression_types[] = {
|
||||
BCH_COMPRESSION_TYPES()
|
||||
NULL
|
||||
};
|
||||
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
|
||||
index 6b29339ea725..ea69099e681d 100644
|
||||
--- a/fs/bcachefs/opts.h
|
||||
+++ b/fs/bcachefs/opts.h
|
||||
@@ -17,6 +17,7 @@ extern const char * const bch2_sb_features[];
|
||||
extern const char * const bch2_sb_compat[];
|
||||
extern const char * const __bch2_btree_ids[];
|
||||
extern const char * const __bch2_csum_opts[];
|
||||
+extern const char * const __bch2_compression_types[];
|
||||
extern const char * const bch2_compression_opts[];
|
||||
extern const char * const __bch2_str_hash_types[];
|
||||
extern const char * const bch2_str_hash_opts[];
|
||||
diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h
|
||||
index f2b38493356d..d5b18ff1645c 100644
|
||||
--- a/fs/bcachefs/sb-errors_format.h
|
||||
+++ b/fs/bcachefs/sb-errors_format.h
|
||||
@@ -305,7 +305,9 @@ enum bch_fsck_flags {
|
||||
x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \
|
||||
x(accounting_key_version_0, 282, FSCK_AUTOFIX) \
|
||||
x(logged_op_but_clean, 283, FSCK_AUTOFIX) \
|
||||
- x(MAX, 295, 0)
|
||||
+ x(compression_opt_not_marked_in_sb, 295, FSCK_AUTOFIX) \
|
||||
+ x(compression_type_not_marked_in_sb, 296, FSCK_AUTOFIX) \
|
||||
+ x(MAX, 297, 0)
|
||||
|
||||
enum bch_sb_error_id {
|
||||
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,65 +0,0 @@
|
||||
From ed144047ef65601342eb7a821a8648b19d6b44a9 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sat, 16 Nov 2024 23:54:19 -0500
|
||||
Subject: [PATCH 097/233] bcachefs: kill bch2_journal_entries_free()
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_journal_iter.c | 17 ++++++-----------
|
||||
fs/bcachefs/btree_journal_iter.h | 2 --
|
||||
2 files changed, 6 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.c b/fs/bcachefs/btree_journal_iter.c
|
||||
index c44889ef9817..39898baa8854 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.c
|
||||
+++ b/fs/bcachefs/btree_journal_iter.c
|
||||
@@ -527,16 +527,6 @@ void bch2_btree_and_journal_iter_init_node_iter(struct btree_trans *trans,
|
||||
|
||||
/* sort and dedup all keys in the journal: */
|
||||
|
||||
-void bch2_journal_entries_free(struct bch_fs *c)
|
||||
-{
|
||||
- struct journal_replay **i;
|
||||
- struct genradix_iter iter;
|
||||
-
|
||||
- genradix_for_each(&c->journal_entries, iter, i)
|
||||
- kvfree(*i);
|
||||
- genradix_free(&c->journal_entries);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* When keys compare equal, oldest compares first:
|
||||
*/
|
||||
@@ -569,7 +559,12 @@ void bch2_journal_keys_put(struct bch_fs *c)
|
||||
keys->data = NULL;
|
||||
keys->nr = keys->gap = keys->size = 0;
|
||||
|
||||
- bch2_journal_entries_free(c);
|
||||
+ struct journal_replay **i;
|
||||
+ struct genradix_iter iter;
|
||||
+
|
||||
+ genradix_for_each(&c->journal_entries, iter, i)
|
||||
+ kvfree(*i);
|
||||
+ genradix_free(&c->journal_entries);
|
||||
}
|
||||
|
||||
static void __journal_keys_sort(struct journal_keys *keys)
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.h b/fs/bcachefs/btree_journal_iter.h
|
||||
index fa8c4f82c9c7..5ddbb7571770 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.h
|
||||
+++ b/fs/bcachefs/btree_journal_iter.h
|
||||
@@ -81,8 +81,6 @@ static inline void bch2_journal_keys_put_initial(struct bch_fs *c)
|
||||
c->journal_keys.initial_ref_held = false;
|
||||
}
|
||||
|
||||
-void bch2_journal_entries_free(struct bch_fs *);
|
||||
-
|
||||
int bch2_journal_keys_sort(struct bch_fs *);
|
||||
|
||||
void bch2_shoot_down_journal_keys(struct bch_fs *, enum btree_id,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,88 +0,0 @@
|
||||
From 1d1374a0837b8ba85c6ef9bf48efe52bf975cd51 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 17 Nov 2024 14:20:35 -0500
|
||||
Subject: [PATCH 098/233] bcachefs: journal keys: sort keys for interior nodes
|
||||
first
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There's an unavoidable issue with btree lookups when we're overlaying
|
||||
journal keys and the journal has many deletions for keys present in the
|
||||
btree - peek operations will have to iterate over all those deletions to
|
||||
find the next live key to return.
|
||||
|
||||
This is mainly a problem for lookups in interior nodes, if we have to
|
||||
traverse to a leaf. Looking up an insert position in a leaf (for journal
|
||||
replay) doesn't have to find the next live key, but walking down the
|
||||
btree does.
|
||||
|
||||
So to ameloriate this, change journal key sort ordering so that we
|
||||
replay keys from roots and interior nodes first.
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_journal_iter.c | 10 ++++------
|
||||
fs/bcachefs/btree_journal_iter.h | 13 ++++++++++---
|
||||
2 files changed, 14 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.c b/fs/bcachefs/btree_journal_iter.c
|
||||
index 39898baa8854..dbc9bc233cca 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.c
|
||||
+++ b/fs/bcachefs/btree_journal_iter.c
|
||||
@@ -172,9 +172,8 @@ static void journal_iter_verify(struct journal_iter *iter)
|
||||
if (iter->idx < keys->size) {
|
||||
struct journal_key *k = keys->data + iter->idx;
|
||||
|
||||
- int cmp = cmp_int(k->btree_id, iter->btree_id) ?:
|
||||
- cmp_int(k->level, iter->level);
|
||||
- BUG_ON(cmp < 0);
|
||||
+ int cmp = __journal_key_btree_cmp(iter->btree_id, iter->level, k);
|
||||
+ BUG_ON(cmp > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,9 +364,8 @@ static struct bkey_s_c bch2_journal_iter_peek(struct journal_iter *iter)
|
||||
while (iter->idx < iter->keys->size) {
|
||||
struct journal_key *k = iter->keys->data + iter->idx;
|
||||
|
||||
- int cmp = cmp_int(k->btree_id, iter->btree_id) ?:
|
||||
- cmp_int(k->level, iter->level);
|
||||
- if (cmp > 0)
|
||||
+ int cmp = __journal_key_btree_cmp(iter->btree_id, iter->level, k);
|
||||
+ if (cmp < 0)
|
||||
break;
|
||||
BUG_ON(cmp);
|
||||
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.h b/fs/bcachefs/btree_journal_iter.h
|
||||
index 5ddbb7571770..118ada4cdd1b 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.h
|
||||
+++ b/fs/bcachefs/btree_journal_iter.h
|
||||
@@ -28,14 +28,21 @@ struct btree_and_journal_iter {
|
||||
bool prefetch;
|
||||
};
|
||||
|
||||
+static inline int __journal_key_btree_cmp(enum btree_id l_btree_id,
|
||||
+ unsigned l_level,
|
||||
+ const struct journal_key *r)
|
||||
+{
|
||||
+ return -cmp_int(l_level, r->level) ?:
|
||||
+ cmp_int(l_btree_id, r->btree_id);
|
||||
+}
|
||||
+
|
||||
static inline int __journal_key_cmp(enum btree_id l_btree_id,
|
||||
unsigned l_level,
|
||||
struct bpos l_pos,
|
||||
const struct journal_key *r)
|
||||
{
|
||||
- return (cmp_int(l_btree_id, r->btree_id) ?:
|
||||
- cmp_int(l_level, r->level) ?:
|
||||
- bpos_cmp(l_pos, r->k->k.p));
|
||||
+ return __journal_key_btree_cmp(l_btree_id, l_level, r) ?:
|
||||
+ bpos_cmp(l_pos, r->k->k.p);
|
||||
}
|
||||
|
||||
static inline int journal_key_cmp(const struct journal_key *l, const struct journal_key *r)
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,83 +0,0 @@
|
||||
From 1a8f5adc2028bd7a11a96f85abae6a0e051c7ba4 Mon Sep 17 00:00:00 2001
|
||||
From: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Date: Sun, 17 Nov 2024 14:39:46 -0500
|
||||
Subject: [PATCH 099/233] bcachefs: btree_and_journal_iter: don't iterate over
|
||||
too many whiteouts when prefetching
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
To help ameloriate issues with peek operations having to skip over
|
||||
deletions in the journal - just bail out if all we're doing is
|
||||
prefetching btree nodes.
|
||||
|
||||
Since btree node prefetching runs every time we iterate to a new node,
|
||||
and has to sequentially scan ahead, this avoids another O(n^2).
|
||||
|
||||
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||||
---
|
||||
fs/bcachefs/btree_iter.c | 2 ++
|
||||
fs/bcachefs/btree_journal_iter.c | 7 +++++++
|
||||
fs/bcachefs/btree_journal_iter.h | 1 +
|
||||
3 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
|
||||
index ed74f0655d98..89f9665ce70d 100644
|
||||
--- a/fs/bcachefs/btree_iter.c
|
||||
+++ b/fs/bcachefs/btree_iter.c
|
||||
@@ -825,6 +825,8 @@ static int btree_path_prefetch_j(struct btree_trans *trans, struct btree_path *p
|
||||
|
||||
bch2_bkey_buf_init(&tmp);
|
||||
|
||||
+ jiter->fail_if_too_many_whiteouts = true;
|
||||
+
|
||||
while (nr-- && !ret) {
|
||||
if (!bch2_btree_node_relock(trans, path, path->level))
|
||||
break;
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.c b/fs/bcachefs/btree_journal_iter.c
|
||||
index dbc9bc233cca..cc7f5fad90c6 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.c
|
||||
+++ b/fs/bcachefs/btree_journal_iter.c
|
||||
@@ -426,6 +426,7 @@ static void btree_and_journal_iter_prefetch(struct btree_and_journal_iter *_iter
|
||||
: (level > 1 ? 1 : 16);
|
||||
|
||||
iter.prefetch = false;
|
||||
+ iter.fail_if_too_many_whiteouts = true;
|
||||
bch2_bkey_buf_init(&tmp);
|
||||
|
||||
while (nr--) {
|
||||
@@ -444,6 +445,7 @@ static void btree_and_journal_iter_prefetch(struct btree_and_journal_iter *_iter
|
||||
struct bkey_s_c bch2_btree_and_journal_iter_peek(struct btree_and_journal_iter *iter)
|
||||
{
|
||||
struct bkey_s_c btree_k, journal_k = bkey_s_c_null, ret;
|
||||
+ size_t iters = 0;
|
||||
|
||||
if (iter->prefetch && iter->journal.level)
|
||||
btree_and_journal_iter_prefetch(iter);
|
||||
@@ -451,6 +453,11 @@ struct bkey_s_c bch2_btree_and_journal_iter_peek(struct btree_and_journal_iter *
|
||||
if (iter->at_end)
|
||||
return bkey_s_c_null;
|
||||
|
||||
+ iters++;
|
||||
+
|
||||
+ if (iters > 20 && iter->fail_if_too_many_whiteouts)
|
||||
+ return bkey_s_c_null;
|
||||
+
|
||||
while ((btree_k = bch2_journal_iter_peek_btree(iter)).k &&
|
||||
bpos_lt(btree_k.k->p, iter->pos))
|
||||
bch2_journal_iter_advance_btree(iter);
|
||||
diff --git a/fs/bcachefs/btree_journal_iter.h b/fs/bcachefs/btree_journal_iter.h
|
||||
index 118ada4cdd1b..9e8f8ab1c6ff 100644
|
||||
--- a/fs/bcachefs/btree_journal_iter.h
|
||||
+++ b/fs/bcachefs/btree_journal_iter.h
|
||||
@@ -26,6 +26,7 @@ struct btree_and_journal_iter {
|
||||
struct bpos pos;
|
||||
bool at_end;
|
||||
bool prefetch;
|
||||
+ bool fail_if_too_many_whiteouts;
|
||||
};
|
||||
|
||||
static inline int __journal_key_btree_cmp(enum btree_id l_btree_id,
|
||||
--
|
||||
2.45.2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user