summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_bio.c4
-rw-r--r--sys/kern/vfs_mount.c9
2 files changed, 11 insertions, 2 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 444c2be..b02d65b 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1170,6 +1170,7 @@ brelse(struct buf *bp)
if (bp->b_iocmd == BIO_WRITE &&
(bp->b_ioflags & BIO_ERROR) &&
+ bp->b_error != ENXIO &&
!(bp->b_flags & B_INVAL)) {
/*
* Failed write, redirty. Must clear BIO_ERROR to prevent
@@ -1177,6 +1178,9 @@ brelse(struct buf *bp)
* this case is not run and the next case is run to
* destroy the buffer. B_INVAL can occur if the buffer
* is outside the range supported by the underlying device.
+ * If the error is that the device went away (ENXIO), we
+ * shouldn't redirty the buffer either, but discard the
+ * data too.
*/
bp->b_ioflags &= ~BIO_ERROR;
bdirty(bp);
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index dfb46e2..6a615b1 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1286,8 +1286,13 @@ dounmount(mp, flags, td)
error = VFS_UNMOUNT(mp, flags, td);
}
vn_finished_write(mp);
- if (error) {
- /* Undo cdir/rdir and rootvnode changes made above. */
+ /*
+ * If we failed to flush the dirty blocks for this mount point,
+ * undo all the cdir/rdir and rootvnode changes we made above.
+ * Unless we failed to do so because the device is reporting that
+ * it doesn't exist anymore.
+ */
+ if (error && error != ENXIO) {
if ((flags & MNT_FORCE) &&
VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp, td) == 0) {
if (mp->mnt_vnodecovered != NULL)
OpenPOWER on IntegriCloud