mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-12 09:58:36 +00:00
First published FreeBSD version of soft updates Feb 5.
This commit is contained in:
parent
a697eb98d4
commit
987614a910
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36210
@ -52,7 +52,6 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* from: @(#)ffs_softdep.c 9.14 (McKusick) 1/15/98
|
||||
*/
|
||||
|
||||
@ -75,7 +74,7 @@
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <machine/pcpu.h>
|
||||
/*#include <machine/pcpu.h>*/
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
@ -141,11 +140,64 @@ struct bio_ops bioops = {
|
||||
softdep_process_worklist, /* io_sync */
|
||||
};
|
||||
|
||||
/*
|
||||
* malloc types defined for the softdep system.
|
||||
*/
|
||||
MALLOC_DEFINE(M_PAGEDEP, "pagedep","File page dependencies");
|
||||
MALLOC_DEFINE(M_INODEDEP, "inodedep","Inode dependencies");
|
||||
MALLOC_DEFINE(M_NEWBLK, "newblk","New block allocation");
|
||||
MALLOC_DEFINE(M_BMSAFEMAP, "bmsafemap","Block or frag allocated from cyl group map");
|
||||
MALLOC_DEFINE(M_ALLOCDIRECT, "allocdirect","Block or frag dependency for an inode");
|
||||
MALLOC_DEFINE(M_INDIRDEP, "indirdep","Indirect block dependencies");
|
||||
MALLOC_DEFINE(M_ALLOCINDIR, "allocindir","Block dependency for an indirect block");
|
||||
MALLOC_DEFINE(M_FREEFRAG, "freefrag","Previously used frag for an inode");
|
||||
MALLOC_DEFINE(M_FREEBLKS, "freeblks","Blocks freed from an inode");
|
||||
MALLOC_DEFINE(M_FREEFILE, "freefile","Inode deallocated");
|
||||
MALLOC_DEFINE(M_DIRADD, "diradd","New directory entry");
|
||||
MALLOC_DEFINE(M_MKDIR, "mkdir","New directory");
|
||||
MALLOC_DEFINE(M_DIRREM, "dirrem","Directory entry deleted");
|
||||
|
||||
#define D_PAGEDEP 0
|
||||
#define D_INODEDEP 1
|
||||
#define D_NEWBLK 2
|
||||
#define D_BMSAFEMAP 3
|
||||
#define D_ALLOCDIRECT 4
|
||||
#define D_INDIRDEP 5
|
||||
#define D_ALLOCINDIR 6
|
||||
#define D_FREEFRAG 7
|
||||
#define D_FREEBLKS 8
|
||||
#define D_FREEFILE 9
|
||||
#define D_DIRADD 10
|
||||
#define D_MKDIR 11
|
||||
#define D_DIRREM 12
|
||||
#define D_LAST D_DIRREM
|
||||
|
||||
/*
|
||||
* translate from workitem type to memory type
|
||||
* MUST match the defines above, such that memtype[D_XXX] == M_XXX
|
||||
*/
|
||||
static struct malloc_type *memtype[] = {
|
||||
M_PAGEDEP,
|
||||
M_INODEDEP,
|
||||
M_NEWBLK,
|
||||
M_BMSAFEMAP,
|
||||
M_ALLOCDIRECT,
|
||||
M_INDIRDEP,
|
||||
M_ALLOCINDIR,
|
||||
M_FREEFRAG,
|
||||
M_FREEBLKS,
|
||||
M_FREEFILE,
|
||||
M_DIRADD,
|
||||
M_MKDIR,
|
||||
M_DIRREM
|
||||
};
|
||||
|
||||
#define DtoM(type) (memtype[type])
|
||||
|
||||
/*
|
||||
* Names of malloc types.
|
||||
*/
|
||||
extern char *memname[];
|
||||
#define TYPENAME(type) ((unsigned)(type) < M_LAST ? memname[type] : "???")
|
||||
#define TYPENAME(type) ((unsigned)(type) < D_LAST ? memtype[type]->ks_shortdesc : "???")
|
||||
|
||||
/*
|
||||
* Locking primitives.
|
||||
@ -317,7 +369,7 @@ sema_release(semap)
|
||||
(item)->wk_state &= ~ONWORKLIST; \
|
||||
LIST_REMOVE(item, wk_list); \
|
||||
} while (0)
|
||||
#define WORKITEM_FREE(item, type) FREE(item, type)
|
||||
#define WORKITEM_FREE(item, type) FREE(item, DtoM(type))
|
||||
|
||||
#else /* DEBUG */
|
||||
static void worklist_insert __P((struct workhead *, struct worklist *));
|
||||
@ -365,7 +417,7 @@ workitem_free(item, type)
|
||||
panic("workitem_free: still on list");
|
||||
if (item->wk_type != type)
|
||||
panic("workitem_free: type mismatch");
|
||||
FREE(item, type);
|
||||
FREE(item, DtoM(type));
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
@ -391,10 +443,11 @@ add_to_worklist(wk)
|
||||
if (wk->wk_state & ONWORKLIST)
|
||||
panic("add_to_worklist: already on list");
|
||||
wk->wk_state |= ONWORKLIST;
|
||||
if (LIST_FIRST(&softdep_workitem_pending) == NULL)
|
||||
if (LIST_FIRST(&softdep_workitem_pending) == NULL) {
|
||||
LIST_INSERT_HEAD(&softdep_workitem_pending, wk, wk_list);
|
||||
else
|
||||
} else {
|
||||
LIST_INSERT_AFTER(worklist_tail, wk, wk_list);
|
||||
}
|
||||
worklist_tail = wk;
|
||||
}
|
||||
|
||||
@ -433,28 +486,28 @@ softdep_process_worklist(matchmnt)
|
||||
FREE_LOCK(&lk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_DIRREM:
|
||||
case D_DIRREM:
|
||||
/* removal of a directory entry */
|
||||
if (WK_DIRREM(wk)->dm_mnt == matchmnt)
|
||||
matchcnt += 1;
|
||||
handle_workitem_remove(WK_DIRREM(wk));
|
||||
break;
|
||||
|
||||
case M_FREEBLKS:
|
||||
case D_FREEBLKS:
|
||||
/* releasing blocks and/or fragments from a file */
|
||||
if (WK_FREEBLKS(wk)->fb_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
handle_workitem_freeblocks(WK_FREEBLKS(wk));
|
||||
break;
|
||||
|
||||
case M_FREEFRAG:
|
||||
case D_FREEFRAG:
|
||||
/* releasing a fragment when replaced as a file grows */
|
||||
if (WK_FREEFRAG(wk)->ff_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
handle_workitem_freefrag(WK_FREEFRAG(wk));
|
||||
break;
|
||||
|
||||
case M_FREEFILE:
|
||||
case D_FREEFILE:
|
||||
/* releasing an inode when its link count drops to 0 */
|
||||
if (WK_FREEFILE(wk)->fx_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
@ -490,7 +543,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
* Await our turn to clear out the queue.
|
||||
*/
|
||||
while (softdep_worklist_busy)
|
||||
sleep(&lbolt, PRIBIO);
|
||||
tsleep(&lbolt, PRIBIO, "sdflsh", 0);
|
||||
softdep_worklist_busy = 1;
|
||||
if ((error = ffs_flushfiles(oldmnt, flags, p)) != 0) {
|
||||
softdep_worklist_busy = 0;
|
||||
@ -518,7 +571,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
break;
|
||||
}
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
error = VOP_FSYNC(devvp, p->p_cred, MNT_WAIT, p);
|
||||
error = VOP_FSYNC(devvp, p->p_ucred, MNT_WAIT, p);
|
||||
VOP_UNLOCK(devvp, 0, p);
|
||||
if (error)
|
||||
break;
|
||||
@ -530,7 +583,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
* activity can keep us busy forever, so we just fail with EBUSY.
|
||||
*/
|
||||
if (loopcnt == 0) {
|
||||
if (oldmnt->mnt_flag & MNT_UNMOUNT)
|
||||
if (oldmnt->mnt_kern_flag & MNTK_UNMOUNT)
|
||||
panic("softdep_flushfiles: looping");
|
||||
error = EBUSY;
|
||||
}
|
||||
@ -617,7 +670,7 @@ pagedep_lookup(ip, lbn, flags, pagedeppp)
|
||||
MALLOC(pagedep, struct pagedep *, sizeof(struct pagedep), M_PAGEDEP,
|
||||
M_WAITOK);
|
||||
bzero(pagedep, sizeof(struct pagedep));
|
||||
pagedep->pd_list.wk_type = M_PAGEDEP;
|
||||
pagedep->pd_list.wk_type = D_PAGEDEP;
|
||||
pagedep->pd_mnt = mp;
|
||||
pagedep->pd_ino = ip->i_number;
|
||||
pagedep->pd_lbn = lbn;
|
||||
@ -681,7 +734,7 @@ inodedep_lookup(fs, inum, flags, inodedeppp)
|
||||
}
|
||||
MALLOC(inodedep, struct inodedep *, sizeof(struct inodedep),
|
||||
M_INODEDEP, M_WAITOK);
|
||||
inodedep->id_list.wk_type = M_INODEDEP;
|
||||
inodedep->id_list.wk_type = D_INODEDEP;
|
||||
inodedep->id_fs = fs;
|
||||
inodedep->id_ino = inum;
|
||||
inodedep->id_state = ALLCOMPLETE;
|
||||
@ -922,12 +975,12 @@ bmsafemap_lookup(bp)
|
||||
panic("bmsafemap_lookup: lock not held");
|
||||
#endif
|
||||
for (wk = LIST_FIRST(&bp->b_dep); wk; wk = LIST_NEXT(wk, wk_list))
|
||||
if (wk->wk_type == M_BMSAFEMAP)
|
||||
if (wk->wk_type == D_BMSAFEMAP)
|
||||
return (WK_BMSAFEMAP(wk));
|
||||
FREE_LOCK(&lk);
|
||||
MALLOC(bmsafemap, struct bmsafemap *, sizeof(struct bmsafemap),
|
||||
M_BMSAFEMAP, M_WAITOK);
|
||||
bmsafemap->sm_list.wk_type = M_BMSAFEMAP;
|
||||
bmsafemap->sm_list.wk_type = D_BMSAFEMAP;
|
||||
bmsafemap->sm_list.wk_state = 0;
|
||||
bmsafemap->sm_buf = bp;
|
||||
LIST_INIT(&bmsafemap->sm_allocdirecthd);
|
||||
@ -988,7 +1041,7 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
|
||||
MALLOC(adp, struct allocdirect *, sizeof(struct allocdirect),
|
||||
M_ALLOCDIRECT, M_WAITOK);
|
||||
bzero(adp, sizeof(struct allocdirect));
|
||||
adp->ad_list.wk_type = M_ALLOCDIRECT;
|
||||
adp->ad_list.wk_type = D_ALLOCDIRECT;
|
||||
adp->ad_lbn = lbn;
|
||||
adp->ad_newblkno = newblkno;
|
||||
adp->ad_oldblkno = oldblkno;
|
||||
@ -1139,7 +1192,7 @@ newfreefrag(ip, blkno, size)
|
||||
panic("newfreefrag: frag size");
|
||||
MALLOC(freefrag, struct freefrag *, sizeof(struct freefrag),
|
||||
M_FREEFRAG, M_WAITOK);
|
||||
freefrag->ff_list.wk_type = M_FREEFRAG;
|
||||
freefrag->ff_list.wk_type = D_FREEFRAG;
|
||||
freefrag->ff_state = ip->i_uid & ~ONWORKLIST; /* XXX - used below */
|
||||
freefrag->ff_inum = ip->i_number;
|
||||
freefrag->ff_fs = fs;
|
||||
@ -1208,7 +1261,7 @@ newallocindir(ip, ptrno, newblkno, oldblkno)
|
||||
MALLOC(aip, struct allocindir *, sizeof(struct allocindir),
|
||||
M_ALLOCINDIR, M_WAITOK);
|
||||
bzero(aip, sizeof(struct allocindir));
|
||||
aip->ai_list.wk_type = M_ALLOCINDIR;
|
||||
aip->ai_list.wk_type = D_ALLOCINDIR;
|
||||
aip->ai_state = ATTACHED;
|
||||
aip->ai_offset = ptrno;
|
||||
aip->ai_newblkno = newblkno;
|
||||
@ -1293,7 +1346,7 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
for (wk = LIST_FIRST(&bp->b_dep); wk;
|
||||
wk = LIST_NEXT(wk, wk_list)) {
|
||||
if (wk->wk_type != M_INDIRDEP)
|
||||
if (wk->wk_type != D_INDIRDEP)
|
||||
continue;
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
break;
|
||||
@ -1351,13 +1404,13 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
if (newindirdep) {
|
||||
if (indirdep->ir_savebp != NULL)
|
||||
brelse(newindirdep->ir_savebp);
|
||||
WORKITEM_FREE((caddr_t)newindirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE((caddr_t)newindirdep, D_INDIRDEP);
|
||||
}
|
||||
if (indirdep)
|
||||
break;
|
||||
MALLOC(newindirdep, struct indirdep *, sizeof(struct indirdep),
|
||||
M_INDIRDEP, M_WAITOK);
|
||||
newindirdep->ir_list.wk_type = M_INDIRDEP;
|
||||
newindirdep->ir_list.wk_type = D_INDIRDEP;
|
||||
newindirdep->ir_state = ATTACHED;
|
||||
LIST_INIT(&newindirdep->ir_deplisthd);
|
||||
LIST_INIT(&newindirdep->ir_donehd);
|
||||
@ -1417,7 +1470,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
|
||||
M_FREEBLKS, M_WAITOK);
|
||||
bzero(freeblks, sizeof(struct freeblks));
|
||||
freeblks->fb_list.wk_type = M_FREEBLKS;
|
||||
freeblks->fb_list.wk_type = D_FREEBLKS;
|
||||
freeblks->fb_uid = ip->i_uid;
|
||||
freeblks->fb_previousinum = ip->i_number;
|
||||
freeblks->fb_devvp = ip->i_devvp;
|
||||
@ -1479,7 +1532,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "sdsetf", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
while (getdirtybuf(&LIST_FIRST(&vp->v_dirtyblkhd), MNT_WAIT)) {
|
||||
@ -1522,7 +1575,7 @@ deallocate_dependencies(bp, inodedep)
|
||||
while ((wk = LIST_FIRST(&bp->b_dep)) != NULL) {
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
/*
|
||||
* None of the indirect pointers will ever be visible,
|
||||
@ -1556,7 +1609,7 @@ deallocate_dependencies(bp, inodedep)
|
||||
WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk);
|
||||
continue;
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
pagedep = WK_PAGEDEP(wk);
|
||||
/*
|
||||
* None of the directory additions will ever be
|
||||
@ -1585,15 +1638,15 @@ deallocate_dependencies(bp, inodedep)
|
||||
}
|
||||
WORKLIST_REMOVE(&pagedep->pd_list);
|
||||
LIST_REMOVE(pagedep, pd_hash);
|
||||
WORKITEM_FREE(pagedep, M_PAGEDEP);
|
||||
WORKITEM_FREE(pagedep, D_PAGEDEP);
|
||||
continue;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
free_allocindir(WK_ALLOCINDIR(wk), inodedep);
|
||||
continue;
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case M_INODEDEP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_INODEDEP:
|
||||
panic("deallocate_dependencies: Unexpected type %s",
|
||||
TYPENAME(wk->wk_type));
|
||||
/* NOTREACHED */
|
||||
@ -1633,7 +1686,7 @@ free_allocdirect(adphead, adp, delay)
|
||||
else
|
||||
add_to_worklist(&adp->ad_freefrag->ff_list);
|
||||
}
|
||||
WORKITEM_FREE(adp, M_ALLOCDIRECT);
|
||||
WORKITEM_FREE(adp, D_ALLOCDIRECT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1641,14 +1694,12 @@ free_allocdirect(adphead, adp, delay)
|
||||
* done until the zero'ed inode has been written to disk.
|
||||
*/
|
||||
void
|
||||
softdep_freefile(ap)
|
||||
struct vop_vfree_args /* {
|
||||
struct vnode *a_pvp;
|
||||
ino_t a_ino;
|
||||
int a_mode;
|
||||
} */ *ap;
|
||||
softdep_freefile(pvp, ino, mode)
|
||||
struct vnode *pvp;
|
||||
ino_t ino;
|
||||
int mode;
|
||||
{
|
||||
struct inode *ip = VTOI(ap->a_pvp);
|
||||
struct inode *ip = VTOI(pvp);
|
||||
struct inodedep *inodedep;
|
||||
struct freefile *freefile;
|
||||
|
||||
@ -1657,10 +1708,10 @@ softdep_freefile(ap)
|
||||
*/
|
||||
MALLOC(freefile, struct freefile *, sizeof(struct freefile),
|
||||
M_FREEFILE, M_WAITOK);
|
||||
freefile->fx_list.wk_type = M_FREEFILE;
|
||||
freefile->fx_list.wk_type = D_FREEFILE;
|
||||
freefile->fx_list.wk_state = 0;
|
||||
freefile->fx_mode = ap->a_mode;
|
||||
freefile->fx_oldinum = ap->a_ino;
|
||||
freefile->fx_mode = mode;
|
||||
freefile->fx_oldinum = ino;
|
||||
freefile->fx_devvp = ip->i_devvp;
|
||||
freefile->fx_fs = ip->i_fs;
|
||||
|
||||
@ -1669,7 +1720,7 @@ softdep_freefile(ap)
|
||||
* been written to disk and we can free the file immediately.
|
||||
*/
|
||||
ACQUIRE_LOCK(&lk);
|
||||
if (inodedep_lookup(ip->i_fs, ap->a_ino, 0, &inodedep) == 0) {
|
||||
if (inodedep_lookup(ip->i_fs, ino, 0, &inodedep) == 0) {
|
||||
add_to_worklist(&freefile->fx_list);
|
||||
FREE_LOCK(&lk);
|
||||
return;
|
||||
@ -1719,7 +1770,7 @@ free_inodedep(inodedep)
|
||||
inodedep->id_nlinkdelta != 0 || inodedep->id_savedino != NULL)
|
||||
return (0);
|
||||
LIST_REMOVE(inodedep, id_hash);
|
||||
WORKITEM_FREE(inodedep, M_INODEDEP);
|
||||
WORKITEM_FREE(inodedep, D_INODEDEP);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -1787,7 +1838,7 @@ handle_workitem_freeblocks(freeblks)
|
||||
if (allerror)
|
||||
softdep_error("handle_workitem_freeblks", allerror);
|
||||
#endif /* DIAGNOSTIC */
|
||||
WORKITEM_FREE(freeblks, M_FREEBLKS);
|
||||
WORKITEM_FREE(freeblks, D_FREEBLKS);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1832,12 +1883,12 @@ indir_trunc(ip, dbn, level, lbn, countp)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
if ((bp = incore(ip->i_devvp, dbn)) != NULL &&
|
||||
(wk = LIST_FIRST(&bp->b_dep)) != NULL) {
|
||||
if (wk->wk_type != M_INDIRDEP ||
|
||||
if (wk->wk_type != D_INDIRDEP ||
|
||||
(indirdep = WK_INDIRDEP(wk))->ir_savebp != bp ||
|
||||
(indirdep->ir_state & GOINGAWAY) == 0)
|
||||
panic("indir_trunc: lost indirdep");
|
||||
WORKLIST_REMOVE(wk);
|
||||
WORKITEM_FREE(indirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE(indirdep, D_INDIRDEP);
|
||||
if (LIST_FIRST(&bp->b_dep) != NULL)
|
||||
panic("indir_trunc: dangling dep");
|
||||
FREE_LOCK(&lk);
|
||||
@ -1895,7 +1946,7 @@ free_allocindir(aip, inodedep)
|
||||
WORKLIST_INSERT(&inodedep->id_inowait,
|
||||
&freefrag->ff_list);
|
||||
}
|
||||
WORKITEM_FREE(aip, M_ALLOCINDIR);
|
||||
WORKITEM_FREE(aip, D_ALLOCINDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1951,36 +2002,32 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp)
|
||||
offset = blkoff(fs, diroffset);
|
||||
MALLOC(dap, struct diradd *, sizeof(struct diradd), M_DIRADD, M_WAITOK);
|
||||
bzero(dap, sizeof(struct diradd));
|
||||
dap->da_list.wk_type = M_DIRADD;
|
||||
dap->da_list.wk_type = D_DIRADD;
|
||||
dap->da_offset = offset;
|
||||
dap->da_newinum = newinum;
|
||||
dap->da_state = ATTACHED;
|
||||
if (newdirbp == NULL) {
|
||||
dap->da_state |= DEPCOMPLETE;
|
||||
ACQUIRE_LOCK(&lk);
|
||||
} else {
|
||||
dap->da_state |= MKDIR_BODY | MKDIR_PARENT;
|
||||
MALLOC(mkdir1, struct mkdir *, sizeof(struct mkdir), M_MKDIR,
|
||||
M_WAITOK);
|
||||
mkdir1->md_list.wk_type = M_MKDIR;
|
||||
mkdir1->md_list.wk_type = D_MKDIR;
|
||||
mkdir1->md_state = MKDIR_BODY;
|
||||
mkdir1->md_diradd = dap;
|
||||
MALLOC(mkdir2, struct mkdir *, sizeof(struct mkdir), M_MKDIR,
|
||||
M_WAITOK);
|
||||
mkdir2->md_list.wk_type = M_MKDIR;
|
||||
mkdir2->md_list.wk_type = D_MKDIR;
|
||||
mkdir2->md_state = MKDIR_PARENT;
|
||||
mkdir2->md_diradd = dap;
|
||||
|
||||
}
|
||||
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
* If this directory entry references a new directory, create
|
||||
* its two additional dependencies: its "." and ".." being written
|
||||
* to disk and the link count increase for its parent directory.
|
||||
*/
|
||||
if (newdirbp != NULL) {
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
* Dependency on "." and ".." being written to disk
|
||||
* If this directory entry references a new directory, create
|
||||
* its two additional dependencies: its "." and ".." being
|
||||
* written to disk and the link count increase for its
|
||||
* parent directory.
|
||||
*/
|
||||
LIST_INSERT_HEAD(&mkdirlisthd, mkdir1, md_mkdirs);
|
||||
WORKLIST_INSERT(&newdirbp->b_dep, &mkdir1->md_list);
|
||||
@ -1991,7 +2038,7 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp)
|
||||
if (inodedep_lookup(dp->i_fs, dp->i_number, 0, &inodedep) == 0
|
||||
|| (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
dap->da_state &= ~MKDIR_PARENT;
|
||||
WORKITEM_FREE(mkdir2, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir2, D_MKDIR);
|
||||
} else {
|
||||
LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
|
||||
WORKLIST_INSERT(&inodedep->id_inowait,&mkdir2->md_list);
|
||||
@ -2095,12 +2142,12 @@ free_diradd(dap)
|
||||
dap->da_state &= ~mkdir->md_state;
|
||||
WORKLIST_REMOVE(&mkdir->md_list);
|
||||
LIST_REMOVE(mkdir, md_mkdirs);
|
||||
WORKITEM_FREE(mkdir, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir, D_MKDIR);
|
||||
}
|
||||
if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
|
||||
panic("free_diradd: unfound ref");
|
||||
}
|
||||
WORKITEM_FREE(dap, M_DIRADD);
|
||||
WORKITEM_FREE(dap, D_DIRADD);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2168,7 +2215,7 @@ newdirrem(bp, dp, ip, isrmdir)
|
||||
MALLOC(dirrem, struct dirrem *, sizeof(struct dirrem),
|
||||
M_DIRREM, M_WAITOK);
|
||||
bzero(dirrem, sizeof(struct dirrem));
|
||||
dirrem->dm_list.wk_type = M_DIRREM;
|
||||
dirrem->dm_list.wk_type = D_DIRREM;
|
||||
dirrem->dm_state = isrmdir ? RMDIR : 0;
|
||||
dirrem->dm_mnt = ITOV(ip)->v_mount;
|
||||
dirrem->dm_oldinum = ip->i_number;
|
||||
@ -2244,7 +2291,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
|
||||
MALLOC(dap, struct diradd *, sizeof(struct diradd),
|
||||
M_DIRADD, M_WAITOK);
|
||||
bzero(dap, sizeof(struct diradd));
|
||||
dap->da_list.wk_type = M_DIRADD;
|
||||
dap->da_list.wk_type = D_DIRADD;
|
||||
dap->da_state = DIRCHG | ATTACHED | DEPCOMPLETE;
|
||||
dap->da_offset = offset;
|
||||
dap->da_newinum = newinum;
|
||||
@ -2261,7 +2308,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
|
||||
*/
|
||||
if (inodedep_lookup(dp->i_fs, newinum, 0, &inodedep) == 0 ||
|
||||
(inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
WORKITEM_FREE(dap, M_DIRADD);
|
||||
WORKITEM_FREE(dap, D_DIRADD);
|
||||
dap = NULL;
|
||||
}
|
||||
|
||||
@ -2330,7 +2377,7 @@ handle_workitem_remove(dirrem)
|
||||
}
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
vput(vp);
|
||||
WORKITEM_FREE(dirrem, M_DIRREM);
|
||||
WORKITEM_FREE(dirrem, D_DIRREM);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -2344,7 +2391,7 @@ handle_workitem_remove(dirrem)
|
||||
if (ip->i_nlink < ip->i_effnlink)
|
||||
panic("handle_workitem_remove: bad dir delta");
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
if ((error = VOP_TRUNCATE(vp, (off_t)0, 0, p->p_cred, p)) != 0)
|
||||
if ((error = UFS_TRUNCATE(vp, (off_t)0, 0, p->p_ucred, p)) != 0)
|
||||
softdep_error("handle_workitem_remove: truncate", error);
|
||||
ACQUIRE_LOCK(&lk);
|
||||
(void) inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, DEPALLOC,
|
||||
@ -2377,7 +2424,6 @@ handle_workitem_freefile(freefile)
|
||||
struct vnode vp;
|
||||
struct inode tip;
|
||||
struct inodedep *idp;
|
||||
struct vop_vfree_args args;
|
||||
int error;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -2390,12 +2436,9 @@ handle_workitem_freefile(freefile)
|
||||
tip.i_dev = freefile->fx_devvp->v_rdev;
|
||||
tip.i_fs = freefile->fx_fs;
|
||||
vp.v_data = &tip;
|
||||
args.a_pvp = &vp;
|
||||
args.a_ino = freefile->fx_oldinum;
|
||||
args.a_mode = freefile->fx_mode;
|
||||
if ((error = ffs_freefile(&args)) != 0)
|
||||
if ((error = ffs_freefile(&vp, freefile->fx_oldinum, freefile->fx_mode)) != 0)
|
||||
softdep_error("handle_workitem_freefile", error);
|
||||
WORKITEM_FREE(freefile, M_FREEFILE);
|
||||
WORKITEM_FREE(freefile, D_FREEFILE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2440,15 +2483,15 @@ softdep_disk_io_initiation(bp)
|
||||
nextwk = LIST_NEXT(wk, wk_list);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
initiate_write_filepage(WK_PAGEDEP(wk), bp);
|
||||
continue;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
initiate_write_inodeblock(WK_INODEDEP(wk), bp);
|
||||
continue;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
if (indirdep->ir_state & GOINGAWAY)
|
||||
panic("disk_io_initiation: indirdep gone");
|
||||
@ -2462,7 +2505,7 @@ softdep_disk_io_initiation(bp)
|
||||
/* inline expand WORKLIST_REMOVE(wk); */
|
||||
wk->wk_state &= ~ONWORKLIST;
|
||||
LIST_REMOVE(wk, wk_list);
|
||||
WORKITEM_FREE(indirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE(indirdep, D_INDIRDEP);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -2475,10 +2518,10 @@ softdep_disk_io_initiation(bp)
|
||||
FREE_LOCK(&lk);
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case M_BMSAFEMAP:
|
||||
case M_ALLOCDIRECT:
|
||||
case M_ALLOCINDIR:
|
||||
case D_MKDIR:
|
||||
case D_BMSAFEMAP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_ALLOCINDIR:
|
||||
continue;
|
||||
|
||||
default:
|
||||
@ -2549,7 +2592,7 @@ initiate_write_inodeblock(inodedep, bp)
|
||||
struct allocdirect *adp, *lastadp;
|
||||
struct dinode *dp;
|
||||
struct fs *fs;
|
||||
ufs_lbn_t prevlbn;
|
||||
ufs_lbn_t prevlbn = 0;
|
||||
int i, deplist;
|
||||
|
||||
if (inodedep->id_state & IOSTARTED)
|
||||
@ -2698,17 +2741,17 @@ softdep_disk_write_complete(bp)
|
||||
WORKLIST_REMOVE(wk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
if (handle_written_filepage(WK_PAGEDEP(wk), bp))
|
||||
WORKLIST_INSERT(&reattach, wk);
|
||||
continue;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
if (handle_written_inodeblock(WK_INODEDEP(wk), bp))
|
||||
WORKLIST_INSERT(&reattach, wk);
|
||||
continue;
|
||||
|
||||
case M_BMSAFEMAP:
|
||||
case D_BMSAFEMAP:
|
||||
bmsafemap = WK_BMSAFEMAP(wk);
|
||||
while (newblk = LIST_FIRST(&bmsafemap->sm_newblkhd)) {
|
||||
newblk->nb_state |= DEPCOMPLETE;
|
||||
@ -2733,26 +2776,26 @@ softdep_disk_write_complete(bp)
|
||||
LIST_REMOVE(inodedep, id_deps);
|
||||
inodedep->id_buf = NULL;
|
||||
}
|
||||
WORKITEM_FREE(bmsafemap, M_BMSAFEMAP);
|
||||
WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case D_MKDIR:
|
||||
handle_written_mkdir(WK_MKDIR(wk), MKDIR_BODY);
|
||||
continue;
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case D_ALLOCDIRECT:
|
||||
adp = WK_ALLOCDIRECT(wk);
|
||||
adp->ad_state |= COMPLETE;
|
||||
handle_allocdirect_partdone(adp);
|
||||
continue;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
aip = WK_ALLOCINDIR(wk);
|
||||
aip->ai_state |= COMPLETE;
|
||||
handle_allocindir_partdone(aip);
|
||||
continue;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
if (indirdep->ir_state & GOINGAWAY)
|
||||
panic("disk_write_complete: indirdep gone");
|
||||
@ -2883,7 +2926,7 @@ handle_allocindir_partdone(aip)
|
||||
LIST_REMOVE(aip, ai_next);
|
||||
if (aip->ai_freefrag != NULL)
|
||||
add_to_worklist(&aip->ai_freefrag->ff_list);
|
||||
WORKITEM_FREE(aip, M_ALLOCINDIR);
|
||||
WORKITEM_FREE(aip, D_ALLOCINDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2986,7 +3029,7 @@ handle_written_inodeblock(inodedep, bp)
|
||||
WORKLIST_REMOVE(wk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_FREEFILE:
|
||||
case D_FREEFILE:
|
||||
/*
|
||||
* We defer adding filefree to the worklist until
|
||||
* all other additions have been made to ensure
|
||||
@ -2998,11 +3041,11 @@ handle_written_inodeblock(inodedep, bp)
|
||||
filefree = wk;
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case D_MKDIR:
|
||||
handle_written_mkdir(WK_MKDIR(wk), MKDIR_PARENT);
|
||||
continue;
|
||||
|
||||
case M_DIRADD:
|
||||
case D_DIRADD:
|
||||
dap = WK_DIRADD(wk);
|
||||
dap->da_state |= COMPLETE;
|
||||
if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
@ -3017,9 +3060,9 @@ handle_written_inodeblock(inodedep, bp)
|
||||
WORKLIST_INSERT(&inodedep->id_pendinghd, wk);
|
||||
continue;
|
||||
|
||||
case M_FREEBLKS:
|
||||
case M_FREEFRAG:
|
||||
case M_DIRREM:
|
||||
case D_FREEBLKS:
|
||||
case D_FREEFRAG:
|
||||
case D_DIRREM:
|
||||
add_to_worklist(wk);
|
||||
continue;
|
||||
|
||||
@ -3066,7 +3109,7 @@ handle_written_mkdir(mkdir, type)
|
||||
LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
|
||||
}
|
||||
LIST_REMOVE(mkdir, md_mkdirs);
|
||||
WORKITEM_FREE(mkdir, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir, D_MKDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3147,7 +3190,7 @@ handle_written_filepage(pagedep, bp)
|
||||
break;
|
||||
if (i == DAHASHSZ) {
|
||||
LIST_REMOVE(pagedep, pd_hash);
|
||||
WORKITEM_FREE(pagedep, M_PAGEDEP);
|
||||
WORKITEM_FREE(pagedep, D_PAGEDEP);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -3343,7 +3386,7 @@ softdep_fsync(vp)
|
||||
panic("softdep_fsync: pending ops");
|
||||
if ((wk = LIST_FIRST(&inodedep->id_pendinghd)) == NULL)
|
||||
break;
|
||||
if (wk->wk_type != M_DIRADD)
|
||||
if (wk->wk_type != D_DIRADD)
|
||||
panic("softdep_fsync: Unexpected type %s",
|
||||
TYPENAME(wk->wk_type));
|
||||
dap = WK_DIRADD(wk);
|
||||
@ -3394,7 +3437,7 @@ softdep_fsync(vp)
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
if (flushparent) {
|
||||
tv = time;
|
||||
if (error = VOP_UPDATE(pvp, &tv, &tv, MNT_WAIT)) {
|
||||
if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) {
|
||||
vput(pvp);
|
||||
return (error);
|
||||
}
|
||||
@ -3490,7 +3533,7 @@ softdep_sync_metadata(ap)
|
||||
wk = LIST_NEXT(wk, wk_list)) {
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case D_ALLOCDIRECT:
|
||||
adp = WK_ALLOCDIRECT(wk);
|
||||
if (adp->ad_state & DEPCOMPLETE)
|
||||
break;
|
||||
@ -3507,7 +3550,7 @@ softdep_sync_metadata(ap)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
break;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
aip = WK_ALLOCINDIR(wk);
|
||||
if (aip->ai_state & DEPCOMPLETE)
|
||||
break;
|
||||
@ -3524,7 +3567,7 @@ softdep_sync_metadata(ap)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
break;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
restart:
|
||||
for (aip = LIST_FIRST(&WK_INDIRDEP(wk)->ir_deplisthd);
|
||||
aip; aip = LIST_NEXT(aip, ai_next)) {
|
||||
@ -3543,7 +3586,7 @@ softdep_sync_metadata(ap)
|
||||
}
|
||||
break;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
if ((error = flush_inodedep_deps(WK_INODEDEP(wk)->id_fs,
|
||||
WK_INODEDEP(wk)->id_ino)) != 0) {
|
||||
FREE_LOCK(&lk);
|
||||
@ -3552,7 +3595,7 @@ softdep_sync_metadata(ap)
|
||||
}
|
||||
break;
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
/*
|
||||
* We are trying to sync a directory that may
|
||||
* have dependencies on both its own metadata
|
||||
@ -3597,7 +3640,7 @@ softdep_sync_metadata(ap)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "sdsynm", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
/*
|
||||
@ -3737,7 +3780,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
struct diradd *dap;
|
||||
struct timeval tv;
|
||||
struct vnode *vp;
|
||||
int gotit, error;
|
||||
int gotit, error = 0;
|
||||
struct buf *bp;
|
||||
ino_t inum;
|
||||
|
||||
@ -3750,7 +3793,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
if (dap->da_state & MKDIR_PARENT) {
|
||||
tv = time;
|
||||
FREE_LOCK(&lk);
|
||||
if (error = VOP_UPDATE(pvp, &tv, &tv, MNT_WAIT))
|
||||
if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT))
|
||||
break;
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
@ -3818,7 +3861,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
* level in the filesystem. Instead, we push the blocks
|
||||
* and wait for them to clear.
|
||||
*/
|
||||
if (error = VOP_FSYNC(vp, p->p_cred, MNT_NOWAIT, p)) {
|
||||
if (error = VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p)) {
|
||||
vput(vp);
|
||||
break;
|
||||
}
|
||||
@ -3826,13 +3869,14 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1,
|
||||
"sdflpd", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
FREE_LOCK(&lk);
|
||||
}
|
||||
tv = time;
|
||||
error = VOP_UPDATE(vp, &tv, &tv, MNT_WAIT);
|
||||
error = UFS_UPDATE(vp, &tv, &tv, MNT_WAIT);
|
||||
vput(vp);
|
||||
if (error)
|
||||
break;
|
||||
@ -3870,7 +3914,7 @@ getdirtybuf(bpp, waitfor)
|
||||
return (0);
|
||||
bp->b_flags |= B_WANTED;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)bp, PRIBIO + 1);
|
||||
tsleep((caddr_t)bp, PRIBIO + 1, "sdsdty", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
if ((bp->b_flags & B_DELWRI) == 0)
|
||||
@ -3906,13 +3950,13 @@ softdep_deallocate_dependencies(bp)
|
||||
* force fsck to be run (though this would best be done
|
||||
* in the mainline code).
|
||||
*/
|
||||
case M_PAGEDEP:
|
||||
case M_INODEDEP:
|
||||
case M_BMSAFEMAP:
|
||||
case M_ALLOCDIRECT:
|
||||
case M_INDIRDEP:
|
||||
case M_ALLOCINDIR:
|
||||
case M_MKDIR:
|
||||
case D_PAGEDEP:
|
||||
case D_INODEDEP:
|
||||
case D_BMSAFEMAP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_INDIRDEP:
|
||||
case D_ALLOCINDIR:
|
||||
case D_MKDIR:
|
||||
#ifdef DEBUG
|
||||
printf("Lost type %s\n", TYPENAME(wk->wk_type));
|
||||
#endif
|
||||
|
@ -52,7 +52,6 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* from: @(#)softdep.h 9.4 (McKusick) 1/15/98
|
||||
*/
|
||||
|
||||
|
@ -52,7 +52,6 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* from: @(#)ffs_softdep.c 9.14 (McKusick) 1/15/98
|
||||
*/
|
||||
|
||||
@ -75,7 +74,7 @@
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <machine/pcpu.h>
|
||||
/*#include <machine/pcpu.h>*/
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
@ -141,11 +140,64 @@ struct bio_ops bioops = {
|
||||
softdep_process_worklist, /* io_sync */
|
||||
};
|
||||
|
||||
/*
|
||||
* malloc types defined for the softdep system.
|
||||
*/
|
||||
MALLOC_DEFINE(M_PAGEDEP, "pagedep","File page dependencies");
|
||||
MALLOC_DEFINE(M_INODEDEP, "inodedep","Inode dependencies");
|
||||
MALLOC_DEFINE(M_NEWBLK, "newblk","New block allocation");
|
||||
MALLOC_DEFINE(M_BMSAFEMAP, "bmsafemap","Block or frag allocated from cyl group map");
|
||||
MALLOC_DEFINE(M_ALLOCDIRECT, "allocdirect","Block or frag dependency for an inode");
|
||||
MALLOC_DEFINE(M_INDIRDEP, "indirdep","Indirect block dependencies");
|
||||
MALLOC_DEFINE(M_ALLOCINDIR, "allocindir","Block dependency for an indirect block");
|
||||
MALLOC_DEFINE(M_FREEFRAG, "freefrag","Previously used frag for an inode");
|
||||
MALLOC_DEFINE(M_FREEBLKS, "freeblks","Blocks freed from an inode");
|
||||
MALLOC_DEFINE(M_FREEFILE, "freefile","Inode deallocated");
|
||||
MALLOC_DEFINE(M_DIRADD, "diradd","New directory entry");
|
||||
MALLOC_DEFINE(M_MKDIR, "mkdir","New directory");
|
||||
MALLOC_DEFINE(M_DIRREM, "dirrem","Directory entry deleted");
|
||||
|
||||
#define D_PAGEDEP 0
|
||||
#define D_INODEDEP 1
|
||||
#define D_NEWBLK 2
|
||||
#define D_BMSAFEMAP 3
|
||||
#define D_ALLOCDIRECT 4
|
||||
#define D_INDIRDEP 5
|
||||
#define D_ALLOCINDIR 6
|
||||
#define D_FREEFRAG 7
|
||||
#define D_FREEBLKS 8
|
||||
#define D_FREEFILE 9
|
||||
#define D_DIRADD 10
|
||||
#define D_MKDIR 11
|
||||
#define D_DIRREM 12
|
||||
#define D_LAST D_DIRREM
|
||||
|
||||
/*
|
||||
* translate from workitem type to memory type
|
||||
* MUST match the defines above, such that memtype[D_XXX] == M_XXX
|
||||
*/
|
||||
static struct malloc_type *memtype[] = {
|
||||
M_PAGEDEP,
|
||||
M_INODEDEP,
|
||||
M_NEWBLK,
|
||||
M_BMSAFEMAP,
|
||||
M_ALLOCDIRECT,
|
||||
M_INDIRDEP,
|
||||
M_ALLOCINDIR,
|
||||
M_FREEFRAG,
|
||||
M_FREEBLKS,
|
||||
M_FREEFILE,
|
||||
M_DIRADD,
|
||||
M_MKDIR,
|
||||
M_DIRREM
|
||||
};
|
||||
|
||||
#define DtoM(type) (memtype[type])
|
||||
|
||||
/*
|
||||
* Names of malloc types.
|
||||
*/
|
||||
extern char *memname[];
|
||||
#define TYPENAME(type) ((unsigned)(type) < M_LAST ? memname[type] : "???")
|
||||
#define TYPENAME(type) ((unsigned)(type) < D_LAST ? memtype[type]->ks_shortdesc : "???")
|
||||
|
||||
/*
|
||||
* Locking primitives.
|
||||
@ -317,7 +369,7 @@ sema_release(semap)
|
||||
(item)->wk_state &= ~ONWORKLIST; \
|
||||
LIST_REMOVE(item, wk_list); \
|
||||
} while (0)
|
||||
#define WORKITEM_FREE(item, type) FREE(item, type)
|
||||
#define WORKITEM_FREE(item, type) FREE(item, DtoM(type))
|
||||
|
||||
#else /* DEBUG */
|
||||
static void worklist_insert __P((struct workhead *, struct worklist *));
|
||||
@ -365,7 +417,7 @@ workitem_free(item, type)
|
||||
panic("workitem_free: still on list");
|
||||
if (item->wk_type != type)
|
||||
panic("workitem_free: type mismatch");
|
||||
FREE(item, type);
|
||||
FREE(item, DtoM(type));
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
@ -391,10 +443,11 @@ add_to_worklist(wk)
|
||||
if (wk->wk_state & ONWORKLIST)
|
||||
panic("add_to_worklist: already on list");
|
||||
wk->wk_state |= ONWORKLIST;
|
||||
if (LIST_FIRST(&softdep_workitem_pending) == NULL)
|
||||
if (LIST_FIRST(&softdep_workitem_pending) == NULL) {
|
||||
LIST_INSERT_HEAD(&softdep_workitem_pending, wk, wk_list);
|
||||
else
|
||||
} else {
|
||||
LIST_INSERT_AFTER(worklist_tail, wk, wk_list);
|
||||
}
|
||||
worklist_tail = wk;
|
||||
}
|
||||
|
||||
@ -433,28 +486,28 @@ softdep_process_worklist(matchmnt)
|
||||
FREE_LOCK(&lk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_DIRREM:
|
||||
case D_DIRREM:
|
||||
/* removal of a directory entry */
|
||||
if (WK_DIRREM(wk)->dm_mnt == matchmnt)
|
||||
matchcnt += 1;
|
||||
handle_workitem_remove(WK_DIRREM(wk));
|
||||
break;
|
||||
|
||||
case M_FREEBLKS:
|
||||
case D_FREEBLKS:
|
||||
/* releasing blocks and/or fragments from a file */
|
||||
if (WK_FREEBLKS(wk)->fb_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
handle_workitem_freeblocks(WK_FREEBLKS(wk));
|
||||
break;
|
||||
|
||||
case M_FREEFRAG:
|
||||
case D_FREEFRAG:
|
||||
/* releasing a fragment when replaced as a file grows */
|
||||
if (WK_FREEFRAG(wk)->ff_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
handle_workitem_freefrag(WK_FREEFRAG(wk));
|
||||
break;
|
||||
|
||||
case M_FREEFILE:
|
||||
case D_FREEFILE:
|
||||
/* releasing an inode when its link count drops to 0 */
|
||||
if (WK_FREEFILE(wk)->fx_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
@ -490,7 +543,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
* Await our turn to clear out the queue.
|
||||
*/
|
||||
while (softdep_worklist_busy)
|
||||
sleep(&lbolt, PRIBIO);
|
||||
tsleep(&lbolt, PRIBIO, "sdflsh", 0);
|
||||
softdep_worklist_busy = 1;
|
||||
if ((error = ffs_flushfiles(oldmnt, flags, p)) != 0) {
|
||||
softdep_worklist_busy = 0;
|
||||
@ -518,7 +571,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
break;
|
||||
}
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
error = VOP_FSYNC(devvp, p->p_cred, MNT_WAIT, p);
|
||||
error = VOP_FSYNC(devvp, p->p_ucred, MNT_WAIT, p);
|
||||
VOP_UNLOCK(devvp, 0, p);
|
||||
if (error)
|
||||
break;
|
||||
@ -530,7 +583,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
* activity can keep us busy forever, so we just fail with EBUSY.
|
||||
*/
|
||||
if (loopcnt == 0) {
|
||||
if (oldmnt->mnt_flag & MNT_UNMOUNT)
|
||||
if (oldmnt->mnt_kern_flag & MNTK_UNMOUNT)
|
||||
panic("softdep_flushfiles: looping");
|
||||
error = EBUSY;
|
||||
}
|
||||
@ -617,7 +670,7 @@ pagedep_lookup(ip, lbn, flags, pagedeppp)
|
||||
MALLOC(pagedep, struct pagedep *, sizeof(struct pagedep), M_PAGEDEP,
|
||||
M_WAITOK);
|
||||
bzero(pagedep, sizeof(struct pagedep));
|
||||
pagedep->pd_list.wk_type = M_PAGEDEP;
|
||||
pagedep->pd_list.wk_type = D_PAGEDEP;
|
||||
pagedep->pd_mnt = mp;
|
||||
pagedep->pd_ino = ip->i_number;
|
||||
pagedep->pd_lbn = lbn;
|
||||
@ -681,7 +734,7 @@ inodedep_lookup(fs, inum, flags, inodedeppp)
|
||||
}
|
||||
MALLOC(inodedep, struct inodedep *, sizeof(struct inodedep),
|
||||
M_INODEDEP, M_WAITOK);
|
||||
inodedep->id_list.wk_type = M_INODEDEP;
|
||||
inodedep->id_list.wk_type = D_INODEDEP;
|
||||
inodedep->id_fs = fs;
|
||||
inodedep->id_ino = inum;
|
||||
inodedep->id_state = ALLCOMPLETE;
|
||||
@ -922,12 +975,12 @@ bmsafemap_lookup(bp)
|
||||
panic("bmsafemap_lookup: lock not held");
|
||||
#endif
|
||||
for (wk = LIST_FIRST(&bp->b_dep); wk; wk = LIST_NEXT(wk, wk_list))
|
||||
if (wk->wk_type == M_BMSAFEMAP)
|
||||
if (wk->wk_type == D_BMSAFEMAP)
|
||||
return (WK_BMSAFEMAP(wk));
|
||||
FREE_LOCK(&lk);
|
||||
MALLOC(bmsafemap, struct bmsafemap *, sizeof(struct bmsafemap),
|
||||
M_BMSAFEMAP, M_WAITOK);
|
||||
bmsafemap->sm_list.wk_type = M_BMSAFEMAP;
|
||||
bmsafemap->sm_list.wk_type = D_BMSAFEMAP;
|
||||
bmsafemap->sm_list.wk_state = 0;
|
||||
bmsafemap->sm_buf = bp;
|
||||
LIST_INIT(&bmsafemap->sm_allocdirecthd);
|
||||
@ -988,7 +1041,7 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
|
||||
MALLOC(adp, struct allocdirect *, sizeof(struct allocdirect),
|
||||
M_ALLOCDIRECT, M_WAITOK);
|
||||
bzero(adp, sizeof(struct allocdirect));
|
||||
adp->ad_list.wk_type = M_ALLOCDIRECT;
|
||||
adp->ad_list.wk_type = D_ALLOCDIRECT;
|
||||
adp->ad_lbn = lbn;
|
||||
adp->ad_newblkno = newblkno;
|
||||
adp->ad_oldblkno = oldblkno;
|
||||
@ -1139,7 +1192,7 @@ newfreefrag(ip, blkno, size)
|
||||
panic("newfreefrag: frag size");
|
||||
MALLOC(freefrag, struct freefrag *, sizeof(struct freefrag),
|
||||
M_FREEFRAG, M_WAITOK);
|
||||
freefrag->ff_list.wk_type = M_FREEFRAG;
|
||||
freefrag->ff_list.wk_type = D_FREEFRAG;
|
||||
freefrag->ff_state = ip->i_uid & ~ONWORKLIST; /* XXX - used below */
|
||||
freefrag->ff_inum = ip->i_number;
|
||||
freefrag->ff_fs = fs;
|
||||
@ -1208,7 +1261,7 @@ newallocindir(ip, ptrno, newblkno, oldblkno)
|
||||
MALLOC(aip, struct allocindir *, sizeof(struct allocindir),
|
||||
M_ALLOCINDIR, M_WAITOK);
|
||||
bzero(aip, sizeof(struct allocindir));
|
||||
aip->ai_list.wk_type = M_ALLOCINDIR;
|
||||
aip->ai_list.wk_type = D_ALLOCINDIR;
|
||||
aip->ai_state = ATTACHED;
|
||||
aip->ai_offset = ptrno;
|
||||
aip->ai_newblkno = newblkno;
|
||||
@ -1293,7 +1346,7 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
for (wk = LIST_FIRST(&bp->b_dep); wk;
|
||||
wk = LIST_NEXT(wk, wk_list)) {
|
||||
if (wk->wk_type != M_INDIRDEP)
|
||||
if (wk->wk_type != D_INDIRDEP)
|
||||
continue;
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
break;
|
||||
@ -1351,13 +1404,13 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
if (newindirdep) {
|
||||
if (indirdep->ir_savebp != NULL)
|
||||
brelse(newindirdep->ir_savebp);
|
||||
WORKITEM_FREE((caddr_t)newindirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE((caddr_t)newindirdep, D_INDIRDEP);
|
||||
}
|
||||
if (indirdep)
|
||||
break;
|
||||
MALLOC(newindirdep, struct indirdep *, sizeof(struct indirdep),
|
||||
M_INDIRDEP, M_WAITOK);
|
||||
newindirdep->ir_list.wk_type = M_INDIRDEP;
|
||||
newindirdep->ir_list.wk_type = D_INDIRDEP;
|
||||
newindirdep->ir_state = ATTACHED;
|
||||
LIST_INIT(&newindirdep->ir_deplisthd);
|
||||
LIST_INIT(&newindirdep->ir_donehd);
|
||||
@ -1417,7 +1470,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
|
||||
M_FREEBLKS, M_WAITOK);
|
||||
bzero(freeblks, sizeof(struct freeblks));
|
||||
freeblks->fb_list.wk_type = M_FREEBLKS;
|
||||
freeblks->fb_list.wk_type = D_FREEBLKS;
|
||||
freeblks->fb_uid = ip->i_uid;
|
||||
freeblks->fb_previousinum = ip->i_number;
|
||||
freeblks->fb_devvp = ip->i_devvp;
|
||||
@ -1479,7 +1532,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "sdsetf", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
while (getdirtybuf(&LIST_FIRST(&vp->v_dirtyblkhd), MNT_WAIT)) {
|
||||
@ -1522,7 +1575,7 @@ deallocate_dependencies(bp, inodedep)
|
||||
while ((wk = LIST_FIRST(&bp->b_dep)) != NULL) {
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
/*
|
||||
* None of the indirect pointers will ever be visible,
|
||||
@ -1556,7 +1609,7 @@ deallocate_dependencies(bp, inodedep)
|
||||
WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk);
|
||||
continue;
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
pagedep = WK_PAGEDEP(wk);
|
||||
/*
|
||||
* None of the directory additions will ever be
|
||||
@ -1585,15 +1638,15 @@ deallocate_dependencies(bp, inodedep)
|
||||
}
|
||||
WORKLIST_REMOVE(&pagedep->pd_list);
|
||||
LIST_REMOVE(pagedep, pd_hash);
|
||||
WORKITEM_FREE(pagedep, M_PAGEDEP);
|
||||
WORKITEM_FREE(pagedep, D_PAGEDEP);
|
||||
continue;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
free_allocindir(WK_ALLOCINDIR(wk), inodedep);
|
||||
continue;
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case M_INODEDEP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_INODEDEP:
|
||||
panic("deallocate_dependencies: Unexpected type %s",
|
||||
TYPENAME(wk->wk_type));
|
||||
/* NOTREACHED */
|
||||
@ -1633,7 +1686,7 @@ free_allocdirect(adphead, adp, delay)
|
||||
else
|
||||
add_to_worklist(&adp->ad_freefrag->ff_list);
|
||||
}
|
||||
WORKITEM_FREE(adp, M_ALLOCDIRECT);
|
||||
WORKITEM_FREE(adp, D_ALLOCDIRECT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1641,14 +1694,12 @@ free_allocdirect(adphead, adp, delay)
|
||||
* done until the zero'ed inode has been written to disk.
|
||||
*/
|
||||
void
|
||||
softdep_freefile(ap)
|
||||
struct vop_vfree_args /* {
|
||||
struct vnode *a_pvp;
|
||||
ino_t a_ino;
|
||||
int a_mode;
|
||||
} */ *ap;
|
||||
softdep_freefile(pvp, ino, mode)
|
||||
struct vnode *pvp;
|
||||
ino_t ino;
|
||||
int mode;
|
||||
{
|
||||
struct inode *ip = VTOI(ap->a_pvp);
|
||||
struct inode *ip = VTOI(pvp);
|
||||
struct inodedep *inodedep;
|
||||
struct freefile *freefile;
|
||||
|
||||
@ -1657,10 +1708,10 @@ softdep_freefile(ap)
|
||||
*/
|
||||
MALLOC(freefile, struct freefile *, sizeof(struct freefile),
|
||||
M_FREEFILE, M_WAITOK);
|
||||
freefile->fx_list.wk_type = M_FREEFILE;
|
||||
freefile->fx_list.wk_type = D_FREEFILE;
|
||||
freefile->fx_list.wk_state = 0;
|
||||
freefile->fx_mode = ap->a_mode;
|
||||
freefile->fx_oldinum = ap->a_ino;
|
||||
freefile->fx_mode = mode;
|
||||
freefile->fx_oldinum = ino;
|
||||
freefile->fx_devvp = ip->i_devvp;
|
||||
freefile->fx_fs = ip->i_fs;
|
||||
|
||||
@ -1669,7 +1720,7 @@ softdep_freefile(ap)
|
||||
* been written to disk and we can free the file immediately.
|
||||
*/
|
||||
ACQUIRE_LOCK(&lk);
|
||||
if (inodedep_lookup(ip->i_fs, ap->a_ino, 0, &inodedep) == 0) {
|
||||
if (inodedep_lookup(ip->i_fs, ino, 0, &inodedep) == 0) {
|
||||
add_to_worklist(&freefile->fx_list);
|
||||
FREE_LOCK(&lk);
|
||||
return;
|
||||
@ -1719,7 +1770,7 @@ free_inodedep(inodedep)
|
||||
inodedep->id_nlinkdelta != 0 || inodedep->id_savedino != NULL)
|
||||
return (0);
|
||||
LIST_REMOVE(inodedep, id_hash);
|
||||
WORKITEM_FREE(inodedep, M_INODEDEP);
|
||||
WORKITEM_FREE(inodedep, D_INODEDEP);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -1787,7 +1838,7 @@ handle_workitem_freeblocks(freeblks)
|
||||
if (allerror)
|
||||
softdep_error("handle_workitem_freeblks", allerror);
|
||||
#endif /* DIAGNOSTIC */
|
||||
WORKITEM_FREE(freeblks, M_FREEBLKS);
|
||||
WORKITEM_FREE(freeblks, D_FREEBLKS);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1832,12 +1883,12 @@ indir_trunc(ip, dbn, level, lbn, countp)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
if ((bp = incore(ip->i_devvp, dbn)) != NULL &&
|
||||
(wk = LIST_FIRST(&bp->b_dep)) != NULL) {
|
||||
if (wk->wk_type != M_INDIRDEP ||
|
||||
if (wk->wk_type != D_INDIRDEP ||
|
||||
(indirdep = WK_INDIRDEP(wk))->ir_savebp != bp ||
|
||||
(indirdep->ir_state & GOINGAWAY) == 0)
|
||||
panic("indir_trunc: lost indirdep");
|
||||
WORKLIST_REMOVE(wk);
|
||||
WORKITEM_FREE(indirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE(indirdep, D_INDIRDEP);
|
||||
if (LIST_FIRST(&bp->b_dep) != NULL)
|
||||
panic("indir_trunc: dangling dep");
|
||||
FREE_LOCK(&lk);
|
||||
@ -1895,7 +1946,7 @@ free_allocindir(aip, inodedep)
|
||||
WORKLIST_INSERT(&inodedep->id_inowait,
|
||||
&freefrag->ff_list);
|
||||
}
|
||||
WORKITEM_FREE(aip, M_ALLOCINDIR);
|
||||
WORKITEM_FREE(aip, D_ALLOCINDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1951,36 +2002,32 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp)
|
||||
offset = blkoff(fs, diroffset);
|
||||
MALLOC(dap, struct diradd *, sizeof(struct diradd), M_DIRADD, M_WAITOK);
|
||||
bzero(dap, sizeof(struct diradd));
|
||||
dap->da_list.wk_type = M_DIRADD;
|
||||
dap->da_list.wk_type = D_DIRADD;
|
||||
dap->da_offset = offset;
|
||||
dap->da_newinum = newinum;
|
||||
dap->da_state = ATTACHED;
|
||||
if (newdirbp == NULL) {
|
||||
dap->da_state |= DEPCOMPLETE;
|
||||
ACQUIRE_LOCK(&lk);
|
||||
} else {
|
||||
dap->da_state |= MKDIR_BODY | MKDIR_PARENT;
|
||||
MALLOC(mkdir1, struct mkdir *, sizeof(struct mkdir), M_MKDIR,
|
||||
M_WAITOK);
|
||||
mkdir1->md_list.wk_type = M_MKDIR;
|
||||
mkdir1->md_list.wk_type = D_MKDIR;
|
||||
mkdir1->md_state = MKDIR_BODY;
|
||||
mkdir1->md_diradd = dap;
|
||||
MALLOC(mkdir2, struct mkdir *, sizeof(struct mkdir), M_MKDIR,
|
||||
M_WAITOK);
|
||||
mkdir2->md_list.wk_type = M_MKDIR;
|
||||
mkdir2->md_list.wk_type = D_MKDIR;
|
||||
mkdir2->md_state = MKDIR_PARENT;
|
||||
mkdir2->md_diradd = dap;
|
||||
|
||||
}
|
||||
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
* If this directory entry references a new directory, create
|
||||
* its two additional dependencies: its "." and ".." being written
|
||||
* to disk and the link count increase for its parent directory.
|
||||
*/
|
||||
if (newdirbp != NULL) {
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
* Dependency on "." and ".." being written to disk
|
||||
* If this directory entry references a new directory, create
|
||||
* its two additional dependencies: its "." and ".." being
|
||||
* written to disk and the link count increase for its
|
||||
* parent directory.
|
||||
*/
|
||||
LIST_INSERT_HEAD(&mkdirlisthd, mkdir1, md_mkdirs);
|
||||
WORKLIST_INSERT(&newdirbp->b_dep, &mkdir1->md_list);
|
||||
@ -1991,7 +2038,7 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp)
|
||||
if (inodedep_lookup(dp->i_fs, dp->i_number, 0, &inodedep) == 0
|
||||
|| (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
dap->da_state &= ~MKDIR_PARENT;
|
||||
WORKITEM_FREE(mkdir2, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir2, D_MKDIR);
|
||||
} else {
|
||||
LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
|
||||
WORKLIST_INSERT(&inodedep->id_inowait,&mkdir2->md_list);
|
||||
@ -2095,12 +2142,12 @@ free_diradd(dap)
|
||||
dap->da_state &= ~mkdir->md_state;
|
||||
WORKLIST_REMOVE(&mkdir->md_list);
|
||||
LIST_REMOVE(mkdir, md_mkdirs);
|
||||
WORKITEM_FREE(mkdir, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir, D_MKDIR);
|
||||
}
|
||||
if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
|
||||
panic("free_diradd: unfound ref");
|
||||
}
|
||||
WORKITEM_FREE(dap, M_DIRADD);
|
||||
WORKITEM_FREE(dap, D_DIRADD);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2168,7 +2215,7 @@ newdirrem(bp, dp, ip, isrmdir)
|
||||
MALLOC(dirrem, struct dirrem *, sizeof(struct dirrem),
|
||||
M_DIRREM, M_WAITOK);
|
||||
bzero(dirrem, sizeof(struct dirrem));
|
||||
dirrem->dm_list.wk_type = M_DIRREM;
|
||||
dirrem->dm_list.wk_type = D_DIRREM;
|
||||
dirrem->dm_state = isrmdir ? RMDIR : 0;
|
||||
dirrem->dm_mnt = ITOV(ip)->v_mount;
|
||||
dirrem->dm_oldinum = ip->i_number;
|
||||
@ -2244,7 +2291,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
|
||||
MALLOC(dap, struct diradd *, sizeof(struct diradd),
|
||||
M_DIRADD, M_WAITOK);
|
||||
bzero(dap, sizeof(struct diradd));
|
||||
dap->da_list.wk_type = M_DIRADD;
|
||||
dap->da_list.wk_type = D_DIRADD;
|
||||
dap->da_state = DIRCHG | ATTACHED | DEPCOMPLETE;
|
||||
dap->da_offset = offset;
|
||||
dap->da_newinum = newinum;
|
||||
@ -2261,7 +2308,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
|
||||
*/
|
||||
if (inodedep_lookup(dp->i_fs, newinum, 0, &inodedep) == 0 ||
|
||||
(inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
WORKITEM_FREE(dap, M_DIRADD);
|
||||
WORKITEM_FREE(dap, D_DIRADD);
|
||||
dap = NULL;
|
||||
}
|
||||
|
||||
@ -2330,7 +2377,7 @@ handle_workitem_remove(dirrem)
|
||||
}
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
vput(vp);
|
||||
WORKITEM_FREE(dirrem, M_DIRREM);
|
||||
WORKITEM_FREE(dirrem, D_DIRREM);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -2344,7 +2391,7 @@ handle_workitem_remove(dirrem)
|
||||
if (ip->i_nlink < ip->i_effnlink)
|
||||
panic("handle_workitem_remove: bad dir delta");
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
if ((error = VOP_TRUNCATE(vp, (off_t)0, 0, p->p_cred, p)) != 0)
|
||||
if ((error = UFS_TRUNCATE(vp, (off_t)0, 0, p->p_ucred, p)) != 0)
|
||||
softdep_error("handle_workitem_remove: truncate", error);
|
||||
ACQUIRE_LOCK(&lk);
|
||||
(void) inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, DEPALLOC,
|
||||
@ -2377,7 +2424,6 @@ handle_workitem_freefile(freefile)
|
||||
struct vnode vp;
|
||||
struct inode tip;
|
||||
struct inodedep *idp;
|
||||
struct vop_vfree_args args;
|
||||
int error;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -2390,12 +2436,9 @@ handle_workitem_freefile(freefile)
|
||||
tip.i_dev = freefile->fx_devvp->v_rdev;
|
||||
tip.i_fs = freefile->fx_fs;
|
||||
vp.v_data = &tip;
|
||||
args.a_pvp = &vp;
|
||||
args.a_ino = freefile->fx_oldinum;
|
||||
args.a_mode = freefile->fx_mode;
|
||||
if ((error = ffs_freefile(&args)) != 0)
|
||||
if ((error = ffs_freefile(&vp, freefile->fx_oldinum, freefile->fx_mode)) != 0)
|
||||
softdep_error("handle_workitem_freefile", error);
|
||||
WORKITEM_FREE(freefile, M_FREEFILE);
|
||||
WORKITEM_FREE(freefile, D_FREEFILE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2440,15 +2483,15 @@ softdep_disk_io_initiation(bp)
|
||||
nextwk = LIST_NEXT(wk, wk_list);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
initiate_write_filepage(WK_PAGEDEP(wk), bp);
|
||||
continue;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
initiate_write_inodeblock(WK_INODEDEP(wk), bp);
|
||||
continue;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
if (indirdep->ir_state & GOINGAWAY)
|
||||
panic("disk_io_initiation: indirdep gone");
|
||||
@ -2462,7 +2505,7 @@ softdep_disk_io_initiation(bp)
|
||||
/* inline expand WORKLIST_REMOVE(wk); */
|
||||
wk->wk_state &= ~ONWORKLIST;
|
||||
LIST_REMOVE(wk, wk_list);
|
||||
WORKITEM_FREE(indirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE(indirdep, D_INDIRDEP);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -2475,10 +2518,10 @@ softdep_disk_io_initiation(bp)
|
||||
FREE_LOCK(&lk);
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case M_BMSAFEMAP:
|
||||
case M_ALLOCDIRECT:
|
||||
case M_ALLOCINDIR:
|
||||
case D_MKDIR:
|
||||
case D_BMSAFEMAP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_ALLOCINDIR:
|
||||
continue;
|
||||
|
||||
default:
|
||||
@ -2549,7 +2592,7 @@ initiate_write_inodeblock(inodedep, bp)
|
||||
struct allocdirect *adp, *lastadp;
|
||||
struct dinode *dp;
|
||||
struct fs *fs;
|
||||
ufs_lbn_t prevlbn;
|
||||
ufs_lbn_t prevlbn = 0;
|
||||
int i, deplist;
|
||||
|
||||
if (inodedep->id_state & IOSTARTED)
|
||||
@ -2698,17 +2741,17 @@ softdep_disk_write_complete(bp)
|
||||
WORKLIST_REMOVE(wk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
if (handle_written_filepage(WK_PAGEDEP(wk), bp))
|
||||
WORKLIST_INSERT(&reattach, wk);
|
||||
continue;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
if (handle_written_inodeblock(WK_INODEDEP(wk), bp))
|
||||
WORKLIST_INSERT(&reattach, wk);
|
||||
continue;
|
||||
|
||||
case M_BMSAFEMAP:
|
||||
case D_BMSAFEMAP:
|
||||
bmsafemap = WK_BMSAFEMAP(wk);
|
||||
while (newblk = LIST_FIRST(&bmsafemap->sm_newblkhd)) {
|
||||
newblk->nb_state |= DEPCOMPLETE;
|
||||
@ -2733,26 +2776,26 @@ softdep_disk_write_complete(bp)
|
||||
LIST_REMOVE(inodedep, id_deps);
|
||||
inodedep->id_buf = NULL;
|
||||
}
|
||||
WORKITEM_FREE(bmsafemap, M_BMSAFEMAP);
|
||||
WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case D_MKDIR:
|
||||
handle_written_mkdir(WK_MKDIR(wk), MKDIR_BODY);
|
||||
continue;
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case D_ALLOCDIRECT:
|
||||
adp = WK_ALLOCDIRECT(wk);
|
||||
adp->ad_state |= COMPLETE;
|
||||
handle_allocdirect_partdone(adp);
|
||||
continue;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
aip = WK_ALLOCINDIR(wk);
|
||||
aip->ai_state |= COMPLETE;
|
||||
handle_allocindir_partdone(aip);
|
||||
continue;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
if (indirdep->ir_state & GOINGAWAY)
|
||||
panic("disk_write_complete: indirdep gone");
|
||||
@ -2883,7 +2926,7 @@ handle_allocindir_partdone(aip)
|
||||
LIST_REMOVE(aip, ai_next);
|
||||
if (aip->ai_freefrag != NULL)
|
||||
add_to_worklist(&aip->ai_freefrag->ff_list);
|
||||
WORKITEM_FREE(aip, M_ALLOCINDIR);
|
||||
WORKITEM_FREE(aip, D_ALLOCINDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2986,7 +3029,7 @@ handle_written_inodeblock(inodedep, bp)
|
||||
WORKLIST_REMOVE(wk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_FREEFILE:
|
||||
case D_FREEFILE:
|
||||
/*
|
||||
* We defer adding filefree to the worklist until
|
||||
* all other additions have been made to ensure
|
||||
@ -2998,11 +3041,11 @@ handle_written_inodeblock(inodedep, bp)
|
||||
filefree = wk;
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case D_MKDIR:
|
||||
handle_written_mkdir(WK_MKDIR(wk), MKDIR_PARENT);
|
||||
continue;
|
||||
|
||||
case M_DIRADD:
|
||||
case D_DIRADD:
|
||||
dap = WK_DIRADD(wk);
|
||||
dap->da_state |= COMPLETE;
|
||||
if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
@ -3017,9 +3060,9 @@ handle_written_inodeblock(inodedep, bp)
|
||||
WORKLIST_INSERT(&inodedep->id_pendinghd, wk);
|
||||
continue;
|
||||
|
||||
case M_FREEBLKS:
|
||||
case M_FREEFRAG:
|
||||
case M_DIRREM:
|
||||
case D_FREEBLKS:
|
||||
case D_FREEFRAG:
|
||||
case D_DIRREM:
|
||||
add_to_worklist(wk);
|
||||
continue;
|
||||
|
||||
@ -3066,7 +3109,7 @@ handle_written_mkdir(mkdir, type)
|
||||
LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
|
||||
}
|
||||
LIST_REMOVE(mkdir, md_mkdirs);
|
||||
WORKITEM_FREE(mkdir, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir, D_MKDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3147,7 +3190,7 @@ handle_written_filepage(pagedep, bp)
|
||||
break;
|
||||
if (i == DAHASHSZ) {
|
||||
LIST_REMOVE(pagedep, pd_hash);
|
||||
WORKITEM_FREE(pagedep, M_PAGEDEP);
|
||||
WORKITEM_FREE(pagedep, D_PAGEDEP);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -3343,7 +3386,7 @@ softdep_fsync(vp)
|
||||
panic("softdep_fsync: pending ops");
|
||||
if ((wk = LIST_FIRST(&inodedep->id_pendinghd)) == NULL)
|
||||
break;
|
||||
if (wk->wk_type != M_DIRADD)
|
||||
if (wk->wk_type != D_DIRADD)
|
||||
panic("softdep_fsync: Unexpected type %s",
|
||||
TYPENAME(wk->wk_type));
|
||||
dap = WK_DIRADD(wk);
|
||||
@ -3394,7 +3437,7 @@ softdep_fsync(vp)
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
if (flushparent) {
|
||||
tv = time;
|
||||
if (error = VOP_UPDATE(pvp, &tv, &tv, MNT_WAIT)) {
|
||||
if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) {
|
||||
vput(pvp);
|
||||
return (error);
|
||||
}
|
||||
@ -3490,7 +3533,7 @@ softdep_sync_metadata(ap)
|
||||
wk = LIST_NEXT(wk, wk_list)) {
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case D_ALLOCDIRECT:
|
||||
adp = WK_ALLOCDIRECT(wk);
|
||||
if (adp->ad_state & DEPCOMPLETE)
|
||||
break;
|
||||
@ -3507,7 +3550,7 @@ softdep_sync_metadata(ap)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
break;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
aip = WK_ALLOCINDIR(wk);
|
||||
if (aip->ai_state & DEPCOMPLETE)
|
||||
break;
|
||||
@ -3524,7 +3567,7 @@ softdep_sync_metadata(ap)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
break;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
restart:
|
||||
for (aip = LIST_FIRST(&WK_INDIRDEP(wk)->ir_deplisthd);
|
||||
aip; aip = LIST_NEXT(aip, ai_next)) {
|
||||
@ -3543,7 +3586,7 @@ softdep_sync_metadata(ap)
|
||||
}
|
||||
break;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
if ((error = flush_inodedep_deps(WK_INODEDEP(wk)->id_fs,
|
||||
WK_INODEDEP(wk)->id_ino)) != 0) {
|
||||
FREE_LOCK(&lk);
|
||||
@ -3552,7 +3595,7 @@ softdep_sync_metadata(ap)
|
||||
}
|
||||
break;
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
/*
|
||||
* We are trying to sync a directory that may
|
||||
* have dependencies on both its own metadata
|
||||
@ -3597,7 +3640,7 @@ softdep_sync_metadata(ap)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "sdsynm", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
/*
|
||||
@ -3737,7 +3780,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
struct diradd *dap;
|
||||
struct timeval tv;
|
||||
struct vnode *vp;
|
||||
int gotit, error;
|
||||
int gotit, error = 0;
|
||||
struct buf *bp;
|
||||
ino_t inum;
|
||||
|
||||
@ -3750,7 +3793,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
if (dap->da_state & MKDIR_PARENT) {
|
||||
tv = time;
|
||||
FREE_LOCK(&lk);
|
||||
if (error = VOP_UPDATE(pvp, &tv, &tv, MNT_WAIT))
|
||||
if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT))
|
||||
break;
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
@ -3818,7 +3861,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
* level in the filesystem. Instead, we push the blocks
|
||||
* and wait for them to clear.
|
||||
*/
|
||||
if (error = VOP_FSYNC(vp, p->p_cred, MNT_NOWAIT, p)) {
|
||||
if (error = VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p)) {
|
||||
vput(vp);
|
||||
break;
|
||||
}
|
||||
@ -3826,13 +3869,14 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1,
|
||||
"sdflpd", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
FREE_LOCK(&lk);
|
||||
}
|
||||
tv = time;
|
||||
error = VOP_UPDATE(vp, &tv, &tv, MNT_WAIT);
|
||||
error = UFS_UPDATE(vp, &tv, &tv, MNT_WAIT);
|
||||
vput(vp);
|
||||
if (error)
|
||||
break;
|
||||
@ -3870,7 +3914,7 @@ getdirtybuf(bpp, waitfor)
|
||||
return (0);
|
||||
bp->b_flags |= B_WANTED;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)bp, PRIBIO + 1);
|
||||
tsleep((caddr_t)bp, PRIBIO + 1, "sdsdty", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
if ((bp->b_flags & B_DELWRI) == 0)
|
||||
@ -3906,13 +3950,13 @@ softdep_deallocate_dependencies(bp)
|
||||
* force fsck to be run (though this would best be done
|
||||
* in the mainline code).
|
||||
*/
|
||||
case M_PAGEDEP:
|
||||
case M_INODEDEP:
|
||||
case M_BMSAFEMAP:
|
||||
case M_ALLOCDIRECT:
|
||||
case M_INDIRDEP:
|
||||
case M_ALLOCINDIR:
|
||||
case M_MKDIR:
|
||||
case D_PAGEDEP:
|
||||
case D_INODEDEP:
|
||||
case D_BMSAFEMAP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_INDIRDEP:
|
||||
case D_ALLOCINDIR:
|
||||
case D_MKDIR:
|
||||
#ifdef DEBUG
|
||||
printf("Lost type %s\n", TYPENAME(wk->wk_type));
|
||||
#endif
|
||||
|
@ -52,7 +52,6 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* from: @(#)softdep.h 9.4 (McKusick) 1/15/98
|
||||
*/
|
||||
|
||||
|
@ -52,7 +52,6 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* from: @(#)ffs_softdep.c 9.14 (McKusick) 1/15/98
|
||||
*/
|
||||
|
||||
@ -75,7 +74,7 @@
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <machine/pcpu.h>
|
||||
/*#include <machine/pcpu.h>*/
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
@ -141,11 +140,64 @@ struct bio_ops bioops = {
|
||||
softdep_process_worklist, /* io_sync */
|
||||
};
|
||||
|
||||
/*
|
||||
* malloc types defined for the softdep system.
|
||||
*/
|
||||
MALLOC_DEFINE(M_PAGEDEP, "pagedep","File page dependencies");
|
||||
MALLOC_DEFINE(M_INODEDEP, "inodedep","Inode dependencies");
|
||||
MALLOC_DEFINE(M_NEWBLK, "newblk","New block allocation");
|
||||
MALLOC_DEFINE(M_BMSAFEMAP, "bmsafemap","Block or frag allocated from cyl group map");
|
||||
MALLOC_DEFINE(M_ALLOCDIRECT, "allocdirect","Block or frag dependency for an inode");
|
||||
MALLOC_DEFINE(M_INDIRDEP, "indirdep","Indirect block dependencies");
|
||||
MALLOC_DEFINE(M_ALLOCINDIR, "allocindir","Block dependency for an indirect block");
|
||||
MALLOC_DEFINE(M_FREEFRAG, "freefrag","Previously used frag for an inode");
|
||||
MALLOC_DEFINE(M_FREEBLKS, "freeblks","Blocks freed from an inode");
|
||||
MALLOC_DEFINE(M_FREEFILE, "freefile","Inode deallocated");
|
||||
MALLOC_DEFINE(M_DIRADD, "diradd","New directory entry");
|
||||
MALLOC_DEFINE(M_MKDIR, "mkdir","New directory");
|
||||
MALLOC_DEFINE(M_DIRREM, "dirrem","Directory entry deleted");
|
||||
|
||||
#define D_PAGEDEP 0
|
||||
#define D_INODEDEP 1
|
||||
#define D_NEWBLK 2
|
||||
#define D_BMSAFEMAP 3
|
||||
#define D_ALLOCDIRECT 4
|
||||
#define D_INDIRDEP 5
|
||||
#define D_ALLOCINDIR 6
|
||||
#define D_FREEFRAG 7
|
||||
#define D_FREEBLKS 8
|
||||
#define D_FREEFILE 9
|
||||
#define D_DIRADD 10
|
||||
#define D_MKDIR 11
|
||||
#define D_DIRREM 12
|
||||
#define D_LAST D_DIRREM
|
||||
|
||||
/*
|
||||
* translate from workitem type to memory type
|
||||
* MUST match the defines above, such that memtype[D_XXX] == M_XXX
|
||||
*/
|
||||
static struct malloc_type *memtype[] = {
|
||||
M_PAGEDEP,
|
||||
M_INODEDEP,
|
||||
M_NEWBLK,
|
||||
M_BMSAFEMAP,
|
||||
M_ALLOCDIRECT,
|
||||
M_INDIRDEP,
|
||||
M_ALLOCINDIR,
|
||||
M_FREEFRAG,
|
||||
M_FREEBLKS,
|
||||
M_FREEFILE,
|
||||
M_DIRADD,
|
||||
M_MKDIR,
|
||||
M_DIRREM
|
||||
};
|
||||
|
||||
#define DtoM(type) (memtype[type])
|
||||
|
||||
/*
|
||||
* Names of malloc types.
|
||||
*/
|
||||
extern char *memname[];
|
||||
#define TYPENAME(type) ((unsigned)(type) < M_LAST ? memname[type] : "???")
|
||||
#define TYPENAME(type) ((unsigned)(type) < D_LAST ? memtype[type]->ks_shortdesc : "???")
|
||||
|
||||
/*
|
||||
* Locking primitives.
|
||||
@ -317,7 +369,7 @@ sema_release(semap)
|
||||
(item)->wk_state &= ~ONWORKLIST; \
|
||||
LIST_REMOVE(item, wk_list); \
|
||||
} while (0)
|
||||
#define WORKITEM_FREE(item, type) FREE(item, type)
|
||||
#define WORKITEM_FREE(item, type) FREE(item, DtoM(type))
|
||||
|
||||
#else /* DEBUG */
|
||||
static void worklist_insert __P((struct workhead *, struct worklist *));
|
||||
@ -365,7 +417,7 @@ workitem_free(item, type)
|
||||
panic("workitem_free: still on list");
|
||||
if (item->wk_type != type)
|
||||
panic("workitem_free: type mismatch");
|
||||
FREE(item, type);
|
||||
FREE(item, DtoM(type));
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
@ -391,10 +443,11 @@ add_to_worklist(wk)
|
||||
if (wk->wk_state & ONWORKLIST)
|
||||
panic("add_to_worklist: already on list");
|
||||
wk->wk_state |= ONWORKLIST;
|
||||
if (LIST_FIRST(&softdep_workitem_pending) == NULL)
|
||||
if (LIST_FIRST(&softdep_workitem_pending) == NULL) {
|
||||
LIST_INSERT_HEAD(&softdep_workitem_pending, wk, wk_list);
|
||||
else
|
||||
} else {
|
||||
LIST_INSERT_AFTER(worklist_tail, wk, wk_list);
|
||||
}
|
||||
worklist_tail = wk;
|
||||
}
|
||||
|
||||
@ -433,28 +486,28 @@ softdep_process_worklist(matchmnt)
|
||||
FREE_LOCK(&lk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_DIRREM:
|
||||
case D_DIRREM:
|
||||
/* removal of a directory entry */
|
||||
if (WK_DIRREM(wk)->dm_mnt == matchmnt)
|
||||
matchcnt += 1;
|
||||
handle_workitem_remove(WK_DIRREM(wk));
|
||||
break;
|
||||
|
||||
case M_FREEBLKS:
|
||||
case D_FREEBLKS:
|
||||
/* releasing blocks and/or fragments from a file */
|
||||
if (WK_FREEBLKS(wk)->fb_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
handle_workitem_freeblocks(WK_FREEBLKS(wk));
|
||||
break;
|
||||
|
||||
case M_FREEFRAG:
|
||||
case D_FREEFRAG:
|
||||
/* releasing a fragment when replaced as a file grows */
|
||||
if (WK_FREEFRAG(wk)->ff_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
handle_workitem_freefrag(WK_FREEFRAG(wk));
|
||||
break;
|
||||
|
||||
case M_FREEFILE:
|
||||
case D_FREEFILE:
|
||||
/* releasing an inode when its link count drops to 0 */
|
||||
if (WK_FREEFILE(wk)->fx_fs == matchfs)
|
||||
matchcnt += 1;
|
||||
@ -490,7 +543,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
* Await our turn to clear out the queue.
|
||||
*/
|
||||
while (softdep_worklist_busy)
|
||||
sleep(&lbolt, PRIBIO);
|
||||
tsleep(&lbolt, PRIBIO, "sdflsh", 0);
|
||||
softdep_worklist_busy = 1;
|
||||
if ((error = ffs_flushfiles(oldmnt, flags, p)) != 0) {
|
||||
softdep_worklist_busy = 0;
|
||||
@ -518,7 +571,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
break;
|
||||
}
|
||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
error = VOP_FSYNC(devvp, p->p_cred, MNT_WAIT, p);
|
||||
error = VOP_FSYNC(devvp, p->p_ucred, MNT_WAIT, p);
|
||||
VOP_UNLOCK(devvp, 0, p);
|
||||
if (error)
|
||||
break;
|
||||
@ -530,7 +583,7 @@ softdep_flushfiles(oldmnt, flags, p)
|
||||
* activity can keep us busy forever, so we just fail with EBUSY.
|
||||
*/
|
||||
if (loopcnt == 0) {
|
||||
if (oldmnt->mnt_flag & MNT_UNMOUNT)
|
||||
if (oldmnt->mnt_kern_flag & MNTK_UNMOUNT)
|
||||
panic("softdep_flushfiles: looping");
|
||||
error = EBUSY;
|
||||
}
|
||||
@ -617,7 +670,7 @@ pagedep_lookup(ip, lbn, flags, pagedeppp)
|
||||
MALLOC(pagedep, struct pagedep *, sizeof(struct pagedep), M_PAGEDEP,
|
||||
M_WAITOK);
|
||||
bzero(pagedep, sizeof(struct pagedep));
|
||||
pagedep->pd_list.wk_type = M_PAGEDEP;
|
||||
pagedep->pd_list.wk_type = D_PAGEDEP;
|
||||
pagedep->pd_mnt = mp;
|
||||
pagedep->pd_ino = ip->i_number;
|
||||
pagedep->pd_lbn = lbn;
|
||||
@ -681,7 +734,7 @@ inodedep_lookup(fs, inum, flags, inodedeppp)
|
||||
}
|
||||
MALLOC(inodedep, struct inodedep *, sizeof(struct inodedep),
|
||||
M_INODEDEP, M_WAITOK);
|
||||
inodedep->id_list.wk_type = M_INODEDEP;
|
||||
inodedep->id_list.wk_type = D_INODEDEP;
|
||||
inodedep->id_fs = fs;
|
||||
inodedep->id_ino = inum;
|
||||
inodedep->id_state = ALLCOMPLETE;
|
||||
@ -922,12 +975,12 @@ bmsafemap_lookup(bp)
|
||||
panic("bmsafemap_lookup: lock not held");
|
||||
#endif
|
||||
for (wk = LIST_FIRST(&bp->b_dep); wk; wk = LIST_NEXT(wk, wk_list))
|
||||
if (wk->wk_type == M_BMSAFEMAP)
|
||||
if (wk->wk_type == D_BMSAFEMAP)
|
||||
return (WK_BMSAFEMAP(wk));
|
||||
FREE_LOCK(&lk);
|
||||
MALLOC(bmsafemap, struct bmsafemap *, sizeof(struct bmsafemap),
|
||||
M_BMSAFEMAP, M_WAITOK);
|
||||
bmsafemap->sm_list.wk_type = M_BMSAFEMAP;
|
||||
bmsafemap->sm_list.wk_type = D_BMSAFEMAP;
|
||||
bmsafemap->sm_list.wk_state = 0;
|
||||
bmsafemap->sm_buf = bp;
|
||||
LIST_INIT(&bmsafemap->sm_allocdirecthd);
|
||||
@ -988,7 +1041,7 @@ softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)
|
||||
MALLOC(adp, struct allocdirect *, sizeof(struct allocdirect),
|
||||
M_ALLOCDIRECT, M_WAITOK);
|
||||
bzero(adp, sizeof(struct allocdirect));
|
||||
adp->ad_list.wk_type = M_ALLOCDIRECT;
|
||||
adp->ad_list.wk_type = D_ALLOCDIRECT;
|
||||
adp->ad_lbn = lbn;
|
||||
adp->ad_newblkno = newblkno;
|
||||
adp->ad_oldblkno = oldblkno;
|
||||
@ -1139,7 +1192,7 @@ newfreefrag(ip, blkno, size)
|
||||
panic("newfreefrag: frag size");
|
||||
MALLOC(freefrag, struct freefrag *, sizeof(struct freefrag),
|
||||
M_FREEFRAG, M_WAITOK);
|
||||
freefrag->ff_list.wk_type = M_FREEFRAG;
|
||||
freefrag->ff_list.wk_type = D_FREEFRAG;
|
||||
freefrag->ff_state = ip->i_uid & ~ONWORKLIST; /* XXX - used below */
|
||||
freefrag->ff_inum = ip->i_number;
|
||||
freefrag->ff_fs = fs;
|
||||
@ -1208,7 +1261,7 @@ newallocindir(ip, ptrno, newblkno, oldblkno)
|
||||
MALLOC(aip, struct allocindir *, sizeof(struct allocindir),
|
||||
M_ALLOCINDIR, M_WAITOK);
|
||||
bzero(aip, sizeof(struct allocindir));
|
||||
aip->ai_list.wk_type = M_ALLOCINDIR;
|
||||
aip->ai_list.wk_type = D_ALLOCINDIR;
|
||||
aip->ai_state = ATTACHED;
|
||||
aip->ai_offset = ptrno;
|
||||
aip->ai_newblkno = newblkno;
|
||||
@ -1293,7 +1346,7 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
for (wk = LIST_FIRST(&bp->b_dep); wk;
|
||||
wk = LIST_NEXT(wk, wk_list)) {
|
||||
if (wk->wk_type != M_INDIRDEP)
|
||||
if (wk->wk_type != D_INDIRDEP)
|
||||
continue;
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
break;
|
||||
@ -1351,13 +1404,13 @@ setup_allocindir_phase2(bp, ip, aip)
|
||||
if (newindirdep) {
|
||||
if (indirdep->ir_savebp != NULL)
|
||||
brelse(newindirdep->ir_savebp);
|
||||
WORKITEM_FREE((caddr_t)newindirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE((caddr_t)newindirdep, D_INDIRDEP);
|
||||
}
|
||||
if (indirdep)
|
||||
break;
|
||||
MALLOC(newindirdep, struct indirdep *, sizeof(struct indirdep),
|
||||
M_INDIRDEP, M_WAITOK);
|
||||
newindirdep->ir_list.wk_type = M_INDIRDEP;
|
||||
newindirdep->ir_list.wk_type = D_INDIRDEP;
|
||||
newindirdep->ir_state = ATTACHED;
|
||||
LIST_INIT(&newindirdep->ir_deplisthd);
|
||||
LIST_INIT(&newindirdep->ir_donehd);
|
||||
@ -1417,7 +1470,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
|
||||
M_FREEBLKS, M_WAITOK);
|
||||
bzero(freeblks, sizeof(struct freeblks));
|
||||
freeblks->fb_list.wk_type = M_FREEBLKS;
|
||||
freeblks->fb_list.wk_type = D_FREEBLKS;
|
||||
freeblks->fb_uid = ip->i_uid;
|
||||
freeblks->fb_previousinum = ip->i_number;
|
||||
freeblks->fb_devvp = ip->i_devvp;
|
||||
@ -1479,7 +1532,7 @@ softdep_setup_freeblocks(ip, length)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "sdsetf", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
while (getdirtybuf(&LIST_FIRST(&vp->v_dirtyblkhd), MNT_WAIT)) {
|
||||
@ -1522,7 +1575,7 @@ deallocate_dependencies(bp, inodedep)
|
||||
while ((wk = LIST_FIRST(&bp->b_dep)) != NULL) {
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
/*
|
||||
* None of the indirect pointers will ever be visible,
|
||||
@ -1556,7 +1609,7 @@ deallocate_dependencies(bp, inodedep)
|
||||
WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk);
|
||||
continue;
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
pagedep = WK_PAGEDEP(wk);
|
||||
/*
|
||||
* None of the directory additions will ever be
|
||||
@ -1585,15 +1638,15 @@ deallocate_dependencies(bp, inodedep)
|
||||
}
|
||||
WORKLIST_REMOVE(&pagedep->pd_list);
|
||||
LIST_REMOVE(pagedep, pd_hash);
|
||||
WORKITEM_FREE(pagedep, M_PAGEDEP);
|
||||
WORKITEM_FREE(pagedep, D_PAGEDEP);
|
||||
continue;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
free_allocindir(WK_ALLOCINDIR(wk), inodedep);
|
||||
continue;
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case M_INODEDEP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_INODEDEP:
|
||||
panic("deallocate_dependencies: Unexpected type %s",
|
||||
TYPENAME(wk->wk_type));
|
||||
/* NOTREACHED */
|
||||
@ -1633,7 +1686,7 @@ free_allocdirect(adphead, adp, delay)
|
||||
else
|
||||
add_to_worklist(&adp->ad_freefrag->ff_list);
|
||||
}
|
||||
WORKITEM_FREE(adp, M_ALLOCDIRECT);
|
||||
WORKITEM_FREE(adp, D_ALLOCDIRECT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1641,14 +1694,12 @@ free_allocdirect(adphead, adp, delay)
|
||||
* done until the zero'ed inode has been written to disk.
|
||||
*/
|
||||
void
|
||||
softdep_freefile(ap)
|
||||
struct vop_vfree_args /* {
|
||||
struct vnode *a_pvp;
|
||||
ino_t a_ino;
|
||||
int a_mode;
|
||||
} */ *ap;
|
||||
softdep_freefile(pvp, ino, mode)
|
||||
struct vnode *pvp;
|
||||
ino_t ino;
|
||||
int mode;
|
||||
{
|
||||
struct inode *ip = VTOI(ap->a_pvp);
|
||||
struct inode *ip = VTOI(pvp);
|
||||
struct inodedep *inodedep;
|
||||
struct freefile *freefile;
|
||||
|
||||
@ -1657,10 +1708,10 @@ softdep_freefile(ap)
|
||||
*/
|
||||
MALLOC(freefile, struct freefile *, sizeof(struct freefile),
|
||||
M_FREEFILE, M_WAITOK);
|
||||
freefile->fx_list.wk_type = M_FREEFILE;
|
||||
freefile->fx_list.wk_type = D_FREEFILE;
|
||||
freefile->fx_list.wk_state = 0;
|
||||
freefile->fx_mode = ap->a_mode;
|
||||
freefile->fx_oldinum = ap->a_ino;
|
||||
freefile->fx_mode = mode;
|
||||
freefile->fx_oldinum = ino;
|
||||
freefile->fx_devvp = ip->i_devvp;
|
||||
freefile->fx_fs = ip->i_fs;
|
||||
|
||||
@ -1669,7 +1720,7 @@ softdep_freefile(ap)
|
||||
* been written to disk and we can free the file immediately.
|
||||
*/
|
||||
ACQUIRE_LOCK(&lk);
|
||||
if (inodedep_lookup(ip->i_fs, ap->a_ino, 0, &inodedep) == 0) {
|
||||
if (inodedep_lookup(ip->i_fs, ino, 0, &inodedep) == 0) {
|
||||
add_to_worklist(&freefile->fx_list);
|
||||
FREE_LOCK(&lk);
|
||||
return;
|
||||
@ -1719,7 +1770,7 @@ free_inodedep(inodedep)
|
||||
inodedep->id_nlinkdelta != 0 || inodedep->id_savedino != NULL)
|
||||
return (0);
|
||||
LIST_REMOVE(inodedep, id_hash);
|
||||
WORKITEM_FREE(inodedep, M_INODEDEP);
|
||||
WORKITEM_FREE(inodedep, D_INODEDEP);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -1787,7 +1838,7 @@ handle_workitem_freeblocks(freeblks)
|
||||
if (allerror)
|
||||
softdep_error("handle_workitem_freeblks", allerror);
|
||||
#endif /* DIAGNOSTIC */
|
||||
WORKITEM_FREE(freeblks, M_FREEBLKS);
|
||||
WORKITEM_FREE(freeblks, D_FREEBLKS);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1832,12 +1883,12 @@ indir_trunc(ip, dbn, level, lbn, countp)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
if ((bp = incore(ip->i_devvp, dbn)) != NULL &&
|
||||
(wk = LIST_FIRST(&bp->b_dep)) != NULL) {
|
||||
if (wk->wk_type != M_INDIRDEP ||
|
||||
if (wk->wk_type != D_INDIRDEP ||
|
||||
(indirdep = WK_INDIRDEP(wk))->ir_savebp != bp ||
|
||||
(indirdep->ir_state & GOINGAWAY) == 0)
|
||||
panic("indir_trunc: lost indirdep");
|
||||
WORKLIST_REMOVE(wk);
|
||||
WORKITEM_FREE(indirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE(indirdep, D_INDIRDEP);
|
||||
if (LIST_FIRST(&bp->b_dep) != NULL)
|
||||
panic("indir_trunc: dangling dep");
|
||||
FREE_LOCK(&lk);
|
||||
@ -1895,7 +1946,7 @@ free_allocindir(aip, inodedep)
|
||||
WORKLIST_INSERT(&inodedep->id_inowait,
|
||||
&freefrag->ff_list);
|
||||
}
|
||||
WORKITEM_FREE(aip, M_ALLOCINDIR);
|
||||
WORKITEM_FREE(aip, D_ALLOCINDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1951,36 +2002,32 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp)
|
||||
offset = blkoff(fs, diroffset);
|
||||
MALLOC(dap, struct diradd *, sizeof(struct diradd), M_DIRADD, M_WAITOK);
|
||||
bzero(dap, sizeof(struct diradd));
|
||||
dap->da_list.wk_type = M_DIRADD;
|
||||
dap->da_list.wk_type = D_DIRADD;
|
||||
dap->da_offset = offset;
|
||||
dap->da_newinum = newinum;
|
||||
dap->da_state = ATTACHED;
|
||||
if (newdirbp == NULL) {
|
||||
dap->da_state |= DEPCOMPLETE;
|
||||
ACQUIRE_LOCK(&lk);
|
||||
} else {
|
||||
dap->da_state |= MKDIR_BODY | MKDIR_PARENT;
|
||||
MALLOC(mkdir1, struct mkdir *, sizeof(struct mkdir), M_MKDIR,
|
||||
M_WAITOK);
|
||||
mkdir1->md_list.wk_type = M_MKDIR;
|
||||
mkdir1->md_list.wk_type = D_MKDIR;
|
||||
mkdir1->md_state = MKDIR_BODY;
|
||||
mkdir1->md_diradd = dap;
|
||||
MALLOC(mkdir2, struct mkdir *, sizeof(struct mkdir), M_MKDIR,
|
||||
M_WAITOK);
|
||||
mkdir2->md_list.wk_type = M_MKDIR;
|
||||
mkdir2->md_list.wk_type = D_MKDIR;
|
||||
mkdir2->md_state = MKDIR_PARENT;
|
||||
mkdir2->md_diradd = dap;
|
||||
|
||||
}
|
||||
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
* If this directory entry references a new directory, create
|
||||
* its two additional dependencies: its "." and ".." being written
|
||||
* to disk and the link count increase for its parent directory.
|
||||
*/
|
||||
if (newdirbp != NULL) {
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
* Dependency on "." and ".." being written to disk
|
||||
* If this directory entry references a new directory, create
|
||||
* its two additional dependencies: its "." and ".." being
|
||||
* written to disk and the link count increase for its
|
||||
* parent directory.
|
||||
*/
|
||||
LIST_INSERT_HEAD(&mkdirlisthd, mkdir1, md_mkdirs);
|
||||
WORKLIST_INSERT(&newdirbp->b_dep, &mkdir1->md_list);
|
||||
@ -1991,7 +2038,7 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp)
|
||||
if (inodedep_lookup(dp->i_fs, dp->i_number, 0, &inodedep) == 0
|
||||
|| (inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
dap->da_state &= ~MKDIR_PARENT;
|
||||
WORKITEM_FREE(mkdir2, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir2, D_MKDIR);
|
||||
} else {
|
||||
LIST_INSERT_HEAD(&mkdirlisthd, mkdir2, md_mkdirs);
|
||||
WORKLIST_INSERT(&inodedep->id_inowait,&mkdir2->md_list);
|
||||
@ -2095,12 +2142,12 @@ free_diradd(dap)
|
||||
dap->da_state &= ~mkdir->md_state;
|
||||
WORKLIST_REMOVE(&mkdir->md_list);
|
||||
LIST_REMOVE(mkdir, md_mkdirs);
|
||||
WORKITEM_FREE(mkdir, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir, D_MKDIR);
|
||||
}
|
||||
if ((dap->da_state & (MKDIR_PARENT | MKDIR_BODY)) != 0)
|
||||
panic("free_diradd: unfound ref");
|
||||
}
|
||||
WORKITEM_FREE(dap, M_DIRADD);
|
||||
WORKITEM_FREE(dap, D_DIRADD);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2168,7 +2215,7 @@ newdirrem(bp, dp, ip, isrmdir)
|
||||
MALLOC(dirrem, struct dirrem *, sizeof(struct dirrem),
|
||||
M_DIRREM, M_WAITOK);
|
||||
bzero(dirrem, sizeof(struct dirrem));
|
||||
dirrem->dm_list.wk_type = M_DIRREM;
|
||||
dirrem->dm_list.wk_type = D_DIRREM;
|
||||
dirrem->dm_state = isrmdir ? RMDIR : 0;
|
||||
dirrem->dm_mnt = ITOV(ip)->v_mount;
|
||||
dirrem->dm_oldinum = ip->i_number;
|
||||
@ -2244,7 +2291,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
|
||||
MALLOC(dap, struct diradd *, sizeof(struct diradd),
|
||||
M_DIRADD, M_WAITOK);
|
||||
bzero(dap, sizeof(struct diradd));
|
||||
dap->da_list.wk_type = M_DIRADD;
|
||||
dap->da_list.wk_type = D_DIRADD;
|
||||
dap->da_state = DIRCHG | ATTACHED | DEPCOMPLETE;
|
||||
dap->da_offset = offset;
|
||||
dap->da_newinum = newinum;
|
||||
@ -2261,7 +2308,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
|
||||
*/
|
||||
if (inodedep_lookup(dp->i_fs, newinum, 0, &inodedep) == 0 ||
|
||||
(inodedep->id_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
WORKITEM_FREE(dap, M_DIRADD);
|
||||
WORKITEM_FREE(dap, D_DIRADD);
|
||||
dap = NULL;
|
||||
}
|
||||
|
||||
@ -2330,7 +2377,7 @@ handle_workitem_remove(dirrem)
|
||||
}
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
vput(vp);
|
||||
WORKITEM_FREE(dirrem, M_DIRREM);
|
||||
WORKITEM_FREE(dirrem, D_DIRREM);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -2344,7 +2391,7 @@ handle_workitem_remove(dirrem)
|
||||
if (ip->i_nlink < ip->i_effnlink)
|
||||
panic("handle_workitem_remove: bad dir delta");
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
if ((error = VOP_TRUNCATE(vp, (off_t)0, 0, p->p_cred, p)) != 0)
|
||||
if ((error = UFS_TRUNCATE(vp, (off_t)0, 0, p->p_ucred, p)) != 0)
|
||||
softdep_error("handle_workitem_remove: truncate", error);
|
||||
ACQUIRE_LOCK(&lk);
|
||||
(void) inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, DEPALLOC,
|
||||
@ -2377,7 +2424,6 @@ handle_workitem_freefile(freefile)
|
||||
struct vnode vp;
|
||||
struct inode tip;
|
||||
struct inodedep *idp;
|
||||
struct vop_vfree_args args;
|
||||
int error;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -2390,12 +2436,9 @@ handle_workitem_freefile(freefile)
|
||||
tip.i_dev = freefile->fx_devvp->v_rdev;
|
||||
tip.i_fs = freefile->fx_fs;
|
||||
vp.v_data = &tip;
|
||||
args.a_pvp = &vp;
|
||||
args.a_ino = freefile->fx_oldinum;
|
||||
args.a_mode = freefile->fx_mode;
|
||||
if ((error = ffs_freefile(&args)) != 0)
|
||||
if ((error = ffs_freefile(&vp, freefile->fx_oldinum, freefile->fx_mode)) != 0)
|
||||
softdep_error("handle_workitem_freefile", error);
|
||||
WORKITEM_FREE(freefile, M_FREEFILE);
|
||||
WORKITEM_FREE(freefile, D_FREEFILE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2440,15 +2483,15 @@ softdep_disk_io_initiation(bp)
|
||||
nextwk = LIST_NEXT(wk, wk_list);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
initiate_write_filepage(WK_PAGEDEP(wk), bp);
|
||||
continue;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
initiate_write_inodeblock(WK_INODEDEP(wk), bp);
|
||||
continue;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
if (indirdep->ir_state & GOINGAWAY)
|
||||
panic("disk_io_initiation: indirdep gone");
|
||||
@ -2462,7 +2505,7 @@ softdep_disk_io_initiation(bp)
|
||||
/* inline expand WORKLIST_REMOVE(wk); */
|
||||
wk->wk_state &= ~ONWORKLIST;
|
||||
LIST_REMOVE(wk, wk_list);
|
||||
WORKITEM_FREE(indirdep, M_INDIRDEP);
|
||||
WORKITEM_FREE(indirdep, D_INDIRDEP);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -2475,10 +2518,10 @@ softdep_disk_io_initiation(bp)
|
||||
FREE_LOCK(&lk);
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case M_BMSAFEMAP:
|
||||
case M_ALLOCDIRECT:
|
||||
case M_ALLOCINDIR:
|
||||
case D_MKDIR:
|
||||
case D_BMSAFEMAP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_ALLOCINDIR:
|
||||
continue;
|
||||
|
||||
default:
|
||||
@ -2549,7 +2592,7 @@ initiate_write_inodeblock(inodedep, bp)
|
||||
struct allocdirect *adp, *lastadp;
|
||||
struct dinode *dp;
|
||||
struct fs *fs;
|
||||
ufs_lbn_t prevlbn;
|
||||
ufs_lbn_t prevlbn = 0;
|
||||
int i, deplist;
|
||||
|
||||
if (inodedep->id_state & IOSTARTED)
|
||||
@ -2698,17 +2741,17 @@ softdep_disk_write_complete(bp)
|
||||
WORKLIST_REMOVE(wk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
if (handle_written_filepage(WK_PAGEDEP(wk), bp))
|
||||
WORKLIST_INSERT(&reattach, wk);
|
||||
continue;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
if (handle_written_inodeblock(WK_INODEDEP(wk), bp))
|
||||
WORKLIST_INSERT(&reattach, wk);
|
||||
continue;
|
||||
|
||||
case M_BMSAFEMAP:
|
||||
case D_BMSAFEMAP:
|
||||
bmsafemap = WK_BMSAFEMAP(wk);
|
||||
while (newblk = LIST_FIRST(&bmsafemap->sm_newblkhd)) {
|
||||
newblk->nb_state |= DEPCOMPLETE;
|
||||
@ -2733,26 +2776,26 @@ softdep_disk_write_complete(bp)
|
||||
LIST_REMOVE(inodedep, id_deps);
|
||||
inodedep->id_buf = NULL;
|
||||
}
|
||||
WORKITEM_FREE(bmsafemap, M_BMSAFEMAP);
|
||||
WORKITEM_FREE(bmsafemap, D_BMSAFEMAP);
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case D_MKDIR:
|
||||
handle_written_mkdir(WK_MKDIR(wk), MKDIR_BODY);
|
||||
continue;
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case D_ALLOCDIRECT:
|
||||
adp = WK_ALLOCDIRECT(wk);
|
||||
adp->ad_state |= COMPLETE;
|
||||
handle_allocdirect_partdone(adp);
|
||||
continue;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
aip = WK_ALLOCINDIR(wk);
|
||||
aip->ai_state |= COMPLETE;
|
||||
handle_allocindir_partdone(aip);
|
||||
continue;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
indirdep = WK_INDIRDEP(wk);
|
||||
if (indirdep->ir_state & GOINGAWAY)
|
||||
panic("disk_write_complete: indirdep gone");
|
||||
@ -2883,7 +2926,7 @@ handle_allocindir_partdone(aip)
|
||||
LIST_REMOVE(aip, ai_next);
|
||||
if (aip->ai_freefrag != NULL)
|
||||
add_to_worklist(&aip->ai_freefrag->ff_list);
|
||||
WORKITEM_FREE(aip, M_ALLOCINDIR);
|
||||
WORKITEM_FREE(aip, D_ALLOCINDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2986,7 +3029,7 @@ handle_written_inodeblock(inodedep, bp)
|
||||
WORKLIST_REMOVE(wk);
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_FREEFILE:
|
||||
case D_FREEFILE:
|
||||
/*
|
||||
* We defer adding filefree to the worklist until
|
||||
* all other additions have been made to ensure
|
||||
@ -2998,11 +3041,11 @@ handle_written_inodeblock(inodedep, bp)
|
||||
filefree = wk;
|
||||
continue;
|
||||
|
||||
case M_MKDIR:
|
||||
case D_MKDIR:
|
||||
handle_written_mkdir(WK_MKDIR(wk), MKDIR_PARENT);
|
||||
continue;
|
||||
|
||||
case M_DIRADD:
|
||||
case D_DIRADD:
|
||||
dap = WK_DIRADD(wk);
|
||||
dap->da_state |= COMPLETE;
|
||||
if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) {
|
||||
@ -3017,9 +3060,9 @@ handle_written_inodeblock(inodedep, bp)
|
||||
WORKLIST_INSERT(&inodedep->id_pendinghd, wk);
|
||||
continue;
|
||||
|
||||
case M_FREEBLKS:
|
||||
case M_FREEFRAG:
|
||||
case M_DIRREM:
|
||||
case D_FREEBLKS:
|
||||
case D_FREEFRAG:
|
||||
case D_DIRREM:
|
||||
add_to_worklist(wk);
|
||||
continue;
|
||||
|
||||
@ -3066,7 +3109,7 @@ handle_written_mkdir(mkdir, type)
|
||||
LIST_INSERT_HEAD(&pagedep->pd_pendinghd, dap, da_pdlist);
|
||||
}
|
||||
LIST_REMOVE(mkdir, md_mkdirs);
|
||||
WORKITEM_FREE(mkdir, M_MKDIR);
|
||||
WORKITEM_FREE(mkdir, D_MKDIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3147,7 +3190,7 @@ handle_written_filepage(pagedep, bp)
|
||||
break;
|
||||
if (i == DAHASHSZ) {
|
||||
LIST_REMOVE(pagedep, pd_hash);
|
||||
WORKITEM_FREE(pagedep, M_PAGEDEP);
|
||||
WORKITEM_FREE(pagedep, D_PAGEDEP);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -3343,7 +3386,7 @@ softdep_fsync(vp)
|
||||
panic("softdep_fsync: pending ops");
|
||||
if ((wk = LIST_FIRST(&inodedep->id_pendinghd)) == NULL)
|
||||
break;
|
||||
if (wk->wk_type != M_DIRADD)
|
||||
if (wk->wk_type != D_DIRADD)
|
||||
panic("softdep_fsync: Unexpected type %s",
|
||||
TYPENAME(wk->wk_type));
|
||||
dap = WK_DIRADD(wk);
|
||||
@ -3394,7 +3437,7 @@ softdep_fsync(vp)
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
if (flushparent) {
|
||||
tv = time;
|
||||
if (error = VOP_UPDATE(pvp, &tv, &tv, MNT_WAIT)) {
|
||||
if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) {
|
||||
vput(pvp);
|
||||
return (error);
|
||||
}
|
||||
@ -3490,7 +3533,7 @@ softdep_sync_metadata(ap)
|
||||
wk = LIST_NEXT(wk, wk_list)) {
|
||||
switch (wk->wk_type) {
|
||||
|
||||
case M_ALLOCDIRECT:
|
||||
case D_ALLOCDIRECT:
|
||||
adp = WK_ALLOCDIRECT(wk);
|
||||
if (adp->ad_state & DEPCOMPLETE)
|
||||
break;
|
||||
@ -3507,7 +3550,7 @@ softdep_sync_metadata(ap)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
break;
|
||||
|
||||
case M_ALLOCINDIR:
|
||||
case D_ALLOCINDIR:
|
||||
aip = WK_ALLOCINDIR(wk);
|
||||
if (aip->ai_state & DEPCOMPLETE)
|
||||
break;
|
||||
@ -3524,7 +3567,7 @@ softdep_sync_metadata(ap)
|
||||
ACQUIRE_LOCK(&lk);
|
||||
break;
|
||||
|
||||
case M_INDIRDEP:
|
||||
case D_INDIRDEP:
|
||||
restart:
|
||||
for (aip = LIST_FIRST(&WK_INDIRDEP(wk)->ir_deplisthd);
|
||||
aip; aip = LIST_NEXT(aip, ai_next)) {
|
||||
@ -3543,7 +3586,7 @@ softdep_sync_metadata(ap)
|
||||
}
|
||||
break;
|
||||
|
||||
case M_INODEDEP:
|
||||
case D_INODEDEP:
|
||||
if ((error = flush_inodedep_deps(WK_INODEDEP(wk)->id_fs,
|
||||
WK_INODEDEP(wk)->id_ino)) != 0) {
|
||||
FREE_LOCK(&lk);
|
||||
@ -3552,7 +3595,7 @@ softdep_sync_metadata(ap)
|
||||
}
|
||||
break;
|
||||
|
||||
case M_PAGEDEP:
|
||||
case D_PAGEDEP:
|
||||
/*
|
||||
* We are trying to sync a directory that may
|
||||
* have dependencies on both its own metadata
|
||||
@ -3597,7 +3640,7 @@ softdep_sync_metadata(ap)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "sdsynm", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
/*
|
||||
@ -3737,7 +3780,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
struct diradd *dap;
|
||||
struct timeval tv;
|
||||
struct vnode *vp;
|
||||
int gotit, error;
|
||||
int gotit, error = 0;
|
||||
struct buf *bp;
|
||||
ino_t inum;
|
||||
|
||||
@ -3750,7 +3793,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
if (dap->da_state & MKDIR_PARENT) {
|
||||
tv = time;
|
||||
FREE_LOCK(&lk);
|
||||
if (error = VOP_UPDATE(pvp, &tv, &tv, MNT_WAIT))
|
||||
if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT))
|
||||
break;
|
||||
ACQUIRE_LOCK(&lk);
|
||||
/*
|
||||
@ -3818,7 +3861,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
* level in the filesystem. Instead, we push the blocks
|
||||
* and wait for them to clear.
|
||||
*/
|
||||
if (error = VOP_FSYNC(vp, p->p_cred, MNT_NOWAIT, p)) {
|
||||
if (error = VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p)) {
|
||||
vput(vp);
|
||||
break;
|
||||
}
|
||||
@ -3826,13 +3869,14 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
|
||||
while (vp->v_numoutput) {
|
||||
vp->v_flag |= VBWAIT;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
|
||||
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1,
|
||||
"sdflpd", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
FREE_LOCK(&lk);
|
||||
}
|
||||
tv = time;
|
||||
error = VOP_UPDATE(vp, &tv, &tv, MNT_WAIT);
|
||||
error = UFS_UPDATE(vp, &tv, &tv, MNT_WAIT);
|
||||
vput(vp);
|
||||
if (error)
|
||||
break;
|
||||
@ -3870,7 +3914,7 @@ getdirtybuf(bpp, waitfor)
|
||||
return (0);
|
||||
bp->b_flags |= B_WANTED;
|
||||
FREE_LOCK_INTERLOCKED(&lk);
|
||||
sleep((caddr_t)bp, PRIBIO + 1);
|
||||
tsleep((caddr_t)bp, PRIBIO + 1, "sdsdty", 0);
|
||||
ACQUIRE_LOCK_INTERLOCKED(&lk);
|
||||
}
|
||||
if ((bp->b_flags & B_DELWRI) == 0)
|
||||
@ -3906,13 +3950,13 @@ softdep_deallocate_dependencies(bp)
|
||||
* force fsck to be run (though this would best be done
|
||||
* in the mainline code).
|
||||
*/
|
||||
case M_PAGEDEP:
|
||||
case M_INODEDEP:
|
||||
case M_BMSAFEMAP:
|
||||
case M_ALLOCDIRECT:
|
||||
case M_INDIRDEP:
|
||||
case M_ALLOCINDIR:
|
||||
case M_MKDIR:
|
||||
case D_PAGEDEP:
|
||||
case D_INODEDEP:
|
||||
case D_BMSAFEMAP:
|
||||
case D_ALLOCDIRECT:
|
||||
case D_INDIRDEP:
|
||||
case D_ALLOCINDIR:
|
||||
case D_MKDIR:
|
||||
#ifdef DEBUG
|
||||
printf("Lost type %s\n", TYPENAME(wk->wk_type));
|
||||
#endif
|
||||
|
@ -52,7 +52,6 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* from: @(#)softdep.h 9.4 (McKusick) 1/15/98
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user