diff options
author | phk <phk@FreeBSD.org> | 2003-05-09 21:25:28 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-05-09 21:25:28 +0000 |
commit | 8ece7cbc43e424a0a5c4071e251ccb97ccf64188 (patch) | |
tree | 736c96da992644bfe28faf2d1a98b0136a07e2d4 | |
parent | f31a9f552a0783f3a8fbaf57e00d360dd3a8f5b4 (diff) | |
download | FreeBSD-src-8ece7cbc43e424a0a5c4071e251ccb97ccf64188.zip FreeBSD-src-8ece7cbc43e424a0a5c4071e251ccb97ccf64188.tar.gz |
When a GEOM (/dev-)device is closed and we find that I/O requests are
still outstanding, give them a chance to complete.
If after 10 seconds we still find outstanding I/O requests, complete
the close with a console warning that the system is likely to panic
later on.
This is a workaround for umount -f not quite doing the right thing.
Approved by: re/scottl
-rw-r--r-- | sys/geom/geom_dev.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index b090d75..2c69f88 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -215,7 +215,7 @@ g_dev_close(dev_t dev, int flags, int fmt, struct thread *td) { struct g_geom *gp; struct g_consumer *cp; - int error, r, w, e; + int error, r, w, e, i; gp = dev->si_drv1; cp = dev->si_drv2; @@ -236,8 +236,20 @@ g_dev_close(dev_t dev, int flags, int fmt, struct thread *td) error = ENXIO; /* We were orphaned */ else error = g_access_rel(cp, r, w, e); - KASSERT((cp->acr || cp->acw) || (cp->nstart == cp->nend), - ("final g_dev_close() with outstanding bios")); + for (i = 0; i < 10 * hz;) { + if (cp->acr != 0 || cp->acw != 0) + break; + if (cp->nstart == cp->nend) + break; + tsleep(&i, PRIBIO, "gdevwclose", hz / 10); + i += hz / 10; + } + if (cp->acr == 0 && cp->acw == 0 && cp->nstart != cp->nend) { + printf("WARNING: Final close of geom_dev(%s) %s %s", + gp->name, + "still has outstanding I/O after 10 seconds.", + "Completing close anyway, panic may happen later."); + } g_topology_unlock(); PICKUP_GIANT(); g_waitidle(); |