diff options
Diffstat (limited to 'sys/geom')
| -rw-r--r-- | sys/geom/geom_dev.c | 4 | ||||
| -rw-r--r-- | sys/geom/geom_disk.c | 10 | ||||
| -rw-r--r-- | sys/geom/geom_subr.c | 10 | ||||
| -rw-r--r-- | sys/geom/geom_vfs.c | 11 | 
4 files changed, 29 insertions, 6 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index db0bc77a752f..a723d06334a0 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -734,6 +734,10 @@ g_dev_done(struct bio *bp2)  		g_trace(G_T_BIO, "g_dev_done(%p) had error %d",  		    bp2, bp2->bio_error);  		bp->bio_flags |= BIO_ERROR; +		if ((bp2->bio_flags & BIO_EXTERR) != 0) { +			bp->bio_flags |= BIO_EXTERR; +			bp->bio_exterr = bp2->bio_exterr; +		}  	} else {  		if (bp->bio_cmd == BIO_READ)  			KNOTE_UNLOCKED(&sc->sc_selinfo.si_note, NOTE_READ); diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index 9dbf00371dba..b267130d1e0c 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -235,8 +235,14 @@ g_disk_done(struct bio *bp)  	bp2 = bp->bio_parent;  	binuptime(&now);  	mtx_lock(&sc->done_mtx); -	if (bp2->bio_error == 0) -		bp2->bio_error = bp->bio_error; +	if (bp2->bio_error == 0) { +		if ((bp->bio_flags & BIO_EXTERR) != 0) { +			bp2->bio_flags |= BIO_EXTERR; +			bp2->bio_exterr = bp->bio_exterr; +		} else { +			bp2->bio_error = bp->bio_error; +		} +	}  	bp2->bio_completed += bp->bio_length - bp->bio_resid;  	if (bp->bio_cmd == BIO_READ) diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index 2a6ce1ab6486..c70d55c6c321 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -1162,8 +1162,14 @@ g_std_done(struct bio *bp)  	struct bio *bp2;  	bp2 = bp->bio_parent; -	if (bp2->bio_error == 0) -		bp2->bio_error = bp->bio_error; +	if (bp2->bio_error == 0) { +		if ((bp->bio_flags & BIO_EXTERR) != 0) { +			bp2->bio_flags |= BIO_EXTERR; +			bp2->bio_exterr = bp->bio_exterr; +		} else { +			bp2->bio_error = bp->bio_error; +		} +	}  	bp2->bio_completed += bp->bio_completed;  	g_destroy_bio(bp);  	bp2->bio_inbed++; diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c index d9e9a6c82da1..122e2f6a02ec 100644 --- a/sys/geom/geom_vfs.c +++ b/sys/geom/geom_vfs.c @@ -26,9 +26,11 @@   * SUCH DAMAGE.   */ +#define	EXTERR_CATEGORY	EXTERR_CAT_GEOMVFS  #include <sys/param.h>  #include <sys/systm.h>  #include <sys/bio.h> +#include <sys/exterrvar.h>  #include <sys/kernel.h>  #include <sys/lock.h>  #include <sys/malloc.h> @@ -153,13 +155,16 @@ g_vfs_done(struct bio *bip)  			g_print_bio("g_vfs_done():", bip, "error = %d%s",  			    bip->bio_error,  			    bip->bio_error != ENXIO ? "" : -			    " supressing further ENXIO"); +			    " suppressing further ENXIO");  		}  	} -	bp->b_error = bip->bio_error;  	bp->b_ioflags = bip->bio_flags;  	if (bip->bio_error)  		bp->b_ioflags |= BIO_ERROR; +	if ((bp->b_ioflags & BIO_EXTERR) != 0) +		bp->b_exterr = bip->bio_exterr; +	else +		bp->b_error = bip->bio_error;  	bp->b_resid = bp->b_bcount - bip->bio_completed;  	g_destroy_bio(bip); @@ -195,6 +200,8 @@ g_vfs_strategy(struct bufobj *bo, struct buf *bp)  		mtx_unlock(&sc->sc_mtx);  		bp->b_error = ENXIO;  		bp->b_ioflags |= BIO_ERROR; +		EXTERROR_KE(&bp->b_exterr, ENXIO, +		    "orphaned or enxio active");  		bufdone(bp);  		return;  	}  | 
