summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-02-19 10:56:09 +0000
committerkib <kib@FreeBSD.org>2007-02-19 10:56:09 +0000
commit8ef495d8e0dcfec2c986e3f999a6f29bc106b587 (patch)
treed1988ef169bf16d7e7598704c9b5bec78b04976d /sys/kern
parenta573a4d361e2b9bd31537d3357e90828da2496a0 (diff)
downloadFreeBSD-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.c98
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);
}
OpenPOWER on IntegriCloud