diff options
author | 2006-06-14 20:01:50 +0000 | |
---|---|---|
committer | 2006-06-14 20:01:50 +0000 | |
commit | 2e6147f207d8e5b50fbb5208246b9d6901cc9815 (patch) | |
tree | 271426e9e129dfbe7376c31fccbc89cd1af722ca | |
parent | .Xr adjfreq and ntpd (diff) | |
download | wireguard-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.c | 4 | ||||
-rw-r--r-- | sys/compat/freebsd/freebsd_file.c | 4 | ||||
-rw-r--r-- | sys/compat/netbsd/netbsd_file.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_lookup.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 61 | ||||
-rw-r--r-- | sys/kern/vfs_sync.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 19 | ||||
-rw-r--r-- | sys/nfs/nfs_syscalls.c | 4 | ||||
-rw-r--r-- | sys/sys/mount.h | 11 | ||||
-rw-r--r-- | sys/ufs/mfs/mfs_vfsops.c | 4 | ||||
-rw-r--r-- | sys/ufs/ufs/inode.h | 3 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_quota.c | 4 | ||||
-rw-r--r-- | sys/xfs/xfs_dev-common.c | 2 |
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; } |