summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_bio.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 6c018a9..6e3f2cd 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -130,6 +130,9 @@ SYSCTL_INT(_vfs, OID_AUTO, dirtybufferflushes, CTLFLAG_RW, &dirtybufferflushes,
static int altbufferflushes;
SYSCTL_INT(_vfs, OID_AUTO, altbufferflushes, CTLFLAG_RW, &altbufferflushes,
0, "Number of fsync flushes to limit dirty buffers");
+static int recursiveflushes;
+SYSCTL_INT(_vfs, OID_AUTO, recursiveflushes, CTLFLAG_RW, &recursiveflushes,
+ 0, "Number of flushes skipped due to being recursive");
static int numdirtybuffers;
SYSCTL_INT(_vfs, OID_AUTO, numdirtybuffers, CTLFLAG_RD, &numdirtybuffers, 0,
"Number of buffers that are dirty (has unwritten changes) at the moment");
@@ -1021,11 +1024,14 @@ bdwrite(struct buf * bp)
* If we have too many dirty buffers, don't create any more.
* If we are wildly over our limit, then force a complete
* cleanup. Otherwise, just keep the situation from getting
- * out of control.
+ * out of control. Note that we have to avoid a recursive
+ * disaster and not try to clean up after our own cleanup!
*/
vp = bp->b_vp;
VI_LOCK(vp);
- if (vp != NULL && vp->v_dirtybufcnt > dirtybufthresh + 10) {
+ if (td->td_proc->p_flag & P_COWINPROGRESS) {
+ recursiveflushes++;
+ } else if (vp != NULL && vp->v_dirtybufcnt > dirtybufthresh + 10) {
VI_UNLOCK(vp);
(void) VOP_FSYNC(vp, td->td_ucred, MNT_NOWAIT, td);
VI_LOCK(vp);
OpenPOWER on IntegriCloud