From 8ddc60049ae330a0af88b01d0b7e12d5001e6bb2 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 1 Apr 2006 20:46:54 +0000 Subject: [PATCH] Use the vnode v_opencount and v_writecount universally. They were previously only used by specfs. Require that VOP_OPEN and VOP_CLOSE calls match. Assert on boundary errors. Clean up umount's FORCECLOSE mode. Adjust deadfs to allow duplicate closes (which can happen due to a forced unmount or revoke). Add vop_stdopen() and vop_stdclose() and adjust the default vnode ops to call them. All VFSs except DEADFS which supply their own vop_open and vop_close now call vop_stdopen() and vop_stdclose() to handle v_opencount and v_writecount adjustments. Change the VOP_OPEN/fp specs. VOP_OPEN (aka vop_stdopen) is now responsible for filling in the file pointer information, rather than the caller of VOP_OPEN. Additionally, when supplied a file pointer, VOP_OPEN is now allowed to populate the file pointer with a different vnode then the one passed to it, which will be used later on to allow filesystems which synthesize different vnodes on open, for example so we can create a generic tty/pty pairing devices rather than scanning for an unused pty, and so we can create swap-backed generic anonymous file descriptors rather than having to use /tmp. And for other purposes as well. Fix UFS's mount/remount/unmount code to make the proper VOP_OPEN and VOP_CLOSE calls when a filesystem is remounted read-only or read-write. --- .../linux/i386/linprocfs/linprocfs_vnops.c | 10 ++- sys/kern/kern_fp.c | 13 +--- sys/kern/kern_subr.c | 4 +- sys/kern/vfs_default.c | 67 ++++++++++++++++++- sys/kern/vfs_lock.c | 3 +- sys/kern/vfs_subr.c | 30 +++++---- sys/kern/vfs_syscalls.c | 19 +----- sys/kern/vfs_vnops.c | 20 ++---- sys/sys/vnode.h | 7 +- sys/vfs/coda/coda_vnops.c | 26 ++++--- sys/vfs/deadfs/dead_vnops.c | 23 ++++++- sys/vfs/fdesc/fdesc_vnops.c | 4 +- sys/vfs/fifofs/fifo_vnops.c | 9 ++- sys/vfs/gnu/ext2fs/ext2_vfsops.c | 12 +++- sys/vfs/hpfs/hpfs_vnops.c | 56 +--------------- sys/vfs/isofs/cd9660/cd9660_vnops.c | 4 +- sys/vfs/mfs/mfs_vfsops.c | 6 +- sys/vfs/mfs/mfs_vnops.c | 10 +-- sys/vfs/msdosfs/msdosfs_vnops.c | 6 +- sys/vfs/nfs/nfs_vnops.c | 5 +- sys/vfs/ntfs/ntfs_vnops.c | 6 +- sys/vfs/nwfs/nwfs_vnops.c | 28 +++++--- sys/vfs/portal/portal_vnops.c | 5 +- sys/vfs/procfs/procfs_vnops.c | 8 +-- sys/vfs/smbfs/smbfs_vnops.c | 18 +++-- sys/vfs/specfs/spec_vnops.c | 15 +++-- sys/vfs/ufs/ffs_vfsops.c | 35 +++++++--- sys/vfs/ufs/ufs_vnops.c | 6 +- sys/vfs/union/union_subr.c | 5 +- 29 files changed, 255 insertions(+), 205 deletions(-) diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c b/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c index e9ec7ec8cb..0fe1fdf05d 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c @@ -39,7 +39,7 @@ * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * * $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_vnops.c,v 1.3.2.5 2001/08/12 14:29:19 rwatson Exp $ - * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c,v 1.27 2006/03/24 18:35:32 dillon Exp $ + * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c,v 1.28 2006/04/01 20:46:50 dillon Exp $ */ /* @@ -147,13 +147,12 @@ linprocfs_open(struct vop_open_args *ap) if (ap->a_mode & FWRITE) pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); - return (0); - + break; default: break; } - return (0); + return (vop_stdopen(ap)); } /* @@ -193,8 +192,7 @@ linprocfs_close(struct vop_close_args *ap) default: break; } - - return (0); + return (vop_stdclose(ap)); } /* diff --git a/sys/kern/kern_fp.c b/sys/kern/kern_fp.c index d8ffbf3d6f..d406d081a5 100644 --- a/sys/kern/kern_fp.c +++ b/sys/kern/kern_fp.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_fp.c,v 1.13 2006/03/29 18:44:50 dillon Exp $ + * $DragonFly: src/sys/kern/kern_fp.c,v 1.14 2006/04/01 20:46:47 dillon Exp $ */ /* @@ -181,21 +181,12 @@ fp_vpopen(struct vnode *vp, int flags, file_t *fpp) fp = *fpp; if ((flags & O_ROOTCRED) == 0 && td->td_proc) fsetcred(fp, td->td_proc->p_ucred); - fp->f_type = DTYPE_VNODE; - fp->f_flag = flags; - fp->f_ops = &vnode_fileops; - fp->f_data = vp; error = VOP_OPEN(vp, flags, td->td_proc->p_ucred, fp, td); if (error) goto bad1; - /* - * All done, update v_writecount now that no more errors can occur. - */ - if (flags & FWRITE) - vp->v_writecount++; - VOP_UNLOCK(vp, 0, td); + vput(vp); return (0); bad1: fp->f_ops = &badfileops; /* open failed, don't close */ diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index 1eb9448131..a4ef928976 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -37,7 +37,7 @@ * * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/kern_subr.c,v 1.31.2.2 2002/04/21 08:09:37 bde Exp $ - * $DragonFly: src/sys/kern/kern_subr.c,v 1.20 2004/11/09 17:52:45 joerg Exp $ + * $DragonFly: src/sys/kern/kern_subr.c,v 1.21 2006/04/01 20:46:47 dillon Exp $ */ #include "opt_ddb.h" @@ -63,7 +63,7 @@ SYSCTL_INT(_kern, KERN_IOV_MAX, iov_max, CTLFLAG_RD, NULL, UIO_MAXIOV, /* * UIO_READ: copy the kernelspace cp to the user or kernelspace UIO - * UIO_WRITE: copy the user or kernelspace UIO to cp + * UIO_WRITE: copy the user or kernelspace UIO to the kernelspace cp * * For userspace UIO's, uio_td must be the current thread. */ diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 40ca040a46..3c530c0009 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -37,13 +37,15 @@ * * * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $ - * $DragonFly: src/sys/kern/vfs_default.c,v 1.31 2006/03/29 18:44:50 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_default.c,v 1.32 2006/04/01 20:46:47 dillon Exp $ */ #include #include #include #include +#include +#include #include #include #include @@ -77,14 +79,14 @@ static struct vnodeopv_entry_desc default_vnodeop_entries[] = { { &vop_default_desc, vop_eopnotsupp }, { &vop_advlock_desc, vop_einval }, { &vop_bwrite_desc, (void *) vop_stdbwrite }, - { &vop_close_desc, vop_null }, { &vop_fsync_desc, vop_null }, { &vop_ioctl_desc, vop_enotty }, { &vop_islocked_desc, (void *) vop_stdislocked }, { &vop_lock_desc, (void *) vop_stdlock }, { &vop_mmap_desc, vop_einval }, { &vop_old_lookup_desc, (void *) vop_nolookup }, - { &vop_open_desc, vop_null }, + { &vop_open_desc, (void *) vop_stdopen }, + { &vop_close_desc, (void *) vop_stdclose }, { &vop_pathconf_desc, vop_einval }, { &vop_poll_desc, (void *) vop_nopoll }, { &vop_readlink_desc, vop_einval }, @@ -1184,6 +1186,65 @@ vop_stdpathconf(ap) /* NOTREACHED */ } +/* + * Standard open. + * + * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp, + * struct thread *a_td) + * + * a_mode: note, 'F' modes, e.g. FREAD, FWRITE + */ +int +vop_stdopen(struct vop_open_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct file *fp; + + if ((fp = ap->a_fp) != NULL) { + switch(vp->v_type) { + case VFIFO: + fp->f_type = DTYPE_FIFO; + break; + default: + fp->f_type = DTYPE_VNODE; + break; + } + fp->f_flag = ap->a_mode & FMASK; + fp->f_ops = &vnode_fileops; + fp->f_data = vp; + vref(vp); + } + if (ap->a_mode & FWRITE) + ++vp->v_writecount; + KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX); + ++vp->v_opencount; + return (0); +} + +/* + * Standard close. + * + * (struct vnode *a_vp, int a_fflag, struct thread *a_td) + * + * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen? + */ +int +vop_stdclose(struct vop_close_args *ap) +{ + struct vnode *vp = ap->a_vp; + + KASSERT(vp->v_opencount > 0, + ("VOP_STDCLOSE: BAD OPENCOUNT %p %d\n", vp, vp->v_opencount)); + if (ap->a_fflag & FWRITE) { + KASSERT(vp->v_writecount > 0, + ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n", + vp, vp->v_writecount)); + --vp->v_writecount; + } + --vp->v_opencount; + return (0); +} + /* * Standard lock. The lock is recursive-capable only if the lock was * initialized with LK_CANRECURSE or that flag is passed in a_flags. diff --git a/sys/kern/vfs_lock.c b/sys/kern/vfs_lock.c index 8734763c29..a11c426f92 100644 --- a/sys/kern/vfs_lock.c +++ b/sys/kern/vfs_lock.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_lock.c,v 1.12 2006/03/27 16:18:34 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_lock.c,v 1.13 2006/04/01 20:46:47 dillon Exp $ */ /* @@ -467,6 +467,7 @@ allocvnode(int lktimeout, int lkflags) vp->v_cstart = 0; vp->v_clen = 0; vp->v_socket = 0; + vp->v_opencount = 0; vp->v_writecount = 0; /* XXX */ lockreinit(&vp->v_lock, "vnode", lktimeout, lkflags); KKASSERT(TAILQ_FIRST(&vp->v_namecache) == NULL); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 86d53dd8a3..5d85f24eec 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -37,7 +37,7 @@ * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_subr.c,v 1.73 2006/03/29 20:46:05 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_subr.c,v 1.74 2006/04/01 20:46:47 dillon Exp $ */ /* @@ -1017,13 +1017,7 @@ v_release_rdev(struct vnode *vp) if ((dev = vp->v_rdev) != NULL) { lwkt_gettoken(&ilock, &spechash_token); SLIST_REMOVE(&dev->si_hlist, vp, vnode, v_specnext); - if (dev_ref_debug && vp->v_opencount != 0) { - printf("releasing rdev with non-0 " - "v_opencount(%d) (revoked?)\n", - vp->v_opencount); - } vp->v_rdev = NULL; - vp->v_opencount = 0; release_dev(dev); lwkt_reltoken(&ilock); } @@ -1056,6 +1050,7 @@ vclean(struct vnode *vp, int flags, struct thread *td) { int active; int retflags = 0; + int n; vm_object_t object; /* @@ -1098,14 +1093,25 @@ vclean(struct vnode *vp, int flags, struct thread *td) KKASSERT((vp->v_flag & VOBJBUF) == 0); /* - * If purging an active vnode, it must be closed and - * deactivated before being reclaimed. XXX + * If purging an active vnode (typically during a forced unmount + * or reboot), it must be closed and deactivated before being + * reclaimed. This isn't really all that safe, but what can + * we do? XXX. * * Note that neither of these routines unlocks the vnode. */ - if (active) { - if (flags & DOCLOSE) - VOP_CLOSE(vp, FNONBLOCK, td); + if (active && (flags & DOCLOSE)) { + while ((n = vp->v_opencount) != 0) { + if (vp->v_writecount) + VOP_CLOSE(vp, FWRITE|FNONBLOCK, td); + else + VOP_CLOSE(vp, FNONBLOCK, td); + if (vp->v_opencount == n) { + printf("Warning: unable to force-close" + " vnode %p\n", vp); + break; + } + } } /* diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 309030900b..6449a5e94a 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -37,7 +37,7 @@ * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.79 2006/03/29 18:44:50 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.80 2006/04/01 20:46:47 dillon Exp $ */ #include @@ -3189,11 +3189,6 @@ fhopen(struct fhopen_args *uap) goto bad; fp = nfp; - fp->f_type = DTYPE_VNODE; - fp->f_flag = fmode & FMASK; - fp->f_ops = &vnode_fileops; - fp->f_data = vp; - error = VOP_OPEN(vp, fmode, p->p_ucred, fp, td); if (error) { /* @@ -3206,16 +3201,10 @@ fhopen(struct fhopen_args *uap) fdrop(fp, td); goto bad; } - if (fmode & FWRITE) - vp->v_writecount++; - - /* - * The fp now owns a reference on the vnode. We still have our own - * ref+lock. - */ - vref(vp); /* + * The fp is given its own reference, we still have our ref and lock. + * * Assert that all regular files must be created with a VM object. */ if (vp->v_type == VREG && vp->v_object == NULL) { @@ -3228,8 +3217,6 @@ fhopen(struct fhopen_args *uap) * The open was successful, associate it with a file descriptor. */ if ((error = fsetfd(p, fp, &indx)) != 0) { - if (fmode & FWRITE) - vp->v_writecount--; fdrop(fp, td); goto bad; } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index c751417aa6..a3cddbf400 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -37,7 +37,7 @@ * * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/vfs_vnops.c,v 1.87.2.13 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.36 2006/03/29 18:44:50 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.37 2006/04/01 20:46:48 dillon Exp $ */ #include @@ -268,15 +268,10 @@ again: /* * Setup the fp so VOP_OPEN can override it. No descriptor has been - * associated with the fp yet so we own it clean. f_data will inherit - * our vp reference as long as we do not shift f_ops to &badfileops. - * f_ncp inherits nl_ncp . + * associated with the fp yet so we own it clean. f_ncp inherits + * nl_ncp . */ if (fp) { - fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE); - fp->f_flag = fmode & FMASK; - fp->f_ops = &vnode_fileops; - fp->f_data = vp; if (vp->v_type == VDIR) { fp->f_ncp = nd->nl_ncp; nd->nl_ncp = NULL; @@ -308,8 +303,6 @@ again: } goto bad; } - if (fmode & FWRITE) - vp->v_writecount++; #if 0 /* @@ -321,8 +314,7 @@ again: /* * Return the vnode. XXX needs some cleaning up. The vnode is - * only returned in the fp == NULL case, otherwise the vnode ref - * is inherited by the fp and we unconditionally unlock it. + * only returned in the fp == NULL case. */ if (fp == NULL) { nd->nl_open_vp = vp; @@ -330,7 +322,7 @@ again: if ((nd->nl_flags & NLC_LOCKVP) == 0) VOP_UNLOCK(vp, 0, td); } else { - VOP_UNLOCK(vp, 0, td); + vput(vp); } return (0); bad: @@ -366,8 +358,6 @@ vn_close(struct vnode *vp, int flags, struct thread *td) { int error; - if (flags & FWRITE) - vp->v_writecount--; if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td)) == 0) { error = VOP_CLOSE(vp, flags, td); VOP_UNLOCK(vp, 0, td); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 17a96d31a2..57585163fd 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -32,7 +32,7 @@ * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/sys/vnode.h,v 1.45 2006/03/29 18:44:52 dillon Exp $ + * $DragonFly: src/sys/sys/vnode.h,v 1.46 2006/04/01 20:46:49 dillon Exp $ */ #ifndef _SYS_VNODE_H_ @@ -146,9 +146,6 @@ vrange_lock_excl(struct vnode *vp, struct vrangelock *vr, * deal with clustered cache coherency issues and, more immediately, to * protect operations associated with the kernel-managed journaling module. * - * NOTE: XXX v_opencount currently only used by specfs. It should be used - * universally. - * * NOTE: The vnode operations vector, v_ops, is a double-indirect that * typically points to &v_mount->mnt_vn_use_ops. We use a double * pointer because mnt_vn_use_ops may change dynamically when e.g. @@ -631,6 +628,8 @@ int vn_stat (struct vnode *vp, struct stat *sb, struct thread *td); dev_t vn_todev (struct vnode *vp); void vfs_timestamp (struct timespec *); int vn_writechk (struct vnode *vp); +int vop_stdopen (struct vop_open_args *ap); +int vop_stdclose (struct vop_close_args *ap); int vop_stdbwrite (struct vop_bwrite_args *ap); int vop_stdislocked (struct vop_islocked_args *ap); int vop_stdlock (struct vop_lock_args *ap); diff --git a/sys/vfs/coda/coda_vnops.c b/sys/vfs/coda/coda_vnops.c index 0e368e13c1..d600fe1ad5 100644 --- a/sys/vfs/coda/coda_vnops.c +++ b/sys/vfs/coda/coda_vnops.c @@ -28,7 +28,7 @@ * * @(#) src/sys/coda/coda_vnops.c,v 1.1.1.1 1998/08/29 21:14:52 rvb Exp $ * $FreeBSD: src/sys/coda/coda_vnops.c,v 1.22.2.1 2001/06/29 16:26:22 shafeeq Exp $ - * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.c,v 1.32 2006/03/29 18:44:53 dillon Exp $ + * $DragonFly: src/sys/vfs/coda/Attic/coda_vnops.c,v 1.33 2006/04/01 20:46:51 dillon Exp $ * */ @@ -241,15 +241,17 @@ coda_open(void *v) /* if (WRITEABLE(flag)) */ if (flag & (FWRITE | O_TRUNC | O_CREAT | O_EXCL)) { MARK_INT_FAIL(CODA_OPEN_STATS); - return(EACCES); + error = EACCES; + goto done; } MARK_INT_SAT(CODA_OPEN_STATS); - return(0); + error = 0; + goto done; } error = venus_open(vtomi((*vpp)), &cp->c_fid, flag, cred, td, &dev, &inode); if (error) - return (error); + goto done; if (!error) { CODADEBUG( CODA_OPEN,myprintf(("open: dev %#lx inode %lu result %d\n", (u_long)dev2udev(dev), (u_long)inode, @@ -260,7 +262,7 @@ coda_open(void *v) an inode pointer. */ error = coda_grab_vnode(dev, inode, &vp); if (error) - return (error); + goto done; /* We get the vnode back locked. Needs unlocked */ VOP_UNLOCK(vp, 0, td); @@ -291,7 +293,7 @@ coda_open(void *v) error = VOP_OPEN(vp, flag, cred, NULL, td); if (error) { printf("coda_open: VOP_OPEN on container failed %d\n", error); - return (error); + goto done; } /* grab (above) does this when it calls newvnode unless it's in the cache*/ if (vp->v_type == VREG) { @@ -301,7 +303,9 @@ coda_open(void *v) vput(vp); } } - +done: + if (error == 0) + vop_stdopen(ap); return(error); } @@ -325,7 +329,8 @@ coda_close(void *v) /* Check for close of control file. */ if (IS_CTL_VP(vp)) { MARK_INT_SAT(CODA_CLOSE_STATS); - return(0); + error = 0; + goto done; } if (IS_UNMOUNTING(cp)) { @@ -345,7 +350,8 @@ coda_close(void *v) printf("coda_close: NO container vp %p/cp %p\n", vp, cp); #endif } - return ENODEV; + error = ENODEV; + goto done; } else { VOP_CLOSE(cp->c_ovp, flag, td); /* Do errors matter here? */ vrele(cp->c_ovp); @@ -361,6 +367,8 @@ coda_close(void *v) vrele(CTOV(cp)); CODADEBUG(CODA_CLOSE, myprintf(("close: result %d\n",error)); ) +done: + vop_stdclose(ap); return(error); } diff --git a/sys/vfs/deadfs/dead_vnops.c b/sys/vfs/deadfs/dead_vnops.c index 9a048f91bc..bc6e3501e5 100644 --- a/sys/vfs/deadfs/dead_vnops.c +++ b/sys/vfs/deadfs/dead_vnops.c @@ -32,7 +32,7 @@ * * @(#)dead_vnops.c 8.1 (Berkeley) 6/10/93 * $FreeBSD: src/sys/miscfs/deadfs/dead_vnops.c,v 1.26 1999/08/28 00:46:42 peter Exp $ - * $DragonFly: src/sys/vfs/deadfs/dead_vnops.c,v 1.15 2006/03/24 18:35:33 dillon Exp $ + * $DragonFly: src/sys/vfs/deadfs/dead_vnops.c,v 1.16 2006/04/01 20:46:53 dillon Exp $ */ #include @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,7 @@ static int dead_ioctl (struct vop_ioctl_args *); static int dead_lock (struct vop_lock_args *); static int dead_lookup (struct vop_old_lookup_args *); static int dead_open (struct vop_open_args *); +static int dead_close (struct vop_close_args *); static int dead_poll (struct vop_poll_args *); static int dead_print (struct vop_print_args *); static int dead_read (struct vop_read_args *); @@ -74,6 +76,7 @@ static struct vnodeopv_entry_desc dead_vnodeop_entries[] = { { &vop_old_mknod_desc, (vnodeopv_entry_t) dead_badop }, { &vop_mmap_desc, (vnodeopv_entry_t) dead_badop }, { &vop_open_desc, (vnodeopv_entry_t) dead_open }, + { &vop_close_desc, (vnodeopv_entry_t) dead_close }, { &vop_pathconf_desc, vop_ebadf }, /* per pathconf(2) */ { &vop_poll_desc, (vnodeopv_entry_t) dead_poll }, { &vop_print_desc, (vnodeopv_entry_t) dead_print }, @@ -121,6 +124,24 @@ dead_open(struct vop_open_args *ap) return (ENXIO); } +/* + * Close always succeeds, and does not warn or panic if v_opencount or + * v_writecount is incorrect, because a forced unmount or revocation + * might have closed the file out from under the descriptor. + */ +static int +dead_close(struct vop_close_args *ap) +{ + struct vnode *vp = ap->a_vp; + + if (vp->v_opencount > 0) { + if ((ap->a_fflag & FWRITE) && vp->v_writecount > 0) + --vp->v_writecount; + --vp->v_opencount; + } + return (0); +} + /* * Vnode op for read * diff --git a/sys/vfs/fdesc/fdesc_vnops.c b/sys/vfs/fdesc/fdesc_vnops.c index b07d34b417..f2aceb2696 100644 --- a/sys/vfs/fdesc/fdesc_vnops.c +++ b/sys/vfs/fdesc/fdesc_vnops.c @@ -36,7 +36,7 @@ * @(#)fdesc_vnops.c 8.9 (Berkeley) 1/21/94 * * $FreeBSD: src/sys/miscfs/fdesc/fdesc_vnops.c,v 1.47.2.1 2001/10/22 22:49:26 chris Exp $ - * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.24 2006/01/13 21:09:27 swildner Exp $ + * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.25 2006/04/01 20:46:53 dillon Exp $ */ /* @@ -251,7 +251,7 @@ fdesc_open(struct vop_open_args *ap) KKASSERT(lp); if (VTOFDESC(vp)->fd_type == Froot) - return (0); + return (vop_stdopen(ap)); /* * XXX Kludge: set lp->lwp_dupfd to contain the value of the the file diff --git a/sys/vfs/fifofs/fifo_vnops.c b/sys/vfs/fifofs/fifo_vnops.c index 0c19d08579..0b5c0f7c18 100644 --- a/sys/vfs/fifofs/fifo_vnops.c +++ b/sys/vfs/fifofs/fifo_vnops.c @@ -32,7 +32,7 @@ * * @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95 * $FreeBSD: src/sys/miscfs/fifofs/fifo_vnops.c,v 1.45.2.4 2003/04/22 10:11:24 bde Exp $ - * $DragonFly: src/sys/vfs/fifofs/fifo_vnops.c,v 1.24 2006/03/27 16:18:37 dillon Exp $ + * $DragonFly: src/sys/vfs/fifofs/fifo_vnops.c,v 1.25 2006/04/01 20:46:53 dillon Exp $ */ #include @@ -254,7 +254,7 @@ fifo_open(struct vop_open_args *ap) } } } - return (0); + return (vop_stdopen(ap)); bad: VOP_CLOSE(vp, ap->a_mode, ap->a_td); return (error); @@ -536,14 +536,17 @@ fifo_close(struct vop_close_args *ap) if (fip->fi_writers == 0) socantrcvmore(fip->fi_readsock); } - if (vp->v_usecount > 1) + if (vp->v_usecount > 1) { + vop_stdclose(ap); return (0); + } error1 = soclose(fip->fi_readsock); error2 = soclose(fip->fi_writesock); FREE(fip, M_FIFOINFO); vp->v_fifoinfo = NULL; if (error1) return (error1); + vop_stdclose(ap); return (error2); } diff --git a/sys/vfs/gnu/ext2fs/ext2_vfsops.c b/sys/vfs/gnu/ext2fs/ext2_vfsops.c index 625d866866..01a5ea957c 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vfsops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vfsops.c @@ -38,7 +38,7 @@ * * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 * $FreeBSD: src/sys/gnu/ext2fs/ext2_vfsops.c,v 1.63.2.7 2002/07/01 00:18:51 iedowse Exp $ - * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.33 2006/03/24 18:35:33 dillon Exp $ + * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.34 2006/04/01 20:46:53 dillon Exp $ */ #include "opt_quota.h" @@ -150,6 +150,7 @@ ext2_mount(struct mount *mp, char *path, caddr_t data, if (mp->mnt_flag & MNT_UPDATE) { ump = VFSTOUFS(mp); fs = ump->um_e2fs; + devvp = ump->um_devvp; error = 0; if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) { flags = WRITECLOSE; @@ -164,12 +165,15 @@ ext2_mount(struct mount *mp, char *path, caddr_t data, ext2_sbupdate(ump, MNT_WAIT); } fs->s_rd_only = 1; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + VOP_OPEN(devvp, FREAD, FSCRED, NULL, td); + VOP_CLOSE(devvp, FREAD|FWRITE, td); + VOP_UNLOCK(devvp, 0, td); } if (!error && (mp->mnt_flag & MNT_RELOAD)) error = ext2_reload(mp, proc0.p_ucred, td); if (error) return (error); - devvp = ump->um_devvp; if (ext2_check_sb_compat(fs->s_es, devvp->v_rdev, (mp->mnt_kern_flag & MNTK_WANTRDWR) == 0) != 0) return (EPERM); @@ -204,6 +208,10 @@ ext2_mount(struct mount *mp, char *path, caddr_t data, fs->s_es->s_state &= ~EXT2_VALID_FS; ext2_sbupdate(ump, MNT_WAIT); fs->s_rd_only = 0; + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, NULL, td); + VOP_CLOSE(devvp, FREAD, td); + VOP_UNLOCK(devvp, 0, td); } if (args.fspec == 0) { /* diff --git a/sys/vfs/hpfs/hpfs_vnops.c b/sys/vfs/hpfs/hpfs_vnops.c index ece5f55126..8854e84b26 100644 --- a/sys/vfs/hpfs/hpfs_vnops.c +++ b/sys/vfs/hpfs/hpfs_vnops.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/hpfs/hpfs_vnops.c,v 1.2.2.2 2002/01/15 18:35:09 semenu Exp $ - * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.30 2006/03/24 18:35:33 dillon Exp $ + * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.31 2006/04/01 20:46:53 dillon Exp $ */ #include @@ -82,8 +82,6 @@ static int hpfs_print (struct vop_print_args *ap); static int hpfs_reclaim (struct vop_reclaim_args *ap); static int hpfs_strategy (struct vop_strategy_args *ap); static int hpfs_access (struct vop_access_args *ap); -static int hpfs_open (struct vop_open_args *ap); -static int hpfs_close (struct vop_close_args *ap); static int hpfs_readdir (struct vop_readdir_args *ap); static int hpfs_lookup (struct vop_old_lookup_args *ap); static int hpfs_create (struct vop_old_create_args *); @@ -794,54 +792,6 @@ hpfs_access(struct vop_access_args *ap) return ((hp->h_mode & mask) == mask ? 0 : EACCES); } -/* - * Open called. - * - * Nothing to do. - * - * hpfs_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred, - * struct proc *a_td) - */ -/* ARGSUSED */ -static int -hpfs_open(struct vop_open_args *ap) -{ -#if HPFS_DEBUG - struct vnode *vp = ap->a_vp; - struct hpfsnode *hp = VTOHP(vp); - - printf("hpfs_open(0x%x):\n",hp->h_no); -#endif - - /* - * Files marked append-only must be opened for appending. - */ - - return (0); -} - -/* - * Close called. - * - * Update the times on the inode. - * - * hpfs_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred, - * struct proc *a_td) - */ -/* ARGSUSED */ -static int -hpfs_close(struct vop_close_args *ap) -{ -#if HPFS_DEBUG - struct vnode *vp = ap->a_vp; - struct hpfsnode *hp = VTOHP(vp); - - printf("hpfs_close: %d\n",hp->h_no); -#endif - - return (0); -} - static int hpfs_de_uiomove(int *error, struct hpfsmount *hpmp, struct hpfsdirent *dep, struct uio *uio) @@ -1284,8 +1234,6 @@ struct vnodeopv_entry_desc hpfs_vnodeop_entries[] = { { &vop_lock_desc, (vnodeopv_entry_t)vop_stdlock }, { &vop_old_lookup_desc, (vnodeopv_entry_t)hpfs_lookup }, { &vop_access_desc, (vnodeopv_entry_t)hpfs_access }, - { &vop_close_desc, (vnodeopv_entry_t)hpfs_close }, - { &vop_open_desc, (vnodeopv_entry_t)hpfs_open }, { &vop_readdir_desc, (vnodeopv_entry_t)hpfs_readdir }, { &vop_fsync_desc, (vnodeopv_entry_t)hpfs_fsync }, { &vop_bmap_desc, (vnodeopv_entry_t)hpfs_bmap }, @@ -1306,8 +1254,6 @@ struct vnodeopv_entry_desc ntfs_vnodeop_entries[] = { { &vop_old_lookup_desc, (vnodeopv_entry_t) hpfs_lookup }, /* lookup */ { &vop_old_create_desc, genfs_eopnotsupp }, /* create */ { &vop_old_mknod_desc, genfs_eopnotsupp }, /* mknod */ - { &vop_open_desc, (vnodeopv_entry_t) hpfs_open }, /* open */ - { &vop_close_desc,(vnodeopv_entry_t) hpfs_close }, /* close */ { &vop_access_desc, (vnodeopv_entry_t) hpfs_access }, /* access */ { &vop_getattr_desc, (vnodeopv_entry_t) hpfs_getattr }, /* getattr */ { &vop_setattr_desc, genfs_eopnotsupp }, /* setattr */ diff --git a/sys/vfs/isofs/cd9660/cd9660_vnops.c b/sys/vfs/isofs/cd9660/cd9660_vnops.c index fc37b45ffe..a5b14a94ff 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vnops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vnops.c @@ -37,7 +37,7 @@ * * @(#)cd9660_vnops.c 8.19 (Berkeley) 5/27/95 * $FreeBSD: src/sys/isofs/cd9660/cd9660_vnops.c,v 1.62 1999/12/15 23:01:51 eivind Exp $ - * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.21 2006/03/29 18:44:55 dillon Exp $ + * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.22 2006/04/01 20:46:53 dillon Exp $ */ #include @@ -284,7 +284,7 @@ cd9660_open(struct vop_open_args *ap) */ if (vp->v_type == VREG || vp->v_type == VDIR) vinitvmio(vp); - return(0); + return(vop_stdopen(ap)); } /* diff --git a/sys/vfs/mfs/mfs_vfsops.c b/sys/vfs/mfs/mfs_vfsops.c index aefd9d9f88..df1f7122bb 100644 --- a/sys/vfs/mfs/mfs_vfsops.c +++ b/sys/vfs/mfs/mfs_vfsops.c @@ -32,7 +32,7 @@ * * @(#)mfs_vfsops.c 8.11 (Berkeley) 6/19/95 * $FreeBSD: src/sys/ufs/mfs/mfs_vfsops.c,v 1.81.2.3 2001/07/04 17:35:21 tegge Exp $ - * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.26 2006/03/24 18:35:34 dillon Exp $ + * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.27 2006/04/01 20:46:53 dillon Exp $ */ @@ -270,8 +270,10 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct thread *td) if (err) goto error_1; } - if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) + if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) { + /* XXX reopen the device vnode read-write */ fs->fs_ronly = 0; + } /* if not updating name...*/ if (args.fspec == 0) { /* diff --git a/sys/vfs/mfs/mfs_vnops.c b/sys/vfs/mfs/mfs_vnops.c index a89e291c24..7f1a757ff3 100644 --- a/sys/vfs/mfs/mfs_vnops.c +++ b/sys/vfs/mfs/mfs_vnops.c @@ -32,7 +32,7 @@ * * @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95 * $FreeBSD: src/sys/ufs/mfs/mfs_vnops.c,v 1.47.2.1 2001/05/22 02:06:43 bp Exp $ - * $DragonFly: src/sys/vfs/mfs/mfs_vnops.c,v 1.22 2006/03/29 18:44:57 dillon Exp $ + * $DragonFly: src/sys/vfs/mfs/mfs_vnops.c,v 1.23 2006/04/01 20:46:53 dillon Exp $ */ #include @@ -116,7 +116,7 @@ mfs_open(struct vop_open_args *ap) if (vp->v_type != VCHR) panic("mfs_open not VCHR"); v_associate_rdev(vp, udev2dev(vp->v_udev, 0)); - return (0); + return (vop_stdopen(ap)); } static int @@ -324,7 +324,7 @@ mfs_close(struct vop_close_args *ap) * we can, free up its vnode. */ if ((error = vinvalbuf(vp, 1, ap->a_td, 0, 0)) != 0) - return (error); + goto done; /* * There should be no way to have any more uses of this * vnode, so if we find any other uses, it is a panic. @@ -343,7 +343,9 @@ mfs_close(struct vop_close_args *ap) mfsp->mfs_dev = NULL; } wakeup((caddr_t)mfsp); - return (0); +done: + vop_stdclose(ap); + return (error); } /* diff --git a/sys/vfs/msdosfs/msdosfs_vnops.c b/sys/vfs/msdosfs/msdosfs_vnops.c index f275b97e38..362ea28d1c 100644 --- a/sys/vfs/msdosfs/msdosfs_vnops.c +++ b/sys/vfs/msdosfs/msdosfs_vnops.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/msdosfs/msdosfs_vnops.c,v 1.95.2.4 2003/06/13 15:05:47 trhodes Exp $ */ -/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.32 2006/03/29 18:44:59 dillon Exp $ */ +/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.33 2006/04/01 20:46:53 dillon Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $ */ /*- @@ -220,7 +220,7 @@ msdosfs_open(struct vop_open_args *ap) if (vp->v_type == VREG || vp->v_type == VDIR) vinitvmio(vp); - return(0); + return(vop_stdopen(ap)); } /* @@ -240,7 +240,7 @@ msdosfs_close(struct vop_close_args *ap) DETIMES(dep, &ts, &ts, &ts); } } - return 0; + return (vop_stdclose(ap)); } /* diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index 9d0db85cb0..3d44d336b8 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -35,7 +35,7 @@ * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.53 2006/03/29 21:07:21 dillon Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.54 2006/04/01 20:46:53 dillon Exp $ */ @@ -539,7 +539,7 @@ nfs_open(struct vop_open_args *ap) np->n_flag &= ~NRMODIFIED; } - return (0); + return (vop_stdopen(ap)); } /* @@ -612,6 +612,7 @@ nfs_close(struct vop_close_args *ap) error = np->n_error; } } + vop_stdclose(ap); return (error); } diff --git a/sys/vfs/ntfs/ntfs_vnops.c b/sys/vfs/ntfs/ntfs_vnops.c index a1cd8fd4ca..c172d240bc 100644 --- a/sys/vfs/ntfs/ntfs_vnops.c +++ b/sys/vfs/ntfs/ntfs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/ntfs/ntfs_vnops.c,v 1.9.2.4 2002/08/06 19:35:18 semenu Exp $ - * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.27 2006/03/29 18:45:01 dillon Exp $ + * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.28 2006/04/01 20:46:53 dillon Exp $ * */ @@ -537,7 +537,7 @@ ntfs_open(struct vop_open_args *ap) * Files marked append-only must be opened for appending. */ - return (0); + return (vop_stdopen(ap)); } /* @@ -559,7 +559,7 @@ ntfs_close(struct vop_close_args *ap) printf("ntfs_close: %d\n",ip->i_number); #endif - return (0); + return (vop_stdclose(ap)); } /* diff --git a/sys/vfs/nwfs/nwfs_vnops.c b/sys/vfs/nwfs/nwfs_vnops.c index 95d661b1e9..5c6f967e98 100644 --- a/sys/vfs/nwfs/nwfs_vnops.c +++ b/sys/vfs/nwfs/nwfs_vnops.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/nwfs/nwfs_vnops.c,v 1.6.2.3 2001/03/14 11:26:59 bp Exp $ - * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.25 2006/03/24 18:35:34 dillon Exp $ + * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.26 2006/04/01 20:46:53 dillon Exp $ */ #include #include @@ -183,11 +183,13 @@ nwfs_open(struct vop_open_args *ap) return (error); np->n_atime = 0; error = VOP_GETATTR(vp, &vattr, ap->a_td); - if (error) return (error); + if (error) + return (error); np->n_mtime = vattr.va_mtime.tv_sec; } else { error = VOP_GETATTR(vp, &vattr, ap->a_td); - if (error) return (error); + if (error) + return (error); if (np->n_mtime != vattr.va_mtime.tv_sec) { if ((error = nwfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1)) == EINTR) return (error); @@ -196,7 +198,7 @@ nwfs_open(struct vop_open_args *ap) } if (np->opened) { np->opened++; - return 0; + return (vop_stdopen(ap)); } nwm = AR_READ; if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) @@ -210,12 +212,13 @@ nwfs_open(struct vop_open_args *ap) error = ncp_open_create_file_or_subdir(nmp, vp, 0, NULL, OC_MODE_OPEN, 0, nwm, &no, ap->a_td,ap->a_cred); } - if (!error) { + np->n_atime = 0; + if (error == 0) { np->opened++; np->n_fh = no.fh; np->n_origfh = no.origfh; + error = vop_stdopen(ap); } - np->n_atime = 0; return (error); } @@ -232,20 +235,23 @@ nwfs_close(struct vop_close_args *ap) NCPVNDEBUG("name=%s,td=%p,c=%d\n",np->n_name,ap->a_td,np->opened); - if (vp->v_type == VDIR) return 0; /* nothing to do now */ error = 0; - if (np->opened == 0) { - return 0; - } + if (vp->v_type == VDIR) + goto done; + if (np->opened == 0) + goto done; error = nwfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1); if (np->opened == 0) { - return 0; + error = 0; /* huh? */ + goto done; } if (--np->opened == 0) { error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh, ap->a_td, proc0.p_ucred); } np->n_atime = 0; +done: + vop_stdclose(ap); return (error); } diff --git a/sys/vfs/portal/portal_vnops.c b/sys/vfs/portal/portal_vnops.c index ff1204c782..cf9baac175 100644 --- a/sys/vfs/portal/portal_vnops.c +++ b/sys/vfs/portal/portal_vnops.c @@ -36,7 +36,7 @@ * @(#)portal_vnops.c 8.14 (Berkeley) 5/21/95 * * $FreeBSD: src/sys/miscfs/portal/portal_vnops.c,v 1.38 1999/12/21 06:29:00 chris Exp $ - * $DragonFly: src/sys/vfs/portal/portal_vnops.c,v 1.25 2006/03/27 01:54:17 dillon Exp $ + * $DragonFly: src/sys/vfs/portal/portal_vnops.c,v 1.26 2006/04/01 20:46:53 dillon Exp $ */ /* @@ -229,7 +229,7 @@ portal_open(struct vop_open_args *ap) * Nothing to do when opening the root node. */ if (vp->v_flag & VROOT) - return (0); + return (vop_stdopen(ap)); /* * Can't be opened unless the caller is set up @@ -415,6 +415,7 @@ portal_open(struct vop_open_args *ap) * happen in vn_open. The whole concept is, well, hmmm. */ td->td_lwp->lwp_dupfd = fd; + vop_stdopen(ap); error = ENXIO; bad:; diff --git a/sys/vfs/procfs/procfs_vnops.c b/sys/vfs/procfs/procfs_vnops.c index 561374c9ae..e1b5438417 100644 --- a/sys/vfs/procfs/procfs_vnops.c +++ b/sys/vfs/procfs/procfs_vnops.c @@ -37,7 +37,7 @@ * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * * $FreeBSD: src/sys/miscfs/procfs/procfs_vnops.c,v 1.76.2.7 2002/01/22 17:22:59 nectar Exp $ - * $DragonFly: src/sys/vfs/procfs/procfs_vnops.c,v 1.28 2006/03/24 18:35:34 dillon Exp $ + * $DragonFly: src/sys/vfs/procfs/procfs_vnops.c,v 1.29 2006/04/01 20:46:53 dillon Exp $ */ /* @@ -161,13 +161,13 @@ procfs_open(struct vop_open_args *ap) if (ap->a_mode & FWRITE) pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); - return (0); + break; default: break; } - return (0); + return (vop_stdopen(ap)); } /* @@ -219,7 +219,7 @@ procfs_close(struct vop_close_args *ap) break; } - return (0); + return (vop_stdclose(ap)); } /* diff --git a/sys/vfs/smbfs/smbfs_vnops.c b/sys/vfs/smbfs/smbfs_vnops.c index d357844c69..d3a5072530 100644 --- a/sys/vfs/smbfs/smbfs_vnops.c +++ b/sys/vfs/smbfs/smbfs_vnops.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.2.2.8 2003/04/04 08:57:23 tjr Exp $ - * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.26 2006/03/24 18:35:34 dillon Exp $ + * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.27 2006/04/01 20:46:53 dillon Exp $ */ #include #include @@ -181,7 +181,7 @@ smbfs_open(struct vop_open_args *ap) if (np->n_opencount == 0) np->n_cached_cred = crhold(ap->a_cred); np->n_opencount++; - return 0; + return (vop_stdopen(ap)); } if (np->n_flag & NMODIFIED) { if ((error = smbfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1)) == EINTR) @@ -204,7 +204,7 @@ smbfs_open(struct vop_open_args *ap) } if (np->n_opencount) { np->n_opencount++; - return 0; + return (vop_stdopen(ap)); } accmode = SMB_AM_OPENREAD; if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) @@ -222,6 +222,8 @@ smbfs_open(struct vop_open_args *ap) np->n_opencount++; } smbfs_attr_cacheremove(vp); + if (error == 0) + vop_stdopen(ap); return error; } @@ -238,25 +240,25 @@ smbfs_closel(struct vop_close_args *ap) SMBVDEBUG("name=%s, pid=%d, c=%d\n",np->n_name, p->p_pid, np->n_opencount); smb_makescred(&scred, td, proc0.p_ucred); + error = 0; if (np->n_opencount == 0) { if (vp->v_type != VDIR) SMBERROR("Negative opencount\n"); - return 0; + goto done; } np->n_opencount--; if (vp->v_type == VDIR) { if (np->n_opencount) - return 0; + goto done; if (np->n_dirseq) { smbfs_findclose(np->n_dirseq, &scred); np->n_dirseq = NULL; } - error = 0; } else { error = smbfs_vinvalbuf(vp, V_SAVE, td, 1); if (np->n_opencount) - return error; + goto done; VOP_GETATTR(vp, &vattr, td); error = smbfs_smb_close(np->n_mount->sm_share, np->n_fid, &np->n_mtime, &scred); @@ -264,6 +266,8 @@ smbfs_closel(struct vop_close_args *ap) crfree(np->n_cached_cred); np->n_cached_cred = NULL; smbfs_attr_cacheremove(vp); +done: + vop_stdclose(ap); return error; } diff --git a/sys/vfs/specfs/spec_vnops.c b/sys/vfs/specfs/spec_vnops.c index f19ba424d0..9330c4c867 100644 --- a/sys/vfs/specfs/spec_vnops.c +++ b/sys/vfs/specfs/spec_vnops.c @@ -32,7 +32,7 @@ * * @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95 * $FreeBSD: src/sys/miscfs/specfs/spec_vnops.c,v 1.131.2.4 2001/02/26 04:23:20 jlemon Exp $ - * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.33 2006/03/29 18:45:03 dillon Exp $ + * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.34 2006/04/01 20:46:53 dillon Exp $ */ #include @@ -130,7 +130,7 @@ static void spec_getpages_iodone (struct bio *bio); * Open a special file. * * spec_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred, - * struct thread *a_td) + * struct file *a_fp, struct thread *a_td) */ /* ARGSUSED */ static int @@ -183,7 +183,6 @@ spec_open(struct vop_open_args *ap) /* * Prevent degenerate open/close sequences from nulling out rdev. */ - ++vp->v_opencount; dev = vp->v_rdev; KKASSERT(dev != NULL); @@ -287,9 +286,10 @@ spec_open(struct vop_open_args *ap) printf("spec_open: %s %d\n", dev->si_name, vp->v_opencount); done: if (error) { - KKASSERT(vp->v_opencount > 0); - if (--vp->v_opencount == 0) + if (vp->v_opencount == 0) v_release_rdev(vp); + } else { + vop_stdopen(ap); } return (error); } @@ -596,15 +596,16 @@ spec_close(struct vop_close_args *ap) * tracking occurs. */ if (dev) { - KKASSERT(vp->v_opencount > 0); + /*KKASSERT(vp->v_opencount > 0);*/ if (dev_ref_debug) { printf("spec_close: %s %d\n", dev->si_name, vp->v_opencount - 1); } - if (--vp->v_opencount == 0) + if (vp->v_opencount == 1) v_release_rdev(vp); release_dev(dev); } + vop_stdclose(ap); return(error); } diff --git a/sys/vfs/ufs/ffs_vfsops.c b/sys/vfs/ufs/ffs_vfsops.c index 83e5d1ed4a..e8d22254d1 100644 --- a/sys/vfs/ufs/ffs_vfsops.c +++ b/sys/vfs/ufs/ffs_vfsops.c @@ -32,7 +32,7 @@ * * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.10 2002/06/23 22:34:52 iedowse Exp $ - * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.37 2006/03/29 18:45:04 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.38 2006/04/01 20:46:54 dillon Exp $ */ #include "opt_quota.h" @@ -146,6 +146,7 @@ ffs_mount(struct mount *mp, /* mount struct pointer */ KKASSERT(td->td_proc); cred = td->td_proc->p_ucred; + devvp = NULL; error = 0; /* @@ -167,6 +168,7 @@ ffs_mount(struct mount *mp, /* mount struct pointer */ /* fs specific cleanup (if any)*/ goto error_1; } + devvp = rootvp; goto dostatfs; /* success*/ @@ -212,8 +214,9 @@ ffs_mount(struct mount *mp, /* mount struct pointer */ } ronly = 1; } - if (!error && (mp->mnt_flag & MNT_RELOAD)) + if (!error && (mp->mnt_flag & MNT_RELOAD)) { error = ffs_reload(mp, NULL, td); + } if (error) { goto error_1; } @@ -254,7 +257,6 @@ ffs_mount(struct mount *mp, /* mount struct pointer */ if (error) goto error_1; } - ronly = 0; } /* @@ -313,16 +315,17 @@ ffs_mount(struct mount *mp, /* mount struct pointer */ if (mp->mnt_flag & MNT_UPDATE) { /* - ******************** - * UPDATE - * If it's not the same vnode, or at least the same device - * then it's not correct. NOTE: devvp->v_rdev may be NULL - * since we haven't opened it, so we compare udev instead. - ******************** + * UPDATE - make sure the resolved vnode represents the same + * device. Note that devvp->v_rdev may be NULL since we + * haven't opened it, so compare udev instead. + * + * Our current open/writecount state is associated with + * um_devvp, so continue using um_devvp and throw away devvp. */ if (devvp != ump->um_devvp) { if (devvp->v_udev == ump->um_devvp->v_udev) { vrele(devvp); + devvp = ump->um_devvp; } else { printf("cannot update mount, udev does" " not match %08x vs %08x\n", @@ -390,6 +393,20 @@ success: fs->fs_ronly = ronly; fs->fs_clean = ronly && (fs->fs_flags & FS_UNCLEAN) == 0 ? 1 : 0; + + /* + * The device must be re-opened as appropriate or + * the device close at unmount time will panic. + */ + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + if (ronly) { + VOP_OPEN(devvp, FREAD, FSCRED, NULL, td); + VOP_CLOSE(devvp, FREAD|FWRITE, td); + } else { + VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, NULL, td); + VOP_CLOSE(devvp, FREAD, td); + } + VOP_UNLOCK(devvp, 0, td); ffs_sbupdate(ump, MNT_WAIT); } } diff --git a/sys/vfs/ufs/ufs_vnops.c b/sys/vfs/ufs/ufs_vnops.c index 5cb72a9383..72eed798be 100644 --- a/sys/vfs/ufs/ufs_vnops.c +++ b/sys/vfs/ufs/ufs_vnops.c @@ -37,7 +37,7 @@ * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $ - * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.37 2006/03/29 20:46:07 dillon Exp $ + * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.38 2006/04/01 20:46:54 dillon Exp $ */ #include "opt_quota.h" @@ -279,7 +279,7 @@ ufs_open(struct vop_open_args *ap) if (vp->v_type == VREG || vp->v_type == VDIR) vinitvmio(vp); - return (0); + return (vop_stdopen(ap)); } /* @@ -299,7 +299,7 @@ ufs_close(struct vop_close_args *ap) if (vp->v_usecount > 1) ufs_itimes(vp); - return (0); + return (vop_stdclose(ap)); } /* diff --git a/sys/vfs/union/union_subr.c b/sys/vfs/union/union_subr.c index b9e12b15cc..196805719e 100644 --- a/sys/vfs/union/union_subr.c +++ b/sys/vfs/union/union_subr.c @@ -36,7 +36,7 @@ * * @(#)union_subr.c 8.20 (Berkeley) 5/20/95 * $FreeBSD: src/sys/miscfs/union/union_subr.c,v 1.43.2.2 2001/12/25 01:44:45 dillon Exp $ - * $DragonFly: src/sys/vfs/union/union_subr.c,v 1.21 2006/03/29 18:45:06 dillon Exp $ + * $DragonFly: src/sys/vfs/union/union_subr.c,v 1.22 2006/04/01 20:46:54 dillon Exp $ */ #include @@ -1037,7 +1037,6 @@ union_vn_create(struct vnode **vpp, struct union_node *un, struct thread *td) vput(vp); return (error); } - vp->v_writecount++; *vpp = vp; return (0); } @@ -1046,8 +1045,6 @@ static int union_vn_close(struct vnode *vp, int fmode, struct ucred *cred, struct thread *td) { - if (fmode & FWRITE) - --vp->v_writecount; return (VOP_CLOSE(vp, fmode, td)); } -- 2.41.0