Index: FreeBSD/sys/kern/vfs_bio.c =================================================================== --- FreeBSD/sys/kern/vfs_bio.c +++ FreeBSD/sys/kern/vfs_bio.c @@ -2633,38 +2633,11 @@ BO_UNLOCK(bp->b_bufobj); bdirty(bp); } - if (bp->b_iocmd == BIO_WRITE && (bp->b_ioflags & BIO_ERROR) && - (bp->b_error != ENXIO || !LIST_EMPTY(&bp->b_dep)) && - !(bp->b_flags & B_INVAL)) { - /* - * Failed write, redirty. All errors except ENXIO (which - * means the device is gone) are treated as being - * transient. - * - * XXX Treating EIO as transient is not correct; the - * contract with the local storage device drivers is that - * they will only return EIO once the I/O is no longer - * retriable. Network I/O also respects this through the - * guarantees of TCP and/or the internal retries of NFS. - * ENOMEM might be transient, but we also have no way of - * knowing when its ok to retry/reschedule. In general, - * this entire case should be made obsolete through better - * error handling/recovery and resource scheduling. - * - * Do this also for buffers that failed with ENXIO, but have - * non-empty dependencies - the soft updates code might need - * to access the buffer to untangle them. - * - * Must clear BIO_ERROR to prevent pages from being scrapped. - */ - bp->b_ioflags &= ~BIO_ERROR; - bdirty(bp); - } else if ((bp->b_flags & (B_NOCACHE | B_INVAL)) || + if ((bp->b_flags & (B_NOCACHE | B_INVAL)) || (bp->b_ioflags & BIO_ERROR) || (bp->b_bufsize <= 0)) { /* - * Either a failed read I/O, or we were asked to free or not - * cache the buffer, or we failed to write to a device that's - * no longer present. + * Either a failed I/O, or we were asked to free or not + * cache the buffer. */ bp->b_flags |= B_INVAL; if (!LIST_EMPTY(&bp->b_dep))