Module Name: src Committed By: manu Date: Wed Sep 21 15:36:33 UTC 2011
Modified Files: src/sys/fs/puffs: puffs_vfsops.c puffs_vnops.c Log Message: Make sure ioflush does not sleep in PUFFS code path, waiting for a mutex, a memory allocation, or a response from the filesystem. This avoids deadlocks in the following situations: 1) when memory is low: ioflush waits the fileystem, the fielsystem waits for memory 2) when the filesystem does not respond (e.g.: network outage ona distributed filesystem) To generate a diff of this commit: cvs rdiff -u -r1.96 -r1.97 src/sys/fs/puffs/puffs_vfsops.c cvs rdiff -u -r1.155 -r1.156 src/sys/fs/puffs/puffs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/fs/puffs/puffs_vfsops.c diff -u src/sys/fs/puffs/puffs_vfsops.c:1.96 src/sys/fs/puffs/puffs_vfsops.c:1.97 --- src/sys/fs/puffs/puffs_vfsops.c:1.96 Sun Jun 12 03:35:54 2011 +++ src/sys/fs/puffs/puffs_vfsops.c Wed Sep 21 15:36:33 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vfsops.c,v 1.96 2011/06/12 03:35:54 rmind Exp $ */ +/* $NetBSD: puffs_vfsops.c,v 1.97 2011/09/21 15:36:33 manu Exp $ */ /* * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.96 2011/06/12 03:35:54 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.97 2011/09/21 15:36:33 manu Exp $"); #include <sys/param.h> #include <sys/mount.h> @@ -513,9 +513,10 @@ { struct puffs_node *pn; struct vnode *vp, *mvp; - int error, rv; + int error, rv, fsyncwait; error = 0; + fsyncwait = (waitfor == MNT_WAIT) ? FSYNC_WAIT : 0; /* Allocate a marker vnode. */ if ((mvp = vnalloc(mp)) == NULL) @@ -574,7 +575,7 @@ pn->pn_stat |= PNODE_FAF; mutex_exit(vp->v_interlock); } - rv = VOP_FSYNC(vp, cred, waitfor, 0, 0); + rv = VOP_FSYNC(vp, cred, fsyncwait, 0, 0); if (waitfor == MNT_LAZY) { mutex_enter(vp->v_interlock); pn->pn_stat &= ~PNODE_FAF; Index: src/sys/fs/puffs/puffs_vnops.c diff -u src/sys/fs/puffs/puffs_vnops.c:1.155 src/sys/fs/puffs/puffs_vnops.c:1.156 --- src/sys/fs/puffs/puffs_vnops.c:1.155 Mon Aug 29 04:12:45 2011 +++ src/sys/fs/puffs/puffs_vnops.c Wed Sep 21 15:36:33 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.155 2011/08/29 04:12:45 manu Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.156 2011/09/21 15:36:33 manu Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.155 2011/08/29 04:12:45 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.156 2011/09/21 15:36:33 manu Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -50,6 +50,8 @@ #include <miscfs/genfs/genfs.h> #include <miscfs/specfs/specdev.h> +extern struct lwp *updateproc; + int puffs_vnop_lookup(void *); int puffs_vnop_create(void *); int puffs_vnop_access(void *); @@ -1357,7 +1359,21 @@ struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); int error, dofaf; - mutex_enter(&pn->pn_sizemtx); + /* + * Make sure ioflush does not get stuck in low + * memory conditions: it should not wait for the + * mutex. + */ + if (curlwp == updateproc) + KASSERT((ap->a_flags & FSYNC_WAIT) == 0); + + if (ap->a_flags & FSYNC_WAIT) { + mutex_enter(&pn->pn_sizemtx); + } else { + if (mutex_tryenter(&pn->pn_sizemtx) == 0) + return EDEADLK; + } + error = flushvncache(vp, ap->a_offlo, ap->a_offhi, (ap->a_flags & FSYNC_WAIT) == FSYNC_WAIT); if (error) @@ -2211,12 +2227,13 @@ struct buf *bp; size_t argsize; size_t tomove, moved; - int error, dofaf, dobiodone; + int error, dofaf, cansleep, dobiodone; pmp = MPTOPUFFSMP(vp->v_mount); bp = ap->a_bp; error = 0; dofaf = 0; + cansleep = 0; pn = VPTOPP(vp); park_rw = NULL; /* explicit */ dobiodone = 1; @@ -2264,8 +2281,9 @@ /* allocate transport structure */ tomove = PUFFS_TOMOVE(bp->b_bcount, pmp); argsize = sizeof(struct puffs_vnmsg_rw); + cansleep = (dofaf || (curlwp == updateproc)) ? 0 : 1; error = puffs_msgmem_alloc(argsize + tomove, &park_rw, - (void *)&rw_msg, dofaf ? 0 : 1); + (void *)&rw_msg, cansleep); if (error) goto out; RWARGS(rw_msg, 0, tomove, bp->b_blkno << DEV_BSHIFT, FSCRED);