예제 #1
0
static int
ffs_rawread_sync(struct vnode *vp)
{
	int error;

	/*
	 * Check for dirty mmap, pending writes and dirty buffers
	 */
	lwkt_gettoken(&vp->v_token);
	if (bio_track_active(&vp->v_track_write) ||
	    !RB_EMPTY(&vp->v_rbdirty_tree) ||
	    (vp->v_flag & VOBJDIRTY) != 0) {
		/* Attempt to msync mmap() regions to clean dirty mmap */ 
		if ((vp->v_flag & VOBJDIRTY) != 0) {
			struct vm_object *obj;
			if ((obj = vp->v_object) != NULL)
				vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
		}

		/* Wait for pending writes to complete */
		error = bio_track_wait(&vp->v_track_write, 0, 0);
		if (error != 0) {
			goto done;
		}
		/* Flush dirty buffers */
		if (!RB_EMPTY(&vp->v_rbdirty_tree)) {
			if ((error = VOP_FSYNC(vp, MNT_WAIT, 0)) != 0) {
				goto done;
			}
			if (bio_track_active(&vp->v_track_write) ||
			    !RB_EMPTY(&vp->v_rbdirty_tree))
				panic("ffs_rawread_sync: dirty bufs");
		}
	} else {
		error = 0;
	}
done:
	lwkt_reltoken(&vp->v_token);
	return error;
}
예제 #2
0
/*
 * Pass 2 - only run after pass 1 has completed or has given up
 *
 *	We ignore TMPFS, NFS, MFS, and SMBFS mounts in this pass.
 */
static int
shutdown_busycount2(struct buf *bp, void *info)
{
	struct vnode *vp;

	/*
	 * Ignore tmpfs and nfs mounts
	 */
	if ((vp = bp->b_vp) != NULL) {
		if (vp->v_tag == VT_TMPFS)
			return (0);
		if (vp->v_tag == VT_NFS)
			return (0);
		if (vp->v_tag == VT_MFS)
			return (0);
		if (vp->v_tag == VT_SMBFS)
			return (0);
	}

	/*
	 * Only count buffers stuck on I/O, ignore everything else
	 */
	if (((bp->b_flags & B_INVAL) == 0 && BUF_REFCNT(bp)) ||
	    ((bp->b_flags & (B_DELWRI|B_INVAL)) == B_DELWRI)) {
		/*
		 * Only count buffers undergoing write I/O
		 * on the related vnode.
		 */
		if (bp->b_vp == NULL || 
		    bio_track_active(&bp->b_vp->v_track_write) == 0) {
			return (0);
		}
#if defined(SHOW_BUSYBUFS) || defined(DIAGNOSTIC)
		kprintf(
	    "%p dev:?, flags:%08x, loffset:%jd, doffset:%jd\n",
		    bp, 
		    bp->b_flags, (intmax_t)bp->b_loffset,
		    (intmax_t)bp->b_bio2.bio_offset);
#endif
		return(1);
	}
	return(0);
}