diff options
author | dillon <dillon@FreeBSD.org> | 2001-02-28 04:13:11 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2001-02-28 04:13:11 +0000 |
commit | f1c1ec2babf0f143df9be6d307aedca0505ea5e5 (patch) | |
tree | 456c8ff2f2660f28d4c071e5678b5032aee74fa6 | |
parent | 2ab101b2392bc752f7731c63d3753c60e65c4432 (diff) | |
download | FreeBSD-src-f1c1ec2babf0f143df9be6d307aedca0505ea5e5.zip FreeBSD-src-f1c1ec2babf0f143df9be6d307aedca0505ea5e5.tar.gz |
Fix lockup for loopback NFS mounts. The pipelined I/O limitations could be
hit on the client side and prevent the server side from retiring writes.
Pipeline operations turned off for all READs (no big loss since reads are
usually synchronous) and for NFS writes, and left on for the default bwrite().
(MFC expected prior to 4.3 freeze)
Testing by: mjacob, dillon
-rw-r--r-- | sys/kern/vfs_bio.c | 10 | ||||
-rw-r--r-- | sys/kern/vfs_cluster.c | 6 | ||||
-rw-r--r-- | sys/nfs/nfs_vnops.c | 8 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 8 |
4 files changed, 23 insertions, 9 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index c124559..8017e19 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -695,6 +695,13 @@ bwrite(struct buf * bp) bp->b_vp->v_numoutput++; vfs_busy_pages(bp, 1); + + /* + * Normal bwrites pipeline writes + */ + bp->b_runningbufspace = bp->b_bufsize; + runningbufspace += bp->b_runningbufspace; + if (curproc != PCPU_GET(idleproc)) curproc->p_stats->p_ru.ru_oublock++; splx(s); @@ -2936,9 +2943,6 @@ vfs_busy_pages(struct buf * bp, int clear_modify) { int i, bogus; - bp->b_runningbufspace = bp->b_bufsize; - runningbufspace += bp->b_runningbufspace; - if (bp->b_flags & B_VMIO) { struct vnode *vp = bp->b_vp; vm_object_t obj; diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index 1c119b4..de6b67e 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -249,9 +249,6 @@ single_block_read: #endif if ((bp->b_flags & B_CLUSTER) == 0) { vfs_busy_pages(bp, 0); - } else { - bp->b_runningbufspace = bp->b_bufsize; - runningbufspace += bp->b_runningbufspace; } bp->b_flags &= ~B_INVAL; bp->b_ioflags &= ~BIO_ERROR; @@ -289,9 +286,6 @@ single_block_read: if ((rbp->b_flags & B_CLUSTER) == 0) { vfs_busy_pages(rbp, 0); - } else { - rbp->b_runningbufspace = rbp->b_bufsize; - runningbufspace += rbp->b_runningbufspace; } rbp->b_flags &= ~B_INVAL; rbp->b_ioflags &= ~BIO_ERROR; diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index 37b977c..d889cf4 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -2869,6 +2869,9 @@ again: * NOTE: we are not clearing B_DONE here, so we have * to do it later on in this routine if we intend to * initiate I/O on the bp. + * + * Note: to avoid loopback deadlocks, we do not + * assign b_runningbufspace. */ if (wcred == NULL) wcred = bp->b_wcred; @@ -3142,7 +3145,12 @@ nfs_writebp(bp, force, procp) curproc->p_stats->p_ru.ru_oublock++; splx(s); + /* + * Note: to avoid loopback deadlocks, we do not + * assign b_runningbufspace. + */ vfs_busy_pages(bp, 1); + if (force) bp->b_flags |= B_WRITEINPROG; BUF_KERNPROC(bp); diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 37b977c..d889cf4 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -2869,6 +2869,9 @@ again: * NOTE: we are not clearing B_DONE here, so we have * to do it later on in this routine if we intend to * initiate I/O on the bp. + * + * Note: to avoid loopback deadlocks, we do not + * assign b_runningbufspace. */ if (wcred == NULL) wcred = bp->b_wcred; @@ -3142,7 +3145,12 @@ nfs_writebp(bp, force, procp) curproc->p_stats->p_ru.ru_oublock++; splx(s); + /* + * Note: to avoid loopback deadlocks, we do not + * assign b_runningbufspace. + */ vfs_busy_pages(bp, 1); + if (force) bp->b_flags |= B_WRITEINPROG; BUF_KERNPROC(bp); |