summaryrefslogtreecommitdiff
path: root/drivers/phy/axiado/git@git.tavy.me:linux.git
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-06-16 13:58:18 +0200
committerChristian Brauner <brauner@kernel.org>2026-06-29 10:31:49 +0200
commit8b6b55bfc7d1a2d9e60a9cabc84ff888440a712a (patch)
tree87f9eb6da178d03bd4be1173aaecec61cbc6f454 /drivers/phy/axiado/git@git.tavy.me:linux.git
parent48b1cc0ac94d1ae89af7ab74e0329a8446b46715 (diff)
btrfs: deny freezing devices undergoing a replace
A device replace opens a target and, on success, frees the source on a live filesystem from btrfs_dev_replace_finishing() - which cannot fail and also runs from a kthread on mount resume. A bdev_freeze() racing the source free or the target swap-in would freeze the filesystem through a claim that is being torn down or replaced, leaving nothing for bdev_thaw() to rebalance. Make both devices unfreezable for the whole replace, with the invariant that a STARTED replace holds one deny on each device and any other state holds none. The target is denied at open (btrfs_open_device_deny_freeze(), undone on btrfs_init_dev_replace_tgtdev()'s error unwind); the source is denied at the start of btrfs_dev_replace_start(), before mark_block_group_to_copy() so every 'leave' unwind sees both denied. The deny tracks the STARTED state and is dropped whenever the replace leaves it: btrfs_dev_replace_finishing() re-allows the target it makes a member and frees the source through btrfs_close_bdev(allow_freeze=true), and its scrub-error path re-allows both as it cancels. Its early failures (before the device swap) keep the replace STARTED and resumable, so both stay denied. Suspending for unmount re-allows both, so they are reopened freezable at the next mount where btrfs_resume_dev_replace_async() re-denies them (staying suspended if a device is frozen right then); a replace cancelled from the suspended state therefore destroys the target without allowing. btrfs_close_bdev() and btrfs_destroy_dev_replace_tgtdev() take an allow_freeze argument to carry this distinction; the unmount path (btrfs_close_one_device()) passes false. On resume, a failed kthread_run() re-allows both devices and goes through the suspend path, resetting the replace to SUSPENDED and finishing the exclusive operation instead of returning straight away. The (re)mount still aborts on that error; routing it through suspend keeps the deny balanced against the unmount teardown and additionally drops BTRFS_EXCLOP_DEV_REPLACE, closing a pre-existing leak that was harmless on the failed mount that frees the fs but would have wedged future exclusive operations after a failed remount-rw. Link: https://patch.msgid.link/20260616-work-super-freeze_deny_upstream-v2-5-b3567c7f994b@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'drivers/phy/axiado/git@git.tavy.me:linux.git')
0 files changed, 0 insertions, 0 deletions