diff options
author | attilio <attilio@FreeBSD.org> | 2008-11-02 10:15:42 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2008-11-02 10:15:42 +0000 |
commit | e1f493235eaeaf3c0cd0e029936db2b5b6e32bf7 (patch) | |
tree | 904da44fc29dcc675df2dfc69f644d6a90befc3c /sys/kern/vfs_syscalls.c | |
parent | 92bf4795aa726561a195b11458e9f2fc6ee74454 (diff) | |
download | FreeBSD-src-e1f493235eaeaf3c0cd0e029936db2b5b6e32bf7.zip FreeBSD-src-e1f493235eaeaf3c0cd0e029936db2b5b6e32bf7.tar.gz |
Improve VFS locking:
- Implement real draining for vfs consumers by not relying on the
mnt_lock and using instead a refcount in order to keep track of lock
requesters.
- Due to the change above, remove the mnt_lock lockmgr because it is now
useless.
- Due to the change above, vfs_busy() is no more linked to a lockmgr.
Change so its KPI by removing the interlock argument and defining 2 new
flags for it: MBF_NOWAIT which basically replaces the LK_NOWAIT of the
old version (which was unlinked from the lockmgr alredy) and
MBF_MNTLSTLOCK which provides the ability to drop the mountlist_mtx
once the mnt interlock is held (ability still desired by most consumers).
- The stub used into vfs_mount_destroy(), that allows to override the
mnt_ref if running for more than 3 seconds, make it totally useless.
Remove it as it was thought to work into older versions.
If a problem of "refcount held never going away" should appear, we will
need to fix properly instead than trust on such hackish solution.
- Fix a bug where returning (with an error) from dounmount() was still
leaving the MNTK_MWAIT flag on even if it the waiters were actually
woken up. Just a place in vfs_mount_destroy() is left because it is
going to recycle the structure in any case, so it doesn't matter.
- Remove the markercnt refcount as it is useless.
This patch modifies VFS ABI and breaks KPI for vfs_busy() so manpages and
__FreeBSD_version will be modified accordingly.
Discussed with: kib
Tested by: pho
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r-- | sys/kern/vfs_syscalls.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 4d40f35..32dc4d1 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -124,7 +124,7 @@ sync(td, uap) mtx_lock(&mountlist_mtx); for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx)) { + if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } @@ -197,7 +197,7 @@ quotactl(td, uap) vfslocked = NDHASGIANT(&nd); NDFREE(&nd, NDF_ONLY_PNBUF); mp = nd.ni_vp->v_mount; - if ((error = vfs_busy(mp, 0, NULL))) { + if ((error = vfs_busy(mp, 0))) { vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); @@ -479,7 +479,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, continue; } #endif - if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx)) { + if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { nmp = TAILQ_NEXT(mp, mnt_list); continue; } @@ -741,7 +741,7 @@ fchdir(td, uap) error = change_dir(vp, td); while (!error && (mp = vp->v_mountedhere) != NULL) { int tvfslocked; - if (vfs_busy(mp, 0, 0)) + if (vfs_busy(mp, 0)) continue; tvfslocked = VFS_LOCK_GIANT(mp); error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td); |