Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_bio.c
Show First 20 Lines • Show All 2,170 Lines • ▼ Show 20 Lines | |||||
#endif /* RACCT */ | #endif /* RACCT */ | ||||
td->td_ru.ru_inblock++; | td->td_ru.ru_inblock++; | ||||
bp->b_iocmd = BIO_READ; | bp->b_iocmd = BIO_READ; | ||||
bp->b_flags &= ~B_INVAL; | bp->b_flags &= ~B_INVAL; | ||||
if ((flags & GB_CKHASH) != 0) { | if ((flags & GB_CKHASH) != 0) { | ||||
bp->b_flags |= B_CKHASH; | bp->b_flags |= B_CKHASH; | ||||
bp->b_ckhashcalc = ckhashfunc; | bp->b_ckhashcalc = ckhashfunc; | ||||
} | } | ||||
if ((flags & GB_CVTENXIO) != 0) | |||||
bp->b_xflags |= BX_CVTENXIO; | |||||
bp->b_ioflags &= ~BIO_ERROR; | bp->b_ioflags &= ~BIO_ERROR; | ||||
if (bp->b_rcred == NOCRED && cred != NOCRED) | if (bp->b_rcred == NOCRED && cred != NOCRED) | ||||
bp->b_rcred = crhold(cred); | bp->b_rcred = crhold(cred); | ||||
vfs_busy_pages(bp, 0); | vfs_busy_pages(bp, 0); | ||||
bp->b_iooffset = dbtob(bp->b_blkno); | bp->b_iooffset = dbtob(bp->b_blkno); | ||||
bstrategy(bp); | bstrategy(bp); | ||||
++readwait; | ++readwait; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 581 Lines • ▼ Show 20 Lines | /* remaining buffers */ | ||||
qindex = QUEUE_DIRTY; | qindex = QUEUE_DIRTY; | ||||
else | else | ||||
qindex = QUEUE_CLEAN; | qindex = QUEUE_CLEAN; | ||||
if ((bp->b_flags & B_DELWRI) == 0 && (bp->b_xflags & BX_VNDIRTY)) | if ((bp->b_flags & B_DELWRI) == 0 && (bp->b_xflags & BX_VNDIRTY)) | ||||
panic("brelse: not dirty"); | panic("brelse: not dirty"); | ||||
bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_RELBUF | B_DIRECT); | bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_RELBUF | B_DIRECT); | ||||
bp->b_xflags &= ~(BX_CVTENXIO); | |||||
kib: Is it reasonable to clean BX_CVTENXIO if the buffer still has the valid content ? If the… | |||||
Done Inline ActionsThe purpose of BX_CVTENXIO is to prevent reading potentially stale data back from disk after we have gotten EIO trying to write it (since we don't know what is actually on disk after a write reports an error). If the latest version of the data for a buffer is still in memory then it's fine to keep using it since we know it is consistent with anything else still in memory. chs: The purpose of BX_CVTENXIO is to prevent reading potentially stale data back from disk after we… | |||||
/* binsfree unlocks bp. */ | /* binsfree unlocks bp. */ | ||||
binsfree(bp, qindex); | binsfree(bp, qindex); | ||||
} | } | ||||
/* | /* | ||||
* Release a buffer back to the appropriate queue but do not try to free | * Release a buffer back to the appropriate queue but do not try to free | ||||
* it. The buffer is expected to be used again soon. | * it. The buffer is expected to be used again soon. | ||||
* | * | ||||
Show All 15 Lines | bqrelse(struct buf *bp) | ||||
qindex = QUEUE_NONE; | qindex = QUEUE_NONE; | ||||
if (BUF_LOCKRECURSED(bp)) { | if (BUF_LOCKRECURSED(bp)) { | ||||
/* do not release to free list */ | /* do not release to free list */ | ||||
BUF_UNLOCK(bp); | BUF_UNLOCK(bp); | ||||
return; | return; | ||||
} | } | ||||
bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF); | bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF); | ||||
bp->b_xflags &= ~(BX_CVTENXIO); | |||||
if (bp->b_flags & B_MANAGED) { | if (bp->b_flags & B_MANAGED) { | ||||
if (bp->b_flags & B_REMFREE) | if (bp->b_flags & B_REMFREE) | ||||
bremfreef(bp); | bremfreef(bp); | ||||
goto out; | goto out; | ||||
} | } | ||||
/* buffers with stale but valid contents */ | /* buffers with stale but valid contents */ | ||||
▲ Show 20 Lines • Show All 2,640 Lines • Show Last 20 Lines |
Is it reasonable to clean BX_CVTENXIO if the buffer still has the valid content ? If the buffer is revived by gbincore(), then should we still operate as if the flag is set ?