On 2011-04-07 11.08, Otto Moerbeek wrote:
> Hi,
>
> I got little feedeback on this diff posed in a rather long thread, so
> I am posting it again.
>
> Please test this, it makes fsck_ffs much faster (especially with -p)
> and less memory hungry in a lot of cases.
I've run it on a variety of file systems now and first of all, it seems
to work without regressions. It also looks like it has about 2/3 of its
previous memory footprint. However, I see very little increase in speed:
Unpatched, run with time /sbin/fsck_ffs -pf /dev/rraid0[adefghi]:
/dev/rraid0a: 2874 files, 82005 used, 46810 free (866 frags, 5743
blocks, 0.7% fragmentation)
/dev/rraid0d: 1477 files, 144486 used, 886745 free (553 frags, 110774
blocks, 0.1% fragmentation)
/dev/rraid0e: 224749 files, 1624996 used, 438155 free (48771 frags,
48673 blocks, 2.4% fragmentation)
/dev/rraid0f: 9437 files, 103157 used, 4024794 free (3370 frags, 502678
blocks, 0.1% fragmentation)
/dev/rraid0g: 498655 files, 6190187 used, 4128604 free (17188 frags,
513927 blocks, 0.2% fragmentation)
/dev/rraid0h: 90459 files, 445770 used, 2649301 free (20357 frags,
328618 blocks, 0.7% fragmentation)
/dev/rraid0i: 35896 files, 666529 used, 1266782 free (9006 frags, 157222
blocks, 0.5% fragmentation)
1m20.35s real 0m2.57s user 0m4.29s system
Patched, run with time /root/fsck_ffs -pf /dev/rraid0[adefghi]:
/dev/rraid0a: 2874 files, 82005 used, 46810 free (866 frags, 5743
blocks, 0.7% fragmentation)
/dev/rraid0d: 1477 files, 144486 used, 886745 free (553 frags, 110774
blocks, 0.1% fragmentation)
/dev/rraid0e: 224749 files, 1624996 used, 438155 free (48771 frags,
48673 blocks, 2.4% fragmentation)
/dev/rraid0f: 9437 files, 103157 used, 4024794 free (3370 frags, 502678
blocks, 0.1% fragmentation)
/dev/rraid0g: 498655 files, 6190187 used, 4128604 free (17188 frags,
513927 blocks, 0.2% fragmentation)
/dev/rraid0h: 90459 files, 445770 used, 2649301 free (20357 frags,
328618 blocks, 0.7% fragmentation)
/dev/rraid0i: 35896 files, 666529 used, 1266782 free (9006 frags, 157222
blocks, 0.5% fragmentation)
1m18.52s real 0m1.32s user 0m3.85s system
The file systems are organized like this:
skynet:~/fsck_ffs_patch# dumpfs -m /dev/rraid0a
# newfs command for /dev/rraid0a
newfs -O 1 -b 16384 -e 4096 -f 2048 -g 16384 -h 64 -m 5 -o time -s
525856 /dev/rraid0a
skynet:~/fsck_ffs_patch# dumpfs -m /dev/rraid0d
# newfs command for /dev/rraid0d
newfs -O 1 -b 16384 -e 4096 -f 2048 -g 16384 -h 64 -m 5 -o time -s
4197120 /dev/rraid0d
skynet:~/fsck_ffs_patch# dumpfs -m /dev/rraid0e
# newfs command for /dev/rraid0e
newfs -O 1 -b 16384 -e 4096 -f 2048 -g 16384 -h 64 -m 5 -o time -s
8390400 /dev/rraid0e
skynet:~/fsck_ffs_patch# dumpfs -m /dev/rraid0f
# newfs command for /dev/rraid0f
newfs -O 1 -b 16384 -e 4096 -f 2048 -g 16384 -h 64 -m 5 -o time -s
16780800 /dev/rraid0f
skynet:~/fsck_ffs_patch# dumpfs -m /dev/rraid0g
# newfs command for /dev/rraid0g
newfs -O 1 -b 16384 -e 4096 -f 2048 -g 16384 -h 64 -m 5 -o time -s
41944320 /dev/rraid0g
skynet:~/fsck_ffs_patch# dumpfs -m /dev/rraid0h
# newfs command for /dev/rraid0h
newfs -O 1 -b 16384 -e 4096 -f 2048 -g 16384 -h 64 -m 5 -o time -s
12583680 /dev/rraid0h
skynet:~/fsck_ffs_patch# dumpfs -m /dev/rraid0i
# newfs command for /dev/rraid0i
newfs -O 1 -b 16384 -e 4096 -f 2048 -g 16384 -h 64 -m 5 -o time -s
7857920 /dev/rraid0i
skynet:~/fsck_ffs_patch#
Btw, I noticed a small change in this diff compared to the one you posted
in the previous discussion thread. I assume this is the correct one to use?
skynet:~# diff fsck_ffs.patch fsck_ffs_2.patch
158c158
< +++ inode.c 31 Mar 2011 16:34:27 -0000
---
> +++ inode.c 4 Apr 2011 09:16:36 -0000
203c203
< + info[i].ino_state = USTATE;
---
> + SET_ISTATE(i, USTATE);
Regards,
/Benny
> Note that to force a check with -p you need to unmount the filesystem,
> mosty practical is do it in single user mode:
>
> # shutdown now
> ..
> # umount -a
> # fsck -pf
>
> (Don't forget the unmount!)
>
> Other way: pull the plug on a machine and let it reboot. That is a
> more realistic check and it is safe because you already backup up all
> your data, right?
>
> -Otto
>
> Index: dir.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/dir.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 dir.c
> --- dir.c 27 Oct 2009 23:59:32 -0000 1.24
> +++ dir.c 4 Apr 2011 09:15:49 -0000
> @@ -443,8 +443,8 @@ linkup(ino_t orphan, ino_t parentdir)
> idesc.id_type = ADDR;
> idesc.id_func = pass4check;
> idesc.id_number = oldlfdir;
> - adjust(&idesc, lncntp[oldlfdir] + 1);
> - lncntp[oldlfdir] = 0;
> + adjust(&idesc, ILNCOUNT(oldlfdir) + 1);
> + ILNCOUNT(oldlfdir) = 0;
> dp = ginode(lfdir);
> }
> if (GET_ISTATE(lfdir) != DFOUND) {
> @@ -457,7 +457,7 @@ linkup(ino_t orphan, ino_t parentdir)
> printf("\n\n");
> return (0);
> }
> - lncntp[orphan]--;
> + ILNCOUNT(orphan)--;
> if (lostdir) {
> if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
> parentdir != (ino_t)-1)
> @@ -465,7 +465,7 @@ linkup(ino_t orphan, ino_t parentdir)
> dp = ginode(lfdir);
> DIP_SET(dp, di_nlink, DIP(dp, di_nlink) + 1);
> inodirty();
> - lncntp[lfdir]++;
> + ILNCOUNT(lfdir)++;
> pwarn("DIR I=%u CONNECTED. ", orphan);
> if (parentdir != (ino_t)-1) {
> printf("PARENT WAS I=%u\n", parentdir);
> @@ -476,7 +476,7 @@ linkup(ino_t orphan, ino_t parentdir)
> * fixes the parent link count so that fsck does
> * not need to be rerun.
> */
> - lncntp[parentdir]++;
> + ILNCOUNT(parentdir)++;
> }
> if (preen == 0)
> printf("\n");
> @@ -636,7 +636,7 @@ allocdir(ino_t parent, ino_t request, in
> DIP_SET(dp, di_nlink, 2);
> inodirty();
> if (ino == ROOTINO) {
> - lncntp[ino] = DIP(dp, di_nlink);
> + ILNCOUNT(ino) = DIP(dp, di_nlink);
> cacheino(dp, ino);
> return(ino);
> }
> @@ -650,8 +650,8 @@ allocdir(ino_t parent, ino_t request, in
> inp->i_dotdot = parent;
> SET_ISTATE(ino, GET_ISTATE(parent));
> if (GET_ISTATE(ino) == DSTATE) {
> - lncntp[ino] = DIP(dp, di_nlink);
> - lncntp[parent]++;
> + ILNCOUNT(ino) = DIP(dp, di_nlink);
> + ILNCOUNT(parent)++;
> }
> dp = ginode(parent);
> DIP_SET(dp, di_nlink, DIP(dp, di_nlink) + 1);
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/extern.h,v
> retrieving revision 1.10
> diff -u -p -r1.10 extern.h
> --- extern.h 25 Jun 2007 19:59:55 -0000 1.10
> +++ extern.h 4 Apr 2011 09:15:49 -0000
> @@ -54,6 +54,7 @@ int ftypeok(union dinode *);
> void getpathname(char *, size_t, ino_t, ino_t);
> void inocleanup(void);
> void inodirty(void);
> +struct inostat *inoinfo(ino_t);
> int linkup(ino_t, ino_t);
> int makeentry(ino_t, ino_t, char *);
> void pass1(void);
> Index: fsck.h
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/fsck.h,v
> retrieving revision 1.23
> diff -u -p -r1.23 fsck.h
> --- fsck.h 10 Jun 2008 23:10:29 -0000 1.23
> +++ fsck.h 4 Apr 2011 09:15:49 -0000
> @@ -66,6 +66,19 @@ union dinode {
> #define BUFSIZ 1024
> #endif
>
> +/*
> + * Each inode on the file system is described by the following structure.
> + * The linkcnt is initially set to the value in the inode. Each time it
> + * is found during the descent in passes 2, 3, and 4 the count is
> + * decremented. Any inodes whose count is non-zero after pass 4 needs to
> + * have its link count adjusted by the value remaining in ino_linkcnt.
> + */
> +struct inostat {
> + char ino_state; /* state of inode, see below */
> + char ino_type; /* type of inode */
> + short ino_linkcnt; /* number of links not found */
> +};
> +
> #define USTATE 01 /* inode not allocated */
> #define FSTATE 02 /* inode is file */
> #define DSTATE 03 /* inode is directory */
> @@ -73,12 +86,20 @@ union dinode {
> #define DCLEAR 05 /* directory is to be cleared */
> #define FCLEAR 06 /* file is to be cleared */
>
> -#define GET_ISTATE(ino) (stmap[(ino)] & 0xf)
> -#define GET_ITYPE(ino) (stmap[(ino)] >> 4)
> -#define SET_ISTATE(ino, v) do { stmap[(ino)] = (stmap[(ino)] & 0xf0) | \
> - ((v) & 0xf); } while (0)
> -#define SET_ITYPE(ino, v) do { stmap[(ino)] = (stmap[(ino)] & 0x0f) | \
> - ((v) << 4); } while (0)
> +/*
> + * Inode state information is contained on per cylinder group lists
> + * which are described by the following structure.
> + */
> +struct inostatlist {
> + long il_numalloced; /* number of inodes allocated in this cg */
> + struct inostat *il_stat;/* inostat info for this cylinder group */
> +} *inostathead;
> +
> +#define GET_ISTATE(ino) (inoinfo(ino)->ino_state)
> +#define GET_ITYPE(ino) (inoinfo(ino)->ino_type)
> +#define SET_ISTATE(ino, v) do { GET_ISTATE(ino) = (v); } while (0)
> +#define SET_ITYPE(ino, v) do { GET_ITYPE(ino) = (v); } while (0)
> +#define ILNCOUNT(ino) (inoinfo(ino)->ino_linkcnt)
>
> /*
> * buffer cache structure.
> @@ -233,8 +254,6 @@ daddr64_t maxfsblock; /* number of bloc
> char *blockmap; /* ptr to primary blk allocation map */
> ino_t maxino; /* number of inodes in file system */
> ino_t lastino; /* last inode in use */
> -u_char *stmap; /* ptr to inode state and type table */
> -int16_t *lncntp; /* ptr to link count table */
>
> ino_t lfdir; /* lost & found directory inode number
> */
> char *lfname; /* lost & found directory name */
> @@ -242,7 +261,6 @@ int lfmode; /* lost & found
> directory
>
> daddr64_t n_blks; /* number of blocks in use */
> daddr64_t n_files; /* number of files in use */
> -long *cginosused; /* # of allocated inodes in each cg */
>
> #define clearinode(dp) \
> if (sblock.fs_magic == FS_UFS1_MAGIC) { \
> Index: inode.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/inode.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 inode.c
> --- inode.c 27 Oct 2009 23:59:32 -0000 1.33
> +++ inode.c 4 Apr 2011 09:16:36 -0000
> @@ -309,7 +309,7 @@ getnextinode(ino_t inumber)
> static caddr_t nextinop;
>
> if (inumber != nextino++ || inumber > maxino)
> - errexit("bad inode number %d to nextinode\n", inumber);
> + errexit("bad inode number %d to nextinode %d\n", inumber,
> nextino);
> if (inumber >= lastinum) {
> readcnt++;
> dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
> @@ -361,8 +361,6 @@ setinodebuf(ino_t inum)
> if (inodebuf == NULL &&
> (inodebuf = malloc((unsigned)inobufsize)) == NULL)
> errexit("Cannot allocate space for inode buffer\n");
> - while (nextino < ROOTINO)
> - (void)getnextinode(nextino);
> }
>
> void
> @@ -578,6 +576,7 @@ allocino(ino_t request, int type)
> struct cg *cgp = &cgrp;
> int cg;
> time_t t;
> + struct inostat *info;
>
> if (request == 0)
> request = ROOTINO;
> @@ -589,6 +588,28 @@ allocino(ino_t request, int type)
> if (ino == maxino)
> return (0);
> cg = ino_to_cg(&sblock, ino);
> + /* If necessary, extend the inoinfo array. grow exponentially */
> + if ((ino % sblock.fs_ipg) >= (uint64_t)inostathead[cg].il_numalloced) {
> + unsigned long newalloced, i;
> + newalloced = MIN(sblock.fs_ipg,
> + MAX(2 * inostathead[cg].il_numalloced, 10));
> + info = calloc(newalloced, sizeof(struct inostat));
> + if (info == NULL) {
> + pwarn("cannot alloc %lu bytes to extend inoinfo\n",
> + sizeof(struct inostat) * newalloced);
> + return 0;
> + }
> + memmove(info, inostathead[cg].il_stat,
> + inostathead[cg].il_numalloced * sizeof(*info));
> + for (i = inostathead[cg].il_numalloced; i < newalloced; i++) {
> + SET_ISTATE(i, USTATE);
> + }
> + if (inostathead[cg].il_numalloced)
> + free(inostathead[cg].il_stat);
> + inostathead[cg].il_stat = info;
> + inostathead[cg].il_numalloced = newalloced;
> + info = inoinfo(ino);
> + }
> getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
> if (!cg_chkmagic(cgp))
> pfatal("CG %d: BAD MAGIC NUMBER\n", cg);
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/main.c,v
> retrieving revision 1.36
> diff -u -p -r1.36 main.c
> --- main.c 12 Aug 2010 15:26:34 -0000 1.36
> +++ main.c 4 Apr 2011 09:15:49 -0000
> @@ -282,12 +282,14 @@ checkfilesys(char *filesys, char *mntpt,
> if (rerun)
> resolved = 0;
> ckfini(resolved); /* Don't mark fs clean if fsck needs to be re-run */
> +
> + for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
> + free(inostathead[cylno].il_stat);
> + free(inostathead);
> + inostathead = NULL;
> +
> free(blockmap);
> blockmap = NULL;
> - free(stmap);
> - stmap = NULL;
> - free(lncntp);
> - lncntp = NULL;
> free(sblock.fs_csp);
> free(sblk.b_un.b_buf);
> free(asblk.b_un.b_buf);
> Index: pass1.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/pass1.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 pass1.c
> --- pass1.c 9 Jul 2010 06:41:17 -0000 1.33
> +++ pass1.c 4 Apr 2011 09:15:49 -0000
> @@ -61,10 +61,13 @@ pass1_info(char *buf, size_t buflen)
> void
> pass1(void)
> {
> - struct inodesc idesc;
> - ino_t inumber, inosused;
> + ino_t inumber, inosused, ninosused;
> + size_t inospace;
> + struct inostat *info;
> int c;
> + struct inodesc idesc;
> daddr64_t i, cgd;
> + u_int8_t *cp;
>
> /*
> * Set file system reserved blocks in used block map.
> @@ -101,13 +104,91 @@ pass1(void)
> inosused = sblock.fs_ipg;
> } else
> inosused = sblock.fs_ipg;
> - cginosused[c] = inosused;
> +
> + /*
> + * If we are using soft updates, then we can trust the
> + * cylinder group inode allocation maps to tell us which
> + * inodes are allocated. We will scan the used inode map
> + * to find the inodes that are really in use, and then
> + * read only those inodes in from disk.
> + */
> + if (preen && usedsoftdep) {
> + cp = &cg_inosused(&cgrp)[(inosused - 1) / CHAR_BIT];
> + for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
> + if (*cp == 0)
> + continue;
> + for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) {
> + if (*cp & i)
> + break;
> + inosused--;
> + }
> + break;
> + }
> + if (inosused < 0)
> + inosused = 0;
> + }
> + /*
> + * Allocate inoinfo structures for the allocated inodes.
> + */
> + inostathead[c].il_numalloced = inosused;
> + if (inosused == 0) {
> + inostathead[c].il_stat = 0;
> + continue;
> + }
> + info = calloc((unsigned)inosused, sizeof(struct inostat));
> + inospace = (unsigned)inosused * sizeof(struct inostat);
> + if (info == NULL)
> + errexit("cannot alloc %u bytes for inoinfo",
> + (unsigned)(sizeof(struct inostat) * inosused));
> + inostathead[c].il_stat = info;
> + /*
> + * Scan the allocated inodes.
> + */
> for (i = 0; i < inosused; i++, inumber++) {
> info_inumber = inumber;
> - if (inumber < ROOTINO)
> + if (inumber < ROOTINO) {
> + (void)getnextinode(inumber);
> continue;
> + }
> checkinode(inumber, &idesc);
> }
> + lastino += 1;
> + if (inosused < sblock.fs_ipg || inumber == lastino)
> + continue;
> + /*
> + * If we were not able to determine in advance which inodes
> + * were in use, then reduce the size of the inoinfo structure
> + * to the size necessary to describe the inodes that we
> + * really found.
> + */
> + if (lastino < (c * sblock.fs_ipg))
> + ninosused = 0;
> + else
> + ninosused = lastino - (c * sblock.fs_ipg);
> + inostathead[c].il_numalloced = ninosused;
> + if (ninosused == 0) {
> + free(inostathead[c].il_stat);
> + inostathead[c].il_stat = 0;
> + continue;
> + }
> + if (ninosused != inosused) {
> + struct inostat *ninfo;
> + size_t ninospace = ninosused * sizeof(*ninfo);
> + if (ninospace / sizeof(*info) != ninosused) {
> + pfatal("too many inodes %llu\n",
> + (unsigned long long)ninosused);
> + exit(8);
> + }
> + ninfo = realloc(info, ninospace);
> + if (ninfo == NULL) {
> + pfatal("cannot realloc %zu bytes to %zu "
> + "for inoinfo\n", inospace, ninospace);
> + exit(8);
> + }
> + if (ninosused > inosused)
> + (void)memset(&ninfo[inosused], 0, ninospace -
> inospace);
> + inostathead[c].il_stat = ninfo;
> + }
> }
> info_fn = NULL;
> freeinodebuf();
> @@ -244,7 +325,7 @@ checkinode(ino_t inumber, struct inodesc
> if (ftypeok(dp) == 0)
> goto unknown;
> n_files++;
> - lncntp[inumber] = DIP(dp, di_nlink);
> + ILNCOUNT(inumber) = DIP(dp, di_nlink);
> if (DIP(dp, di_nlink) <= 0) {
> zlnp = malloc(sizeof *zlnp);
> if (zlnp == NULL) {
> Index: pass2.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/pass2.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 pass2.c
> --- pass2.c 27 Oct 2009 23:59:32 -0000 1.29
> +++ pass2.c 4 Apr 2011 09:15:49 -0000
> @@ -213,15 +213,15 @@ pass2(void)
> if (reply("FIX") == 0)
> continue;
> (void)makeentry(inp->i_number, inp->i_parent, "..");
> - lncntp[inp->i_parent]--;
> + ILNCOUNT(inp->i_parent)--;
> continue;
> }
> fileerror(inp->i_parent, inp->i_number,
> "BAD INODE NUMBER FOR '..'");
> if (reply("FIX") == 0)
> continue;
> - lncntp[inp->i_dotdot]++;
> - lncntp[inp->i_parent]--;
> + ILNCOUNT(inp->i_dotdot)++;
> + ILNCOUNT(inp->i_parent)--;
> inp->i_dotdot = inp->i_parent;
> (void)changeino(inp->i_number, "..", inp->i_parent);
> }
> @@ -318,7 +318,7 @@ pass2check(struct inodesc *idesc)
> proto.d_reclen = entrysize;
> memcpy(dirp, &proto, (size_t)entrysize);
> idesc->id_entryno++;
> - lncntp[dirp->d_ino]--;
> + ILNCOUNT(dirp->d_ino)--;
> dirp = (struct direct *)((char *)(dirp) + entrysize);
> memset(dirp, 0, (size_t)n);
> dirp->d_reclen = n;
> @@ -353,7 +353,7 @@ chk1:
> proto.d_reclen = dirp->d_reclen - n;
> dirp->d_reclen = n;
> idesc->id_entryno++;
> - lncntp[dirp->d_ino]--;
> + ILNCOUNT(dirp->d_ino)--;
> dirp = (struct direct *)((char *)(dirp) + n);
> memset(dirp, 0, (size_t)proto.d_reclen);
> dirp->d_reclen = proto.d_reclen;
> @@ -390,7 +390,7 @@ chk1:
> }
> idesc->id_entryno++;
> if (dirp->d_ino != 0)
> - lncntp[dirp->d_ino]--;
> + ILNCOUNT(dirp->d_ino)--;
> return (ret|KEEPON);
> chk2:
> if (dirp->d_ino == 0)
> @@ -446,7 +446,7 @@ again:
> dp = ginode(dirp->d_ino);
> SET_ISTATE(dirp->d_ino, (DIP(dp, di_mode) & IFMT) ==
> IFDIR ? DSTATE : FSTATE);
> - lncntp[dirp->d_ino] = DIP(dp, di_nlink);
> + ILNCOUNT(dirp->d_ino) = DIP(dp, di_nlink);
> goto again;
>
> case DSTATE:
> @@ -481,7 +481,7 @@ again:
> if (reply("FIX") == 1)
> ret |= ALTERED;
> }
> - lncntp[dirp->d_ino]--;
> + ILNCOUNT(dirp->d_ino)--;
> break;
>
> default:
> Index: pass3.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/pass3.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 pass3.c
> --- pass3.c 27 Oct 2009 23:59:32 -0000 1.14
> +++ pass3.c 4 Apr 2011 09:15:49 -0000
> @@ -73,7 +73,7 @@ pass3(void)
> }
> if (linkup(orphan, inp->i_dotdot)) {
> inp->i_parent = inp->i_dotdot = lfdir;
> - lncntp[lfdir]--;
> + ILNCOUNT(lfdir)--;
> pinp = getinoinfo(inp->i_parent);
> inp->i_parentp = pinp;
> inp->i_sibling = pinp->i_child;
> Index: pass4.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/pass4.c,v
> retrieving revision 1.19
> diff -u -p -r1.19 pass4.c
> --- pass4.c 27 Oct 2009 23:59:32 -0000 1.19
> +++ pass4.c 4 Apr 2011 09:15:49 -0000
> @@ -66,7 +66,7 @@ pass4(void)
> info_fn = pass4_info;
> for (c = 0; c < sblock.fs_ncg; c++) {
> inumber = c * sblock.fs_ipg;
> - for (i = 0; i < cginosused[c]; i++, inumber++) {
> + for (i = 0; i < inostathead[c].il_numalloced; i++, inumber++) {
> if (inumber < ROOTINO)
> continue;
> idesc.id_number = inumber;
> @@ -74,7 +74,7 @@ pass4(void)
>
> case FSTATE:
> case DFOUND:
> - n = lncntp[inumber];
> + n = ILNCOUNT(inumber);
> if (n) {
> adjust(&idesc, (short)n);
> break;
> Index: pass5.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/pass5.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 pass5.c
> --- pass5.c 9 Jul 2010 06:41:17 -0000 1.39
> +++ pass5.c 4 Apr 2011 09:15:49 -0000
> @@ -230,7 +230,7 @@ pass5(void)
> if (fs->fs_postblformat == FS_42POSTBLFMT)
> ocg->cg_magic = CG_MAGIC;
> j = fs->fs_ipg * c;
> - for (i = 0; i < cginosused[c]; j++, i++) {
> + for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
> switch (GET_ISTATE(j)) {
>
> case USTATE:
> Index: setup.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/setup.c,v
> retrieving revision 1.46
> diff -u -p -r1.46 setup.c
> --- setup.c 12 Aug 2010 15:26:34 -0000 1.46
> +++ setup.c 4 Apr 2011 09:15:49 -0000
> @@ -427,22 +427,11 @@ found:
> (unsigned)bmapsize);
> goto badsblabel;
> }
> - stmap = calloc((unsigned)(maxino + 1), sizeof(char));
> - if (stmap == NULL) {
> - printf("cannot alloc %u bytes for stmap\n",
> - (unsigned)(maxino + 1));
> - goto badsblabel;
> - }
> - lncntp = calloc((unsigned)(maxino + 1), sizeof(int16_t));
> - if (lncntp == NULL) {
> - printf("cannot alloc %zu bytes for lncntp\n",
> - (maxino + 1) * sizeof(int16_t));
> - goto badsblabel;
> - }
> - cginosused = calloc((unsigned)sblock.fs_ncg, sizeof(long));
> - if (cginosused == NULL) {
> - printf("cannot alloc %u bytes for cginosused\n",
> - (unsigned)sblock.fs_ncg);
> + inostathead = calloc((unsigned)(sblock.fs_ncg),
> + sizeof(struct inostatlist));
> + if (inostathead == NULL) {
> + printf("cannot alloc %u bytes for inostathead\n",
> + (unsigned)(sizeof(struct inostatlist) * (sblock.fs_ncg)));
> goto badsblabel;
> }
> numdirs = MAX(sblock.fs_cstotal.cs_ndir, 128);
> Index: utilities.c
> ===================================================================
> RCS file: /cvs/src/sbin/fsck_ffs/utilities.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 utilities.c
> --- utilities.c 10 Dec 2009 16:01:51 -0000 1.37
> +++ utilities.c 4 Apr 2011 09:15:49 -0000
> @@ -116,6 +116,25 @@ reply(char *question)
> }
>
> /*
> + * Look up state information for an inode.
> + */
> +struct inostat *
> +inoinfo(ino_t inum)
> +{
> + static struct inostat unallocated = { USTATE, 0, 0 };
> + struct inostatlist *ilp;
> + int iloff;
> +
> + if (inum > maxino)
> + errexit("inoinfo: inumber %d out of range", inum);
> + ilp = &inostathead[inum / sblock.fs_ipg];
> + iloff = inum % sblock.fs_ipg;
> + if (iloff >= ilp->il_numalloced)
> + return (&unallocated);
> + return (&ilp->il_stat[iloff]);
> +}
> +
> +/*
> * Malloc buffers and set up cache.
> */
> void
>
--
internetlabbet.se / work: +46 8 551 124 80 / "Words must
Benny Lvfgren / mobile: +46 70 718 11 90 / be weighed,
/ fax: +46 8 551 124 89 / not counted."
/ email: benny -at- internetlabbet.se