From 9569e81b84ed0c26711793ca8d937e6f7e27e6b3 Mon Sep 17 00:00:00 2001 From: jhb Date: Tue, 11 Jul 2006 20:52:08 +0000 Subject: - Add conditional VFS Giant locking to getdents_common() (linux ABIs), ibcs2_getdents(), ibcs2_read(), ogetdirentries(), svr4_sys_getdents(), and svr4_sys_getdents64() similar to that in getdirentries(). - Mark ibcs2_getdents(), ibcs2_read(), linux_getdents(), linux_getdents64(), linux_readdir(), ogetdirentries(), svr4_sys_getdents(), and svr4_sys_getdents64() MPSAFE. --- sys/kern/vfs_extattr.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'sys/kern/vfs_extattr.c') diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 4d6868c..e9f83f0 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -3569,7 +3569,7 @@ ogetdirentries(td, uap) struct iovec aiov, kiov; struct dirent *dp, *edp; caddr_t dirbuf; - int error, eofflag, readcnt; + int error, eofflag, readcnt, vfslocked; long loff; /* XXX arbitrary sanity limit on `count'. */ @@ -3583,7 +3583,9 @@ ogetdirentries(td, uap) } vp = fp->f_vnode; unionread: + vfslocked = VFS_LOCK_GIANT(vp->v_mount); if (vp->v_type != VDIR) { + VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (EINVAL); } @@ -3601,6 +3603,7 @@ unionread: error = mac_check_vnode_readdir(td->td_ucred, vp); if (error) { VOP_UNLOCK(vp, 0, td); + VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } @@ -3658,15 +3661,19 @@ unionread: } VOP_UNLOCK(vp, 0, td); if (error) { + 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) + if (error == -1) { + VFS_UNLOCK_GIANT(vfslocked); goto unionread; + } if (error) { + VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (error); } @@ -3685,10 +3692,12 @@ unionread: 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); td->td_retval[0] = uap->count - auio.uio_resid; -- cgit v1.1