summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-07-11 20:52:08 +0000
committerjhb <jhb@FreeBSD.org>2006-07-11 20:52:08 +0000
commit9569e81b84ed0c26711793ca8d937e6f7e27e6b3 (patch)
tree94d4dd9191eef2b3777b8242fb56fc1d507c2645 /sys/kern
parent05bff8fb74812f6551cd13f62046027a7d91e606 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/kern/syscalls.master2
-rw-r--r--sys/kern/vfs_extattr.c13
-rw-r--r--sys/kern/vfs_syscalls.c13
3 files changed, 23 insertions, 5 deletions
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index ba53824..ecd8c8f 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -304,7 +304,7 @@
154 AUE_NULL UNIMPL nosys
; 155 is initialized by the NFS code, if present.
155 AUE_NFSSVC MNOIMPL { int nfssvc(int flag, caddr_t argp); }
-156 AUE_GETDIRENTRIES COMPAT { int getdirentries(int fd, char *buf, \
+156 AUE_GETDIRENTRIES MCOMPAT { int getdirentries(int fd, char *buf, \
u_int count, long *basep); }
157 AUE_STATFS MCOMPAT4 { int statfs(char *path, \
struct ostatfs *buf); }
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;
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 4d6868c..e9f83f0 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.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;
OpenPOWER on IntegriCloud