On Tue, Apr 22, 2025 at 04:14:48AM +0100, Al Viro wrote: > On Mon, Apr 21, 2025 at 06:03:19PM +0100, Al Viro wrote: > > On Mon, Apr 21, 2025 at 05:29:47PM +0100, Al Viro wrote: > > > > > What's to prevent the 'beneath' case from getting mnt mount --move'd > > > away *AND* the ex-parent from getting unmounted while we are blocked > > > in inode_lock? At this point we are not holding any locks whatsoever > > > (and all mount-related locks nest inside inode_lock(), so we couldn't > > > hold them there anyway). > > > > > > Hit that race and watch a very unhappy umount... > > > > While we are at it, in normal case inode_unlock() in unlock_mount() > > is safe since we have dentry (and associated mount) pinned by > > struct path we'd fed to matching lock_mount(). No longer true for > > the 'beneath' case, AFAICS... > > Completely untested patch follows; 'beneath' case in do_lock_mount() is made > to grab mount reference to match the dentry one (same lifetime; dropped > simultaneously), unlock_mount() unlocks the inode *before* namespace_unlock(), > so we don't depend upon the externally held references. Afaict both isssues you mentioned shouldn't exist. So I'd first like to have details on how they're supposed to happen before fiddling with the code, please.