diff options
author | mckusick <mckusick@FreeBSD.org> | 2000-01-13 07:17:39 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2000-01-13 07:17:39 +0000 |
commit | 28d13b9ecffd9565cf62780e302268170cb6fb75 (patch) | |
tree | a68ae3e316c47e097e73934c4c9eea5c8c12f70a | |
parent | 93d3303e02611de4dd3ea6d2ed1b44f55f354b03 (diff) | |
download | FreeBSD-src-28d13b9ecffd9565cf62780e302268170cb6fb75.zip FreeBSD-src-28d13b9ecffd9565cf62780e302268170cb6fb75.tar.gz |
A panic occurs during an fsync when a dirty block associated with
a vnode has not been written (which would clear certain of its
dependencies). The problems arises because fsync with MNT_NOWAIT
no longer pushes all the dirty blocks associated with a vnode. It
skips those that require rollbacks, since they will just get instantly
dirty again. Such skipped blocks are marked so that they will not be
skipped a second time (otherwise circular dependencies would never
clear). So, we fsync twice to ensure that everything will be written
at least once.
-rw-r--r-- | sys/contrib/softupdates/ffs_softdep.c | 11 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 11 |
2 files changed, 14 insertions, 8 deletions
diff --git a/sys/contrib/softupdates/ffs_softdep.c b/sys/contrib/softupdates/ffs_softdep.c index 2759b0d..db63d71 100644 --- a/sys/contrib/softupdates/ffs_softdep.c +++ b/sys/contrib/softupdates/ffs_softdep.c @@ -52,7 +52,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)ffs_softdep.c 9.48 (McKusick) 1/10/00 + * from: @(#)ffs_softdep.c 9.49 (McKusick) 1/12/00 * $FreeBSD$ */ @@ -4227,10 +4227,13 @@ flush_pagedep_deps(pvp, mp, diraddhdp) * the full semantics of a synchronous VOP_FSYNC as * that may end up here again, once for each directory * level in the filesystem. Instead, we push the blocks - * and wait for them to clear. + * and wait for them to clear. We have to fsync twice + * because the first call may choose to defer blocks + * that still have dependencies, but deferral will + * happen at most once. */ - if ((error = - VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p))) { + if ((error=VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p)) || + (error=VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p))) { vput(vp); break; } diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 2759b0d..db63d71 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -52,7 +52,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)ffs_softdep.c 9.48 (McKusick) 1/10/00 + * from: @(#)ffs_softdep.c 9.49 (McKusick) 1/12/00 * $FreeBSD$ */ @@ -4227,10 +4227,13 @@ flush_pagedep_deps(pvp, mp, diraddhdp) * the full semantics of a synchronous VOP_FSYNC as * that may end up here again, once for each directory * level in the filesystem. Instead, we push the blocks - * and wait for them to clear. + * and wait for them to clear. We have to fsync twice + * because the first call may choose to defer blocks + * that still have dependencies, but deferral will + * happen at most once. */ - if ((error = - VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p))) { + if ((error=VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p)) || + (error=VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p))) { vput(vp); break; } |