Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Fix errors observed while trying to fill the fil...
details: https://anonhg.NetBSD.org/src/rev/0873ff2a9303
branches: trunk
changeset: 494274:0873ff2a9303
user: perseant <perseant%NetBSD.org@localhost>
date: Tue Jul 04 22:30:37 2000 +0000
description:
Fix errors observed while trying to fill the filesystem with yesterday's
fixes:
- Write copies of bfree and avail in the CLEANERINFO block, so the
cleaner doesn't have to guess which superblock has the current
information (if indeed any do).
- Tighten up accounting of lfs_avail (more needs to be done).
- When cleansing indirect blocks of UNWRITTEN, make sure not to mark
them clean, since they'll need to be rewritten later.
diffstat:
sys/ufs/lfs/lfs.h | 21 ++--
sys/ufs/lfs/lfs_balloc.c | 8 +-
sys/ufs/lfs/lfs_inode.c | 6 +-
sys/ufs/lfs/lfs_segment.c | 220 ++++++++++++++++++++------------------------
sys/ufs/lfs/lfs_syscalls.c | 11 +-
5 files changed, 119 insertions(+), 147 deletions(-)
diffs (truncated from 516 to 300 lines):
diff -r 85d62b895378 -r 0873ff2a9303 sys/ufs/lfs/lfs.h
--- a/sys/ufs/lfs/lfs.h Tue Jul 04 22:25:06 2000 +0000
+++ b/sys/ufs/lfs/lfs.h Tue Jul 04 22:30:37 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs.h,v 1.27 2000/07/03 01:45:46 perseant Exp $ */
+/* $NetBSD: lfs.h,v 1.28 2000/07/04 22:30:37 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -352,8 +352,10 @@
* to pass information between the cleaner and the kernel.
*/
typedef struct _cleanerinfo {
- u_int32_t clean; /* K: number of clean segments */
- u_int32_t dirty; /* K: number of dirty segments */
+ u_int32_t clean; /* number of clean segments */
+ u_int32_t dirty; /* number of dirty segments */
+ u_int32_t bfree; /* disk blocks free */
+ u_int32_t avail; /* disk blocks available */
} CLEANERINFO;
#define CLEANSIZE_SU(fs) \
@@ -504,21 +506,18 @@
* of segment summaries and inode blocks taken into account.
*/
/* Estimate number of clean blocks not available for writing */
-#define LFS_EST_CMETA(F) ((u_int32_t)(((F)->lfs_dmeta * \
- (u_int64_t)(F)->lfs_nclean) / \
+#define LFS_EST_CMETA(F) ((((F)->lfs_dmeta * (u_int64_t)(F)->lfs_nclean) / \
((F)->lfs_nseg - (F)->lfs_nclean)))
/* Estimate total size of the disk not including metadata */
-#define LFS_EST_NONMETA(F) ((F)->lfs_dsize - fsbtodb((F), (F)->lfs_minfreeseg *\
- (F)->lfs_ssize) - \
- (F)->lfs_dmeta - LFS_EST_CMETA(F))
+#define LFS_EST_NONMETA(F) ((F)->lfs_dsize - (F)->lfs_dmeta - LFS_EST_CMETA(F))
/* Estimate number of blocks actually available for writing */
-#define LFS_EST_BFREE(F) ((F)->lfs_bfree - LFS_EST_CMETA(F))
+#define LFS_EST_BFREE(F) ((F)->lfs_bfree - LFS_EST_CMETA(F) - (F)->lfs_dmeta)
/* Amount of non-meta space not available to mortal man */
-#define LFS_EST_RSVD(F) ((u_int32_t)(((LFS_EST_NONMETA(F) * \
- (u_int64_t)(F)->lfs_minfree)) / 100))
+#define LFS_EST_RSVD(F) ((LFS_EST_NONMETA(F) * (u_int64_t)(F)->lfs_minfree) / \
+ 100)
/* Can credential C write BB blocks */
#define ISSPACE(F, BB, C) \
diff -r 85d62b895378 -r 0873ff2a9303 sys/ufs/lfs/lfs_balloc.c
--- a/sys/ufs/lfs/lfs_balloc.c Tue Jul 04 22:25:06 2000 +0000
+++ b/sys/ufs/lfs/lfs_balloc.c Tue Jul 04 22:30:37 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_balloc.c,v 1.23 2000/07/03 20:12:42 perseant Exp $ */
+/* $NetBSD: lfs_balloc.c,v 1.24 2000/07/04 22:30:37 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -140,12 +140,6 @@
lbn = lblkno(fs, ap->a_startoffset);
(void)lfs_check(vp, lbn, 0);
-#ifdef DEBUG
- if(!VOP_ISLOCKED(vp)) {
- printf("lfs_balloc: warning: ino %d not locked\n",ip->i_number);
- }
-#endif
-
/*
* Three cases: it's a block beyond the end of file, it's a block in
* the file that may or may not have been assigned a disk address or
diff -r 85d62b895378 -r 0873ff2a9303 sys/ufs/lfs/lfs_inode.c
--- a/sys/ufs/lfs/lfs_inode.c Tue Jul 04 22:25:06 2000 +0000
+++ b/sys/ufs/lfs/lfs_inode.c Tue Jul 04 22:30:37 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_inode.c,v 1.40 2000/07/03 01:45:51 perseant Exp $ */
+/* $NetBSD: lfs_inode.c,v 1.41 2000/07/04 22:30:37 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -685,7 +685,7 @@
}
bp->b_flags |= B_BUSY | B_INVAL | B_VFLUSH;
if (bp->b_flags & B_DELWRI)
- fs->lfs_avail += bp->b_bcount;
+ fs->lfs_avail += btodb(bp->b_bcount);
if (bp->b_flags & B_LOCKED) {
bp->b_flags &= ~B_LOCKED;
--locked_queue_count;
@@ -710,7 +710,7 @@
}
bp->b_flags |= B_BUSY | B_INVAL | B_VFLUSH;
if (bp->b_flags & B_DELWRI)
- fs->lfs_avail += bp->b_bcount;
+ fs->lfs_avail += btodb(bp->b_bcount);
if (bp->b_flags & B_LOCKED) {
bp->b_flags &= ~B_LOCKED;
--locked_queue_count;
diff -r 85d62b895378 -r 0873ff2a9303 sys/ufs/lfs/lfs_segment.c
--- a/sys/ufs/lfs/lfs_segment.c Tue Jul 04 22:25:06 2000 +0000
+++ b/sys/ufs/lfs/lfs_segment.c Tue Jul 04 22:30:37 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_segment.c,v 1.54 2000/07/03 08:20:58 perseant Exp $ */
+/* $NetBSD: lfs_segment.c,v 1.55 2000/07/04 22:30:37 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -397,16 +397,6 @@
continue;
}
-#if 0 /* XXX KS - if we skip the ifile, things could go badly for us. */
- if(WRITEINPROG(vp)) {
- lfs_vunref(vp);
-#ifdef DEBUG_LFS
- ivndebug(vp,"writevnodes/writeinprog");
-#endif
- continue;
- }
-#endif
-
needs_unlock = 0;
if (VOP_ISLOCKED(vp)) {
if (vp != fs->lfs_ivnode &&
@@ -426,8 +416,7 @@
only_cleaning = 0;
/*
- * Write the inode/file if dirty and it's not the
- * the IFILE.
+ * Write the inode/file if dirty and it's not the IFILE.
*/
if ((ip->i_flag & IN_ALLMOD) ||
(vp->v_dirtyblkhd.lh_first != NULL))
@@ -478,10 +467,10 @@
struct segment *sp;
struct vnode *vp;
SEGUSE *segusep;
+ CLEANERINFO *cip;
ufs_daddr_t ibno;
int do_ckp, error, i;
int writer_set = 0;
- int need_unlock = 0;
fs = VFSTOUFS(mp)->um_lfs;
@@ -514,6 +503,14 @@
}
/*
+ * Synchronize cleaner information
+ */
+ LFS_CLEANERINFO(cip, fs, bp);
+ cip->bfree = fs->lfs_bfree;
+ cip->avail = fs->lfs_avail;
+ (void) VOP_BWRITE(bp);
+
+ /*
* 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.
@@ -578,30 +575,15 @@
if (do_ckp || fs->lfs_doifile) {
redo:
vp = fs->lfs_ivnode;
- /*
- * Depending on the circumstances of our calling, the ifile
- * inode might be locked. If it is, and if it is locked by
- * us, we should VREF instead of vget here.
- */
- need_unlock = 0;
- if(VOP_ISLOCKED(vp)
- && vp->v_lock.lk_lockholder == curproc->p_pid) {
- VREF(vp);
- } else {
- while (vget(vp, LK_EXCLUSIVE))
- continue;
- need_unlock = 1;
- }
+
+ vget(vp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY);
+
ip = VTOI(vp);
if (vp->v_dirtyblkhd.lh_first != NULL)
lfs_writefile(fs, sp, vp);
(void)lfs_writeinode(fs, sp, ip);
- /* Only vput if we used vget() above. */
- if(need_unlock)
- vput(vp);
- else
- vrele(vp);
+ vput(vp);
if (lfs_writeseg(fs, sp) && do_ckp)
goto redo;
@@ -758,13 +740,6 @@
TIMEVAL_TO_TIMESPEC(&time, &ts);
LFS_ITIMES(ip, &ts, &ts, &ts);
- /* XXX IN_ALLMOD */
- if(ip->i_flag & IN_CLEANING)
- ip->i_flag &= ~IN_CLEANING;
- else
- ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED |
- IN_UPDATE | IN_ACCESSED);
-
/*
* If this is the Ifile, and we've already written the Ifile in this
* partial segment, just overwrite it (it's not on disk yet) and
@@ -787,8 +762,10 @@
* addresses to disk.
*/
if (ip->i_lfs_effnblks != ip->i_ffs_blocks) {
+#ifdef DEBUG_LFS
printf("lfs_writeinode: cleansing ino %d (%d != %d)\n",
ip->i_number, ip->i_lfs_effnblks, ip->i_ffs_blocks);
+#endif
for (daddrp = cdp->di_db; daddrp < cdp->di_ib + NIADDR;
daddrp++) {
if (*daddrp == UNWRITTEN) {
@@ -800,6 +777,18 @@
}
}
+ /* XXX IN_ALLMOD */
+ if(ip->i_flag & IN_CLEANING)
+ ip->i_flag &= ~IN_CLEANING;
+ else {
+ ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE |
+ IN_ACCESSED);
+ if (ip->i_lfs_effnblks == ip->i_ffs_blocks) {
+ ip->i_flag &= ~IN_MODIFIED;
+ } else if (ip->i_flag & IN_MODIFIED)
+ fs->lfs_uinodes++;
+ }
+
if(ip->i_number == LFS_IFILE_INUM) /* We know sp->idp == NULL */
sp->idp = ((struct dinode *)bp->b_data) +
(sp->ninodes % INOPB(fs));
@@ -1000,7 +989,7 @@
struct segment *sp;
{
SEGUSE *sup;
- struct buf *bp, *ibp;
+ struct buf *bp;
struct lfs *fs;
struct vnode *vp;
struct indir a[NIADDR + 2], *ap;
@@ -1056,96 +1045,70 @@
switch (num) {
case 0:
ooff = ip->i_ffs_db[lbn];
- if(vp != fs->lfs_ivnode && ooff == 0) {
-#ifdef DEBUG_LFS
+#ifdef DEBUG
+ if (ooff == 0) {
printf("lfs_updatemeta[1]: warning: writing "
- "ino %d lbn %d at 0x%x, was 0x%x\n",
- ip->i_number, lbn, off, ooff);
+ "ino %d lbn %d at 0x%x, was 0x0\n",
+ ip->i_number, lbn, off);
+ }
#endif
- } else {
- if (ooff == UNWRITTEN)
- ip->i_ffs_blocks += bb;
- ip->i_ffs_db[lbn] = off;
- }
+ if (ooff == UNWRITTEN)
+ ip->i_ffs_blocks += bb;
+ ip->i_ffs_db[lbn] = off;
break;
case 1:
ooff = ip->i_ffs_ib[a[0].in_off];
- if(vp != fs->lfs_ivnode && ooff == 0) {
-#ifdef DEBUG_LFS
+#ifdef DEBUG
+ if (ooff == 0) {
printf("lfs_updatemeta[2]: warning: writing "
- "ino %d lbn %d at 0x%x, was 0x%x\n",
- ip->i_number, lbn, off, ooff);
+ "ino %d lbn %d at 0x%x, was 0x0\n",
+ ip->i_number, lbn, off);
+ }
#endif
- } else {
- if (ooff == UNWRITTEN)
- ip->i_ffs_blocks += bb;
- ip->i_ffs_ib[a[0].in_off] = off;
- }
+ if (ooff == UNWRITTEN)
+ ip->i_ffs_blocks += bb;
+ ip->i_ffs_ib[a[0].in_off] = off;
break;
default:
ap = &a[num - 1];
if (bread(vp, ap->in_lbn, fs->lfs_bsize, NOCRED, &bp))
panic("lfs_updatemeta: bread bno %d",
ap->in_lbn);
Home |
Main Index |
Thread Index |
Old Index