summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsturm <sturm@openbsd.org>2006-06-14 20:01:50 +0000
committersturm <sturm@openbsd.org>2006-06-14 20:01:50 +0000
commit2e6147f207d8e5b50fbb5208246b9d6901cc9815 (patch)
tree271426e9e129dfbe7376c31fccbc89cd1af722ca
parent.Xr adjfreq and ntpd (diff)
downloadwireguard-openbsd-2e6147f207d8e5b50fbb5208246b9d6901cc9815.tar.xz
wireguard-openbsd-2e6147f207d8e5b50fbb5208246b9d6901cc9815.zip
move vfs_busy() to rwlocks and properly hide the locking api from vfs
ok tedu, pedro
-rw-r--r--sys/compat/common/vfs_syscalls_25.c4
-rw-r--r--sys/compat/freebsd/freebsd_file.c4
-rw-r--r--sys/compat/netbsd/netbsd_file.c4
-rw-r--r--sys/kern/vfs_lookup.c4
-rw-r--r--sys/kern/vfs_subr.c61
-rw-r--r--sys/kern/vfs_sync.c4
-rw-r--r--sys/kern/vfs_syscalls.c19
-rw-r--r--sys/nfs/nfs_syscalls.c4
-rw-r--r--sys/sys/mount.h11
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c4
-rw-r--r--sys/ufs/ufs/inode.h3
-rw-r--r--sys/ufs/ufs/ufs_quota.c4
-rw-r--r--sys/xfs/xfs_dev-common.c2
13 files changed, 65 insertions, 63 deletions
diff --git a/sys/compat/common/vfs_syscalls_25.c b/sys/compat/common/vfs_syscalls_25.c
index 58cab278b23..f017af71580 100644
--- a/sys/compat/common/vfs_syscalls_25.c
+++ b/sys/compat/common/vfs_syscalls_25.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls_25.c,v 1.10 2006/04/30 14:20:07 sturm Exp $ */
+/* $OpenBSD: vfs_syscalls_25.c,v 1.11 2006/06/14 20:01:50 sturm Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -181,7 +181,7 @@ compat_25_sys_getfsstat(p, v, retval)
for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT)) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE)) {
nmp = CIRCLEQ_NEXT(mp, mnt_list);
continue;
}
diff --git a/sys/compat/freebsd/freebsd_file.c b/sys/compat/freebsd/freebsd_file.c
index 89ac1fcc0b2..46f0e69e051 100644
--- a/sys/compat/freebsd/freebsd_file.c
+++ b/sys/compat/freebsd/freebsd_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: freebsd_file.c,v 1.23 2006/04/30 14:20:07 sturm Exp $ */
+/* $OpenBSD: freebsd_file.c,v 1.24 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: freebsd_file.c,v 1.3 1996/05/03 17:03:09 christos Exp $ */
/*
@@ -660,7 +660,7 @@ freebsd_sys_getfsstat(p, v, retval)
for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT)) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE)) {
nmp = CIRCLEQ_NEXT(mp, mnt_list);
continue;
}
diff --git a/sys/compat/netbsd/netbsd_file.c b/sys/compat/netbsd/netbsd_file.c
index f02653634b1..d7e3b0bd20d 100644
--- a/sys/compat/netbsd/netbsd_file.c
+++ b/sys/compat/netbsd/netbsd_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netbsd_file.c,v 1.9 2006/04/30 14:20:07 sturm Exp $ */
+/* $OpenBSD: netbsd_file.c,v 1.10 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: freebsd_file.c,v 1.3 1996/05/03 17:03:09 christos Exp $ */
/*
@@ -634,7 +634,7 @@ netbsd_sys_getfsstat(p, v, retval)
for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT)) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE)) {
nmp = CIRCLEQ_NEXT(mp, mnt_list);
continue;
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 37b2ffe0fe8..9fa13cc7c93 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_lookup.c,v 1.32 2006/04/30 14:20:07 sturm Exp $ */
+/* $OpenBSD: vfs_lookup.c,v 1.33 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: vfs_lookup.c,v 1.17 1996/02/09 19:00:59 christos Exp $ */
/*
@@ -513,7 +513,7 @@ dirloop:
*/
while (dp->v_type == VDIR && (mp = dp->v_mountedhere) &&
(cnp->cn_flags & NOCROSSMOUNT) == 0) {
- if (vfs_busy(mp, 0))
+ if (vfs_busy(mp, VB_READ|VB_UMWAIT))
continue;
VOP_UNLOCK(dp, 0, p);
error = VFS_ROOT(mp, &tdp);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 3170b903426..88458c67924 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.127 2006/06/02 20:25:09 pedro Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.128 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -145,36 +145,31 @@ vntblinit(void)
* Mark a mount point as busy. Used to synchronize access and to delay
* unmounting.
*
- * historical behavior:
- * - LK_NOWAIT means that we should just ignore the mount point if it's
- * being unmounted.
- * - no flags means that we should sleep on the mountpoint and then
- * fail.
+ * Default behaviour is to attempt getting a READ lock and in case of an
+ * ongoing unmount, to wait for it to finish and then return failure.
*/
int
vfs_busy(struct mount *mp, int flags)
{
- int lkflags;
+ int rwflags = 0;
- switch (flags) {
- case LK_NOWAIT:
- lkflags = LK_SHARED|LK_NOWAIT;
- break;
- case 0:
- lkflags = LK_SHARED;
- break;
- default:
- lkflags = flags;
- }
+ /* new mountpoints need their lock initialised */
+ if (mp->mnt_lock.rwl_name == NULL)
+ rw_init(&mp->mnt_lock, "vfslock");
- /*
- * Always sleepfail. We will only sleep for an exclusive lock
- * and the exclusive lock will only be acquired when unmounting.
- */
- lkflags |= LK_SLEEPFAIL;
+ if (flags & VB_WRITE)
+ rwflags |= RW_WRITE;
+ else
+ rwflags |= RW_READ;
+
+ if (flags & VB_UMWAIT)
+ rwflags |= RW_SLEEPFAIL;
+ else
+ rwflags |= RW_NOSLEEP;
+
+ if (rw_enter(&mp->mnt_lock, rwflags))
+ return (EBUSY);
- if (lockmgr(&mp->mnt_lock, lkflags, NULL))
- return (ENOENT);
return (0);
}
@@ -184,13 +179,16 @@ vfs_busy(struct mount *mp, int flags)
void
vfs_unbusy(struct mount *mp)
{
- lockmgr(&mp->mnt_lock, LK_RELEASE, NULL);
+ rw_exit(&mp->mnt_lock);
}
int
vfs_isbusy(struct mount *mp)
{
- return (lockstatus(&mp->mnt_lock));
+ if (RWLOCK_OWNER(&mp->mnt_lock) > 0)
+ return (1);
+ else
+ return (0);
}
/*
@@ -212,8 +210,7 @@ vfs_rootmountalloc(char *fstypename, char *devname, struct mount **mpp)
return (ENODEV);
mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
bzero((char *)mp, (u_long)sizeof(struct mount));
- lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
- (void)vfs_busy(mp, LK_NOWAIT);
+ (void) vfs_busy(mp, VB_READ|VB_UMIGNORE);
LIST_INIT(&mp->mnt_vnodelist);
mp->mnt_vfc = vfsp;
mp->mnt_op = vfsp->vfc_vfsops;
@@ -1165,7 +1162,7 @@ vgonel(struct vnode *vp, struct proc *p)
*/
mp = vp->v_specmountpoint;
if (mp != NULL) {
- if (!vfs_busy(mp, LK_EXCLUSIVE)) {
+ if (!vfs_busy(mp, VB_WRITE|VB_UMWAIT)) {
flags = MNT_FORCE | MNT_DOOMED;
dounmount(mp, flags, p, NULL);
}
@@ -1332,7 +1329,7 @@ printlockedvnodes(void)
for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT)) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE)) {
nmp = CIRCLEQ_NEXT(mp, mnt_list);
continue;
}
@@ -1419,7 +1416,7 @@ sysctl_vnode(char *where, size_t *sizep, struct proc *p)
for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT)) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE)) {
nmp = CIRCLEQ_NEXT(mp, mnt_list);
continue;
}
@@ -1720,7 +1717,7 @@ vfs_unmountall(void)
for (mp = CIRCLEQ_LAST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
nmp = CIRCLEQ_PREV(mp, mnt_list);
- if ((vfs_busy(mp, LK_EXCLUSIVE|LK_NOWAIT)) != 0)
+ if ((vfs_busy(mp, VB_WRITE|VB_UMIGNORE)) != 0)
continue;
if ((error = dounmount(mp, MNT_FORCE, curproc, NULL)) != 0) {
printf("unmount of %s failed with error %d\n",
diff --git a/sys/kern/vfs_sync.c b/sys/kern/vfs_sync.c
index 6068ff5473e..8694baa5c39 100644
--- a/sys/kern/vfs_sync.c
+++ b/sys/kern/vfs_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_sync.c,v 1.39 2006/04/30 14:20:07 sturm Exp $ */
+/* $OpenBSD: vfs_sync.c,v 1.40 2006/06/14 20:01:50 sturm Exp $ */
/*
* Portions of this code are:
@@ -353,7 +353,7 @@ sync_fsync(void *v)
* Walk the list of vnodes pushing all that are dirty and
* not already on the sync list.
*/
- if (vfs_busy(mp, LK_NOWAIT) == 0) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE) == 0) {
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
VFS_SYNC(mp, MNT_LAZY, ap->a_cred, ap->a_p);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index a1fd7f46d4f..fc4ae8e5ef3 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.135 2006/05/27 17:37:42 sturm Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.136 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -150,7 +150,7 @@ sys_mount(struct proc *p, void *v, register_t *retval)
if (flag & MNT_NOEXEC)
SCARG(uap, flags) |= MNT_NOEXEC;
}
- if ((error = vfs_busy(mp, LK_NOWAIT)) != 0) {
+ if ((error = vfs_busy(mp, VB_READ|VB_UMIGNORE)) != 0) {
vput(vp);
return (error);
}
@@ -236,8 +236,7 @@ sys_mount(struct proc *p, void *v, register_t *retval)
mp = (struct mount *)malloc((u_long)sizeof(struct mount),
M_MOUNT, M_WAITOK);
bzero((char *)mp, (u_long)sizeof(struct mount));
- lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
- (void) vfs_busy(mp, LK_NOWAIT);
+ (void) vfs_busy(mp, VB_READ|VB_UMIGNORE);
mp->mnt_op = vfsp->vfc_vfsops;
mp->mnt_vfc = vfsp;
mp->mnt_flag |= (vfsp->vfc_flags & MNT_VISFLAGMASK);
@@ -403,7 +402,7 @@ sys_unmount(struct proc *p, void *v, register_t *retval)
}
vput(vp);
- if (vfs_busy(mp, LK_EXCLUSIVE))
+ if (vfs_busy(mp, VB_WRITE|VB_UMWAIT))
return (EBUSY);
return (dounmount(mp, SCARG(uap, flags), p, vp));
@@ -434,7 +433,7 @@ dounmount(struct mount *mp, int flags, struct proc *p, struct vnode *olddp)
if (error && error != EIO && !(flags & MNT_DOOMED)) {
if ((mp->mnt_flag & MNT_RDONLY) == 0 && hadsyncer)
(void) vfs_allocate_syncvnode(mp);
- lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, NULL);
+ vfs_unbusy(mp);
return (error);
}
@@ -449,7 +448,7 @@ dounmount(struct mount *mp, int flags, struct proc *p, struct vnode *olddp)
if (!LIST_EMPTY(&mp->mnt_vnodelist))
panic("unmount: dangling vnode");
- lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, NULL);
+ vfs_unbusy(mp);
free(mp, M_MOUNT);
return (0);
@@ -472,7 +471,7 @@ sys_sync(struct proc *p, void *v, register_t *retval)
for (mp = CIRCLEQ_LAST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT)) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE)) {
nmp = CIRCLEQ_PREV(mp, mnt_list);
continue;
}
@@ -627,7 +626,7 @@ sys_getfsstat(struct proc *p, void *v, register_t *retval)
for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT)) {
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE)) {
nmp = CIRCLEQ_NEXT(mp, mnt_list);
continue;
}
@@ -703,7 +702,7 @@ sys_fchdir(struct proc *p, void *v, register_t *retval)
error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
while (!error && (mp = vp->v_mountedhere) != NULL) {
- if (vfs_busy(mp, 0))
+ if (vfs_busy(mp, VB_READ|VB_UMWAIT))
continue;
error = VFS_ROOT(mp, &tdp);
vfs_unbusy(mp);
diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c
index 9ac032a6323..e6156abe717 100644
--- a/sys/nfs/nfs_syscalls.c
+++ b/sys/nfs/nfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_syscalls.c,v 1.46 2006/04/30 14:20:07 sturm Exp $ */
+/* $OpenBSD: nfs_syscalls.c,v 1.47 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */
/*
@@ -177,7 +177,7 @@ nfs_clientd(struct nfsmount *nmp, struct ucred *cred, struct nfsd_cargs *ncd,
error = tsleep((caddr_t)&nmp->nm_authstr, PSOCK | PCATCH,
"nqnfstimr", hz / 3);
if (error == EINTR || error == ERESTART) {
- if (vfs_busy(nmp->nm_mountp, LK_EXCLUSIVE) == 0)
+ if (vfs_busy(nmp->nm_mountp, VB_WRITE|VB_UMWAIT) == 0)
dounmount(nmp->nm_mountp, MNT_FORCE, p, NULL);
}
}
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index d6912d908f6..153b4e20dee 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount.h,v 1.71 2006/05/28 03:55:56 pedro Exp $ */
+/* $OpenBSD: mount.h,v 1.72 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: mount.h,v 1.48 1996/02/18 11:55:47 fvdl Exp $ */
/*
@@ -40,7 +40,7 @@
#include <sys/ucred.h>
#endif
#include <sys/queue.h>
-#include <sys/lock.h>
+#include <sys/rwlock.h>
typedef struct { int32_t val[2]; } fsid_t; /* file system id type */
@@ -372,7 +372,7 @@ struct mount {
struct vnode *mnt_vnodecovered; /* vnode we mounted on */
struct vnode *mnt_syncer; /* syncer vnode */
struct vnodelst mnt_vnodelist; /* list of vnodes this mount */
- struct lock mnt_lock; /* mount structure lock */
+ struct rwlock mnt_lock; /* mount structure lock */
int mnt_flag; /* flags */
int mnt_maxsymlinklen; /* max size of short symlink */
struct statfs mnt_stat; /* cache of filesystem stats */
@@ -564,6 +564,11 @@ struct netexport {
* exported vnode operations
*/
int vfs_busy(struct mount *, int);
+#define VB_READ 0x01
+#define VB_WRITE 0x02
+#define VB_UMIGNORE 0x04 /* ignore unmount in progress */
+#define VB_UMWAIT 0x08 /* wait for unmount to finish */
+
int vfs_isbusy(struct mount *);
int vfs_mount_foreach_vnode(struct mount *, int (*func)(struct vnode *,
void *), void *);
diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c
index 1b826228a1e..6c20f2834a6 100644
--- a/sys/ufs/mfs/mfs_vfsops.c
+++ b/sys/ufs/mfs/mfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfs_vfsops.c,v 1.32 2006/04/30 14:20:08 sturm Exp $ */
+/* $OpenBSD: mfs_vfsops.c,v 1.33 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $ */
/*
@@ -263,7 +263,7 @@ mfs_start(struct mount *mp, int flags, struct proc *p)
* EINTR/ERESTART.
*/
if (sleepreturn != 0) {
- if (vfs_busy(mp, LK_EXCLUSIVE|LK_NOWAIT) ||
+ if (vfs_busy(mp, VB_WRITE|VB_UMIGNORE) ||
dounmount(mp, 0, p, NULL))
CLRSIG(p, CURSIG(p));
sleepreturn = 0;
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index b7bc81d2152..b6436af8398 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: inode.h,v 1.32 2005/12/28 20:48:18 pedro Exp $ */
+/* $OpenBSD: inode.h,v 1.33 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */
/*
@@ -38,6 +38,7 @@
*/
#include <sys/buf.h>
+#include <sys/lock.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ext2fs/ext2fs_dinode.h>
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index 3b00eddb730..c1736332089 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_quota.c,v 1.23 2006/04/30 14:20:08 sturm Exp $ */
+/* $OpenBSD: ufs_quota.c,v 1.24 2006/06/14 20:01:50 sturm Exp $ */
/* $NetBSD: ufs_quota.c,v 1.8 1996/02/09 22:36:09 christos Exp $ */
/*
@@ -1028,7 +1028,7 @@ ufs_quotactl(struct mount *mp, int cmds, uid_t uid, caddr_t arg,
if ((u_int)type >= MAXQUOTAS)
return (EINVAL);
- if (vfs_busy(mp, LK_NOWAIT))
+ if (vfs_busy(mp, VB_READ|VB_UMIGNORE))
return (0);
diff --git a/sys/xfs/xfs_dev-common.c b/sys/xfs/xfs_dev-common.c
index 533bcae5a02..55100533536 100644
--- a/sys/xfs/xfs_dev-common.c
+++ b/sys/xfs/xfs_dev-common.c
@@ -180,7 +180,7 @@ xfs_devclose_common(dev_t dev, d_thread_t *proc)
*/
if (xfs[minor(dev)].mp != NULL) {
- if (xfs_vfs_busy(xfs[minor(dev)].mp, 0, NULL, proc)) {
+ if (xfs_vfs_busy(xfs[minor(dev)].mp, VB_READ|VB_UMWAIT, NULL, proc)) {
NNPFSDEB(XDEBNODE, ("xfs_dev_close: vfs_busy() --> BUSY\n"));
return EBUSY;
}