+ ubc_upl_abort(pl, 0);
+ return (EBUSY);
+ }
+ if (bp->nb_dirtyend > 0) {
+ /*
+ * if there's a dirty range in the buffer, check to
+ * see if it extends beyond the pageout region
+ *
+ * if the dirty region lies completely within the
+ * pageout region, we just invalidate the buffer
+ * because it's all being written out now anyway.
+ *
+ * if any of the dirty region lies outside the
+ * pageout region, we'll try to clip the dirty
+ * region to eliminate the portion that's being
+ * paged out. If that's not possible, because
+ * the dirty region extends before and after the
+ * pageout region, then we'll just return EBUSY.
+ */
+ off_t boff, start, end;
+ boff = NBOFF(bp);
+ start = off;
+ end = off + xsize;
+ /* clip end to EOF */
+ if (end > np->n_size)
+ end = np->n_size;
+ start -= boff;
+ end -= boff;
+ if ((bp->nb_dirtyoff < start) &&
+ (bp->nb_dirtyend > end)) {
+ /* not gonna be able to clip the dirty region */
+ FSDBG(323, vp, bp, 0xd00deebc, EBUSY);
+ if (!nofreeupl)
+ ubc_upl_abort(pl, 0);
+ return (EBUSY);
+ }
+ if ((bp->nb_dirtyoff < start) ||
+ (bp->nb_dirtyend > end)) {
+ /* clip dirty region, if necessary */
+ if (bp->nb_dirtyoff < start)
+ bp->nb_dirtyend = min(bp->nb_dirtyend, start);
+ if (bp->nb_dirtyend > end)
+ bp->nb_dirtyoff = max(bp->nb_dirtyoff, end);
+ FSDBG(323, bp, bp->nb_dirtyoff, bp->nb_dirtyend, 0xd00dee00);
+ /* we're leaving this block dirty */
+ continue;
+ }
+ }
+ nfs_buf_remfree(bp);
+ SET(bp->nb_flags, (NB_BUSY | NB_INVAL));
+ if (ISSET(bp->nb_flags, NB_NEEDCOMMIT)) {
+ CLR(bp->nb_flags, NB_NEEDCOMMIT);
+ np->n_needcommitcnt--;
+ CHECK_NEEDCOMMITCNT(np);