diff options
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 253 |
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 */ |