Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Do not needlessly dirty segment table blocks dur...
details: https://anonhg.NetBSD.org/src/rev/79662ed38129
branches: trunk
changeset: 499127:79662ed38129
user: perseant <perseant%NetBSD.org@localhost>
date: Sun Nov 12 07:58:36 2000 +0000
description:
Do not needlessly dirty segment table blocks during lfs_segwrite,
preventing needless disk activity when the filesystem is idle. (PR #10979.)
diffstat:
sys/ufs/lfs/lfs.h | 14 ++++++++-
sys/ufs/lfs/lfs_bio.c | 10 ++----
sys/ufs/lfs/lfs_segment.c | 68 ++++++++++++++++++++++++++++++++--------------
sys/ufs/lfs/lfs_vnops.c | 6 +++-
4 files changed, 68 insertions(+), 30 deletions(-)
diffs (229 lines):
diff -r a7e5172ebb78 -r 79662ed38129 sys/ufs/lfs/lfs.h
--- a/sys/ufs/lfs/lfs.h Sun Nov 12 06:52:37 2000 +0000
+++ b/sys/ufs/lfs/lfs.h Sun Nov 12 07:58:36 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs.h,v 1.32 2000/09/13 00:07:56 perseant Exp $ */
+/* $NetBSD: lfs.h,v 1.33 2000/11/12 07:58:36 perseant Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -482,6 +482,18 @@
(CP) = (CLEANERINFO *)(BP)->b_data; \
}
+/* Synchronize the Ifile cleaner info with current avail and bfree */
+#define LFS_SYNC_CLEANERINFO(cip, fs, bp, w) do { \
+ if ((w) || (cip)->bfree != (fs)->lfs_bfree || \
+ (cip)->avail != (fs)->lfs_avail - (fs)->lfs_ravail) { \
+ printf("update cleaner info at %s:%d\n", __FILE__, __LINE__); \
+ (cip)->bfree = (fs)->lfs_bfree; \
+ (cip)->avail = (fs)->lfs_avail - (fs)->lfs_ravail; \
+ (void) VOP_BWRITE(bp); /* Ifile */ \
+ } else \
+ brelse(bp); \
+} while(0)
+
/* Read in the block with a specific inode from the ifile. */
#define LFS_IENTRY(IP, F, IN, BP) { \
int _e; \
diff -r a7e5172ebb78 -r 79662ed38129 sys/ufs/lfs/lfs_bio.c
--- a/sys/ufs/lfs/lfs_bio.c Sun Nov 12 06:52:37 2000 +0000
+++ b/sys/ufs/lfs/lfs_bio.c Sun Nov 12 07:58:36 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_bio.c,v 1.30 2000/09/13 00:07:56 perseant Exp $ */
+/* $NetBSD: lfs_bio.c,v 1.31 2000/11/12 07:58:36 perseant Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -154,9 +154,7 @@
/* Wake up the cleaner */
LFS_CLEANERINFO(cip, fs, bp);
- cip->bfree = fs->lfs_bfree;
- cip->avail = fs->lfs_avail - fs->lfs_ravail;
- (void) VOP_BWRITE(bp); /* Ifile */
+ LFS_SYNC_CLEANERINFO(cip, fs, bp, 0);
wakeup(&lfs_allclean_wakeup);
wakeup(&fs->lfs_nextseg);
@@ -279,9 +277,7 @@
* so it CANT_WAIT.
*/
LFS_CLEANERINFO(cip, fs, cbp);
- cip->bfree = fs->lfs_bfree;
- cip->avail = fs->lfs_avail;
- (void) VOP_BWRITE(cbp);
+ LFS_SYNC_CLEANERINFO(cip, fs, cbp, 0);
printf("lfs_bwrite: out of available space, "
"waiting on cleaner\n");
diff -r a7e5172ebb78 -r 79662ed38129 sys/ufs/lfs/lfs_segment.c
--- a/sys/ufs/lfs/lfs_segment.c Sun Nov 12 06:52:37 2000 +0000
+++ b/sys/ufs/lfs/lfs_segment.c Sun Nov 12 07:58:36 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_segment.c,v 1.60 2000/11/12 02:13:51 toshii Exp $ */
+/* $NetBSD: lfs_segment.c,v 1.61 2000/11/12 07:58:36 perseant Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -466,10 +466,10 @@
struct segment *sp;
struct vnode *vp;
SEGUSE *segusep;
- CLEANERINFO *cip;
ufs_daddr_t ibno;
- int do_ckp, error, i;
+ int do_ckp, did_ckp, error, i;
int writer_set = 0;
+ int dirty;
fs = VFSTOUFS(mp)->um_lfs;
@@ -478,15 +478,21 @@
lfs_imtime(fs);
+ /* printf("lfs_segwrite: ifile flags are 0x%lx\n",
+ (long)(VTOI(fs->lfs_ivnode)->i_flag)); */
+
#if 0
/*
* If we are not the cleaner, and there is no space available,
* wait until cleaner writes.
*/
- if(!(flags & SEGM_CLEAN)
- && (!fs->lfs_seglock || !(fs->lfs_sp->seg_flags & SEGM_CLEAN)))
+ if(!(flags & SEGM_CLEAN) && !(fs->lfs_seglock && fs->lfs_sp &&
+ (fs->lfs_sp->seg_flags & SEGM_CLEAN)))
{
while (fs->lfs_avail <= 0) {
+ LFS_CLEANERINFO(cip, fs, bp);
+ LFS_SYNC_CLEANERINFO(cip, fs, bp, 0);
+
wakeup(&lfs_allclean_wakeup);
wakeup(&fs->lfs_nextseg);
error = tsleep(&fs->lfs_avail, PRIBIO + 1, "lfs_av2",
@@ -498,14 +504,6 @@
}
#endif
/*
- * Synchronize cleaner information
- */
- LFS_CLEANERINFO(cip, fs, bp);
- cip->bfree = fs->lfs_bfree;
- cip->avail = fs->lfs_avail - fs->lfs_ravail;
- (void) VOP_BWRITE(bp); /* Ifile */
-
- /*
* Allocate a segment structure and enough space to hold pointers to
* the maximum possible number of buffers which can be described in a
* single summary block.
@@ -550,23 +548,34 @@
if (do_ckp) {
for (ibno = fs->lfs_cleansz + fs->lfs_segtabsz;
--ibno >= fs->lfs_cleansz; ) {
+ dirty = 0;
if (bread(fs->lfs_ivnode, ibno, fs->lfs_bsize, NOCRED, &bp))
panic("lfs_segwrite: ifile read");
segusep = (SEGUSE *)bp->b_data;
- for (i = fs->lfs_sepb; i--; segusep++)
- segusep->su_flags &= ~SEGUSE_ACTIVE;
+ for (i = fs->lfs_sepb; i--; segusep++) {
+ if (segusep->su_flags & SEGUSE_ACTIVE) {
+ segusep->su_flags &= ~SEGUSE_ACTIVE;
+ ++dirty;
+ }
+ }
/* But the current segment is still ACTIVE */
segusep = (SEGUSE *)bp->b_data;
if (datosn(fs, fs->lfs_curseg) / fs->lfs_sepb ==
- (ibno-fs->lfs_cleansz))
+ (ibno-fs->lfs_cleansz)) {
segusep[datosn(fs, fs->lfs_curseg) %
fs->lfs_sepb].su_flags |= SEGUSE_ACTIVE;
- error = VOP_BWRITE(bp); /* Ifile */
+ --dirty;
+ }
+ if (dirty)
+ error = VOP_BWRITE(bp); /* Ifile */
+ else
+ brelse(bp);
}
}
-
+
+ did_ckp = 0;
if (do_ckp || fs->lfs_doifile) {
redo:
vp = fs->lfs_ivnode;
@@ -576,12 +585,16 @@
ip = VTOI(vp);
if (vp->v_dirtyblkhd.lh_first != NULL)
lfs_writefile(fs, sp, vp);
- (void)lfs_writeinode(fs, sp, ip);
+ if (ip->i_flag & IN_ALLMOD)
+ ++did_ckp;
+ (void) lfs_writeinode(fs, sp, ip);
vput(vp);
if (lfs_writeseg(fs, sp) && do_ckp)
goto redo;
+ /* The ifile should now be all clear */
+ LFS_CLR_UINO(ip, IN_ALLMOD);
} else {
(void) lfs_writeseg(fs, sp);
}
@@ -594,7 +607,20 @@
fs->lfs_doifile = 0;
if(writer_set && --fs->lfs_writer==0)
wakeup(&fs->lfs_dirops);
-
+
+ /*
+ * If we didn't write the Ifile, we didn't really do anything.
+ * That means that (1) there is a checkpoint on disk and (2)
+ * nothing has changed since it was written.
+ *
+ * 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) printf("lfs_segwrite: no checkpoint\n"); */
+ }
+
if(lfs_dostats) {
++lfs_stats.nwrites;
if (sp->seg_flags & SEGM_SYNC)
@@ -1225,7 +1251,7 @@
--cip->clean;
++cip->dirty;
fs->lfs_nclean = cip->clean;
- (void) VOP_BWRITE(bp); /* Ifile */
+ LFS_SYNC_CLEANERINFO(cip, fs, bp, 1);
fs->lfs_lastseg = fs->lfs_curseg;
fs->lfs_curseg = fs->lfs_nextseg;
diff -r a7e5172ebb78 -r 79662ed38129 sys/ufs/lfs/lfs_vnops.c
--- a/sys/ufs/lfs/lfs_vnops.c Sun Nov 12 06:52:37 2000 +0000
+++ b/sys/ufs/lfs/lfs_vnops.c Sun Nov 12 07:58:36 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_vnops.c,v 1.46 2000/10/14 23:22:14 perseant Exp $ */
+/* $NetBSD: lfs_vnops.c,v 1.47 2000/11/12 07:58:36 perseant Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -287,6 +287,10 @@
struct proc *a_p;
} */ *ap = v;
+ /* Ignore the trickle syncer */
+ if (ap->a_flags & FSYNC_LAZY)
+ return 0;
+
return (VOP_UPDATE(ap->a_vp, NULL, NULL,
(ap->a_flags & FSYNC_WAIT) != 0 ? UPDATE_WAIT : 0));
}
Home |
Main Index |
Thread Index |
Old Index