diff options
author | Julian Elischer <julian@FreeBSD.org> | 1998-05-19 23:07:25 +0000 |
---|---|---|
committer | Julian Elischer <julian@FreeBSD.org> | 1998-05-19 23:07:25 +0000 |
commit | 25db4e8a667ad9bdce0aaa23abf1512c99f19887 (patch) | |
tree | 9fed6360c01da53d94a157e41f90046bc595f1c9 | |
parent | 46e752be057fa715c2251113b9f118dfba903634 (diff) | |
download | src-25db4e8a667ad9bdce0aaa23abf1512c99f19887.tar.gz src-25db4e8a667ad9bdce0aaa23abf1512c99f19887.zip |
Bring up-to-date with Whistle's current version
Includes some debugging code.
Notes
Notes:
svn path=/head/; revision=36234
-rw-r--r-- | contrib/sys/softupdates/ffs_softdep.c | 88 | ||||
-rw-r--r-- | contrib/sys/softupdates/softdep.h | 3 | ||||
-rw-r--r-- | sys/contrib/softupdates/ffs_softdep.c | 88 | ||||
-rw-r--r-- | sys/contrib/softupdates/softdep.h | 3 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 88 | ||||
-rw-r--r-- | sys/ufs/ffs/softdep.h | 3 |
6 files changed, 255 insertions, 18 deletions
diff --git a/contrib/sys/softupdates/ffs_softdep.c b/contrib/sys/softupdates/ffs_softdep.c index 25acbd2dae95..4123e33f6618 100644 --- a/contrib/sys/softupdates/ffs_softdep.c +++ b/contrib/sys/softupdates/ffs_softdep.c @@ -54,6 +54,7 @@ * SUCH DAMAGE. * * @(#)ffs_softdep.c 9.23 (McKusick) 2/20/98 + * $Id:$ */ /* @@ -65,6 +66,7 @@ #ifndef DEBUG #define DEBUG #endif +#define NEWINODE 0x4000 #include <sys/param.h> #include <sys/buf.h> @@ -954,6 +956,7 @@ softdep_mount(devvp, mp, fs, cred) struct buf *bp; int error, cyl; + mp->mnt_flag &= ~MNT_ASYNC; mp->mnt_flag |= MNT_SOFTDEP; /* * When doing soft updates, the counters in the @@ -1040,6 +1043,7 @@ softdep_setup_inomapdep(bp, ip, newinum) panic("softdep_setup_inomapdep: found inode"); inodedep->id_buf = bp; inodedep->id_state &= ~DEPCOMPLETE; +inodedep->id_state |= NEWINODE; bmsafemap = bmsafemap_lookup(bp); LIST_INSERT_HEAD(&bmsafemap->sm_inodedephd, inodedep, id_deps); FREE_LOCK(&lk); @@ -1528,11 +1532,20 @@ setup_allocindir_phase2(bp, ip, aip) newindirdep->ir_state = ATTACHED; LIST_INIT(&newindirdep->ir_deplisthd); LIST_INIT(&newindirdep->ir_donehd); - newindirdep->ir_saveddata = (ufs_daddr_t *)bp->b_data; +#ifdef __FreeBSD__ + if (bp->b_blkno == bp->b_lblkno) { +#if 0 /* we know this happens.. research suggested.. */ + printf("setup_allocindir_phase2: need bmap, blk %d\n", + bp->b_lblkno); +#endif + VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, + NULL, NULL); + } +#endif /* __FreeBSD__ */ newindirdep->ir_savebp = getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0); - bcopy((caddr_t)newindirdep->ir_saveddata, - newindirdep->ir_savebp->b_data, bp->b_bcount); + bp->b_flags |= B_XXX; + bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount); } } @@ -1716,6 +1729,8 @@ deallocate_dependencies(bp, inodedep) panic("deallocate_dependencies: not indir"); bcopy(bp->b_data, indirdep->ir_savebp->b_data, bp->b_bcount); +if ((indirdep->ir_savebp->b_flags & B_BUSY) == 0 || (bp->b_flags & B_BUSY) == 0) +panic("deallocate_dependencies: buffer unlocked"); WORKLIST_REMOVE(wk); WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk); continue; @@ -1980,6 +1995,7 @@ indir_trunc(ip, dbn, level, lbn, countp) struct indirdep *indirdep; int i, lbnadd, nblocks; int error, allerror = 0; +int debug; fs = ip->i_fs; lbnadd = 1; @@ -2000,6 +2016,7 @@ 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) { +debug = 1; if (wk->wk_type != D_INDIRDEP || (indirdep = WK_INDIRDEP(wk))->ir_savebp != bp || (indirdep->ir_state & GOINGAWAY) == 0) @@ -2010,11 +2027,14 @@ indir_trunc(ip, dbn, level, lbn, countp) panic("indir_trunc: dangling dep"); FREE_LOCK(&lk); } else { +debug = 2; FREE_LOCK(&lk); error = bread(ip->i_devvp, dbn, (int)fs->fs_bsize, NOCRED, &bp); if (error) return (error); } +if ((bp->b_flags & B_BUSY) == 0) +panic("indir_trunc: unlocked buf"); /* * Recursively free indirect blocks. */ @@ -2031,7 +2051,10 @@ indir_trunc(ip, dbn, level, lbn, countp) ffs_blkfree(ip, nb, fs->fs_bsize); *countp += nblocks; } +if (debug == i) +printf("debug %d\n", debug); bp->b_flags |= B_INVAL; + bp->b_flags &= ~B_XXX; brelse(bp); return (allerror); } @@ -2615,6 +2638,8 @@ softdep_disk_io_initiation(bp) * dependency can be freed. */ if (LIST_FIRST(&indirdep->ir_deplisthd) == NULL) { + indirdep->ir_savebp->b_flags &= ~B_XXX; + indirdep->ir_savebp->b_flags |= B_INVAL; brelse(indirdep->ir_savebp); /* inline expand WORKLIST_REMOVE(wk); */ wk->wk_state &= ~ONWORKLIST; @@ -2628,7 +2653,11 @@ softdep_disk_io_initiation(bp) ACQUIRE_LOCK(&lk); indirdep->ir_state &= ~ATTACHED; indirdep->ir_state |= UNDONE; - bp->b_data = indirdep->ir_savebp->b_data; + MALLOC(indirdep->ir_saveddata, caddr_t, bp->b_bcount, + M_INDIRDEP, M_WAITOK); + bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount); + bcopy(indirdep->ir_savebp->b_data, bp->b_data, + bp->b_bcount); FREE_LOCK(&lk); continue; @@ -2646,6 +2675,30 @@ softdep_disk_io_initiation(bp) } } +void +scan_page(bp) + struct buf *bp; +{ + struct inodedep *inodedep; + struct direct *dp; + struct fs *fs; + caddr_t cp; + + fs = VTOI(bp->b_vp)->i_fs; + for (cp = bp->b_data; cp < &bp->b_data[bp->b_bcount]; + cp += dp->d_reclen) { + dp = (struct direct *)cp; + if (dp->d_reclen <= 0) + break; + if (dp->d_ino == 0) + continue; + if (inodedep_lookup(fs, dp->d_ino, 0, &inodedep) == 0) + continue; + if (inodedep->id_state & NEWINODE) + panic("scan_page: unallocated inode"); + } +} + /* * Called from within the procedure above to deal with unsatisfied * allocation dependencies in a directory. The buffer must be locked, @@ -2689,6 +2742,7 @@ initiate_write_filepage(pagedep, bp) dap->da_state |= UNDONE; } } +/*scan_page(bp);*/ FREE_LOCK(&lk); } @@ -2913,7 +2967,9 @@ softdep_disk_write_complete(bp) indirdep = WK_INDIRDEP(wk); if (indirdep->ir_state & GOINGAWAY) panic("disk_write_complete: indirdep gone"); - bp->b_data = (caddr_t)indirdep->ir_saveddata; + bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount); + FREE(indirdep->ir_saveddata, M_INDIRDEP); + indirdep->ir_saveddata = 0; indirdep->ir_state &= ~UNDONE; indirdep->ir_state |= ATTACHED; while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) { @@ -3081,6 +3137,7 @@ handle_written_inodeblock(inodedep, bp) bdirty(bp); return (1); } +inodedep->id_state &= ~NEWINODE; /* * Roll forward anything that had to be rolled back before * the inode could be updated. @@ -3201,6 +3258,8 @@ diradd_inode_written(dap, inodedep) { struct pagedep *pagedep; +if (inodedep->id_state & NEWINODE) +panic("diradd_inode_written: unallocated inode"); dap->da_state |= COMPLETE; if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) { if (dap->da_state & DIRCHG) @@ -3570,7 +3629,11 @@ softdep_fsync(vp) } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); if (flushparent) { +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) { vput(pvp); return (error); @@ -3654,6 +3717,13 @@ softdep_sync_metadata(ap) waitfor = MNT_NOWAIT; top: if (getdirtybuf(&LIST_FIRST(&vp->v_dirtyblkhd), MNT_WAIT) == 0) { + while (vp->v_numoutput) { + vp->v_flag |= VBWAIT; + FREE_LOCK_INTERLOCKED(&lk); + tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, + "sdsynm", 0); + ACQUIRE_LOCK_INTERLOCKED(&lk); + } FREE_LOCK(&lk); return (0); } @@ -3931,7 +4001,11 @@ flush_pagedep_deps(pvp, mp, diraddhdp) * has a MKDIR_PARENT dependency. */ if (dap->da_state & MKDIR_PARENT) { +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ FREE_LOCK(&lk); if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) break; @@ -4015,7 +4089,11 @@ flush_pagedep_deps(pvp, mp, diraddhdp) } FREE_LOCK(&lk); } +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ error = UFS_UPDATE(vp, &tv, &tv, MNT_WAIT); vput(vp); if (error) diff --git a/contrib/sys/softupdates/softdep.h b/contrib/sys/softupdates/softdep.h index 3435f6304173..71bb7fa4f706 100644 --- a/contrib/sys/softupdates/softdep.h +++ b/contrib/sys/softupdates/softdep.h @@ -53,6 +53,7 @@ * SUCH DAMAGE. * * @(#)softdep.h 9.5 (McKusick) 2/11/98 + * $Id:$ */ #include <sys/queue.h> @@ -352,7 +353,7 @@ struct allocdirect { struct indirdep { struct worklist ir_list; /* buffer holding indirect block */ # define ir_state ir_list.wk_state /* indirect block pointer state */ - ufs_daddr_t *ir_saveddata; /* buffer cache contents */ + caddr_t ir_saveddata; /* buffer cache contents */ struct buf *ir_savebp; /* buffer holding safe copy */ struct allocindirhd ir_donehd; /* done waiting to update safecopy */ struct allocindirhd ir_deplisthd; /* allocindir deps for this block */ diff --git a/sys/contrib/softupdates/ffs_softdep.c b/sys/contrib/softupdates/ffs_softdep.c index 25acbd2dae95..4123e33f6618 100644 --- a/sys/contrib/softupdates/ffs_softdep.c +++ b/sys/contrib/softupdates/ffs_softdep.c @@ -54,6 +54,7 @@ * SUCH DAMAGE. * * @(#)ffs_softdep.c 9.23 (McKusick) 2/20/98 + * $Id:$ */ /* @@ -65,6 +66,7 @@ #ifndef DEBUG #define DEBUG #endif +#define NEWINODE 0x4000 #include <sys/param.h> #include <sys/buf.h> @@ -954,6 +956,7 @@ softdep_mount(devvp, mp, fs, cred) struct buf *bp; int error, cyl; + mp->mnt_flag &= ~MNT_ASYNC; mp->mnt_flag |= MNT_SOFTDEP; /* * When doing soft updates, the counters in the @@ -1040,6 +1043,7 @@ softdep_setup_inomapdep(bp, ip, newinum) panic("softdep_setup_inomapdep: found inode"); inodedep->id_buf = bp; inodedep->id_state &= ~DEPCOMPLETE; +inodedep->id_state |= NEWINODE; bmsafemap = bmsafemap_lookup(bp); LIST_INSERT_HEAD(&bmsafemap->sm_inodedephd, inodedep, id_deps); FREE_LOCK(&lk); @@ -1528,11 +1532,20 @@ setup_allocindir_phase2(bp, ip, aip) newindirdep->ir_state = ATTACHED; LIST_INIT(&newindirdep->ir_deplisthd); LIST_INIT(&newindirdep->ir_donehd); - newindirdep->ir_saveddata = (ufs_daddr_t *)bp->b_data; +#ifdef __FreeBSD__ + if (bp->b_blkno == bp->b_lblkno) { +#if 0 /* we know this happens.. research suggested.. */ + printf("setup_allocindir_phase2: need bmap, blk %d\n", + bp->b_lblkno); +#endif + VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, + NULL, NULL); + } +#endif /* __FreeBSD__ */ newindirdep->ir_savebp = getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0); - bcopy((caddr_t)newindirdep->ir_saveddata, - newindirdep->ir_savebp->b_data, bp->b_bcount); + bp->b_flags |= B_XXX; + bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount); } } @@ -1716,6 +1729,8 @@ deallocate_dependencies(bp, inodedep) panic("deallocate_dependencies: not indir"); bcopy(bp->b_data, indirdep->ir_savebp->b_data, bp->b_bcount); +if ((indirdep->ir_savebp->b_flags & B_BUSY) == 0 || (bp->b_flags & B_BUSY) == 0) +panic("deallocate_dependencies: buffer unlocked"); WORKLIST_REMOVE(wk); WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk); continue; @@ -1980,6 +1995,7 @@ indir_trunc(ip, dbn, level, lbn, countp) struct indirdep *indirdep; int i, lbnadd, nblocks; int error, allerror = 0; +int debug; fs = ip->i_fs; lbnadd = 1; @@ -2000,6 +2016,7 @@ 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) { +debug = 1; if (wk->wk_type != D_INDIRDEP || (indirdep = WK_INDIRDEP(wk))->ir_savebp != bp || (indirdep->ir_state & GOINGAWAY) == 0) @@ -2010,11 +2027,14 @@ indir_trunc(ip, dbn, level, lbn, countp) panic("indir_trunc: dangling dep"); FREE_LOCK(&lk); } else { +debug = 2; FREE_LOCK(&lk); error = bread(ip->i_devvp, dbn, (int)fs->fs_bsize, NOCRED, &bp); if (error) return (error); } +if ((bp->b_flags & B_BUSY) == 0) +panic("indir_trunc: unlocked buf"); /* * Recursively free indirect blocks. */ @@ -2031,7 +2051,10 @@ indir_trunc(ip, dbn, level, lbn, countp) ffs_blkfree(ip, nb, fs->fs_bsize); *countp += nblocks; } +if (debug == i) +printf("debug %d\n", debug); bp->b_flags |= B_INVAL; + bp->b_flags &= ~B_XXX; brelse(bp); return (allerror); } @@ -2615,6 +2638,8 @@ softdep_disk_io_initiation(bp) * dependency can be freed. */ if (LIST_FIRST(&indirdep->ir_deplisthd) == NULL) { + indirdep->ir_savebp->b_flags &= ~B_XXX; + indirdep->ir_savebp->b_flags |= B_INVAL; brelse(indirdep->ir_savebp); /* inline expand WORKLIST_REMOVE(wk); */ wk->wk_state &= ~ONWORKLIST; @@ -2628,7 +2653,11 @@ softdep_disk_io_initiation(bp) ACQUIRE_LOCK(&lk); indirdep->ir_state &= ~ATTACHED; indirdep->ir_state |= UNDONE; - bp->b_data = indirdep->ir_savebp->b_data; + MALLOC(indirdep->ir_saveddata, caddr_t, bp->b_bcount, + M_INDIRDEP, M_WAITOK); + bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount); + bcopy(indirdep->ir_savebp->b_data, bp->b_data, + bp->b_bcount); FREE_LOCK(&lk); continue; @@ -2646,6 +2675,30 @@ softdep_disk_io_initiation(bp) } } +void +scan_page(bp) + struct buf *bp; +{ + struct inodedep *inodedep; + struct direct *dp; + struct fs *fs; + caddr_t cp; + + fs = VTOI(bp->b_vp)->i_fs; + for (cp = bp->b_data; cp < &bp->b_data[bp->b_bcount]; + cp += dp->d_reclen) { + dp = (struct direct *)cp; + if (dp->d_reclen <= 0) + break; + if (dp->d_ino == 0) + continue; + if (inodedep_lookup(fs, dp->d_ino, 0, &inodedep) == 0) + continue; + if (inodedep->id_state & NEWINODE) + panic("scan_page: unallocated inode"); + } +} + /* * Called from within the procedure above to deal with unsatisfied * allocation dependencies in a directory. The buffer must be locked, @@ -2689,6 +2742,7 @@ initiate_write_filepage(pagedep, bp) dap->da_state |= UNDONE; } } +/*scan_page(bp);*/ FREE_LOCK(&lk); } @@ -2913,7 +2967,9 @@ softdep_disk_write_complete(bp) indirdep = WK_INDIRDEP(wk); if (indirdep->ir_state & GOINGAWAY) panic("disk_write_complete: indirdep gone"); - bp->b_data = (caddr_t)indirdep->ir_saveddata; + bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount); + FREE(indirdep->ir_saveddata, M_INDIRDEP); + indirdep->ir_saveddata = 0; indirdep->ir_state &= ~UNDONE; indirdep->ir_state |= ATTACHED; while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) { @@ -3081,6 +3137,7 @@ handle_written_inodeblock(inodedep, bp) bdirty(bp); return (1); } +inodedep->id_state &= ~NEWINODE; /* * Roll forward anything that had to be rolled back before * the inode could be updated. @@ -3201,6 +3258,8 @@ diradd_inode_written(dap, inodedep) { struct pagedep *pagedep; +if (inodedep->id_state & NEWINODE) +panic("diradd_inode_written: unallocated inode"); dap->da_state |= COMPLETE; if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) { if (dap->da_state & DIRCHG) @@ -3570,7 +3629,11 @@ softdep_fsync(vp) } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); if (flushparent) { +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) { vput(pvp); return (error); @@ -3654,6 +3717,13 @@ softdep_sync_metadata(ap) waitfor = MNT_NOWAIT; top: if (getdirtybuf(&LIST_FIRST(&vp->v_dirtyblkhd), MNT_WAIT) == 0) { + while (vp->v_numoutput) { + vp->v_flag |= VBWAIT; + FREE_LOCK_INTERLOCKED(&lk); + tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, + "sdsynm", 0); + ACQUIRE_LOCK_INTERLOCKED(&lk); + } FREE_LOCK(&lk); return (0); } @@ -3931,7 +4001,11 @@ flush_pagedep_deps(pvp, mp, diraddhdp) * has a MKDIR_PARENT dependency. */ if (dap->da_state & MKDIR_PARENT) { +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ FREE_LOCK(&lk); if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) break; @@ -4015,7 +4089,11 @@ flush_pagedep_deps(pvp, mp, diraddhdp) } FREE_LOCK(&lk); } +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ error = UFS_UPDATE(vp, &tv, &tv, MNT_WAIT); vput(vp); if (error) diff --git a/sys/contrib/softupdates/softdep.h b/sys/contrib/softupdates/softdep.h index 3435f6304173..71bb7fa4f706 100644 --- a/sys/contrib/softupdates/softdep.h +++ b/sys/contrib/softupdates/softdep.h @@ -53,6 +53,7 @@ * SUCH DAMAGE. * * @(#)softdep.h 9.5 (McKusick) 2/11/98 + * $Id:$ */ #include <sys/queue.h> @@ -352,7 +353,7 @@ struct allocdirect { struct indirdep { struct worklist ir_list; /* buffer holding indirect block */ # define ir_state ir_list.wk_state /* indirect block pointer state */ - ufs_daddr_t *ir_saveddata; /* buffer cache contents */ + caddr_t ir_saveddata; /* buffer cache contents */ struct buf *ir_savebp; /* buffer holding safe copy */ struct allocindirhd ir_donehd; /* done waiting to update safecopy */ struct allocindirhd ir_deplisthd; /* allocindir deps for this block */ diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 25acbd2dae95..4123e33f6618 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -54,6 +54,7 @@ * SUCH DAMAGE. * * @(#)ffs_softdep.c 9.23 (McKusick) 2/20/98 + * $Id:$ */ /* @@ -65,6 +66,7 @@ #ifndef DEBUG #define DEBUG #endif +#define NEWINODE 0x4000 #include <sys/param.h> #include <sys/buf.h> @@ -954,6 +956,7 @@ softdep_mount(devvp, mp, fs, cred) struct buf *bp; int error, cyl; + mp->mnt_flag &= ~MNT_ASYNC; mp->mnt_flag |= MNT_SOFTDEP; /* * When doing soft updates, the counters in the @@ -1040,6 +1043,7 @@ softdep_setup_inomapdep(bp, ip, newinum) panic("softdep_setup_inomapdep: found inode"); inodedep->id_buf = bp; inodedep->id_state &= ~DEPCOMPLETE; +inodedep->id_state |= NEWINODE; bmsafemap = bmsafemap_lookup(bp); LIST_INSERT_HEAD(&bmsafemap->sm_inodedephd, inodedep, id_deps); FREE_LOCK(&lk); @@ -1528,11 +1532,20 @@ setup_allocindir_phase2(bp, ip, aip) newindirdep->ir_state = ATTACHED; LIST_INIT(&newindirdep->ir_deplisthd); LIST_INIT(&newindirdep->ir_donehd); - newindirdep->ir_saveddata = (ufs_daddr_t *)bp->b_data; +#ifdef __FreeBSD__ + if (bp->b_blkno == bp->b_lblkno) { +#if 0 /* we know this happens.. research suggested.. */ + printf("setup_allocindir_phase2: need bmap, blk %d\n", + bp->b_lblkno); +#endif + VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno, + NULL, NULL); + } +#endif /* __FreeBSD__ */ newindirdep->ir_savebp = getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0); - bcopy((caddr_t)newindirdep->ir_saveddata, - newindirdep->ir_savebp->b_data, bp->b_bcount); + bp->b_flags |= B_XXX; + bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount); } } @@ -1716,6 +1729,8 @@ deallocate_dependencies(bp, inodedep) panic("deallocate_dependencies: not indir"); bcopy(bp->b_data, indirdep->ir_savebp->b_data, bp->b_bcount); +if ((indirdep->ir_savebp->b_flags & B_BUSY) == 0 || (bp->b_flags & B_BUSY) == 0) +panic("deallocate_dependencies: buffer unlocked"); WORKLIST_REMOVE(wk); WORKLIST_INSERT(&indirdep->ir_savebp->b_dep, wk); continue; @@ -1980,6 +1995,7 @@ indir_trunc(ip, dbn, level, lbn, countp) struct indirdep *indirdep; int i, lbnadd, nblocks; int error, allerror = 0; +int debug; fs = ip->i_fs; lbnadd = 1; @@ -2000,6 +2016,7 @@ 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) { +debug = 1; if (wk->wk_type != D_INDIRDEP || (indirdep = WK_INDIRDEP(wk))->ir_savebp != bp || (indirdep->ir_state & GOINGAWAY) == 0) @@ -2010,11 +2027,14 @@ indir_trunc(ip, dbn, level, lbn, countp) panic("indir_trunc: dangling dep"); FREE_LOCK(&lk); } else { +debug = 2; FREE_LOCK(&lk); error = bread(ip->i_devvp, dbn, (int)fs->fs_bsize, NOCRED, &bp); if (error) return (error); } +if ((bp->b_flags & B_BUSY) == 0) +panic("indir_trunc: unlocked buf"); /* * Recursively free indirect blocks. */ @@ -2031,7 +2051,10 @@ indir_trunc(ip, dbn, level, lbn, countp) ffs_blkfree(ip, nb, fs->fs_bsize); *countp += nblocks; } +if (debug == i) +printf("debug %d\n", debug); bp->b_flags |= B_INVAL; + bp->b_flags &= ~B_XXX; brelse(bp); return (allerror); } @@ -2615,6 +2638,8 @@ softdep_disk_io_initiation(bp) * dependency can be freed. */ if (LIST_FIRST(&indirdep->ir_deplisthd) == NULL) { + indirdep->ir_savebp->b_flags &= ~B_XXX; + indirdep->ir_savebp->b_flags |= B_INVAL; brelse(indirdep->ir_savebp); /* inline expand WORKLIST_REMOVE(wk); */ wk->wk_state &= ~ONWORKLIST; @@ -2628,7 +2653,11 @@ softdep_disk_io_initiation(bp) ACQUIRE_LOCK(&lk); indirdep->ir_state &= ~ATTACHED; indirdep->ir_state |= UNDONE; - bp->b_data = indirdep->ir_savebp->b_data; + MALLOC(indirdep->ir_saveddata, caddr_t, bp->b_bcount, + M_INDIRDEP, M_WAITOK); + bcopy(bp->b_data, indirdep->ir_saveddata, bp->b_bcount); + bcopy(indirdep->ir_savebp->b_data, bp->b_data, + bp->b_bcount); FREE_LOCK(&lk); continue; @@ -2646,6 +2675,30 @@ softdep_disk_io_initiation(bp) } } +void +scan_page(bp) + struct buf *bp; +{ + struct inodedep *inodedep; + struct direct *dp; + struct fs *fs; + caddr_t cp; + + fs = VTOI(bp->b_vp)->i_fs; + for (cp = bp->b_data; cp < &bp->b_data[bp->b_bcount]; + cp += dp->d_reclen) { + dp = (struct direct *)cp; + if (dp->d_reclen <= 0) + break; + if (dp->d_ino == 0) + continue; + if (inodedep_lookup(fs, dp->d_ino, 0, &inodedep) == 0) + continue; + if (inodedep->id_state & NEWINODE) + panic("scan_page: unallocated inode"); + } +} + /* * Called from within the procedure above to deal with unsatisfied * allocation dependencies in a directory. The buffer must be locked, @@ -2689,6 +2742,7 @@ initiate_write_filepage(pagedep, bp) dap->da_state |= UNDONE; } } +/*scan_page(bp);*/ FREE_LOCK(&lk); } @@ -2913,7 +2967,9 @@ softdep_disk_write_complete(bp) indirdep = WK_INDIRDEP(wk); if (indirdep->ir_state & GOINGAWAY) panic("disk_write_complete: indirdep gone"); - bp->b_data = (caddr_t)indirdep->ir_saveddata; + bcopy(indirdep->ir_saveddata, bp->b_data, bp->b_bcount); + FREE(indirdep->ir_saveddata, M_INDIRDEP); + indirdep->ir_saveddata = 0; indirdep->ir_state &= ~UNDONE; indirdep->ir_state |= ATTACHED; while ((aip = LIST_FIRST(&indirdep->ir_donehd)) != 0) { @@ -3081,6 +3137,7 @@ handle_written_inodeblock(inodedep, bp) bdirty(bp); return (1); } +inodedep->id_state &= ~NEWINODE; /* * Roll forward anything that had to be rolled back before * the inode could be updated. @@ -3201,6 +3258,8 @@ diradd_inode_written(dap, inodedep) { struct pagedep *pagedep; +if (inodedep->id_state & NEWINODE) +panic("diradd_inode_written: unallocated inode"); dap->da_state |= COMPLETE; if ((dap->da_state & ALLCOMPLETE) == ALLCOMPLETE) { if (dap->da_state & DIRCHG) @@ -3570,7 +3629,11 @@ softdep_fsync(vp) } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); if (flushparent) { +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) { vput(pvp); return (error); @@ -3654,6 +3717,13 @@ softdep_sync_metadata(ap) waitfor = MNT_NOWAIT; top: if (getdirtybuf(&LIST_FIRST(&vp->v_dirtyblkhd), MNT_WAIT) == 0) { + while (vp->v_numoutput) { + vp->v_flag |= VBWAIT; + FREE_LOCK_INTERLOCKED(&lk); + tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, + "sdsynm", 0); + ACQUIRE_LOCK_INTERLOCKED(&lk); + } FREE_LOCK(&lk); return (0); } @@ -3931,7 +4001,11 @@ flush_pagedep_deps(pvp, mp, diraddhdp) * has a MKDIR_PARENT dependency. */ if (dap->da_state & MKDIR_PARENT) { +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ FREE_LOCK(&lk); if (error = UFS_UPDATE(pvp, &tv, &tv, MNT_WAIT)) break; @@ -4015,7 +4089,11 @@ flush_pagedep_deps(pvp, mp, diraddhdp) } FREE_LOCK(&lk); } +#ifndef __FreeBSD__ tv = time; +#else + getmicrotime(&tv); +#endif /* __FreeBSD__ */ error = UFS_UPDATE(vp, &tv, &tv, MNT_WAIT); vput(vp); if (error) diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h index 3435f6304173..71bb7fa4f706 100644 --- a/sys/ufs/ffs/softdep.h +++ b/sys/ufs/ffs/softdep.h @@ -53,6 +53,7 @@ * SUCH DAMAGE. * * @(#)softdep.h 9.5 (McKusick) 2/11/98 + * $Id:$ */ #include <sys/queue.h> @@ -352,7 +353,7 @@ struct allocdirect { struct indirdep { struct worklist ir_list; /* buffer holding indirect block */ # define ir_state ir_list.wk_state /* indirect block pointer state */ - ufs_daddr_t *ir_saveddata; /* buffer cache contents */ + caddr_t ir_saveddata; /* buffer cache contents */ struct buf *ir_savebp; /* buffer holding safe copy */ struct allocindirhd ir_donehd; /* done waiting to update safecopy */ struct allocindirhd ir_deplisthd; /* allocindir deps for this block */ |