summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux/linux_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linux/linux_file.c')
-rw-r--r--sys/compat/linux/linux_file.c27
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);
OpenPOWER on IntegriCloud