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/compat/linux/linux_file.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'sys/compat/linux/linux_file.c') 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); -- cgit v1.1