Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/miscfs/genfs Protect genfs_do_putpages() against vnodes ...
details: https://anonhg.NetBSD.org/src/rev/3edca2d5ba37
branches: trunk
changeset: 351996:3edca2d5ba37
user: hannken <hannken%NetBSD.org@localhost>
date: Thu Mar 09 10:10:02 2017 +0000
description:
Protect genfs_do_putpages() against vnodes disappearing during
a forced mount update from read-write to read-only.
diffstat:
sys/miscfs/genfs/genfs_io.c | 72 +++++++++++++++++++++++++++-----------------
1 files changed, 44 insertions(+), 28 deletions(-)
diffs (129 lines):
diff -r 098848836892 -r 3edca2d5ba37 sys/miscfs/genfs/genfs_io.c
--- a/sys/miscfs/genfs/genfs_io.c Thu Mar 09 09:57:36 2017 +0000
+++ b/sys/miscfs/genfs/genfs_io.c Thu Mar 09 10:10:02 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: genfs_io.c,v 1.64 2017/03/01 10:47:26 hannken Exp $ */
+/* $NetBSD: genfs_io.c,v 1.65 2017/03/09 10:10:02 hannken Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.64 2017/03/01 10:47:26 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.65 2017/03/09 10:10:02 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -842,11 +842,11 @@
bool pagedaemon = curlwp == uvm.pagedaemon_lwp;
struct lwp * const l = curlwp ? curlwp : &lwp0;
struct genfs_node * const gp = VTOG(vp);
+ struct mount *trans_mp;
int flags;
int dirtygen;
bool modified;
- bool need_wapbl;
- bool has_trans;
+ bool holds_wapbl;
bool cleanall;
bool onworklst;
@@ -859,9 +859,8 @@
UVMHIST_LOG(ubchist, "vp %p pages %d off 0x%x len 0x%x",
vp, uobj->uo_npages, startoff, endoff - startoff);
- has_trans = false;
- need_wapbl = (!pagedaemon && vp->v_mount && vp->v_mount->mnt_wapbl &&
- (origflags & PGO_JOURNALLOCKED) == 0);
+ trans_mp = NULL;
+ holds_wapbl = false;
retry:
modified = false;
@@ -874,10 +873,10 @@
if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL)
vn_syncer_remove_from_worklist(vp);
}
- if (has_trans) {
- if (need_wapbl)
- WAPBL_END(vp->v_mount);
- fstrans_done(vp->v_mount);
+ if (trans_mp) {
+ if (holds_wapbl)
+ WAPBL_END(trans_mp);
+ fstrans_done(trans_mp);
}
mutex_exit(slock);
return (0);
@@ -887,24 +886,41 @@
* the vnode has pages, set up to process the request.
*/
- if (!has_trans && (flags & PGO_CLEANIT) != 0) {
- mutex_exit(slock);
+ if (trans_mp == NULL && (flags & PGO_CLEANIT) != 0) {
if (pagedaemon) {
- error = fstrans_start_nowait(vp->v_mount, FSTRANS_LAZY);
- if (error)
- return error;
- } else
- fstrans_start(vp->v_mount, FSTRANS_LAZY);
- if (need_wapbl) {
- error = WAPBL_BEGIN(vp->v_mount);
+ /* Pagedaemon must not sleep here. */
+ trans_mp = vp->v_mount;
+ error = fstrans_start_nowait(trans_mp, FSTRANS_LAZY);
if (error) {
- fstrans_done(vp->v_mount);
+ mutex_exit(slock);
return error;
}
+ } else {
+ /*
+ * Cannot use vdeadcheck() here as this operation
+ * usually gets used from VOP_RECLAIM(). Test for
+ * change of v_mount instead and retry on change.
+ */
+ mutex_exit(slock);
+ trans_mp = vp->v_mount;
+ fstrans_start(trans_mp, FSTRANS_LAZY);
+ if (vp->v_mount != trans_mp) {
+ fstrans_done(trans_mp);
+ trans_mp = NULL;
+ } else {
+ holds_wapbl = (trans_mp->mnt_wapbl &&
+ (origflags & PGO_JOURNALLOCKED) == 0);
+ if (holds_wapbl) {
+ error = WAPBL_BEGIN(trans_mp);
+ if (error) {
+ fstrans_done(trans_mp);
+ return error;
+ }
+ }
+ }
+ mutex_enter(slock);
+ goto retry;
}
- has_trans = true;
- mutex_enter(slock);
- goto retry;
}
error = 0;
@@ -1277,10 +1293,10 @@
goto retry;
}
- if (has_trans) {
- if (need_wapbl)
- WAPBL_END(vp->v_mount);
- fstrans_done(vp->v_mount);
+ if (trans_mp) {
+ if (holds_wapbl)
+ WAPBL_END(trans_mp);
+ fstrans_done(trans_mp);
}
return (error);
Home |
Main Index |
Thread Index |
Old Index