summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/ufs/ffs/ffs_softdep.c253
1 files changed, 191 insertions, 62 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index cbd426c..fbc4b2c 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -254,12 +254,15 @@ static void
acquire_lock(lk)
struct lockit *lk;
{
+ pid_t holder;
if (lk->lkt_held != -1) {
- if (lk->lkt_held == CURPROC->p_pid)
+ holder = lk->lkt_held;
+ FREE_LOCK(lk);
+ if (holder == CURPROC->p_pid)
panic("softdep_lock: locking against myself");
else
- panic("softdep_lock: lock held by %d", lk->lkt_held);
+ panic("softdep_lock: lock held by %d", holder);
}
lk->lkt_spl = splbio();
lk->lkt_held = CURPROC->p_pid;
@@ -281,13 +284,16 @@ static void
acquire_lock_interlocked(lk)
struct lockit *lk;
{
+ pid_t holder;
if (lk->lkt_held != -1) {
- if (lk->lkt_held == CURPROC->p_pid)
+ holder = lk->lkt_held;
+ FREE_LOCK(lk);
+ if (holder == CURPROC->p_pid)
panic("softdep_lock_interlocked: locking against self");
else
panic("softdep_lock_interlocked: lock held by %d",
- lk->lkt_held);
+ holder);
}
lk->lkt_held = CURPROC->p_pid;
lockcnt++;
@@ -359,8 +365,11 @@ sema_release(semap)
struct sema *semap;
{
- if (semap->value <= 0 || semap->holder != CURPROC->p_pid)
+ if (semap->value <= 0 || semap->holder != CURPROC->p_pid) {
+ if (lk.lkt_held != -1)
+ FREE_LOCK(&lk);
panic("sema_release: not held");
+ }
if (--semap->value > 0) {
semap->value = 0;
wakeup(semap);
@@ -400,8 +409,10 @@ worklist_insert(head, item)
if (lk.lkt_held == -1)
panic("worklist_insert: lock not held");
- if (item->wk_state & ONWORKLIST)
+ if (item->wk_state & ONWORKLIST) {
+ FREE_LOCK(&lk);
panic("worklist_insert: already on list");
+ }
item->wk_state |= ONWORKLIST;
LIST_INSERT_HEAD(head, item, wk_list);
}
@@ -413,8 +424,10 @@ worklist_remove(item)
if (lk.lkt_held == -1)
panic("worklist_remove: lock not held");
- if ((item->wk_state & ONWORKLIST) == 0)
+ if ((item->wk_state & ONWORKLIST) == 0) {
+ FREE_LOCK(&lk);
panic("worklist_remove: not on list");
+ }
item->wk_state &= ~ONWORKLIST;
LIST_REMOVE(item, wk_list);
}
@@ -425,10 +438,16 @@ workitem_free(item, type)
int type;
{
- if (item->wk_state & ONWORKLIST)
+ if (item->wk_state & ONWORKLIST) {
+ if (lk.lkt_held != -1)
+ FREE_LOCK(&lk);
panic("workitem_free: still on list");
- if (item->wk_type != type)
+ }
+ if (item->wk_type != type) {
+ if (lk.lkt_held != -1)
+ FREE_LOCK(&lk);
panic("workitem_free: type mismatch");
+ }
FREE(item, DtoM(type));
}
#endif /* DEBUG */
@@ -493,8 +512,11 @@ add_to_worklist(wk)
{
static struct worklist *worklist_tail;
- if (wk->wk_state & ONWORKLIST)
+ if (wk->wk_state & ONWORKLIST) {
+ if (lk.lkt_held != -1)
+ FREE_LOCK(&lk);
panic("add_to_worklist: already on list");
+ }
wk->wk_state |= ONWORKLIST;
if (LIST_FIRST(&softdep_workitem_pending) == NULL)
LIST_INSERT_HEAD(&softdep_workitem_pending, wk, wk_list);
@@ -1146,8 +1168,10 @@ softdep_setup_inomapdep(bp, ip, newinum)
* the cylinder group map from which it was allocated.
*/
ACQUIRE_LOCK(&lk);
- if ((inodedep_lookup(ip->i_fs, newinum, DEPALLOC | NODELAY, &inodedep)))
+ if ((inodedep_lookup(ip->i_fs, newinum, DEPALLOC|NODELAY, &inodedep))) {
+ FREE_LOCK(&lk);
panic("softdep_setup_inomapdep: found inode");
+ }
inodedep->id_buf = bp;
inodedep->id_state &= ~DEPCOMPLETE;
bmsafemap = bmsafemap_lookup(bp);
@@ -1298,8 +1322,10 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
WORKLIST_INSERT(&bp->b_dep, &adp->ad_list);
if (lbn >= NDADDR) {
/* allocating an indirect block */
- if (oldblkno != 0)
+ if (oldblkno != 0) {
+ FREE_LOCK(&lk);
panic("softdep_setup_allocdirect: non-zero indir");
+ }
} else {
/*
* Allocating a direct block.
@@ -1338,8 +1364,10 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
if (oldadp->ad_lbn >= lbn)
break;
}
- if (oldadp == NULL)
+ if (oldadp == NULL) {
+ FREE_LOCK(&lk);
panic("softdep_setup_allocdirect: lost entry");
+ }
/* insert in middle of list */
TAILQ_INSERT_BEFORE(oldadp, adp, ad_next);
if (oldadp->ad_lbn == lbn)
@@ -1365,10 +1393,12 @@ allocdirect_merge(adphead, newadp, oldadp)
#endif
if (newadp->ad_oldblkno != oldadp->ad_newblkno ||
newadp->ad_oldsize != oldadp->ad_newsize ||
- newadp->ad_lbn >= NDADDR)
+ newadp->ad_lbn >= NDADDR) {
+ FREE_LOCK(&lk);
panic("allocdirect_check: old %d != new %d || lbn %ld >= %d",
newadp->ad_oldblkno, oldadp->ad_newblkno, newadp->ad_lbn,
NDADDR);
+ }
newadp->ad_oldblkno = oldadp->ad_oldblkno;
newadp->ad_oldsize = oldadp->ad_oldsize;
/*
@@ -1610,8 +1640,10 @@ setup_allocindir_phase2(bp, ip, aip)
break;
freefrag = NULL;
if (oldaip != NULL) {
- if (oldaip->ai_newblkno != aip->ai_oldblkno)
+ if (oldaip->ai_newblkno != aip->ai_oldblkno) {
+ FREE_LOCK(&lk);
panic("setup_allocindir_phase2: blkno");
+ }
aip->ai_oldblkno = oldaip->ai_oldblkno;
freefrag = aip->ai_freefrag;
aip->ai_freefrag = oldaip->ai_freefrag;
@@ -1730,8 +1762,10 @@ softdep_setup_freeblocks(ip, length)
*/
ACQUIRE_LOCK(&lk);
(void) inodedep_lookup(fs, ip->i_number, DEPALLOC, &inodedep);
- if ((inodedep->id_state & IOSTARTED) != 0)
+ if ((inodedep->id_state & IOSTARTED) != 0) {
+ FREE_LOCK(&lk);
panic("softdep_setup_freeblocks: inode busy");
+ }
/*
* Add the freeblks structure to the list of operations that
* must await the zero'ed inode being written to disk. If we
@@ -1825,14 +1859,18 @@ deallocate_dependencies(bp, inodedep)
* copy, allowing the safe copy to be freed and holding
* on to the real copy for later use in indir_trunc.
*/
- if (indirdep->ir_state & GOINGAWAY)
+ if (indirdep->ir_state & GOINGAWAY) {
+ FREE_LOCK(&lk);
panic("deallocate_dependencies: already gone");
+ }
indirdep->ir_state |= GOINGAWAY;
while ((aip = LIST_FIRST(&indirdep->ir_deplisthd)) != 0)
free_allocindir(aip, inodedep);
if (bp->b_lblkno >= 0 ||
- bp->b_blkno != indirdep->ir_savebp->b_lblkno)
+ bp->b_blkno != indirdep->ir_savebp->b_lblkno) {
+ FREE_LOCK(&lk);
panic("deallocate_dependencies: not indir");
+ }
bcopy(bp->b_data, indirdep->ir_savebp->b_data,
bp->b_bcount);
WORKLIST_REMOVE(wk);
@@ -1879,11 +1917,13 @@ deallocate_dependencies(bp, inodedep)
case D_ALLOCDIRECT:
case D_INODEDEP:
+ FREE_LOCK(&lk);
panic("deallocate_dependencies: Unexpected type %s",
TYPENAME(wk->wk_type));
/* NOTREACHED */
default:
+ FREE_LOCK(&lk);
panic("deallocate_dependencies: Unknown type %s",
TYPENAME(wk->wk_type));
/* NOTREACHED */
@@ -2001,8 +2041,10 @@ check_inode_unwritten(inodedep)
FREE(inodedep->id_savedino, M_INODEDEP);
inodedep->id_savedino = NULL;
}
- if (free_inodedep(inodedep) == 0)
+ if (free_inodedep(inodedep) == 0) {
+ FREE_LOCK(&lk);
panic("check_inode_unwritten: busy inode");
+ }
return (1);
}
@@ -2140,12 +2182,16 @@ indir_trunc(ip, dbn, level, lbn, countp)
(wk = LIST_FIRST(&bp->b_dep)) != NULL) {
if (wk->wk_type != D_INDIRDEP ||
(indirdep = WK_INDIRDEP(wk))->ir_savebp != bp ||
- (indirdep->ir_state & GOINGAWAY) == 0)
+ (indirdep->ir_state & GOINGAWAY) == 0) {
+ FREE_LOCK(&lk);
panic("indir_trunc: lost indirdep");
+ }
WORKLIST_REMOVE(wk);
WORKITEM_FREE(indirdep, D_INDIRDEP);
- if (LIST_FIRST(&bp->b_dep) != NULL)
+ if (LIST_FIRST(&bp->b_dep) != NULL) {
+ FREE_LOCK(&lk);
panic("indir_trunc: dangling dep");
+ }
FREE_LOCK(&lk);
} else {
FREE_LOCK(&lk);
@@ -2412,8 +2458,10 @@ free_diradd(dap)
LIST_REMOVE(mkdir, md_mkdirs);
WORKITEM_FREE(mkdir, D_MKDIR);
}
- if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
+ if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0) {
+ FREE_LOCK(&lk);
panic("free_diradd: unfound ref");
+ }
}
WORKITEM_FREE(dap, D_DIRADD);
}
@@ -2541,11 +2589,15 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
/*
* Must be ATTACHED at this point.
*/
- if ((dap->da_state & ATTACHED) == 0)
+ if ((dap->da_state & ATTACHED) == 0) {
+ FREE_LOCK(&lk);
panic("newdirrem: not ATTACHED");
- if (dap->da_newinum != ip->i_number)
+ }
+ if (dap->da_newinum != ip->i_number) {
+ FREE_LOCK(&lk);
panic("newdirrem: inum %d should be %d",
ip->i_number, dap->da_newinum);
+ }
/*
* If we are deleting a changed name that never made it to disk,
* then return the dirrem describing the previous inode (which
@@ -2703,8 +2755,10 @@ softdep_change_linkcnt(ip)
ACQUIRE_LOCK(&lk);
(void) inodedep_lookup(ip->i_fs, ip->i_number, DEPALLOC, &inodedep);
- if (ip->i_nlink < ip->i_effnlink)
+ if (ip->i_nlink < ip->i_effnlink) {
+ FREE_LOCK(&lk);
panic("softdep_change_linkcnt: bad delta");
+ }
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
FREE_LOCK(&lk);
}
@@ -2730,16 +2784,20 @@ handle_workitem_remove(dirrem)
}
ip = VTOI(vp);
ACQUIRE_LOCK(&lk);
- if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0)
+ if ((inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, 0, &inodedep)) == 0){
+ FREE_LOCK(&lk);
panic("handle_workitem_remove: lost inodedep");
+ }
/*
* Normal file deletion.
*/
if ((dirrem->dm_state & RMDIR) == 0) {
ip->i_nlink--;
ip->i_flag |= IN_CHANGE;
- if (ip->i_nlink < ip->i_effnlink)
+ if (ip->i_nlink < ip->i_effnlink) {
+ FREE_LOCK(&lk);
panic("handle_workitem_remove: bad file delta");
+ }
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
FREE_LOCK(&lk);
vput(vp);
@@ -2756,8 +2814,10 @@ handle_workitem_remove(dirrem)
*/
ip->i_nlink -= 2;
ip->i_flag |= IN_CHANGE;
- if (ip->i_nlink < ip->i_effnlink)
+ if (ip->i_nlink < ip->i_effnlink) {
+ FREE_LOCK(&lk);
panic("handle_workitem_remove: bad dir delta");
+ }
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
FREE_LOCK(&lk);
if ((error = UFS_TRUNCATE(vp, (off_t)0, 0, p->p_ucred, p)) != 0)
@@ -2822,9 +2882,10 @@ handle_workitem_freefile(freefile)
fs = VFSTOUFS(freefile->fx_mnt)->um_fs;
#ifdef DEBUG
ACQUIRE_LOCK(&lk);
- if (inodedep_lookup(fs, freefile->fx_oldinum, 0, &idp))
- panic("handle_workitem_freefile: inodedep survived");
+ error = inodedep_lookup(fs, freefile->fx_oldinum, 0, &idp);
FREE_LOCK(&lk);
+ if (error)
+ panic("handle_workitem_freefile: inodedep survived");
#endif
tip.i_devvp = freefile->fx_devvp;
tip.i_dev = freefile->fx_devvp->v_rdev;
@@ -2962,10 +3023,12 @@ initiate_write_filepage(pagedep, bp)
LIST_FOREACH(dap, &pagedep->pd_diraddhd[i], da_pdlist) {
ep = (struct direct *)
((char *)bp->b_data + dap->da_offset);
- if (ep->d_ino != dap->da_newinum)
+ if (ep->d_ino != dap->da_newinum) {
+ FREE_LOCK(&lk);
panic("%s: dir inum %d != new %d",
"initiate_write_filepage",
ep->d_ino, dap->da_newinum);
+ }
if (dap->da_state & DIRCHG)
ep->d_ino = dap->da_previous->dm_oldinum;
else
@@ -3026,23 +3089,31 @@ initiate_write_inodeblock(inodedep, bp)
for (deplist = 0, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp;
adp = TAILQ_NEXT(adp, ad_next)) {
#ifdef DIAGNOSTIC
- if (deplist != 0 && prevlbn >= adp->ad_lbn)
+ if (deplist != 0 && prevlbn >= adp->ad_lbn) {
+ FREE_LOCK(&lk);
panic("softdep_write_inodeblock: lbn order");
+ }
prevlbn = adp->ad_lbn;
if (adp->ad_lbn < NDADDR &&
- dp->di_db[adp->ad_lbn] != adp->ad_newblkno)
+ dp->di_db[adp->ad_lbn] != adp->ad_newblkno) {
+ FREE_LOCK(&lk);
panic("%s: direct pointer #%ld mismatch %d != %d",
"softdep_write_inodeblock", adp->ad_lbn,
dp->di_db[adp->ad_lbn], adp->ad_newblkno);
+ }
if (adp->ad_lbn >= NDADDR &&
- dp->di_ib[adp->ad_lbn - NDADDR] != adp->ad_newblkno)
+ dp->di_ib[adp->ad_lbn - NDADDR] != adp->ad_newblkno) {
+ FREE_LOCK(&lk);
panic("%s: indirect pointer #%ld mismatch %d != %d",
"softdep_write_inodeblock", adp->ad_lbn - NDADDR,
dp->di_ib[adp->ad_lbn - NDADDR], adp->ad_newblkno);
+ }
deplist |= 1 << adp->ad_lbn;
- if ((adp->ad_state & ATTACHED) == 0)
+ if ((adp->ad_state & ATTACHED) == 0) {
+ FREE_LOCK(&lk);
panic("softdep_write_inodeblock: Unknown state 0x%x",
adp->ad_state);
+ }
#endif /* DIAGNOSTIC */
adp->ad_state &= ~ATTACHED;
adp->ad_state |= UNDONE;
@@ -3064,16 +3135,20 @@ initiate_write_inodeblock(inodedep, bp)
dp->di_size = fs->fs_bsize * adp->ad_lbn + adp->ad_oldsize;
for (i = adp->ad_lbn + 1; i < NDADDR; i++) {
#ifdef DIAGNOSTIC
- if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
+ if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0) {
+ FREE_LOCK(&lk);
panic("softdep_write_inodeblock: lost dep1");
+ }
#endif /* DIAGNOSTIC */
dp->di_db[i] = 0;
}
for (i = 0; i < NIADDR; i++) {
#ifdef DIAGNOSTIC
if (dp->di_ib[i] != 0 &&
- (deplist & ((1 << NDADDR) << i)) == 0)
+ (deplist & ((1 << NDADDR) << i)) == 0) {
+ FREE_LOCK(&lk);
panic("softdep_write_inodeblock: lost dep2");
+ }
#endif /* DIAGNOSTIC */
dp->di_ib[i] = 0;
}
@@ -3198,8 +3273,10 @@ softdep_disk_write_complete(bp)
case D_INDIRDEP:
indirdep = WK_INDIRDEP(wk);
- if (indirdep->ir_state & GOINGAWAY)
+ if (indirdep->ir_state & GOINGAWAY) {
+ lk.lkt_held = -1;
panic("disk_write_complete: indirdep gone");
+ }
bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount);
FREE(indirdep->ir_saveddata, M_INDIRDEP);
indirdep->ir_saveddata = 0;
@@ -3207,8 +3284,10 @@ softdep_disk_write_complete(bp)
indirdep->ir_state |= ATTACHED;
while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) {
handle_allocindir_partdone(aip);
- if (aip == LIST_FIRST(&indirdep->ir_donehd))
+ if (aip == LIST_FIRST(&indirdep->ir_donehd)) {
+ lk.lkt_held = -1;
panic("disk_write_complete: not gone");
+ }
}
WORKLIST_INSERT(&reattach, wk);
if ((bp->b_flags & B_DELWRI) == 0)
@@ -3217,6 +3296,7 @@ softdep_disk_write_complete(bp)
continue;
default:
+ lk.lkt_held = -1;
panic("handle_disk_write_complete: Unknown type %s",
TYPENAME(wk->wk_type));
/* NOTREACHED */
@@ -3251,8 +3331,10 @@ handle_allocdirect_partdone(adp)
if ((adp->ad_state & ALLCOMPLETE) != ALLCOMPLETE)
return;
- if (adp->ad_buf != NULL)
+ if (adp->ad_buf != NULL) {
+ lk.lkt_held = -1;
panic("handle_allocdirect_partdone: dangling dep");
+ }
/*
* The on-disk inode cannot claim to be any larger than the last
* fragment that has been written. Otherwise, the on-disk inode
@@ -3287,8 +3369,10 @@ handle_allocdirect_partdone(adp)
/* found our block */
if (listadp == adp)
break;
- if (listadp == NULL)
+ if (listadp == NULL) {
+ lk.lkt_held = -1;
panic("handle_allocdirect_partdone: lost dep");
+ }
#endif /* DEBUG */
return;
}
@@ -3321,8 +3405,10 @@ handle_allocindir_partdone(aip)
if ((aip->ai_state & ALLCOMPLETE) != ALLCOMPLETE)
return;
- if (aip->ai_buf != NULL)
+ if (aip->ai_buf != NULL) {
+ lk.lkt_held = -1;
panic("handle_allocindir_partdone: dangling dependency");
+ }
indirdep = aip->ai_indirdep;
if (indirdep->ir_state & UNDONE) {
LIST_REMOVE(aip, ai_next);
@@ -3353,8 +3439,10 @@ handle_written_inodeblock(inodedep, bp)
struct dinode *dp;
int hadchanges;
- if ((inodedep->id_state & IOSTARTED) == 0)
+ if ((inodedep->id_state & IOSTARTED) == 0) {
+ lk.lkt_held = -1;
panic("handle_written_inodeblock: not started");
+ }
inodedep->id_state &= ~IOSTARTED;
inodedep->id_state |= COMPLETE;
dp = (struct dinode *)bp->b_data +
@@ -3382,21 +3470,27 @@ handle_written_inodeblock(inodedep, bp)
hadchanges = 0;
for (adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp; adp = nextadp) {
nextadp = TAILQ_NEXT(adp, ad_next);
- if (adp->ad_state & ATTACHED)
+ if (adp->ad_state & ATTACHED) {
+ lk.lkt_held = -1;
panic("handle_written_inodeblock: new entry");
+ }
if (adp->ad_lbn < NDADDR) {
- if (dp->di_db[adp->ad_lbn] != adp->ad_oldblkno)
+ if (dp->di_db[adp->ad_lbn] != adp->ad_oldblkno) {
+ lk.lkt_held = -1;
panic("%s: %s #%ld mismatch %d != %d",
"handle_written_inodeblock",
"direct pointer", adp->ad_lbn,
dp->di_db[adp->ad_lbn], adp->ad_oldblkno);
+ }
dp->di_db[adp->ad_lbn] = adp->ad_newblkno;
} else {
- if (dp->di_ib[adp->ad_lbn - NDADDR] != 0)
+ if (dp->di_ib[adp->ad_lbn - NDADDR] != 0) {
+ lk.lkt_held = -1;
panic("%s: %s #%ld allocated as %d",
"handle_written_inodeblock",
"indirect pointer", adp->ad_lbn - NDADDR,
dp->di_ib[adp->ad_lbn - NDADDR]);
+ }
dp->di_ib[adp->ad_lbn - NDADDR] = adp->ad_newblkno;
}
adp->ad_state &= ~UNDONE;
@@ -3408,8 +3502,10 @@ handle_written_inodeblock(inodedep, bp)
/*
* Reset the file size to its most up-to-date value.
*/
- if (inodedep->id_savedsize == -1)
+ if (inodedep->id_savedsize == -1) {
+ lk.lkt_held = -1;
panic("handle_written_inodeblock: bad size");
+ }
if (dp->di_size != inodedep->id_savedsize) {
dp->di_size = inodedep->id_savedsize;
hadchanges = 1;
@@ -3446,8 +3542,10 @@ handle_written_inodeblock(inodedep, bp)
* that it will be done after all the old blocks
* have been freed.
*/
- if (filefree != NULL)
+ if (filefree != NULL) {
+ lk.lkt_held = -1;
panic("handle_written_inodeblock: filefree");
+ }
filefree = wk;
continue;
@@ -3466,14 +3564,17 @@ handle_written_inodeblock(inodedep, bp)
continue;
default:
+ lk.lkt_held = -1;
panic("handle_written_inodeblock: Unknown type %s",
TYPENAME(wk->wk_type));
/* NOTREACHED */
}
}
if (filefree != NULL) {
- if (free_inodedep(inodedep) == 0)
+ if (free_inodedep(inodedep) == 0) {
+ lk.lkt_held = -1;
panic("handle_written_inodeblock: live inodedep");
+ }
add_to_worklist(filefree);
return (0);
}
@@ -3520,8 +3621,10 @@ handle_written_mkdir(mkdir, type)
struct diradd *dap;
struct pagedep *pagedep;
- if (mkdir->md_state != type)
+ if (mkdir->md_state != type) {
+ lk.lkt_held = -1;
panic("handle_written_mkdir: bad type");
+ }
dap = mkdir->md_diradd;
dap->da_state &= ~type;
if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) == 0)
@@ -3555,8 +3658,10 @@ handle_written_filepage(pagedep, bp)
struct direct *ep;
int i, chgs;
- if ((pagedep->pd_state & IOSTARTED) == 0)
+ if ((pagedep->pd_state & IOSTARTED) == 0) {
+ lk.lkt_held = -1;
panic("handle_written_filepage: not started");
+ }
pagedep->pd_state &= ~IOSTARTED;
/*
* Process any directory removals that have been committed.
@@ -3578,8 +3683,10 @@ handle_written_filepage(pagedep, bp)
for (dap = LIST_FIRST(&pagedep->pd_diraddhd[i]); dap;
dap = nextdap) {
nextdap = LIST_NEXT(dap, da_pdlist);
- if (dap->da_state & ATTACHED)
+ if (dap->da_state & ATTACHED) {
+ lk.lkt_held = -1;
panic("handle_written_filepage: attached");
+ }
ep = (struct direct *)
((char *)bp->b_data + dap->da_offset);
ep->d_ino = dap->da_newinum;
@@ -3691,13 +3798,15 @@ softdep_update_inodeblock(ip, bp, waitfor)
*/
ACQUIRE_LOCK(&lk);
if (inodedep_lookup(ip->i_fs, ip->i_number, 0, &inodedep) == 0) {
+ FREE_LOCK(&lk);
if (ip->i_effnlink != ip->i_nlink)
panic("softdep_update_inodeblock: bad link count");
- FREE_LOCK(&lk);
return;
}
- if (inodedep->id_nlinkdelta != ip->i_nlink - ip->i_effnlink)
+ if (inodedep->id_nlinkdelta != ip->i_nlink - ip->i_effnlink) {
+ FREE_LOCK(&lk);
panic("softdep_update_inodeblock: bad delta");
+ }
/*
* Changes have been initiated. Anything depending on these
* changes cannot occur until this inode has been written.
@@ -3808,14 +3917,18 @@ softdep_fsync(vp)
if (LIST_FIRST(&inodedep->id_inowait) != NULL ||
LIST_FIRST(&inodedep->id_bufwait) != NULL ||
TAILQ_FIRST(&inodedep->id_inoupdt) != NULL ||
- TAILQ_FIRST(&inodedep->id_newinoupdt) != NULL)
+ TAILQ_FIRST(&inodedep->id_newinoupdt) != NULL) {
+ FREE_LOCK(&lk);
panic("softdep_fsync: pending ops");
+ }
for (error = 0, flushparent = 0; ; ) {
if ((wk = LIST_FIRST(&inodedep->id_pendinghd)) == NULL)
break;
- if (wk->wk_type != D_DIRADD)
+ if (wk->wk_type != D_DIRADD) {
+ FREE_LOCK(&lk);
panic("softdep_fsync: Unexpected type %s",
TYPENAME(wk->wk_type));
+ }
dap = WK_DIRADD(wk);
/*
* Flush our parent if this directory entry
@@ -3828,8 +3941,10 @@ softdep_fsync(vp)
mnt = pagedep->pd_mnt;
parentino = pagedep->pd_ino;
lbn = pagedep->pd_lbn;
- if ((dap->da_state & (MKDIR_BODY | COMPLETE)) != COMPLETE)
+ if ((dap->da_state & (MKDIR_BODY | COMPLETE)) != COMPLETE) {
+ FREE_LOCK(&lk);
panic("softdep_fsync: dirty");
+ }
flushparent = dap->da_state & MKDIR_PARENT;
/*
* If we are being fsync'ed as part of vgone'ing this vnode,
@@ -3900,8 +4015,10 @@ softdep_fsync_mountdev(vp)
*/
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
continue;
- if ((bp->b_flags & B_DELWRI) == 0)
+ if ((bp->b_flags & B_DELWRI) == 0) {
+ FREE_LOCK(&lk);
panic("softdep_fsync_mountdev: not dirty");
+ }
/*
* We are only interested in bitmaps with outstanding
* dependencies.
@@ -4127,6 +4244,7 @@ loop:
break;
default:
+ FREE_LOCK(&lk);
panic("softdep_sync_metadata: Unknown type %s",
TYPENAME(wk->wk_type));
/* NOTREACHED */
@@ -4309,8 +4427,10 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
*/
if (dap != LIST_FIRST(diraddhdp))
continue;
- if (dap->da_state & MKDIR_PARENT)
+ if (dap->da_state & MKDIR_PARENT) {
+ FREE_LOCK(&lk);
panic("flush_pagedep_deps: MKDIR_PARENT");
+ }
}
/*
* A newly allocated directory must have its "." and
@@ -4342,8 +4462,10 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
*/
if (dap != LIST_FIRST(diraddhdp))
continue;
- if (dap->da_state & MKDIR_BODY)
+ if (dap->da_state & MKDIR_BODY) {
+ FREE_LOCK(&lk);
panic("flush_pagedep_deps: MKDIR_BODY");
+ }
}
/*
* Flush the inode on which the directory entry depends.
@@ -4355,8 +4477,10 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
* locate that buffer, ensure that there will be no rollback
* caused by a bitmap dependency, then write the inode buffer.
*/
- if (inodedep_lookup(ump->um_fs, inum, 0, &inodedep) == 0)
+ if (inodedep_lookup(ump->um_fs, inum, 0, &inodedep) == 0) {
+ FREE_LOCK(&lk);
panic("flush_pagedep_deps: lost inode");
+ }
/*
* If the inode still has bitmap dependencies,
* push them to disk.
@@ -4387,8 +4511,10 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
* If we have failed to get rid of all the dependencies
* then something is seriously wrong.
*/
- if (dap == LIST_FIRST(diraddhdp))
+ if (dap == LIST_FIRST(diraddhdp)) {
+ FREE_LOCK(&lk);
panic("flush_pagedep_deps: flush failed");
+ }
}
if (error)
ACQUIRE_LOCK(&lk);
@@ -4480,6 +4606,8 @@ request_cleanup(resource, islocked)
break;
default:
+ if (islocked)
+ FREE_LOCK(&lk);
panic("request_cleanup: unknown type");
}
/*
@@ -4710,6 +4838,7 @@ softdep_count_dependencies(bp, wantcount)
continue;
default:
+ FREE_LOCK(&lk);
panic("softdep_check_for_rollback: Unexpected type %s",
TYPENAME(wk->wk_type));
/* NOTREACHED */
OpenPOWER on IntegriCloud