1
0
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:
Julian Elischer 1998-05-19 20:18:42 +00:00
parent a697eb98d4
commit 987614a910
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36210
6 changed files with 504 additions and 375 deletions

View File

@ -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

View File

@ -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
*/

View File

@ -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

View File

@ -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
*/

View File

@ -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

View File

@ -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
*/