diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-10-12 14:31:19 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-10-22 18:50:18 +0200 |
| commit | c84de57efe88c9c513cfbc3746361502db0978e2 (patch) | |
| tree | 0a50ec683feffc3cd903c5c066ed7dc50dab1866 /tools/lib/python/kdoc/python_version.py | |
| parent | 073d71c5118f40449d9c7df828677aaa437372e1 (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/kdoc/python_version.py')
0 files changed, 0 insertions, 0 deletions
