From 8ef495d8e0dcfec2c986e3f999a6f29bc106b587 Mon Sep 17 00:00:00 2001 From: kib Date: Mon, 19 Feb 2007 10:56:09 +0000 Subject: Remove union_dircheckp hook, it is not needed by new unionfs code anymore. As consequence, getdirentries() no longer needs to drop/reacquire directory vnode lock, that would allow it to be reclaimed in between. Reported and tested by: Peter Holm Approved by: rodrigc (unionfs) MFC after: 1 week --- sys/kern/vfs_syscalls.c | 98 +++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 65 deletions(-) (limited to 'sys/kern') diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 47a6372..07ba22e 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -87,8 +87,6 @@ static int setutimes(struct thread *td, struct vnode *, static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, struct thread *td); -int (*union_dircheckp)(struct thread *td, struct vnode **, struct file *); - /* * The module initialization routine for POSIX asynchronous I/O will * set this to the version of AIO that it implements. (Zero means @@ -3657,44 +3655,26 @@ unionread: } FREE(dirbuf, M_TEMP); } - VOP_UNLOCK(vp, 0, td); if (error) { + VOP_UNLOCK(vp, 0, td); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } - if (uap->count == auio.uio_resid) { - if (union_dircheckp) { - error = union_dircheckp(td, &vp, fp); - if (error == -1) { - VFS_UNLOCK_GIANT(vfslocked); - goto unionread; - } - if (error) { - VFS_UNLOCK_GIANT(vfslocked); - fdrop(fp, td); - return (error); - } - } - /* - * XXX We could delay dropping the lock above but - * union_dircheckp complicates things. - */ - vn_lock(vp, LK_EXCLUSIVE|LK_RETRY, td); - if ((vp->v_vflag & VV_ROOT) && - (vp->v_mount->mnt_flag & MNT_UNION)) { - struct vnode *tvp = vp; - vp = vp->v_mount->mnt_vnodecovered; - VREF(vp); - fp->f_vnode = vp; - fp->f_data = vp; - fp->f_offset = 0; - vput(tvp); - VFS_UNLOCK_GIANT(vfslocked); - goto unionread; - } - VOP_UNLOCK(vp, 0, td); + if (uap->count == auio.uio_resid && + (vp->v_vflag & VV_ROOT) && + (vp->v_mount->mnt_flag & MNT_UNION)) { + struct vnode *tvp = vp; + vp = vp->v_mount->mnt_vnodecovered; + VREF(vp); + fp->f_vnode = vp; + fp->f_data = vp; + fp->f_offset = 0; + vput(tvp); + VFS_UNLOCK_GIANT(vfslocked); + goto unionread; } + VOP_UNLOCK(vp, 0, td); VFS_UNLOCK_GIANT(vfslocked); error = copyout(&loff, uap->basep, sizeof(long)); fdrop(fp, td); @@ -3743,6 +3723,7 @@ getdirentries(td, uap) unionread: vfslocked = VFS_LOCK_GIANT(vp->v_mount); if (vp->v_type != VDIR) { + VFS_UNLOCK_GIANT(vfslocked); error = EINVAL; goto fail; } @@ -3765,44 +3746,31 @@ unionread: error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); fp->f_offset = auio.uio_offset; - VOP_UNLOCK(vp, 0, td); - if (error) - goto fail; - if (uap->count == auio.uio_resid) { - if (union_dircheckp) { - error = union_dircheckp(td, &vp, fp); - if (error == -1) { - VFS_UNLOCK_GIANT(vfslocked); - goto unionread; - } - if (error) - goto fail; - } - /* - * XXX We could delay dropping the lock above but - * union_dircheckp complicates things. - */ - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - if ((vp->v_vflag & VV_ROOT) && - (vp->v_mount->mnt_flag & MNT_UNION)) { - struct vnode *tvp = vp; - vp = vp->v_mount->mnt_vnodecovered; - VREF(vp); - fp->f_vnode = vp; - fp->f_data = vp; - fp->f_offset = 0; - vput(tvp); - VFS_UNLOCK_GIANT(vfslocked); - goto unionread; - } + if (error) { VOP_UNLOCK(vp, 0, td); + VFS_UNLOCK_GIANT(vfslocked); + goto fail; + } + if (uap->count == auio.uio_resid && + (vp->v_vflag & VV_ROOT) && + (vp->v_mount->mnt_flag & MNT_UNION)) { + struct vnode *tvp = vp; + vp = vp->v_mount->mnt_vnodecovered; + VREF(vp); + fp->f_vnode = vp; + fp->f_data = vp; + fp->f_offset = 0; + vput(tvp); + VFS_UNLOCK_GIANT(vfslocked); + goto unionread; } + VOP_UNLOCK(vp, 0, td); + VFS_UNLOCK_GIANT(vfslocked); if (uap->basep != NULL) { error = copyout(&loff, uap->basep, sizeof(long)); } td->td_retval[0] = uap->count - auio.uio_resid; fail: - VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } -- cgit v1.1