summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2000-01-13 07:17:39 +0000
committermckusick <mckusick@FreeBSD.org>2000-01-13 07:17:39 +0000
commit28d13b9ecffd9565cf62780e302268170cb6fb75 (patch)
treea68ae3e316c47e097e73934c4c9eea5c8c12f70a
parent93d3303e02611de4dd3ea6d2ed1b44f55f354b03 (diff)
downloadFreeBSD-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.c11
-rw-r--r--sys/ufs/ffs/ffs_softdep.c11
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;
}
OpenPOWER on IntegriCloud