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/compat/linux/linux_file.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/compat/linux/linux_file.c')
-rw-r--r-- | sys/compat/linux/linux_file.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index ca6b7a6..cd50aa4 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -259,7 +259,17 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, struct l_dirent64 linux_dirent64; int buflen, error, eofflag, nbytes, justone; u_long *cookies = NULL, *cookiep; - int ncookies; + int ncookies, vfslocked; + + nbytes = args->count; + if (nbytes == 1) { + /* readdir(2) case. Always struct dirent. */ + if (is64bit) + return (EINVAL); + nbytes = sizeof(linux_dirent); + justone = 1; + } else + justone = 0; if ((error = getvnode(td->td_proc->p_fd, args->fd, &fp)) != 0) return (error); @@ -270,23 +280,13 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, } vp = fp->f_vnode; + vfslocked = VFS_LOCK_GIANT(vp->v_mount); if (vp->v_type != VDIR) { + VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (EINVAL); } - nbytes = args->count; - if (nbytes == 1) { - /* readdir(2) case. Always struct dirent. */ - if (is64bit) { - fdrop(fp, td); - return (EINVAL); - } - nbytes = sizeof(linux_dirent); - justone = 1; - } else - justone = 0; - off = fp->f_offset; buflen = max(LINUX_DIRBLKSIZ, nbytes); @@ -439,6 +439,7 @@ out: free(cookies, M_TEMP); VOP_UNLOCK(vp, 0, td); + VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); free(buf, M_TEMP); return (error); |