--- sys/kern/vfs_bio.c (revision 253339) +++ sys/kern/vfs_bio.c (working copy) @@ -1146,7 +1146,7 @@ if (bo->bo_dirty.bv_cnt > dirtybufthresh + 10) { (void) VOP_FSYNC(bp->b_vp, MNT_NOWAIT, curthread); altbufferflushes++; - } else if (bo->bo_dirty.bv_cnt > dirtybufthresh) { + } else if (bdflush_required(bo)) { BO_LOCK(bo); /* * Try to find a buffer to flush. @@ -1438,6 +1438,24 @@ } /* + * Flushing is deemed necessary if at least one of the following is true: + * - bo is hogging more than dirtybufthresh buffers (previous behavior) + * - numdirtybuffers exceeds dirtybufthresh + * - we are or act as bufdaemon (TDP_NORUNNINGBUF) + */ +int +bdflush_required(struct bufobj *bo) +{ + struct thread *td = curthread; + + KASSERT(bo != NULL, ("bdflush_required: NULL bo")); + + return ((bo->bo_dirty.bv_cnt > dirtybufthresh) || + (numdirtybuffers > dirtybufthresh) || + (td && (td->td_pflags & TDP_NORUNNINGBUF))); +} + +/* * brelse: * * Release a busy buffer and, if requested, free its resources. The --- sys/sys/buf.h (revision 253339) +++ sys/sys/buf.h (working copy) @@ -486,6 +486,7 @@ void bdata2bio(struct buf *bp, struct bio *bip); void bwillwrite(void); int buf_dirty_count_severe(void); +int bdflush_required(struct bufobj *bo); void bremfree(struct buf *); void bremfreef(struct buf *); /* XXX Force bremfree, only for nfs. */ int bread(struct vnode *, daddr_t, int, struct ucred *, struct buf **); --- sys/ufs/ffs/ffs_snapshot.c (revision 253339) +++ sys/ufs/ffs/ffs_snapshot.c (working copy) @@ -2161,7 +2161,7 @@ struct buf *nbp; int bp_bdskip; - if (bo->bo_dirty.bv_cnt <= dirtybufthresh) + if (!bdflush_required(bo)) return; td = curthread;