Greatly reduce memory requirements when fsck'ing filesystems with lots
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 12 Oct 2006 04:04:03 +0000 (04:04 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 12 Oct 2006 04:04:03 +0000 (04:04 +0000)
of directories (23 million directories in my case), primarily by using
the correct ufs1_ino_t type instead of ino_t.  Use a linear allocator
for these as well to pack the allocations optimally.

14 files changed:
sbin/fsck/Makefile
sbin/fsck/dir.c
sbin/fsck/fsck.h
sbin/fsck/fsutil.c
sbin/fsck/fsutil.h
sbin/fsck/inode.c
sbin/fsck/memzone.c [new file with mode: 0644]
sbin/fsck/memzone.h [new file with mode: 0644]
sbin/fsck/pass1.c
sbin/fsck/pass1b.c
sbin/fsck/pass2.c
sbin/fsck/pass3.c
sbin/fsck/pass4.c
sbin/fsck/utilities.c

index 4463773..a9527b3 100644 (file)
@@ -1,11 +1,12 @@
 #      @(#)Makefile    8.2 (Berkeley) 4/27/95
 # $FreeBSD: src/sbin/fsck/Makefile,v 1.5.6.1 2001/04/25 10:58:17 ru Exp $
-# $DragonFly: src/sbin/fsck/Makefile,v 1.3 2003/08/08 04:18:37 dillon Exp $
+# $DragonFly: src/sbin/fsck/Makefile,v 1.4 2006/10/12 04:04:03 dillon Exp $
 
 PROG=  fsck
 MAN=   fsck.8
 SRCS=  dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
-       pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
+       pass5.c preen.c setup.c utilities.c memzone.c \
+       ffs_subr.c ffs_tables.c
 CFLAGS+=-W
 .PATH: ${.CURDIR}/../../sys/vfs/ufs
 
index f092ab0..685146a 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)dir.c   8.8 (Berkeley) 4/28/95
  * $FreeBSD: src/sbin/fsck/dir.c,v 1.15 1999/08/28 00:12:45 peter Exp $
- * $DragonFly: src/sbin/fsck/dir.c,v 1.9 2006/04/03 01:58:49 dillon Exp $
+ * $DragonFly: src/sbin/fsck/dir.c,v 1.10 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -62,10 +62,10 @@ struct      odirtemplate odirhead = {
 static int chgino(struct inodesc *);
 static int dircheck(struct inodesc *, struct direct *);
 static int expanddir(struct ufs1_dinode *dp, char *name);
-static void freedir(ino_t ino, ino_t parent);
+static void freedir(ufs1_ino_t ino, ufs1_ino_t parent);
 static struct direct *fsck_readdir(struct inodesc *);
 static struct bufarea *getdirblk(ufs_daddr_t blkno, long size);
-static int lftempname(char *bufp, ino_t ino);
+static int lftempname(char *bufp, ufs1_ino_t ino);
 static int mkentry(struct inodesc *);
 
 /*
@@ -263,14 +263,14 @@ dircheck(struct inodesc *idesc, struct direct *dp)
 }
 
 void
-direrror(ino_t ino, char *errmesg)
+direrror(ufs1_ino_t ino, char *errmesg)
 {
 
        fileerror(ino, ino, errmesg);
 }
 
 void
-fileerror(ino_t cwd, ino_t ino, char *errmesg)
+fileerror(ufs1_ino_t cwd, ufs1_ino_t ino, char *errmesg)
 {
        struct ufs1_dinode *dp;
        char pathbuf[MAXPATHLEN + 1];
@@ -315,7 +315,7 @@ adjust(struct inodesc *idesc, int lcnt)
                         * linkup is answered no, but clri is answered yes.
                         */
                        saveresolved = resolved;
-                       if (linkup(idesc->id_number, (ino_t)0, NULL) == 0) {
+                       if (linkup(idesc->id_number, (ufs1_ino_t)0, NULL) == 0) {
                                resolved = saveresolved;
                                clri(idesc, "UNREF", 0);
                                return;
@@ -408,11 +408,11 @@ chgino(struct inodesc *idesc)
 }
 
 int
-linkup(ino_t orphan, ino_t parentdir, char *name)
+linkup(ufs1_ino_t orphan, ufs1_ino_t parentdir, char *name)
 {
        struct ufs1_dinode *dp;
        int lostdir;
-       ino_t oldlfdir;
+       ufs1_ino_t oldlfdir;
        struct inodesc idesc;
        char tempname[BUFSIZ];
 
@@ -439,7 +439,7 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
                } else {
                        pwarn("NO lost+found DIRECTORY");
                        if (preen || reply("CREATE")) {
-                               lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
+                               lfdir = allocdir(ROOTINO, (ufs1_ino_t)0, lfmode);
                                if (lfdir != 0) {
                                        if (makeentry(ROOTINO, lfdir, lfname) != 0) {
                                                numdirs++;
@@ -466,7 +466,7 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
                if (reply("REALLOCATE") == 0)
                        return (0);
                oldlfdir = lfdir;
-               if ((lfdir = allocdir(ROOTINO, (ino_t)0, lfmode)) == 0) {
+               if ((lfdir = allocdir(ROOTINO, (ufs1_ino_t)0, lfmode)) == 0) {
                        pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n");
                        return (0);
                }
@@ -495,14 +495,14 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
        inoinfo(orphan)->ino_linkcnt--;
        if (lostdir) {
                if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
-                   parentdir != (ino_t)-1)
+                   parentdir != (ufs1_ino_t)-1)
                        makeentry(orphan, lfdir, "..");
                dp = ginode(lfdir);
                dp->di_nlink++;
                inodirty();
                inoinfo(lfdir)->ino_linkcnt++;
                pwarn("DIR I=%lu CONNECTED. ", orphan);
-               if (parentdir != (ino_t)-1) {
+               if (parentdir != (ufs1_ino_t)-1) {
                        printf("PARENT WAS I=%lu\n", (u_long)parentdir);
                        /*
                         * The parent directory, because of the ordering
@@ -523,7 +523,7 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
  * fix an entry in a directory.
  */
 int
-changeino(ino_t dir, char *name, ino_t newnum)
+changeino(ufs1_ino_t dir, char *name, ufs1_ino_t newnum)
 {
        struct inodesc idesc;
 
@@ -541,7 +541,7 @@ changeino(ino_t dir, char *name, ino_t newnum)
  * make an entry in a directory
  */
 int
-makeentry(ino_t parent, ino_t ino, char *name)
+makeentry(ufs1_ino_t parent, ufs1_ino_t ino, char *name)
 {
        struct ufs1_dinode *dp;
        struct inodesc idesc;
@@ -629,10 +629,10 @@ bad:
 /*
  * allocate a new directory
  */
-ino_t
-allocdir(ino_t parent, ino_t request, int mode)
+ufs1_ino_t
+allocdir(ufs1_ino_t parent, ufs1_ino_t request, int mode)
 {
-       ino_t ino;
+       ufs1_ino_t ino;
        char *cp;
        struct ufs1_dinode *dp;
        struct bufarea *bp;
@@ -685,7 +685,7 @@ allocdir(ino_t parent, ino_t request, int mode)
  * free a directory inode
  */
 static void
-freedir(ino_t ino, ino_t parent)
+freedir(ufs1_ino_t ino, ufs1_ino_t parent)
 {
        struct ufs1_dinode *dp;
 
@@ -701,9 +701,9 @@ freedir(ino_t ino, ino_t parent)
  * generate a temporary name for the lost+found directory.
  */
 static int
-lftempname(char *bufp, ino_t ino)
+lftempname(char *bufp, ufs1_ino_t ino)
 {
-       ino_t in;
+       ufs1_ino_t in;
        char *cp;
        int namlen;
 
index 17252c7..465c4ae 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)fsck.h      8.4 (Berkeley) 5/9/95
  * $FreeBSD: src/sbin/fsck/fsck.h,v 1.12.2.1 2001/01/23 23:11:07 iedowse Exp $
- * $DragonFly: src/sbin/fsck/fsck.h,v 1.6 2006/09/10 01:26:27 dillon Exp $
+ * $DragonFly: src/sbin/fsck/fsck.h,v 1.7 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <unistd.h>
@@ -119,8 +119,8 @@ enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
 struct inodesc {
        enum fixstate id_fix;   /* policy on fixing errors */
        int (*id_func)();       /* function to be applied to blocks of inode */
-       ino_t id_number;        /* inode number described */
-       ino_t id_parent;        /* for DATA nodes, their parent */
+       ufs1_ino_t id_number;   /* inode number described */
+       ufs1_ino_t id_parent;   /* for DATA nodes, their parent */
        ufs_daddr_t id_blkno;   /* current block number being examined */
        int id_numfrags;        /* number of frags contained in block */
        quad_t id_filesize;     /* for DATA nodes, the size of the directory */
@@ -167,7 +167,7 @@ struct dups *muldup;                /* end of unique duplicate dup block numbers */
  */
 struct zlncnt {
        struct zlncnt *next;
-       ino_t zlncnt;
+       ufs1_ino_t zlncnt;
 };
 struct zlncnt *zlnhead;                /* head of zero link count list */
 
@@ -176,9 +176,9 @@ struct zlncnt *zlnhead;             /* head of zero link count list */
  */
 struct inoinfo {
        struct  inoinfo *i_nexthash;    /* next entry in hash chain */
-       ino_t   i_number;               /* inode number of this entry */
-       ino_t   i_parent;               /* inode number of parent */
-       ino_t   i_dotdot;               /* inode number of `..' */
+       ufs1_ino_t      i_number;               /* inode number of this entry */
+       ufs1_ino_t      i_parent;               /* inode number of parent */
+       ufs1_ino_t      i_dotdot;               /* inode number of `..' */
        size_t  i_isize;                /* size of inode */
        u_int   i_numblks;              /* size of block array in bytes */
        ufs_daddr_t i_blks[1];          /* actually longer */
@@ -218,9 +218,9 @@ int fswritefd;              /* file descriptor for writing file system */
 
 ufs_daddr_t maxfsblock;                /* number of blocks in the file system */
 char   *blockmap;              /* ptr to primary blk allocation map */
-ino_t  maxino;                 /* number of inodes in file system */
+ufs1_ino_t     maxino;                 /* number of inodes in file system */
 
-ino_t  lfdir;                  /* lost & found directory inode number */
+ufs1_ino_t     lfdir;                  /* lost & found directory inode number */
 char   *lfname;                /* lost & found directory name */
 int    lfmode;                 /* lost & found directory creation mode */
 
@@ -249,17 +249,17 @@ struct fstab;
 
 void           adjust(struct inodesc *, int lcnt);
 ufs_daddr_t    allocblk(long frags);
-ino_t          allocdir(ino_t parent, ino_t request, int mode);
-ino_t          allocino(ino_t request, int type);
-void           blkerror(ino_t ino, char *type, ufs_daddr_t blk);
+ufs1_ino_t             allocdir(ufs1_ino_t parent, ufs1_ino_t request, int mode);
+ufs1_ino_t             allocino(ufs1_ino_t request, int type);
+void           blkerror(ufs1_ino_t ino, char *type, ufs_daddr_t blk);
 char          *blockcheck(char *name);
 int            bread(int fd, char *buf, ufs_daddr_t blk, long size);
 void           bufinit(void);
 void           bwrite(int fd, char *buf, ufs_daddr_t blk, long size);
-void           cacheino(struct ufs1_dinode *dp, ino_t inumber);
+void           cacheino(struct ufs1_dinode *dp, ufs1_ino_t inumber);
 void           catch(int);
 void           catchquit(int);
-int            changeino(ino_t dir, char *name, ino_t newnum);
+int            changeino(ufs1_ino_t dir, char *name, ufs1_ino_t newnum);
 int            checkfstab(int preen, int maxrun,
                        int (*docheck)(struct fstab *),
                        int (*chkit)(char *, char *, long, int));
@@ -268,33 +268,33 @@ void              ckfini(int markclean);
 int            ckinode(struct ufs1_dinode *dp, struct inodesc *);
 void           clri(struct inodesc *, char *type, int flag);
 int            clearentry(struct inodesc *);
-void           direrror(ino_t ino, char *errmesg);
+void           direrror(ufs1_ino_t ino, char *errmesg);
 int            dirscan(struct inodesc *);
 int            dofix(struct inodesc *, char *msg);
 void           ffs_clrblock(struct fs *, u_char *, ufs_daddr_t);
 void           ffs_fragacct(struct fs *, int, int32_t [], int);
 int            ffs_isblock(struct fs *, u_char *, ufs_daddr_t);
 void           ffs_setblock(struct fs *, u_char *, ufs_daddr_t);
-void           fileerror(ino_t cwd, ino_t ino, char *errmesg);
+void           fileerror(ufs1_ino_t cwd, ufs1_ino_t ino, char *errmesg);
 int            findino(struct inodesc *);
 int            findname(struct inodesc *);
 void           flush(int fd, struct bufarea *bp);
 void           freeblk(ufs_daddr_t blkno, long frags);
-void           freeino(ino_t ino);
+void           freeino(ufs1_ino_t ino);
 void           freeinodebuf(void);
 int            ftypeok(struct ufs1_dinode *dp);
 void           getblk(struct bufarea *bp, ufs_daddr_t blk, long size);
 struct bufarea *getdatablk(ufs_daddr_t blkno, long size);
-struct inoinfo *getinoinfo(ino_t inumber);
-struct ufs1_dinode  *getnextinode(ino_t inumber);
-void           getpathname(char *namebuf, ino_t curdir, ino_t ino);
-struct ufs1_dinode  *ginode(ino_t inumber);
+struct inoinfo *getinoinfo(ufs1_ino_t inumber);
+struct ufs1_dinode  *getnextinode(ufs1_ino_t inumber);
+void           getpathname(char *namebuf, ufs1_ino_t curdir, ufs1_ino_t ino);
+struct ufs1_dinode  *ginode(ufs1_ino_t inumber);
 void           infohandler(int sig);
 void           inocleanup(void);
 void           inodirty(void);
-struct inostat *inoinfo(ino_t inum);
-int            linkup(ino_t orphan, ino_t parentdir, char *name);
-int            makeentry(ino_t parent, ino_t ino, char *name);
+struct inostat *inoinfo(ufs1_ino_t inum);
+int            linkup(ufs1_ino_t orphan, ufs1_ino_t parentdir, char *name);
+int            makeentry(ufs1_ino_t parent, ufs1_ino_t ino, char *name);
 void           panic(const char *fmt, ...);
 void           pass1(void);
 void           pass1b(void);
@@ -305,10 +305,10 @@ void              pass4(void);
 int            pass4check(struct inodesc *);
 void           pass5(void);
 void           pfatal(const char *fmt, ...);
-void           pinode(ino_t ino);
+void           pinode(ufs1_ino_t ino);
 void           propagate(void);
 void           pwarn(const char *fmt, ...);
 int            reply(char *question);
-void           setinodebuf(ino_t);
+void           setinodebuf(ufs1_ino_t);
 int            setup(char *dev);
 void           voidquit(int);
index 1a84478..54941b5 100644 (file)
@@ -33,7 +33,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sbin/fsck/fsutil.c,v 1.2.2.1 2001/08/01 05:47:55 obrien Exp $
- * $DragonFly: src/sbin/fsck/fsutil.c,v 1.5 2004/12/18 21:43:38 swildner Exp $
+ * $DragonFly: src/sbin/fsck/fsutil.c,v 1.6 2006/10/12 04:04:03 dillon Exp $
  *
  * $NetBSD: fsutil.c,v 1.7 1998/07/30 17:41:03 thorpej Exp $
  */
@@ -306,38 +306,3 @@ retry:
 }
 #endif
 
-
-void *
-emalloc(size_t s)
-{
-       void *p;
-
-       p = malloc(s);
-       if (p == NULL)
-               err(1, "malloc failed");
-       return (p);
-}
-
-
-void *
-erealloc(void *p, size_t s)
-{
-       void *q;
-
-       q = realloc(p, s);
-       if (q == NULL)
-               err(1, "realloc failed");
-       return (q);
-}
-
-
-char *
-estrdup(const char *s)
-{
-       char *p;
-
-       p = strdup(s);
-       if (p == NULL)
-               err(1, "strdup failed");
-       return (p);
-}
index 89ada29..71269d8 100644 (file)
@@ -29,7 +29,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sbin/fsck/fsutil.h,v 1.3.2.1 2001/08/01 05:47:55 obrien Exp $
- * $DragonFly: src/sbin/fsck/fsutil.h,v 1.3 2003/11/01 17:15:58 drhodus Exp $
+ * $DragonFly: src/sbin/fsck/fsutil.h,v 1.4 2006/10/12 04:04:03 dillon Exp $
  */
 
 void perror(const char *);
@@ -51,9 +51,6 @@ const char *cdevname(void);
 void setcdevname(const char *, int);
 struct statfs *getmntpt(const char *);
 int  hotroot(void);
-void *emalloc(size_t);
-void *erealloc(void *, size_t);
-char *estrdup(const char *);
 
 #define        CHECK_PREEN     0x0001
 #define        CHECK_VERBOSE   0x0002
index 63ba34a..15a0020 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)inode.c 8.8 (Berkeley) 4/28/95
  * $FreeBSD: src/sbin/fsck/inode.c,v 1.20 2000/02/28 20:02:41 mckusick Exp $
- * $DragonFly: src/sbin/fsck/inode.c,v 1.10 2006/09/10 01:26:27 dillon Exp $
+ * $DragonFly: src/sbin/fsck/inode.c,v 1.11 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -47,8 +47,9 @@
 #include <string.h>
 
 #include "fsck.h"
+#include "memzone.h"
 
-static ino_t startinum;
+static ufs1_ino_t startinum;
 
 static int iblock(struct inodesc *, long ilevel, quad_t isize);
 
@@ -269,7 +270,7 @@ chkrange(ufs_daddr_t blk, int cnt)
  * General purpose interface for reading inodes.
  */
 struct ufs1_dinode *
-ginode(ino_t inumber)
+ginode(ufs1_ino_t inumber)
 {
        ufs_daddr_t iblk;
 
@@ -290,12 +291,12 @@ ginode(ino_t inumber)
  * Special purpose version of ginode used to optimize first pass
  * over all the inodes in numerical order.
  */
-ino_t nextino, lastinum;
+ufs1_ino_t nextino, lastinum;
 long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
 struct ufs1_dinode *inodebuf;
 
 struct ufs1_dinode *
-getnextinode(ino_t inumber)
+getnextinode(ufs1_ino_t inumber)
 {
        long size;
        ufs_daddr_t dblk;
@@ -324,7 +325,7 @@ getnextinode(ino_t inumber)
 }
 
 void
-setinodebuf(ino_t inum)
+setinodebuf(ufs1_ino_t inum)
 {
 
        if (inum % sblock.fs_ipg != 0)
@@ -366,8 +367,10 @@ freeinodebuf(void)
  *
  * Enter inodes into the cache.
  */
+static struct memzone inoinfo_zone;
+
 void
-cacheino(struct ufs1_dinode *dp, ino_t inumber)
+cacheino(struct ufs1_dinode *dp, ufs1_ino_t inumber)
 {
        struct inoinfo *inp;
        struct inoinfo **inpp;
@@ -376,15 +379,15 @@ cacheino(struct ufs1_dinode *dp, ino_t inumber)
        blks = howmany(dp->di_size, sblock.fs_bsize);
        if (blks > NDADDR)
                blks = NDADDR + NIADDR;
-       inp = (struct inoinfo *)
-               malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
+       inp = mzalloc(&inoinfo_zone, 
+                     sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
        if (inp == NULL)
                errx(EEXIT, "cannot increase directory list");
        inpp = &inphead[DIRHASH(inumber)];
        inp->i_nexthash = *inpp;
        *inpp = inp;
-       inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0;
-       inp->i_dotdot = (ino_t)0;
+       inp->i_parent = inumber == ROOTINO ? ROOTINO : (ufs1_ino_t)0;
+       inp->i_dotdot = (ufs1_ino_t)0;
        inp->i_number = inumber;
        inp->i_isize = dp->di_size;
        inp->i_numblks = blks * sizeof(ufs_daddr_t);
@@ -403,7 +406,7 @@ cacheino(struct ufs1_dinode *dp, ino_t inumber)
  * Look up an inode cache structure.
  */
 struct inoinfo *
-getinoinfo(ino_t inumber)
+getinoinfo(ufs1_ino_t inumber)
 {
        struct inoinfo *inp;
 
@@ -426,8 +429,7 @@ inocleanup(void)
 
        if (inphead == NULL)
                return;
-       for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--)
-               free((char *)(*inpp));
+       mzpurge(&inoinfo_zone);
        free((char *)inphead);
        free((char *)inpsort);
        inphead = inpsort = NULL;
@@ -504,7 +506,7 @@ clearentry(struct inodesc *idesc)
 }
 
 void
-pinode(ino_t ino)
+pinode(ufs1_ino_t ino)
 {
        struct ufs1_dinode *dp;
        char *p;
@@ -530,7 +532,7 @@ pinode(ino_t ino)
 }
 
 void
-blkerror(ino_t ino, char *type, ufs_daddr_t blk)
+blkerror(ufs1_ino_t ino, char *type, ufs_daddr_t blk)
 {
 
        pfatal("%ld %s I=%lu", blk, type, ino);
@@ -558,10 +560,10 @@ blkerror(ino_t ino, char *type, ufs_daddr_t blk)
 /*
  * allocate an unused inode
  */
-ino_t
-allocino(ino_t request, int type)
+ufs1_ino_t
+allocino(ufs1_ino_t request, int type)
 {
-       ino_t ino;
+       ufs1_ino_t ino;
        struct ufs1_dinode *dp;
        struct cg *cgp = &cgrp;
        int cg;
@@ -618,7 +620,7 @@ allocino(ino_t request, int type)
  * deallocate an inode
  */
 void
-freeino(ino_t ino)
+freeino(ufs1_ino_t ino)
 {
        struct inodesc idesc;
        struct ufs1_dinode *dp;
diff --git a/sbin/fsck/memzone.c b/sbin/fsck/memzone.c
new file mode 100644 (file)
index 0000000..c257d74
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
+ * 
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * $DragonFly: src/sbin/fsck/memzone.c,v 1.1 2006/10/12 04:04:03 dillon Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "memzone.h"
+
+/*
+ * Efficiently allocate memory that will only be freed in bulk
+ */
+void *
+mzalloc(struct memzone *zone, int bytes)
+{
+       struct memchunk *chunk;
+       void *ptr;
+
+       if ((chunk = zone->curr) != NULL) {
+               if (bytes > chunk->bytes - zone->index) {
+                       chunk->next = zone->list;
+                       zone->list = chunk;
+                       zone->curr = NULL;
+                       chunk = NULL;
+               }
+       }
+       if (chunk == NULL) {
+               chunk = malloc(sizeof(*chunk));
+               if (chunk == NULL)
+                       return(NULL);
+               bzero(chunk, sizeof(*chunk));
+               chunk->base = mmap(NULL, MEMZONE_CHUNK, PROT_READ|PROT_WRITE,
+                                  MAP_ANON|MAP_PRIVATE, -1, 0);
+               if (chunk->base == MAP_FAILED) {
+                       free(chunk);
+                       return(NULL);
+               }
+               chunk->bytes = MEMZONE_CHUNK;
+               zone->curr = chunk;
+               zone->index = 0;
+       }
+       if (bytes > chunk->bytes)
+               pfatal("allocation to large for mzalloc!");
+       ptr = chunk->base + zone->index;
+       zone->index += (bytes + 7) & ~7;
+       return(ptr);
+}
+
+/*
+ * Free memory in bulk
+ */
+void *
+mzpurge(struct memzone *zone)
+{
+       struct memchunk *chunk;
+
+       if ((chunk = zone->curr) != NULL) {
+               chunk->next = zone->list;
+               zone->list = chunk;
+               zone->curr = NULL;
+       }
+       while ((chunk = zone->list) != NULL) {
+               zone->list = chunk->next;
+               munmap(chunk->base, chunk->bytes);
+               free(chunk);
+       }
+}
+
diff --git a/sbin/fsck/memzone.h b/sbin/fsck/memzone.h
new file mode 100644 (file)
index 0000000..8a25d39
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
+ * 
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * $DragonFly: src/sbin/fsck/memzone.h,v 1.1 2006/10/12 04:04:03 dillon Exp $
+ */
+
+struct memchunk {
+       struct memchunk *next;
+       char *base;
+       int bytes;
+};
+
+struct memzone {
+       struct memchunk *list;
+       struct memchunk *curr;
+       int index;
+};
+
+#define MEMZONE_CHUNK  (1024*1024)
+
+void *mzalloc(struct memzone *zone, int bytes);
+void *mzpurge(struct memzone *zone);
+
index 196d06e..0fe36af 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)pass1.c 8.6 (Berkeley) 4/28/95
  * $FreeBSD: src/sbin/fsck/pass1.c,v 1.16.2.5 2002/06/23 22:34:58 iedowse Exp $
- * $DragonFly: src/sbin/fsck/pass1.c,v 1.8 2006/04/03 01:58:49 dillon Exp $
+ * $DragonFly: src/sbin/fsck/pass1.c,v 1.9 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
 
 static ufs_daddr_t badblk;
 static ufs_daddr_t dupblk;
-static ino_t lastino;          /* last inode in use */
+static ufs1_ino_t lastino;             /* last inode in use */
 
-static void checkinode(ino_t inumber, struct inodesc *);
+static void checkinode(ufs1_ino_t inumber, struct inodesc *);
 
 void
 pass1(void)
 {
        u_int8_t *cp;
-       ino_t inumber;
+       ufs1_ino_t inumber;
        int c, i, cgd, inosused;
        struct inostat *info;
        struct inodesc idesc;
@@ -172,7 +172,7 @@ pass1(void)
 }
 
 static void
-checkinode(ino_t inumber, struct inodesc *idesc)
+checkinode(ufs1_ino_t inumber, struct inodesc *idesc)
 {
        struct ufs1_dinode *dp;
        struct zlncnt *zlnp;
index b915a50..fb0107c 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)pass1b.c        8.4 (Berkeley) 4/28/95
  * $FreeBSD: src/sbin/fsck/pass1b.c,v 1.7.2.1 2001/01/23 23:11:07 iedowse Exp $
- * $DragonFly: src/sbin/fsck/pass1b.c,v 1.7 2006/04/03 01:58:49 dillon Exp $
+ * $DragonFly: src/sbin/fsck/pass1b.c,v 1.8 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -53,7 +53,7 @@ pass1b(void)
        int c, i;
        struct ufs1_dinode *dp;
        struct inodesc idesc;
-       ino_t inumber;
+       ufs1_ino_t inumber;
 
        memset(&idesc, 0, sizeof(struct inodesc));
        idesc.id_type = ADDR;
index 3629f8f..3dbde71 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)pass2.c 8.9 (Berkeley) 4/28/95
  * $FreeBSD: src/sbin/fsck/pass2.c,v 1.10.2.2 2001/11/24 15:14:59 iedowse Exp $
- * $DragonFly: src/sbin/fsck/pass2.c,v 1.10 2006/09/10 01:26:27 dillon Exp $
+ * $DragonFly: src/sbin/fsck/pass2.c,v 1.11 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -196,7 +196,7 @@ pass2(void)
                    inoinfo(inp->i_number)->ino_state == DSTATE)
                        inoinfo(inp->i_number)->ino_state = DFOUND;
                if (inp->i_dotdot == inp->i_parent ||
-                   inp->i_dotdot == (ino_t)-1)
+                   inp->i_dotdot == (ufs1_ino_t)-1)
                        continue;
                if (inp->i_dotdot == 0) {
                        inp->i_dotdot = inp->i_parent;
@@ -348,11 +348,11 @@ chk1:
                fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
                pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
                        dirp->d_name);
-               inp->i_dotdot = (ino_t)-1;
+               inp->i_dotdot = (ufs1_ino_t)-1;
        } else if (dirp->d_reclen < entrysize) {
                fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
                pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
-               inp->i_dotdot = (ino_t)-1;
+               inp->i_dotdot = (ufs1_ino_t)-1;
        } else if (inp->i_parent != 0) {
                /*
                 * We know the parent, so fix now.
index 28633e5..4b06b81 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)pass3.c 8.2 (Berkeley) 4/27/95
  * $FreeBSD: src/sbin/fsck/pass3.c,v 1.7.2.1 2001/01/23 23:11:07 iedowse Exp $
- * $DragonFly: src/sbin/fsck/pass3.c,v 1.5 2004/02/04 17:39:59 joerg Exp $
+ * $DragonFly: src/sbin/fsck/pass3.c,v 1.6 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -50,7 +50,7 @@ pass3(void)
 {
        struct inoinfo *inp;
        int loopcnt, inpindex, state;
-       ino_t orphan;
+       ufs1_ino_t orphan;
        struct inodesc idesc;
        char namebuf[MAXNAMLEN+1];
 
index 9932227..9682183 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)pass4.c 8.4 (Berkeley) 4/28/95
  * $FreeBSD: src/sbin/fsck/pass4.c,v 1.7.2.1 2001/01/23 23:11:07 iedowse Exp $
- * $DragonFly: src/sbin/fsck/pass4.c,v 1.6 2006/04/03 01:58:49 dillon Exp $
+ * $DragonFly: src/sbin/fsck/pass4.c,v 1.7 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -48,7 +48,7 @@
 void
 pass4(void)
 {
-       ino_t inumber;
+       ufs1_ino_t inumber;
        struct zlncnt *zlnp;
        struct ufs1_dinode *dp;
        struct inodesc idesc;
index 6a0aa99..fd35817 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @(#)utilities.c     8.6 (Berkeley) 5/19/95
  * $FreeBSD: src/sbin/fsck/utilities.c,v 1.11.2.3 2001/01/23 23:11:07 iedowse Exp $
- * $DragonFly: src/sbin/fsck/utilities.c,v 1.9 2006/04/03 01:58:49 dillon Exp $
+ * $DragonFly: src/sbin/fsck/utilities.c,v 1.10 2006/10/12 04:04:03 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -112,7 +112,7 @@ reply(char *question)
  * Look up state information for an inode.
  */
 struct inostat *
-inoinfo(ino_t inum)
+inoinfo(ufs1_ino_t inum)
 {
        static struct inostat unallocated = { USTATE, 0, 0 };
        struct inostatlist *ilp;
@@ -425,7 +425,7 @@ freeblk(ufs_daddr_t blkno, long frags)
  * Find a pathname
  */
 void
-getpathname(char *namebuf, ino_t curdir, ino_t ino)
+getpathname(char *namebuf, ufs1_ino_t curdir, ufs1_ino_t ino)
 {
        int len;
        char *cp;