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