Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Jun 2006 11:25:29 +0300
From:      Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Question about synchronization (nfssvc, vfs_busy)
Message-ID:  <20060606082529.GA767@pm513-1.comsys.ntu-kpi.kiev.ua>
In-Reply-To: <20060605173045.GA45380@deviant.kiev.zoral.com.ua>
References:  <20060605110136.GA1348@pm513-1.comsys.ntu-kpi.kiev.ua> <20060605173045.GA45380@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060606082529.GA767>