PR kern/38141 lookup/vfs_busy acquire rwlock recursively

- sys_sync: acquire a write lock on the mount since the operation modifies
  the mount structure.
- sys_fchdir: use vfs_trybusy(). If an unmount is in progress, just fail it.
This commit is contained in:
ad 2008-05-06 12:54:25 +00:00
parent dab1996c70
commit 39d40db63f
1 changed files with 6 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_syscalls.c,v 1.355 2008/05/06 12:51:22 ad Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.356 2008/05/06 12:54:25 ad Exp $ */
/*- /*-
* Copyright (c) 2008 The NetBSD Foundation, Inc. * Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -63,7 +63,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.355 2008/05/06 12:51:22 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.356 2008/05/06 12:54:25 ad Exp $");
#include "opt_compat_netbsd.h" #include "opt_compat_netbsd.h"
#include "opt_compat_43.h" #include "opt_compat_43.h"
@ -821,7 +821,7 @@ sys_sync(struct lwp *l, const void *v, register_t *retval)
mutex_enter(&mountlist_lock); mutex_enter(&mountlist_lock);
for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist; for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
mp = nmp) { mp = nmp) {
if (vfs_trybusy(mp, RW_READER, &nmp)) { if (vfs_trybusy(mp, RW_WRITER, &nmp)) {
continue; continue;
} }
if ((mp->mnt_flag & MNT_RDONLY) == 0) { if ((mp->mnt_flag & MNT_RDONLY) == 0) {
@ -1131,9 +1131,10 @@ sys_fchdir(struct lwp *l, const struct sys_fchdir_args *uap, register_t *retval)
goto out; goto out;
} }
while ((mp = vp->v_mountedhere) != NULL) { while ((mp = vp->v_mountedhere) != NULL) {
if (vfs_busy(mp, RW_READER)) error = vfs_trybusy(mp, RW_READER, NULL);
continue;
vput(vp); vput(vp);
if (error != 0) {
goto out;
error = VFS_ROOT(mp, &tdp); error = VFS_ROOT(mp, &tdp);
vfs_unbusy(mp, false, NULL); vfs_unbusy(mp, false, NULL);
if (error) if (error)