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>