Question about synchronization (nfssvc, vfs_busy)

Andrey Simonenko simon at comsys.ntu-kpi.kiev.ua
Tue Jun 6 01:43:20 PDT 2006


On Mon, Jun 05, 2006 at 08:30:45PM +0300, Konstantin Belousov wrote:
> On Mon, Jun 05, 2006 at 02:01:36PM +0300, Andrey Simonenko wrote:
> > 2.
> > 
> > If vfs_busy() is called without LK_NOWAIT flag, then it can sleep
> > if a filesystem is being unmounted.  At some point unmount() will
> If vfs_busy() is called without LK_NOWAIT and fs is being unmounted,
> then vfs_busy returns with ENOENT error, isn't it ?
> 

Yes, it returns ENOENT, but before this event vfs_busy() sets MNTK_MWAIT
flag and sleeps on mount point address.  When vfs_mount_destroy() sees
MNTK_MWAIT, it wakes up a thread which sleeps in vfs_busy().  Since
vfs_busy() and vfs_mount_destroy() are active only if MNT_MTX(mp) is
acquired, vfs_mount_destroy() continues own execution, deallocating
mount point, so mutex address passed to msleep() in vfs_busy() is not
valid any more.

> > reach vfs_mount_destroy() and since there is one ref from vfs_busy()
> > it will sleep 3 seconds and will notice MNTK_MWAIT flag and wake up
> > a process, which is sleeping in vfs_busy().  How woken up process
> > can work with mount structure in vfs_busy() after wakeup(), which
> > could be already deallocated in vfs_mount_destroy()?
> vfs_busy() internally increases the ref count for mount point, so, it cannot
> be taken from under it (look for MNT_REF/MNT_REL). Simultameous entrance
> into the code in question in vfs_busy/vfs_mount_destroy is protected
> by mnt_mtx (MNT_ILOCK/MNT_IUNLOCK).
> 
> 

A reference counter is increased, but in vfs_mount_destroy() in first
for() (mnt_ref != 0) is checked only 3 seconds, then debug message is
outputted.  Let me ask in other words, how vfs_ref() guarantees that
unmount() in vfs_mount_destroy() will not deallocate a mount point (see
checks in first for() loop, also assume that mnt_holdcnt, mnt_writeopcount
and mnt_secondary_writes are equal to zero)?

I also wanted to ask similar question about vfs_getvfs(), but as I
understand in CURRENT it was corrected.


More information about the freebsd-hackers mailing list