Avoid the nbp lookup in the final loop iteration in flushbuflist().

The end of the loop must re-lookup the next buf since the bufobj lock
is dropped in the loop body. If the lookup fails, the loop is restarted.
This mechanism non-obviously also terminates the loop when the end of
the buf list is reached. Split up the two loops termination cases to
make the code a bit less fragile. No functional change intended.

Reviewed by:	kib
MFC after:	1 week
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D12730
This commit is contained in:
Mark Johnston 2017-10-20 14:56:13 +00:00
parent 62bf13cbf9
commit a3e8a25a52

View File

@ -1746,8 +1746,6 @@ flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo, int slpflag,
((flags & V_ALT) && (bp->b_xflags & BX_ALTDATA) == 0)) {
continue;
}
lblkno = 0;
xflags = 0;
if (nbp != NULL) {
lblkno = nbp->b_lblkno;
xflags = nbp->b_xflags & (BX_VNDIRTY | BX_VNCLEAN);
@ -1782,6 +1780,8 @@ flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo, int slpflag,
bp->b_flags &= ~B_ASYNC;
brelse(bp);
BO_LOCK(bo);
if (nbp == NULL)
break;
nbp = gbincore(bo, lblkno);
if (nbp == NULL || (nbp->b_xflags & (BX_VNDIRTY | BX_VNCLEAN))
!= xflags)