summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2006-11-07 12:29:46 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2006-11-07 12:29:46 +0000
commite90e9c3373241b8d500165743322d06e40e4e6e6 (patch)
treed1cd168f1ac3867c9543ab5da43de27886046980 /sys
parentc37717c54482d0b8ec16387e091cc61a9154c465 (diff)
a fix derived from freebsd 1.196 revision.
due to ffs_sync not be able to sync some buffers here is another instance of softdep code that must ensure proper syncing. try harder to flush MKDIR_BODY dependancy if such still exists during pagedep flush (that is by syncing first block of the dir). pedro@ ok
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 552d1e6b9cd..bef37a6a1c3 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_softdep.c,v 1.78 2006/10/20 13:02:55 mickey Exp $ */
+/* $OpenBSD: ffs_softdep.c,v 1.79 2006/11/07 12:29:45 mickey Exp $ */
/*
* Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
@@ -5085,6 +5085,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
struct diraddhd *diraddhdp;
{
struct proc *p = CURPROC; /* XXX */
+ struct worklist *wk;
struct inodedep *inodedep;
struct ufsmount *ump;
struct diradd *dap;
@@ -5139,7 +5140,34 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
break;
}
drain_output(vp, 0);
+ /*
+ * If first block is still dirty with a D_MKDIR
+ * dependency then it needs to be written now.
+ */
+ for (;;) {
+ error = 0;
+ ACQUIRE_LOCK(&lk);
+ bp = incore(vp, 0);
+ if (bp == NULL) {
+ FREE_LOCK(&lk);
+ break;
+ }
+ LIST_FOREACH(wk, &bp->b_dep, wk_list)
+ if (wk->wk_type == D_MKDIR)
+ break;
+ if (wk) {
+ gotit = getdirtybuf(bp, MNT_WAIT);
+ FREE_LOCK(&lk);
+ if (gotit && (error = bwrite(bp)) != 0)
+ break;
+ } else
+ FREE_LOCK(&lk);
+ break;
+ }
vput(vp);
+ /* Flushing of first block failed */
+ if (error)
+ break;
ACQUIRE_LOCK(&lk);
/*
* If that cleared dependencies, go on to next.