summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-02-28 04:13:11 +0000
committerdillon <dillon@FreeBSD.org>2001-02-28 04:13:11 +0000
commitf1c1ec2babf0f143df9be6d307aedca0505ea5e5 (patch)
tree456c8ff2f2660f28d4c071e5678b5032aee74fa6
parent2ab101b2392bc752f7731c63d3753c60e65c4432 (diff)
downloadFreeBSD-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.c10
-rw-r--r--sys/kern/vfs_cluster.c6
-rw-r--r--sys/nfs/nfs_vnops.c8
-rw-r--r--sys/nfsclient/nfs_vnops.c8
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);
OpenPOWER on IntegriCloud