summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-08-27 01:31:12 +0000
committerkib <kib@FreeBSD.org>2013-08-27 01:31:12 +0000
commit9426e190e7d41951c9bafa9b1c8e6756607e475c (patch)
tree4a0ff072d95f46af4aeae2178801b816e141a0e3
parent5f8ac855694c0f2266dab9f85530b4a331b47ed2 (diff)
downloadFreeBSD-src-9426e190e7d41951c9bafa9b1c8e6756607e475c.zip
FreeBSD-src-9426e190e7d41951c9bafa9b1c8e6756607e475c.tar.gz
When allocating a pbuf for the cluster write, do not sleep waiting
for the available pbuf when passed vnode is backing md(4). Other i/o directed to the same md device might already hold pbufs, and then we could deadlock since only our progress can free a pbuf needed for wakeup. Obtained from: projects/vm6 Reminded and tested by: pho MFC after: 1 week
-rw-r--r--sys/kern/vfs_cluster.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index c98db81..9601082 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -837,7 +837,9 @@ cluster_wbuild(struct vnode *vp, long size, daddr_t start_lbn, int len,
(tbp->b_bcount != tbp->b_bufsize) ||
(tbp->b_bcount != size) ||
(len == 1) ||
- ((bp = getpbuf(&cluster_pbuf_freecnt)) == NULL)) {
+ ((bp = (vp->v_vflag & VV_MD) != 0 ?
+ trypbuf(&cluster_pbuf_freecnt) :
+ getpbuf(&cluster_pbuf_freecnt)) == NULL)) {
totalwritten += tbp->b_bufsize;
bawrite(tbp);
++start_lbn;
OpenPOWER on IntegriCloud