bcachefs: implement online filesystem shrinking - #1073
Conversation
|
Nice work — the reconcile-based approach for online shrinking is the right direction. Some feedback: On-disk format: Adding The evacuation loop: The
Allocation cutoff: if (unlikely(ca->mi.target_nbuckets && bucket >= ca->mi.target_nbuckets)) {This replaces
This inline function does a division ( Commented-out code: The Style nits:
Testing: Good that you have ktest tests for this: https://github.com/jullanggit/ktest/tree/shrink. Consider adding cases for:
Overall this is solid WIP. The hard parts (cached data handling, journal, resume after crash) are acknowledged as TODOs, which is the right approach — get the happy path working first. — ProofOfConcept |
6303f5b to
990d039
Compare
|
Thank you for the review! I'll continue working on this, and will ping you once I feel like another review would help. |
a6d79f5 to
82c906f
Compare
| Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202602181006.rLTgu86r-lkp@intel.com/
this addition is backwards compatible because new fields are initialized to zero, which means no pending resize, and are not read by older kernels
avoids stripe reshuffling
also comment in outline of shrink path
…elying on ca->mi.target_nbuckets avoids possible edge cases if device is being removed mid-shrink etc.
This is done analogous to the remove alloc info path
…nto caller bch2_dev_remove_alloc() now does the same operations wheter it is passed a cutoff or not. Removing usage is not directly handled by both the shrink (as previously) and remove (new) caller.
explanation not needed
use helper macros and add comments
extracts some duplicate logic
…r_extent_reconcile_phys_update and update comments
…and mark it as such
… it is cleared before next transaction starts
In the definitive tail-empty check inside __bch2_dev_shrink(), the outer CLASS(btree_trans, trans) from the write-buffer flush call was still alive when tail_head_snapshot() created its own btree_trans via the same macro. This produced two live btree_trans for the same kernel thread, and the DEBUG BUG_ON in __bch2_trans_get() fired when it found the first trans still on the list with trans->locked set (from __bch2_trans_relock during the flush). Fix by narrowing the outer trans scope with an inner brace block so the flush trans is released before tail_head_snapshot() allocates its own.
|
Hey @koverstreet! |
|
There are still some things I'd like to improve / add, among them a more fuzz-style tester and copying the code over into the userspace implementation. The latter shouldn't be very hard and I'd say both of these don't stand in the way of this PR :) |
…hange this was due to the bch2_dev_resize_update_target also doing validation, but allowing 0 to go through because we also used it to reset. Now the two tasks are split into separate functions
|
uhh, this is a massive series :) are you aware that we're now working in the bcachefs-tools repo? and there's a shrink PR or maybe two there |
|
Ah no I wasn't aware of that, in that case I'll prioritize porting the implementation over. The PR over there does copy most of the same commits but is on a branch I don't have access to so I can't update it. I guess I'll write @Komzpa first and if that doesn't work open another one. |
Implement online filesystem shrinking through reconcile. Closes #781 once done.
This is hopefully complementary to #1070, which targets offline shrink.
Goal
A robust online shrinking implementation, that automatically resumes after restarts/crashes, as shrinking is a potentially long-running operation, and supports changing the target size mid-shrink.
Current state
Implementation
Reuses large parts of the device remove/evacuate paths
Documentation
Inline in https://github.com/jullanggit/bcachefs/blob/shrink/fs/bcachefs/init/dev.c - tho could maybe use an update
Testing
https://github.com/jullanggit/ktest/tree/shrink