Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'v6.6-vfs.super.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull superblock fixes from Christian Brauner:
"Two follow-up fixes for the super work this cycle:

- Move a misplaced lockep assertion before we potentially free the
object containing the lock.

- Ensure that filesystems which match superblocks in sget{_fc}()
based on sb->s_fs_info are guaranteed to see a valid sb->s_fs_info
as long as a superblock still appears on the filesystem type's
superblock list.

What we want as a proper solution for next cycle is to split
sb->free_sb() out of sb->kill_sb() so that we can simply call
kill_super_notify() after sb->kill_sb() but before sb->free_sb().

Currently, this is lumped together in sb->kill_sb()"

* tag 'v6.6-vfs.super.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
super: ensure valid info
super: move lockdep assert

+31 -20
+31 -20
fs/super.c
··· 434 434 spin_unlock(&sb_lock); 435 435 } 436 436 437 + static void kill_super_notify(struct super_block *sb) 438 + { 439 + lockdep_assert_not_held(&sb->s_umount); 440 + 441 + /* already notified earlier */ 442 + if (sb->s_flags & SB_DEAD) 443 + return; 444 + 445 + /* 446 + * Remove it from @fs_supers so it isn't found by new 447 + * sget{_fc}() walkers anymore. Any concurrent mounter still 448 + * managing to grab a temporary reference is guaranteed to 449 + * already see SB_DYING and will wait until we notify them about 450 + * SB_DEAD. 451 + */ 452 + spin_lock(&sb_lock); 453 + hlist_del_init(&sb->s_instances); 454 + spin_unlock(&sb_lock); 455 + 456 + /* 457 + * Let concurrent mounts know that this thing is really dead. 458 + * We don't need @sb->s_umount here as every concurrent caller 459 + * will see SB_DYING and either discard the superblock or wait 460 + * for SB_DEAD. 461 + */ 462 + super_wake(sb, SB_DEAD); 463 + } 437 464 438 465 /** 439 466 * deactivate_locked_super - drop an active reference to superblock ··· 480 453 unregister_shrinker(&s->s_shrink); 481 454 fs->kill_sb(s); 482 455 456 + kill_super_notify(s); 457 + 483 458 /* 484 459 * Since list_lru_destroy() may sleep, we cannot call it from 485 460 * put_super(), where we hold the sb_lock. Therefore we destroy ··· 489 460 */ 490 461 list_lru_destroy(&s->s_dentry_lru); 491 462 list_lru_destroy(&s->s_inode_lru); 492 - 493 - /* 494 - * Remove it from @fs_supers so it isn't found by new 495 - * sget{_fc}() walkers anymore. Any concurrent mounter still 496 - * managing to grab a temporary reference is guaranteed to 497 - * already see SB_DYING and will wait until we notify them about 498 - * SB_DEAD. 499 - */ 500 - spin_lock(&sb_lock); 501 - hlist_del_init(&s->s_instances); 502 - spin_unlock(&sb_lock); 503 - 504 - /* 505 - * Let concurrent mounts know that this thing is really dead. 506 - * We don't need @sb->s_umount here as every concurrent caller 507 - * will see SB_DYING and either discard the superblock or wait 508 - * for SB_DEAD. 509 - */ 510 - super_wake(s, SB_DEAD); 511 463 512 464 put_filesystem(fs); 513 465 put_super(s); ··· 580 570 return true; 581 571 } 582 572 wait_var_event(&sb->s_flags, wait_dead(sb)); 583 - put_super(sb); 584 573 lockdep_assert_not_held(&sb->s_umount); 574 + put_super(sb); 585 575 return false; 586 576 } 587 577 ··· 1288 1278 { 1289 1279 dev_t dev = sb->s_dev; 1290 1280 generic_shutdown_super(sb); 1281 + kill_super_notify(sb); 1291 1282 free_anon_bdev(dev); 1292 1283 } 1293 1284 EXPORT_SYMBOL(kill_anon_super);