summaryrefslogtreecommitdiff
path: root/tools/lib/python
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-10-12 14:31:19 +0200
committerChristian Brauner <brauner@kernel.org>2026-10-22 18:50:18 +0200
commitc84de57efe88c9c513cfbc3746361502db0978e2 (patch)
tree0a50ec683feffc3cd903c5c066ed7dc50dab1866 /tools/lib/python
parent073d71c5118f40449d9c7df828677aaa437372e1 (diff)
super: convert to plain hashtable
Convert the rhltable to a plain hashtable under a spinlock. The walks keep their place with a cursor entry in the chain. A claim is unhashed the moment it's dropped and a walk that finds a superblock that isn't born yet waits for it to be born or to die and looks again. Since hashing can't fail anymore the entry for the superblock's own s_dev is embedded in struct super_block and the preallocation in alloc_super() goes away. This all simplifies things quite a lot. It also fixes a btrfs bug where fs_bdev_freeze() ended up freezing a btrfs filesystem through a stale member that open_ctree() had already released while the freeze was waiting for SB_BORN. The resume doesn't find a holder for that device anymore so the filesystem stays frozen for good. The walks return superblocks instead of table entries now and user_get_super() hands out the passive reference the walk took. Reproducer, a three device btrfs with a stale copy of a removed member. dm-delay under the remaining members stretches the window between btrfs_open_devices() and btrfs_free_extra_devids(): truncate -s 1G a1 a2 b A1=$(losetup -f --show a1); A2=$(losetup -f --show a2); B=$(losetup -f --show b) mkfs.btrfs -f -d single -m single $A1 $A2 $B cp b b.old mount $A1 /mnt && btrfs device remove 3 /mnt && umount /mnt OLD=$(losetup -f --show b.old) dmsetup create d1 --table "0 $(blockdev --getsz $A1) delay $A1 0 200" dmsetup create d2 --table "0 $(blockdev --getsz $A2) delay $A2 0 200" dmsetup create old --table "0 $(blockdev --getsz $OLD) linear $OLD 0" mount -o device=/dev/mapper/d2,device=/dev/mapper/old /dev/mapper/d1 /mnt & sleep 1; dmsetup suspend old; wait dmsetup resume old touch /mnt/foo # hangs until fsfreeze -u /mnt That left btrfs frozen in 5 of 5 rounds with the same tables issued through raw dm ioctls. The -o degraded variant needs the mount held between the insertion and the bd_fsfreeze_count check in fs_bdev_register() with a kprobe. Fixes: cdb5146f8d5f ("fs: look up superblocks via the device table in fs_holder_ops") Link: https://patch.msgid.link/20261012-work-super-dev_hash-v1-2-305cf71cd334@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'tools/lib/python')
0 files changed, 0 insertions, 0 deletions