Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src fsck_lfs can now write to the filesystem, allowing it to cor...



details:   https://anonhg.NetBSD.org/src/rev/257551b2e17a
branches:  trunk
changeset: 486231:257551b2e17a
user:      perseant <perseant%NetBSD.org@localhost>
date:      Tue May 16 04:55:58 2000 +0000

description:
fsck_lfs can now write to the filesystem, allowing it to correct most
(though still not all) errors in a damaged lfs.  Segment byte accounting
is corrected in pass 5.  "fsck_lfs -p" will do a partial roll-forward,
verifying the checkpoint from the newer superblock.  fscknames[] is
updated so that fsck knows about fsck_lfs.

diffstat:

 sbin/fsck_lfs/Makefile    |   11 +-
 sbin/fsck_lfs/fsck.h      |    8 +-
 sbin/fsck_lfs/fsck_lfs.8  |   21 +-
 sbin/fsck_lfs/inode.c     |  184 +++++++++++++----------
 sbin/fsck_lfs/main.c      |  174 ++++++----------------
 sbin/fsck_lfs/pass0.c     |  225 ++++++++++++++++-------------
 sbin/fsck_lfs/pass1.c     |  102 +++++++++----
 sbin/fsck_lfs/pass1b.c    |  101 -------------
 sbin/fsck_lfs/pass5.c     |  349 ++++-----------------------------------------
 sbin/fsck_lfs/setup.c     |  159 +++++++++++++++-----
 sbin/fsck_lfs/utilities.c |   46 +++++-
 sys/sys/disklabel.h       |    4 +-
 12 files changed, 558 insertions(+), 826 deletions(-)

diffs (truncated from 2001 to 300 lines):

diff -r ac06651a65e2 -r 257551b2e17a sbin/fsck_lfs/Makefile
--- a/sbin/fsck_lfs/Makefile    Tue May 16 00:59:12 2000 +0000
+++ b/sbin/fsck_lfs/Makefile    Tue May 16 04:55:58 2000 +0000
@@ -1,16 +1,13 @@
-#      $NetBSD: Makefile,v 1.1 1999/03/18 02:02:18 perseant Exp $
+#      $NetBSD: Makefile,v 1.2 2000/05/16 04:55:59 perseant Exp $
 #      @(#)Makefile    8.1 (Berkeley) 6/5/93
 
 PROG=  fsck_lfs
 MAN=   fsck_lfs.8
 SRCS=  dir.c inode.c main.c pass1.c pass2.c pass3.c pass4.c \
-       fsutil.c setup.c utilities.c lfs_cksum.c vars.c # lfs_subr.c
-SRCS+=  pass0.c
-#SRCS+= pass1b.c pass5.c ffs_subr.c ffs_tables.c
+       fsutil.c setup.c utilities.c lfs_cksum.c vars.c
+SRCS+=  pass0.c pass5.c
 FSCK=   ${.CURDIR}/../fsck
 .PATH: ${.CURDIR}/../../sys/ufs/lfs ${FSCK}
-CPPFLAGS+=-I${FSCK} #-I../../sys -I../../include -DVERBOSE_BLOCKMAP
-CFLAGS+=-g
-LDFLAGS+=-g
+CPPFLAGS+=-I${FSCK}
 
 .include <bsd.prog.mk>
diff -r ac06651a65e2 -r 257551b2e17a sbin/fsck_lfs/fsck.h
--- a/sbin/fsck_lfs/fsck.h      Tue May 16 00:59:12 2000 +0000
+++ b/sbin/fsck_lfs/fsck.h      Tue May 16 04:55:58 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fsck.h,v 1.3 2000/01/20 21:32:31 perseant Exp $        */
+/*     $NetBSD: fsck.h,v 1.4 2000/05/16 04:55:59 perseant Exp $        */
 
 /*
  * Copyright (c) 1997
@@ -208,13 +208,15 @@
 ino_t allocino __P((ino_t, int));
 int ino_to_fsba __P((struct lfs *, ino_t));
 struct bufarea *getfileblk __P((struct lfs *, struct dinode *, ino_t));
-struct bufarea *lfs_bginode __P((ino_t));
 struct dinode *ginode __P((ino_t));
 struct dinode *lfs_ginode __P((ino_t));
 struct dinode *lfs_difind __P((struct lfs *, ino_t, struct dinode *));
-struct ifile *lfs_ientry __P((ino_t));
+struct ifile *lfs_ientry __P((ino_t, struct bufarea **));
 struct inoinfo *getinoinfo __P((ino_t));
 void getblk __P((struct bufarea *, daddr_t, long));
 void getdblk __P((struct bufarea *, daddr_t, long));
+int check_summary(struct lfs *, SEGSUM *, daddr_t);
+SEGUSE *lfs_gseguse(int, struct bufarea **);
+daddr_t lfs_ino_daddr(ino_t);
 
 #include "fsck_vars.h"
diff -r ac06651a65e2 -r 257551b2e17a sbin/fsck_lfs/fsck_lfs.8
--- a/sbin/fsck_lfs/fsck_lfs.8  Tue May 16 00:59:12 2000 +0000
+++ b/sbin/fsck_lfs/fsck_lfs.8  Tue May 16 04:55:58 2000 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: fsck_lfs.8,v 1.2 1999/03/19 17:29:44 perseant Exp $
+.\"    $NetBSD: fsck_lfs.8,v 1.3 2000/05/16 04:55:59 perseant Exp $
 .\"
 .\" Copyright (c) 1980, 1989, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -102,8 +102,7 @@
 .Bl -tag -width indent
 .It Fl b
 Use the block specified immediately after the flag as
-the super block for the filesystem.  Block 32 is usually
-an alternative super block.
+the super block for the filesystem.
 .It Fl d
 Print debugging output.
 .\" .It Fl f
@@ -131,8 +130,9 @@
 which is assumed to be affirmative;
 do not open the filesystem for writing.
 .It Fl p
-Specify ``preen'' mode.  In fsck_lfs this currently does nothing, though
-in the future it will perform a roll-forward.
+Specify ``preen'' mode.  Currently, in this mode
+.Nm fsck_lfs
+simply checks validity of the newer checkpoint.
 .It Fl y
 Assume a yes response to all questions asked by 
 .Nm fsck_lfs ;
@@ -143,7 +143,7 @@
 .Bl -enum -indent indent -compact
 Inconsistencies checked are as follows:
 .It
-Blocks claimed by more than one inode or the free map.
+Blocks claimed by more than one inode.
 .It
 Blocks claimed by an inode outside the range of the filesystem.
 .It
@@ -159,8 +159,6 @@
 .It
 Bad inode format.
 .It
-Blocks not accounted for anywhere.
-.It
 Directory checks:
 .Bl -item -indent indent -compact
 .It 
@@ -177,9 +175,7 @@
 .It 
 More blocks for inodes than there are in the filesystem.
 .It
-Bad free block map format.
-.It
-Total free block and/or free inode count incorrect.
+Segment block counts incorrect, or ``clean'' segments containing live data.
 .El
 .El
 .Pp
@@ -205,7 +201,8 @@
 .Re
 .Sh BUGS
 .Nm Fsck_lfs
-cannot currently make any repairs, even a roll-forward.
+cannot currently perform a full roll-forward, or correct all of the
+errors that it can detect.
 .Sh HISTORY
 The
 .Nm
diff -r ac06651a65e2 -r 257551b2e17a sbin/fsck_lfs/inode.c
--- a/sbin/fsck_lfs/inode.c     Tue May 16 00:59:12 2000 +0000
+++ b/sbin/fsck_lfs/inode.c     Tue May 16 04:55:58 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inode.c,v 1.4 2000/01/20 21:32:31 perseant Exp $       */
+/*     $NetBSD: inode.c,v 1.5 2000/05/16 04:55:59 perseant Exp $       */
 
 /*
  * Copyright (c) 1997, 1998
@@ -52,13 +52,13 @@
 #include "fsutil.h"
 #include "extern.h"
 
-extern struct dinode **din_table;
 extern SEGUSE *seg_table;
+extern daddr_t *din_table;
 
 static int iblock __P((struct inodesc *, long, u_int64_t));
 int blksreqd(struct lfs *, int);
 int lfs_maxino(void);
-SEGUSE *lfs_gseguse(int);
+SEGUSE *lfs_gseguse(int, struct bufarea **);
 /* static void dump_inoblk __P((struct lfs *, struct dinode *)); */
 
 /* stolen from lfs_inode.c */
@@ -205,109 +205,123 @@
     return bp;
 }
 
-int lfs_maxino(void)
-{
-#if 1
-    struct dinode *idinode;
-
-    idinode = lfs_difind(&sblock,sblock.lfs_ifile,&ifblock);
-    return ((idinode->di_size
-            - (sblock.lfs_cleansz + sblock.lfs_segtabsz) * sblock.lfs_bsize)
-        / sblock.lfs_bsize) * sblock.lfs_ifpb - 1;
-#else
-    return sblock.lfs_nfiles;
-#endif
-}
-
+#if 0
 static struct dinode *gidinode(void)
 {
     static struct dinode *idinode;
 
     if(!idinode) {              /* only need to do this once */
         idinode = lfs_difind(&sblock,sblock.lfs_ifile,&ifblock);
-        if(din_table[LFS_IFILE_INUM]
-           && din_table[LFS_IFILE_INUM]->di_gen > idinode->di_gen) {
-            printf("XXX replacing IFILE gen %d with gen %d\n",
-                   idinode->di_gen, din_table[LFS_IFILE_INUM]->di_gen);
-            idinode = din_table[LFS_IFILE_INUM];
-        }
     }
     return idinode;
 }
-
-struct bufarea *
-lfs_bginode(ino_t ino)
-{
-    ino_t blkno;
-
-    /* this is almost verbatim from lfs.h LFS_IENTRY */
-    blkno = ino/sblock.lfs_ifpb + sblock.lfs_cleansz + sblock.lfs_segtabsz;
-
-    return getfileblk(&sblock,gidinode(),blkno);
-}
+#endif
 
 struct ifile *
-lfs_ientry(ino_t ino)
+lfs_ientry(ino_t ino, struct bufarea **bpp)
 {
     struct ifile *ifp;
-    struct bufarea *bp;
 
-    bp = lfs_bginode(ino);
-    if(bp)
+    *bpp = getfileblk(&sblock, lfs_ginode(LFS_IFILE_INUM),
+                     ino/sblock.lfs_ifpb + sblock.lfs_cleansz +
+                     sblock.lfs_segtabsz);
+    if(*bpp)
     {
-        ifp = (struct ifile *)malloc(sizeof(*ifp));
-        *ifp = (((struct ifile *)(bp->b_un.b_buf))[ino%sblock.lfs_ifpb]);
-        bp->b_flags &= ~B_INUSE;
-        
-        return ifp;
+           ifp = (((struct ifile *)((*bpp)->b_un.b_buf)) +
+                  (ino%sblock.lfs_ifpb));
+           return ifp;
     }
     else
-        return NULL;
+           return NULL;
 }
 
 SEGUSE *
-lfs_gseguse(int segnum)
+lfs_gseguse(int segnum, struct bufarea **bpp)
 {
     int blkno;
-    struct bufarea *bp;
 
     blkno = segnum/(sblock.lfs_bsize/sizeof(SEGUSE)) + sblock.lfs_cleansz;
-    bp = getfileblk(&sblock,gidinode(),blkno);
-    bp->b_flags &= ~B_INUSE;
-    return ((SEGUSE *)bp->b_un.b_buf) + segnum%(sblock.lfs_bsize/sizeof(SEGUSE));
+    (*bpp) = getfileblk(&sblock,lfs_ginode(LFS_IFILE_INUM),blkno);
+    return ((SEGUSE *)(*bpp)->b_un.b_buf) + segnum%(sblock.lfs_bsize/sizeof(SEGUSE));
+}
+
+daddr_t
+lfs_ino_daddr(ino_t inumber)
+{
+       daddr_t daddr;
+       IFILE *ifp;
+       struct bufarea *bp;
+
+       if(din_table[inumber]) {
+               daddr = din_table[inumber];
+       } else {
+               if(inumber == LFS_IFILE_INUM)
+                       daddr = sblock.lfs_idaddr;
+               else {
+                       ifp = lfs_ientry(inumber, &bp);
+                       if(ifp==NULL) {
+                               return NULL;
+                       }
+                       if(ifp->if_daddr == LFS_UNUSED_DADDR) {
+                               bp->b_flags &= ~B_INUSE;
+                               return NULL;
+                       }
+                       
+                       bp->b_flags &= ~B_INUSE;
+                       daddr = ifp->if_daddr;
+               }
+               
+               din_table[inumber] = daddr;
+               seg_table[datosn(&sblock,daddr)].su_nbytes += DINODE_SIZE;
+       }
+       return daddr;
 }
 
 struct dinode *
-lfs_ginode(ino_t inumber) {
+lfs_ginode(ino_t inumber)
+{
     struct ifile *ifp;
     struct dinode *din;
+    struct bufarea *bp;
+    daddr_t daddr;
 
-    if (inumber == LFS_IFILE_INUM)
-        return gidinode();
-    if (/* inumber < ROOTINO || */ inumber > maxino)
-        errexit("bad inode number %d to lfs_ginode\n", inumber);
-    /* printf("[lfs_ginode: looking up inode %ld]\n",inumber); */
-    ifp = lfs_ientry(inumber);
-    if(ifp==NULL
-       || ifp->if_daddr == LFS_UNUSED_DADDR
-       || ifp->if_daddr == UNASSIGNED) {
-        return NULL;
+    if (inumber > maxino)
+           errexit("bad inode number %d to lfs_ginode\n", inumber);
+
+#if 0
+    if (inumber == LFS_IFILE_INUM) {
+           daddr = sblock.lfs_idaddr;
+           if(din_table[LFS_IFILE_INUM] == 0) {
+                   din_table[LFS_IFILE_INUM] = daddr;
+                   seg_table[datosn(&sblock,daddr)].su_nbytes += DINODE_SIZE;
+           }
+           return gidinode();
     }
+#endif



Home | Main Index | Thread Index | Old Index