diff options
author | jhb <jhb@FreeBSD.org> | 2006-07-11 20:52:08 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2006-07-11 20:52:08 +0000 |
commit | 9569e81b84ed0c26711793ca8d937e6f7e27e6b3 (patch) | |
tree | 94d4dd9191eef2b3777b8242fb56fc1d507c2645 /sys/kern/vfs_extattr.c | |
parent | 05bff8fb74812f6551cd13f62046027a7d91e606 (diff) | |
download | FreeBSD-src-9569e81b84ed0c26711793ca8d937e6f7e27e6b3.zip FreeBSD-src-9569e81b84ed0c26711793ca8d937e6f7e27e6b3.tar.gz |
- 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.
Diffstat (limited to 'sys/kern/vfs_extattr.c')
-rw-r--r-- | sys/kern/vfs_extattr.c | 13 |
1 files changed, 11 insertions, 2 deletions
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; |