[Midnightbsd-cvs] src [8654] trunk/sys/ufs/ffs/ffs_softdep.c: fix a very old softdep bug.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sun Sep 25 16:02:53 EDT 2016
Revision: 8654
http://svnweb.midnightbsd.org/src/?rev=8654
Author: laffer1
Date: 2016-09-25 16:02:52 -0400 (Sun, 25 Sep 2016)
Log Message:
-----------
fix a very old softdep bug.
Modified Paths:
--------------
trunk/sys/ufs/ffs/ffs_softdep.c
Modified: trunk/sys/ufs/ffs/ffs_softdep.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_softdep.c 2016-09-25 20:02:16 UTC (rev 8653)
+++ trunk/sys/ufs/ffs/ffs_softdep.c 2016-09-25 20:02:52 UTC (rev 8654)
@@ -976,7 +976,7 @@
struct freework *, ufs_lbn_t, ufs2_daddr_t, int, int, int);
static int jwait(struct worklist *, int);
static struct inodedep *inodedep_lookup_ip(struct inode *);
-static int bmsafemap_rollbacks(struct bmsafemap *);
+static int bmsafemap_backgroundwrite(struct bmsafemap *, struct buf *);
static struct freefile *handle_bufwait(struct inodedep *, struct workhead *);
static void handle_jwork(struct workhead *);
static struct mkdir *setup_newdir(struct diradd *, ino_t, ino_t, struct buf *,
@@ -1800,7 +1800,7 @@
while ((wk = LIST_FIRST(&oldbp->b_dep)) != NULL) {
LIST_REMOVE(wk, wk_list);
if (wk->wk_type == D_BMSAFEMAP &&
- bmsafemap_rollbacks(WK_BMSAFEMAP(wk)))
+ bmsafemap_backgroundwrite(WK_BMSAFEMAP(wk), newbp))
dirty = 1;
if (wktail == 0)
LIST_INSERT_HEAD(&newbp->b_dep, wk, wk_list);
@@ -5178,9 +5178,15 @@
return (new);
/* Replace a jfreefrag with a jnewblk. */
if (new->wk_type == D_JFREEFRAG) {
+ if (WK_JNEWBLK(old)->jn_blkno != WK_JFREEFRAG(new)->fr_blkno)
+ panic("jnewblk_merge: blkno mismatch: %p, %p",
+ old, new);
cancel_jfreefrag(WK_JFREEFRAG(new));
return (old);
}
+ if (old->wk_type != D_JNEWBLK || new->wk_type != D_JNEWBLK)
+ panic("jnewblk_merge: Bad type: old %d new %d\n",
+ old->wk_type, new->wk_type);
/*
* Handle merging of two jnewblk records that describe
* different sets of fragments in the same block.
@@ -10507,7 +10513,7 @@
ino_t ino;
if (bmsafemap->sm_state & IOSTARTED)
- panic("initiate_write_bmsafemap: Already started\n");
+ return;
bmsafemap->sm_state |= IOSTARTED;
/*
* Clear any inode allocations which are pending journal writes.
@@ -10518,10 +10524,6 @@
inosused = cg_inosused(cgp);
LIST_FOREACH(jaddref, &bmsafemap->sm_jaddrefhd, ja_bmdeps) {
ino = jaddref->ja_ino % fs->fs_ipg;
- /*
- * If this is a background copy the inode may not
- * be marked used yet.
- */
if (isset(inosused, ino)) {
if ((jaddref->ja_mode & IFMT) == IFDIR)
cgp->cg_cs.cs_ndir--;
@@ -10530,7 +10532,7 @@
jaddref->ja_state &= ~ATTACHED;
jaddref->ja_state |= UNDONE;
stat_jaddref++;
- } else if ((bp->b_xflags & BX_BKGRDMARKER) == 0)
+ } else
panic("initiate_write_bmsafemap: inode %d "
"marked free", jaddref->ja_ino);
}
@@ -10545,9 +10547,8 @@
LIST_FOREACH(jnewblk, &bmsafemap->sm_jnewblkhd, jn_deps) {
if (jnewblk_rollback(jnewblk, fs, cgp, blksfree))
continue;
- if ((bp->b_xflags & BX_BKGRDMARKER) == 0)
- panic("initiate_write_bmsafemap: block %jd "
- "marked free", jnewblk->jn_blkno);
+ panic("initiate_write_bmsafemap: block %jd "
+ "marked free", jnewblk->jn_blkno);
}
}
/*
@@ -11282,12 +11283,24 @@
* only be called with lk and the buf lock on the cg held.
*/
static int
-bmsafemap_rollbacks(bmsafemap)
+bmsafemap_backgroundwrite(bmsafemap, bp)
struct bmsafemap *bmsafemap;
+ struct buf *bp;
{
+ int dirty;
- return (!LIST_EMPTY(&bmsafemap->sm_jaddrefhd) |
- !LIST_EMPTY(&bmsafemap->sm_jnewblkhd));
+ dirty = !LIST_EMPTY(&bmsafemap->sm_jaddrefhd) |
+ !LIST_EMPTY(&bmsafemap->sm_jnewblkhd);
+ /*
+ * If we're initiating a background write we need to process the
+ * rollbacks as they exist now, not as they exist when IO starts.
+ * No other consumers will look at the contents of the shadowed
+ * buf so this is safe to do here.
+ */
+ if (bp->b_xflags & BX_BKGRDMARKER)
+ initiate_write_bmsafemap(bmsafemap, bp);
+
+ return (dirty);
}
/*
More information about the Midnightbsd-cvs
mailing list