diff --git a/sys/ufs/lfs/lfs.h b/sys/ufs/lfs/lfs.h index a3663209b268..efc77d47ccc6 100644 --- a/sys/ufs/lfs/lfs.h +++ b/sys/ufs/lfs/lfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: lfs.h,v 1.39 2002/05/14 20:03:53 perseant Exp $ */ +/* $NetBSD: lfs.h,v 1.40 2002/06/16 00:13:15 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -765,6 +765,7 @@ struct segment { #define SEGM_SYNC 0x04 /* wait for segment */ #define SEGM_PROT 0x08 /* don't inactivate at segunlock */ u_int16_t seg_flags; /* run-time flags for this segment */ + u_int32_t seg_iocount; /* number of ios pending */ }; struct lfs_cluster { @@ -773,8 +774,10 @@ struct lfs_cluster { size_t bufsize; /* Size of kept data */ #define LFS_CL_MALLOC 0x00000001 #define LFS_CL_SHIFT 0x00000002 +#define LFS_CL_SYNC 0x00000004 u_int32_t flags; /* Flags */ struct lfs *fs; /* LFS that this belongs to */ + struct segment *seg; /* Segment structure, for LFS_CL_SYNC */ void *saveaddr; /* Original contents of saveaddr */ char *olddata; /* Original b_data, if LFS_CL_MALLOC */ }; diff --git a/sys/ufs/lfs/lfs_cksum.c b/sys/ufs/lfs/lfs_cksum.c index 98eb1b16cd3b..35ba63d8fce7 100644 --- a/sys/ufs/lfs/lfs_cksum.c +++ b/sys/ufs/lfs/lfs_cksum.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_cksum.c,v 1.19 2001/11/15 09:48:29 lukem Exp $ */ +/* $NetBSD: lfs_cksum.c,v 1.20 2002/06/16 00:13:15 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: lfs_cksum.c,v 1.19 2001/11/15 09:48:29 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_cksum.c,v 1.20 2002/06/16 00:13:15 perseant Exp $"); #include #ifdef _KERNEL @@ -83,6 +83,7 @@ __KERNEL_RCSID(0, "$NetBSD: lfs_cksum.c,v 1.19 2001/11/15 09:48:29 lukem Exp $") #include #include #include +#include /* * Simple, general purpose, fast checksum. Data must be short-aligned. diff --git a/sys/ufs/lfs/lfs_extern.h b/sys/ufs/lfs/lfs_extern.h index 16f0df1c7b36..4714def659b6 100644 --- a/sys/ufs/lfs/lfs_extern.h +++ b/sys/ufs/lfs/lfs_extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_extern.h,v 1.30 2002/05/14 20:03:53 perseant Exp $ */ +/* $NetBSD: lfs_extern.h,v 1.31 2002/06/16 00:13:15 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -204,32 +204,34 @@ void lfs_unmark_vnode(struct vnode *); void lfs_itimes(struct inode *, struct timespec *, struct timespec *, struct timespec *); -int lfs_balloc (void *); -int lfs_valloc (void *); -int lfs_vfree (void *); -int lfs_bwrite (void *); -int lfs_update (void *); -int lfs_truncate(void *); -int lfs_blkatoff(void *); -int lfs_fsync (void *); -int lfs_symlink (void *); -int lfs_mknod (void *); -int lfs_create (void *); -int lfs_mkdir (void *); -int lfs_read (void *); -int lfs_remove (void *); -int lfs_rmdir (void *); -int lfs_link (void *); -int lfs_rename (void *); -int lfs_getattr (void *); -int lfs_setattr (void *); -int lfs_close (void *); -int lfs_inactive(void *); -int lfs_reclaim (void *); -int lfs_write (void *); -int lfs_whiteout(void *); -int lfs_getpages(void *); -int lfs_putpages(void *); +int lfs_balloc (void *); +int lfs_valloc (void *); +int lfs_vfree (void *); +int lfs_bwrite (void *); +int lfs_update (void *); +int lfs_truncate (void *); +int lfs_blkatoff (void *); +int lfs_fsync (void *); +int lfs_symlink (void *); +int lfs_mknod (void *); +int lfs_create (void *); +int lfs_mkdir (void *); +int lfs_read (void *); +int lfs_remove (void *); +int lfs_rmdir (void *); +int lfs_link (void *); +int lfs_rename (void *); +int lfs_getattr (void *); +int lfs_setattr (void *); +int lfs_close (void *); +int lfsspec_close(void *); +int lfsfifo_close(void *); +int lfs_inactive (void *); +int lfs_reclaim (void *); +int lfs_write (void *); +int lfs_whiteout (void *); +int lfs_getpages (void *); +int lfs_putpages (void *); __END_DECLS extern int lfs_mount_type; diff --git a/sys/ufs/lfs/lfs_segment.c b/sys/ufs/lfs/lfs_segment.c index 584639d06626..96ee14d167c3 100644 --- a/sys/ufs/lfs/lfs_segment.c +++ b/sys/ufs/lfs/lfs_segment.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_segment.c,v 1.78 2002/05/24 22:13:57 perseant Exp $ */ +/* $NetBSD: lfs_segment.c,v 1.79 2002/06/16 00:13:15 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.78 2002/05/24 22:13:57 perseant Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.79 2002/06/16 00:13:15 perseant Exp $"); #define ivndebug(vp,str) printf("ino %d: %s\n",VTOI(vp)->i_number,(str)) @@ -104,11 +104,15 @@ __KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.78 2002/05/24 22:13:57 perseant Ex #include #include +#include #include extern int count_lock_queue(void); extern struct simplelock vnode_free_list_slock; /* XXX */ +static void lfs_generic_callback(struct buf *, void (*)(struct buf *)); +static void lfs_super_aiodone(struct buf *); +static void lfs_cluster_aiodone(struct buf *); static void lfs_cluster_callback(struct buf *); static struct buf **lookahead_pagemove(struct buf **, int, size_t *); @@ -290,8 +294,9 @@ lfs_vflush(struct vnode *vp) } SET_FLUSHING(fs,vp); - if (fs->lfs_nactive > LFS_MAX_ACTIVE) { - error = lfs_segwrite(vp->v_mount, SEGM_SYNC|SEGM_CKP); + if (fs->lfs_nactive > LFS_MAX_ACTIVE || + (fs->lfs_sp->seg_flags & SEGM_CKP)) { + error = lfs_segwrite(vp->v_mount, SEGM_CKP | SEGM_SYNC); CLR_FLUSHING(fs,vp); lfs_segunlock(fs); return error; @@ -351,11 +356,9 @@ lfs_vflush(struct vnode *vp) * artificially incremented by lfs_seglock(). */ if (fs->lfs_seglock > 1) { - s = splbio(); while (fs->lfs_iocount > 1) (void)tsleep(&fs->lfs_iocount, PRIBIO + 1, "lfs_vflush", 0); - splx(s); } lfs_segunlock(fs); @@ -692,8 +695,8 @@ lfs_segwrite(struct mount *mp, int flags) * Take the flags off of the segment so that lfs_segunlock * doesn't have to write the superblock either. */ - if (did_ckp == 0) { - sp->seg_flags &= ~(SEGM_SYNC|SEGM_CKP); + if (do_ckp && !did_ckp) { + sp->seg_flags &= ~SEGM_CKP; /* if (do_ckp) printf("lfs_segwrite: no checkpoint\n"); */ } @@ -1443,12 +1446,20 @@ lfs_newclusterbuf(struct lfs *fs, struct vnode *vp, daddr_t addr, int n) cl = (struct lfs_cluster *)malloc(sizeof(*cl), M_SEGMENT, M_WAITOK); bpp = (struct buf **)malloc(n*sizeof(*bpp), M_SEGMENT, M_WAITOK); - memset(cl,0,sizeof(*cl)); + memset(cl, 0, sizeof(*cl)); cl->fs = fs; cl->bpp = bpp; cl->bufcount = 0; cl->bufsize = 0; + /* If this segment is being written synchronously, note that */ + if (fs->lfs_sp->seg_flags & SEGM_SYNC) { + cl->flags |= LFS_CL_SYNC; + cl->seg = fs->lfs_sp; + ++cl->seg->seg_iocount; + /* printf("+ %x => %d\n", cl->seg, cl->seg->seg_iocount); */ + } + /* Get an empty buffer header, or maybe one with something on it */ s = splbio(); if((bp = bufqueues[BQ_EMPTY].tqh_first) != NULL) { @@ -1791,7 +1802,6 @@ lfs_writeseg(struct lfs *fs, struct segment *sp) /* * Construct the cluster. */ - s = splbio(); while (fs->lfs_iocount >= LFS_THROTTLE) { #ifdef DEBUG_LFS printf("[%d]", fs->lfs_iocount); @@ -1841,7 +1851,9 @@ lfs_writeseg(struct lfs *fs, struct segment *sp) bp->b_flags &= ~(B_ERROR | B_READ | B_DELWRI | B_DONE); cl->bpp[cl->bufcount++] = bp; vp = bp->b_vp; + s = splbio(); ++vp->v_numoutput; + splx(s); /* * Although it cannot be freed for reuse before the @@ -1875,6 +1887,7 @@ lfs_writeseg(struct lfs *fs, struct segment *sp) * XXX KS - Shouldn't we set *both* if both types * of blocks are present (traverse the dirty list?) */ + s = splbio(); if ((i == 1 || (i > 1 && vp && *bpp && (*bpp)->b_vp != vp)) && (bp = LIST_FIRST(&vp->v_dirtyblkhd)) != NULL && @@ -1890,8 +1903,10 @@ lfs_writeseg(struct lfs *fs, struct segment *sp) else LFS_SET_UINO(ip, IN_MODIFIED); } + splx(s); wakeup(vp); } + s = splbio(); ++cbp->b_vp->v_numoutput; splx(s); /* @@ -1967,8 +1982,8 @@ lfs_writesuper(struct lfs *fs, daddr_t daddr) vop_strategy_a.a_bp = bp; s = splbio(); ++bp->b_vp->v_numoutput; - ++fs->lfs_iocount; splx(s); + ++fs->lfs_iocount; (strategy)(&vop_strategy_a); } @@ -2030,8 +2045,8 @@ lfs_callback(struct buf *bp) lfs_freebuf(bp); } -void -lfs_supercallback(struct buf *bp) +static void +lfs_super_aiodone(struct buf *bp) { struct lfs *fs; @@ -2044,13 +2059,13 @@ lfs_supercallback(struct buf *bp) } static void -lfs_cluster_callback(struct buf *bp) +lfs_cluster_aiodone(struct buf *bp) { struct lfs_cluster *cl; struct lfs *fs; struct buf *tbp; struct vnode *vp; - int error=0; + int s, error=0; char *cp; extern int locked_queue_count; extern long locked_queue_bytes; @@ -2101,8 +2116,10 @@ lfs_cluster_callback(struct buf *bp) tbp->b_flags |= B_INVAL; if(!(tbp->b_flags & B_CALL)) { bremfree(tbp); + s = splbio(); if(vp) reassignbuf(tbp, vp); + splx(s); tbp->b_flags |= B_ASYNC; /* for biodone */ } #ifdef DIAGNOSTIC @@ -2112,27 +2129,7 @@ lfs_cluster_callback(struct buf *bp) } #endif if (tbp->b_flags & (B_BUSY | B_CALL)) { - /* - * Prevent vp from being moved between hold list - * and free list by giving it an extra hold, - * and then inline HOLDRELE, minus the TAILQ - * manipulation. - * - * lfs_vunref() will put the vnode back on the - * appropriate free list the next time it is - * called (in thread context). - */ - if (vp) - VHOLD(vp); biodone(tbp); - if (vp) { - simple_lock(&vp->v_interlock); - if (vp->v_holdcnt <= 0) - panic("lfs_cluster_callback: " - "holdcnt vp %p", vp); - vp->v_holdcnt--; - simple_unlock(&vp->v_interlock); - } } } @@ -2151,23 +2148,26 @@ lfs_cluster_callback(struct buf *bp) bp->b_iodone = NULL; bp->b_flags &= ~B_DELWRI; bp->b_flags |= B_DONE; + s = splbio(); reassignbuf(bp, bp->b_vp); + splx(s); brelse(bp); - free(cl->bpp, M_SEGMENT); - free(cl, M_SEGMENT); - + /* Note i/o done */ + if (cl->flags & LFS_CL_SYNC) { + if (--cl->seg->seg_iocount == 0) + wakeup(&cl->seg->seg_iocount); + /* printf("- %x => %d\n", cl->seg, cl->seg->seg_iocount); */ + } #ifdef DIAGNOSTIC if (fs->lfs_iocount == 0) - panic("lfs_callback: zero iocount\n"); + panic("lfs_cluster_aiodone: zero iocount\n"); #endif if (--fs->lfs_iocount < LFS_THROTTLE) wakeup(&fs->lfs_iocount); #if 0 if (fs->lfs_iocount == 0) { /* - * XXX - do we really want to do this in a callback? - * * Vinvalbuf can move locked buffers off the locked queue * and we have no way of knowing about this. So, after * doing a big write, we recalculate how many buffers are @@ -2177,6 +2177,33 @@ lfs_cluster_callback(struct buf *bp) wakeup(&locked_queue_count); } #endif + + free(cl->bpp, M_SEGMENT); + free(cl, M_SEGMENT); +} + +static void +lfs_generic_callback(struct buf *bp, void (*aiodone)(struct buf *)) +{ + /* reset b_iodone for when this is a single-buf i/o. */ + bp->b_iodone = aiodone; + + simple_lock(&uvm.aiodoned_lock); /* locks uvm.aio_done */ + TAILQ_INSERT_TAIL(&uvm.aio_done, bp, b_freelist); + wakeup(&uvm.aiodoned); + simple_unlock(&uvm.aiodoned_lock); +} + +static void +lfs_cluster_callback(struct buf *bp) +{ + lfs_generic_callback(bp, lfs_cluster_aiodone); +} + +void +lfs_supercallback(struct buf *bp) +{ + lfs_generic_callback(bp, lfs_super_aiodone); } /* diff --git a/sys/ufs/lfs/lfs_subr.c b/sys/ufs/lfs/lfs_subr.c index 6ce58de0aa6e..d54d76b01ee1 100644 --- a/sys/ufs/lfs/lfs_subr.c +++ b/sys/ufs/lfs/lfs_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_subr.c,v 1.25 2002/05/24 22:13:57 perseant Exp $ */ +/* $NetBSD: lfs_subr.c,v 1.26 2002/06/16 00:13:15 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: lfs_subr.c,v 1.25 2002/05/24 22:13:57 perseant Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_subr.c,v 1.26 2002/06/16 00:13:15 perseant Exp $"); #include #include @@ -131,7 +131,6 @@ void lfs_seglock(struct lfs *fs, unsigned long flags) { struct segment *sp; - int s; if (fs->lfs_seglock) { if (fs->lfs_lockpid == curproc->p_pid) { @@ -152,6 +151,7 @@ lfs_seglock(struct lfs *fs, unsigned long flags) M_SEGMENT, M_WAITOK); sp->seg_flags = flags; sp->vp = NULL; + sp->seg_iocount = 0; (void) lfs_initseg(fs); /* @@ -160,9 +160,7 @@ lfs_seglock(struct lfs *fs, unsigned long flags) * so we artificially increment it by one until we've scheduled all of * the writes we intend to do. */ - s = splbio(); ++fs->lfs_iocount; - splx(s); } /* @@ -174,7 +172,6 @@ lfs_segunlock(struct lfs *fs) { struct segment *sp; unsigned long sync, ckp; - int s; struct buf *bp; struct vnode *vp, *nvp; struct mount *mp; @@ -265,7 +262,9 @@ lfs_segunlock(struct lfs *fs) free(sp->bpp, M_SEGMENT); sp->bpp = NULL; - free(sp, M_SEGMENT); + /* The sync case holds a reference in `sp' to be freed below */ + if (!sync) + free(sp, M_SEGMENT); fs->lfs_sp = NULL; /* @@ -273,7 +272,6 @@ lfs_segunlock(struct lfs *fs) * At the moment, the user's process hangs around so we can * sleep. */ - s = splbio(); if (--fs->lfs_iocount < LFS_THROTTLE) wakeup(&fs->lfs_iocount); if(fs->lfs_iocount == 0) { @@ -282,6 +280,16 @@ lfs_segunlock(struct lfs *fs) wakeup(&locked_queue_count); wakeup(&fs->lfs_iocount); } + /* + * If we're not checkpointing, we don't have to block + * other processes to wait for a synchronous write + * to complete. + */ + if (!ckp) { + --fs->lfs_seglock; + fs->lfs_lockpid = 0; + wakeup(&fs->lfs_seglock); + } /* * We let checkpoints happen asynchronously. That means * that during recovery, we have to roll forward between @@ -289,10 +297,16 @@ lfs_segunlock(struct lfs *fs) * superblocks to make sure that the checkpoint described * by a superblock completed. */ - while (sync && fs->lfs_iocount) + while (ckp && sync && fs->lfs_iocount) (void)tsleep(&fs->lfs_iocount, PRIBIO + 1, - "lfs vflush", 0); - splx(s); + "lfs_iocount", 0); + while (sync && sp->seg_iocount) { + (void)tsleep(&sp->seg_iocount, PRIBIO + 1, + "seg_iocount", 0); + /* printf("sleeping on iocount %x == %d\n", sp, sp->seg_iocount); */ + } + if (sync) + free(sp, M_SEGMENT); if (ckp) { fs->lfs_nactive = 0; /* If we *know* everything's on disk, write both sbs */ @@ -300,10 +314,11 @@ lfs_segunlock(struct lfs *fs) lfs_writesuper(fs,fs->lfs_sboffs[fs->lfs_activesb]); fs->lfs_activesb = 1 - fs->lfs_activesb; lfs_writesuper(fs,fs->lfs_sboffs[fs->lfs_activesb]); + + --fs->lfs_seglock; + fs->lfs_lockpid = 0; + wakeup(&fs->lfs_seglock); } - --fs->lfs_seglock; - fs->lfs_lockpid = 0; - wakeup(&fs->lfs_seglock); } else if (fs->lfs_seglock == 0) { panic ("Seglock not held"); } else { diff --git a/sys/ufs/lfs/lfs_syscalls.c b/sys/ufs/lfs/lfs_syscalls.c index 17ca48073090..841032745608 100644 --- a/sys/ufs/lfs/lfs_syscalls.c +++ b/sys/ufs/lfs/lfs_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_syscalls.c,v 1.66 2002/06/06 00:46:24 perseant Exp $ */ +/* $NetBSD: lfs_syscalls.c,v 1.67 2002/06/16 00:13:16 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: lfs_syscalls.c,v 1.66 2002/06/06 00:46:24 perseant Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_syscalls.c,v 1.67 2002/06/16 00:13:16 perseant Exp $"); #define LFS /* for prototypes in syscallargs.h */ @@ -282,7 +282,7 @@ lfs_markv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt) * any Ifile blocks that we might be asked to clean will never get * to the disk. */ - lfs_seglock(fs, SEGM_SYNC|SEGM_CLEAN|SEGM_CKP); + lfs_seglock(fs, SEGM_CLEAN | SEGM_CKP | SEGM_SYNC); /* Mark blocks/inodes dirty. */ error = 0; @@ -444,6 +444,7 @@ lfs_markv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt) printf("lfs_markv: wrong da same seg: %x vs %x\n", blkp->bi_daddr, dbtofsb(fs, b_daddr)); } + do_again++; continue; } } @@ -465,9 +466,13 @@ lfs_markv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt) s = splbio(); bp = incore(vp, blkp->bi_lbn); if (bp && bp->b_bcount > blkp->bi_size) { - printf("lfs_markv: %ld > %d (fixed)\n", - bp->b_bcount, blkp->bi_size); - blkp->bi_size = bp->b_bcount; + splx(s); + printf("lfs_markv: ino %d lbn %d fragment size changed (%ld > %d), try again\n", + blkp->bi_inode, blkp->bi_lbn, + bp->b_bcount, blkp->bi_size); + do_again++; + continue; + /* blkp->bi_size = bp->b_bcount; */ } splx(s); } @@ -524,7 +529,7 @@ lfs_markv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt) * over the newly cleaned data contained in a checkpoint, and then * we'd be unhappy at recovery time. */ - lfs_segwrite(mntp, SEGM_SYNC|SEGM_CLEAN|SEGM_CKP); + lfs_segwrite(mntp, SEGM_CLEAN | SEGM_CKP | SEGM_SYNC); lfs_segunlock(fs); @@ -884,6 +889,7 @@ sys_lfs_segclean(struct proc *p, void *v, register_t *retval) struct lfs *fs; fsid_t fsid; int error; + unsigned long segnum; if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) return (error); @@ -894,8 +900,9 @@ sys_lfs_segclean(struct proc *p, void *v, register_t *retval) return (ENOENT); fs = VFSTOUFS(mntp)->um_lfs; + segnum = SCARG(uap, segment); - if (dtosn(fs, fs->lfs_curseg) == SCARG(uap, segment)) + if (dtosn(fs, fs->lfs_curseg) == segnum) return (EBUSY); if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0) @@ -903,7 +910,17 @@ sys_lfs_segclean(struct proc *p, void *v, register_t *retval) #ifdef LFS_AGGRESSIVE_SEGLOCK lfs_seglock(fs, SEGM_PROT); #endif - LFS_SEGENTRY(sup, fs, SCARG(uap, segment), bp); + LFS_SEGENTRY(sup, fs, segnum, bp); + if (sup->su_nbytes) { + printf("lfs_segclean: not cleaning segment %lu: %d live bytes\n", + segnum, sup->su_nbytes); + brelse(bp); +#ifdef LFS_AGGRESSIVE_SEGLOCK + lfs_segunlock(fs); +#endif + vfs_unbusy(mntp); + return (EBUSY); + } if (sup->su_flags & SEGUSE_ACTIVE) { brelse(bp); #ifdef LFS_AGGRESSIVE_SEGLOCK @@ -924,7 +941,7 @@ sys_lfs_segclean(struct proc *p, void *v, register_t *retval) fs->lfs_avail += segtod(fs, 1); if (sup->su_flags & SEGUSE_SUPERBLOCK) fs->lfs_avail -= btofsb(fs, LFS_SBPAD); - if (fs->lfs_version > 1 && SCARG(uap, segment) == 0 && + if (fs->lfs_version > 1 && segnum == 0 && fs->lfs_start < btofsb(fs, LFS_LABELPAD)) fs->lfs_avail -= btofsb(fs, LFS_LABELPAD) - fs->lfs_start; fs->lfs_bfree += sup->su_nsums * btofsb(fs, fs->lfs_sumsize) + @@ -1240,9 +1257,7 @@ lfs_fakebuf(struct lfs *fs, struct vnode *vp, int lbn, size_t size, caddr_t uadd #endif #if 0 bp->b_saveaddr = (caddr_t)fs; - s = splbio(); ++fs->lfs_iocount; - splx(s); #endif bp->b_bufsize = size; bp->b_bcount = size; diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c index 086a0399feae..7e1cb84594e5 100644 --- a/sys/ufs/lfs/lfs_vfsops.c +++ b/sys/ufs/lfs/lfs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vfsops.c,v 1.76 2002/05/17 21:42:38 perseant Exp $ */ +/* $NetBSD: lfs_vfsops.c,v 1.77 2002/06/16 00:13:16 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.76 2002/05/17 21:42:38 perseant Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.77 2002/06/16 00:13:16 perseant Exp $"); #if defined(_KERNEL_OPT) #include "opt_quota.h" @@ -1174,7 +1174,7 @@ lfs_unmount(struct mount *mp, int mntflags, struct proc *p) { struct ufsmount *ump; struct lfs *fs; - int error, flags, ronly, s; + int error, flags, ronly; flags = 0; if (mntflags & MNT_FORCE) @@ -1231,10 +1231,8 @@ lfs_unmount(struct mount *mp, int mntflags, struct proc *p) vgone(fs->lfs_ivnode); /* Wait for superblock writes to complete */ - s = splbio(); while (fs->lfs_iocount) tsleep(&fs->lfs_iocount, PRIBIO + 1, "lfs_umount", 0); - splx(s); ronly = !fs->lfs_ronly; if (ump->um_devvp->v_type != VBAD) diff --git a/sys/ufs/lfs/lfs_vnops.c b/sys/ufs/lfs/lfs_vnops.c index 95008a87e2ed..4eb0398ea8ca 100644 --- a/sys/ufs/lfs/lfs_vnops.c +++ b/sys/ufs/lfs/lfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vnops.c,v 1.64 2002/05/17 21:42:38 perseant Exp $ */ +/* $NetBSD: lfs_vnops.c,v 1.65 2002/06/16 00:13:16 perseant Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.64 2002/05/17 21:42:38 perseant Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.65 2002/06/16 00:13:16 perseant Exp $"); #include #include @@ -164,7 +164,7 @@ const struct vnodeopv_entry_desc lfs_specop_entries[] = { { &vop_create_desc, spec_create }, /* create */ { &vop_mknod_desc, spec_mknod }, /* mknod */ { &vop_open_desc, spec_open }, /* open */ - { &vop_close_desc, ufsspec_close }, /* close */ + { &vop_close_desc, lfsspec_close }, /* close */ { &vop_access_desc, ufs_access }, /* access */ { &vop_getattr_desc, lfs_getattr }, /* getattr */ { &vop_setattr_desc, lfs_setattr }, /* setattr */ @@ -217,7 +217,7 @@ const struct vnodeopv_entry_desc lfs_fifoop_entries[] = { { &vop_create_desc, fifo_create }, /* create */ { &vop_mknod_desc, fifo_mknod }, /* mknod */ { &vop_open_desc, fifo_open }, /* open */ - { &vop_close_desc, ufsfifo_close }, /* close */ + { &vop_close_desc, lfsfifo_close }, /* close */ { &vop_access_desc, ufs_access }, /* access */ { &vop_getattr_desc, lfs_getattr }, /* getattr */ { &vop_setattr_desc, lfs_setattr }, /* setattr */ @@ -864,15 +864,67 @@ lfs_close(void *v) struct inode *ip = VTOI(vp); struct timespec ts; - simple_lock(&vp->v_interlock); if (vp->v_usecount > 1) { TIMEVAL_TO_TIMESPEC(&time, &ts); LFS_ITIMES(ip, &ts, &ts, &ts); } - simple_unlock(&vp->v_interlock); return (0); } +/* + * Close wrapper for special devices. + * + * Update the times on the inode then do device close. + */ +int +lfsspec_close(void *v) +{ + struct vop_close_args /* { + struct vnode *a_vp; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct vnode *vp; + struct inode *ip; + struct timespec ts; + + vp = ap->a_vp; + ip = VTOI(vp); + if (vp->v_usecount > 1) { + TIMEVAL_TO_TIMESPEC(&time, &ts); + LFS_ITIMES(ip, &ts, &ts, &ts); + } + return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap)); +} + +/* + * Close wrapper for fifo's. + * + * Update the times on the inode then do device close. + */ +int +lfsfifo_close(void *v) +{ + struct vop_close_args /* { + struct vnode *a_vp; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct vnode *vp; + struct inode *ip; + struct timespec ts; + + vp = ap->a_vp; + ip = VTOI(vp); + if (ap->a_vp->v_usecount > 1) { + TIMEVAL_TO_TIMESPEC(&time, &ts); + LFS_ITIMES(ip, &ts, &ts, &ts); + } + return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap)); +} + /* * Reclaim an inode so that it can be used for other purposes. */ diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h index 943afe0c60a8..872a15ecc276 100644 --- a/sys/ufs/ufs/inode.h +++ b/sys/ufs/ufs/inode.h @@ -1,4 +1,4 @@ -/* $NetBSD: inode.h,v 1.27 2001/12/18 10:57:23 fvdl Exp $ */ +/* $NetBSD: inode.h,v 1.28 2002/06/16 00:13:17 perseant Exp $ */ /* * Copyright (c) 1982, 1989, 1993 @@ -45,7 +45,6 @@ #include #include #include -#include #include /* @@ -176,9 +175,6 @@ struct inode { #define IN_SPACECOUNTED 0x0400 /* Blocks to be freed in free count. */ #if defined(_KERNEL) -#if defined(_KERNEL_OPT) -#include "fs_lfs.h" /* for ITIMES */ -#endif /* _KERNEL_OPT */ /* * Structure used to pass around logical block paths generated by * ufs_getlbns and used by truncate and bmap code. @@ -234,23 +230,12 @@ struct indir { } \ } -#ifdef LFS -#define ITIMES(ip, acc, mod, cre) { \ - if (IS_EXT2_VNODE((ip)->i_vnode)) \ - EXT2FS_ITIMES(ip, acc, mod, cre) \ - else if(IS_LFS_VNODE((ip)->i_vnode)) \ - lfs_itimes(ip, acc, mod, cre); \ - else \ - FFS_ITIMES(ip, acc, mod, cre) \ -} -#else /* ! LFS */ #define ITIMES(ip, acc, mod, cre) { \ if (IS_EXT2_VNODE((ip)->i_vnode)) \ EXT2FS_ITIMES(ip, acc, mod, cre) \ else \ FFS_ITIMES(ip, acc, mod, cre) \ } -#endif /* ! LFS */ /* Determine if soft dependencies are being done */ #define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)