diff options
author | kib <kib@FreeBSD.org> | 2007-02-19 10:56:09 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2007-02-19 10:56:09 +0000 |
commit | 8ef495d8e0dcfec2c986e3f999a6f29bc106b587 (patch) | |
tree | d1988ef169bf16d7e7598704c9b5bec78b04976d /sys/kern | |
parent | a573a4d361e2b9bd31537d3357e90828da2496a0 (diff) | |
download | FreeBSD-src-8ef495d8e0dcfec2c986e3f999a6f29bc106b587.zip FreeBSD-src-8ef495d8e0dcfec2c986e3f999a6f29bc106b587.tar.gz |
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
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_syscalls.c | 98 |
1 files changed, 33 insertions, 65 deletions
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); } |