On Thu, 4 Sep 2014, David Vasek wrote: > This one is better. Nice catch, though there are more worms in this can.
> + pwarn("INCORRECT BLOCK COUNT I=%llu (%llu should be %llu)", > + (unsigned long long)inumber, > + (unsigned long long)DIP(dp, di_blocks), > + (unsigned long long)idesc->id_entryno); While di_blocks is unsigned, daddr_t is signed so we cast and print blocks as long long's. Starting from your diff, I've done a pass across fsck_ffs for other places where the wrong types are used. For example, allocdir() is getting the inode for the directory, so it should return an ino_t; contrawise, frag counts have to fit in a 32bits, so use int for the arguments to alloblk() and freeblk(). Note, this diff also corrects what clearly must be an error in the checking of the fragment bitmaps in pass5.c where the wrong macro was used in the check, resulting the "ALLOCATED FRAG # MARKED FREE" warning never being shown! This was happy on a clean filesystem (I haven't intentionally corrupted a filesystem for testing) and I've installed this on my laptop. oks? Philip Guenther Index: dir.c =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/dir.c,v retrieving revision 1.29 diff -u -p -r1.29 dir.c --- dir.c 11 Jun 2013 16:42:04 -0000 1.29 +++ dir.c 5 Sep 2014 08:36:43 -0000 @@ -552,7 +552,7 @@ bad: /* * allocate a new directory */ -int +ino_t allocdir(ino_t parent, ino_t request, int mode) { ino_t ino; Index: extern.h =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/extern.h,v retrieving revision 1.12 diff -u -p -r1.12 extern.h --- extern.h 11 Jun 2013 16:42:04 -0000 1.12 +++ extern.h 5 Sep 2014 08:36:43 -0000 @@ -26,8 +26,8 @@ */ void adjust(struct inodesc *, short); -int allocblk(long); -int allocdir(ino_t, ino_t, int); +daddr_t allocblk(int); +ino_t allocdir(ino_t, ino_t, int); void blkerror(ino_t, char *, daddr_t); int bread(int, char *, daddr_t, long); void bufinit(void); @@ -47,7 +47,7 @@ void fileerror(ino_t, ino_t, char *); int findino(struct inodesc *); int findname(struct inodesc *); void flush(int, struct bufarea *); -void freeblk(daddr_t, long); +void freeblk(daddr_t, int); void freeino(ino_t); void freeinodebuf(void); int ftypeok(union dinode *); Index: fsck.h =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/fsck.h,v retrieving revision 1.29 diff -u -p -r1.29 fsck.h --- fsck.h 9 May 2014 13:19:34 -0000 1.29 +++ fsck.h 5 Sep 2014 08:36:43 -0000 @@ -161,16 +161,16 @@ enum fixstate {DONTKNOW, NOFIX, FIX, IGN struct inodesc { daddr_t id_blkno; /* current block number being examined */ quad_t id_filesize; /* for DATA nodes, the size of the directory */ + u_int64_t id_entryno; /* for DATA nodes, current entry number */ + ino_t id_number; /* inode number described */ + ino_t id_parent; /* for DATA nodes, their parent */ int (*id_func) /* function to be applied to blocks of inode */ (struct inodesc *); struct direct *id_dirp; /* for DATA nodes, ptr to current entry */ char *id_name; /* for DATA nodes, name to find or enter */ - ino_t id_number; /* inode number described */ - ino_t id_parent; /* for DATA nodes, their parent */ - enum fixstate id_fix; /* policy on fixing errors */ int id_numfrags; /* number of frags contained in block */ int id_loc; /* for DATA nodes, current location in dir */ - int id_entryno; /* for DATA nodes, current entry number */ + enum fixstate id_fix; /* policy on fixing errors */ char id_type; /* type of descriptor, DATA or ADDR */ }; /* file types */ Index: inode.c =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/inode.c,v retrieving revision 1.42 diff -u -p -r1.42 inode.c --- inode.c 21 May 2014 18:53:05 -0000 1.42 +++ inode.c 5 Sep 2014 08:36:43 -0000 @@ -602,7 +602,7 @@ allocino(ino_t request, int type) 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", + pwarn("cannot alloc %zu bytes to extend inoinfo\n", sizeof(struct inostat) * newalloced); return 0; } Index: pass1.c =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/pass1.c,v retrieving revision 1.38 diff -u -p -r1.38 pass1.c --- pass1.c 11 Jun 2013 16:42:04 -0000 1.38 +++ pass1.c 5 Sep 2014 08:36:43 -0000 @@ -139,8 +139,7 @@ pass1(void) 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)); + errexit("cannot alloc %zu bytes for inoinfo", inospace); inostathead[c].il_stat = info; /* * Scan the allocated inodes. @@ -175,6 +174,7 @@ pass1(void) 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); @@ -282,8 +282,8 @@ checkinode(ino_t inumber, struct inodesc for (j = ndb; j < NDADDR; j++) if (DIP(dp, di_db[j]) != 0) { if (debug) - printf("bad direct addr: %ld\n", - (long)DIP(dp, di_db[j])); + printf("bad direct addr: %lld\n", + (long long)DIP(dp, di_db[j])); goto unknown; } for (j = 0, ndb -= NDADDR; ndb > 0; j++) @@ -291,8 +291,8 @@ checkinode(ino_t inumber, struct inodesc for (; j < NIADDR; j++) if (DIP(dp, di_ib[j]) != 0) { if (debug) - printf("bad indirect addr: %ld\n", - (long)DIP(dp, di_ib[j])); + printf("bad indirect addr: %lld\n", + (long long)DIP(dp, di_ib[j])); goto unknown; } if (ftypeok(dp) == 0) @@ -327,9 +327,9 @@ checkinode(ino_t inumber, struct inodesc (void)ckinode(dp, idesc); idesc->id_entryno *= btodb(sblock.fs_fsize); if (DIP(dp, di_blocks) != idesc->id_entryno) { - pwarn("INCORRECT BLOCK COUNT I=%llu (%ld should be %d)", - (unsigned long long)inumber, (long)DIP(dp, di_blocks), - idesc->id_entryno); + pwarn("INCORRECT BLOCK COUNT I=%llu (%lld should be %lld)", + (unsigned long long)inumber, (long long)DIP(dp, di_blocks), + (long long)idesc->id_entryno); if (preen) printf(" (CORRECTED)\n"); else if (reply("CORRECT") == 0) Index: pass2.c =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/pass2.c,v retrieving revision 1.34 diff -u -p -r1.34 pass2.c --- pass2.c 11 Jun 2013 16:42:04 -0000 1.34 +++ pass2.c 5 Sep 2014 08:36:43 -0000 @@ -162,12 +162,12 @@ pass2(void) getpathname(pathbuf, sizeof pathbuf, inp->i_number, inp->i_number); if (usedsoftdep) - pfatal("%s %s: LENGTH %ld NOT MULTIPLE of %d", - "DIRECTORY", pathbuf, (long)inp->i_isize, + pfatal("%s %s: LENGTH %zu NOT MULTIPLE of %d", + "DIRECTORY", pathbuf, inp->i_isize, DIRBLKSIZ); else - pwarn("%s %s: LENGTH %ld NOT MULTIPLE OF %d", - "DIRECTORY", pathbuf, (long)inp->i_isize, + pwarn("%s %s: LENGTH %zu NOT MULTIPLE OF %d", + "DIRECTORY", pathbuf, inp->i_isize, DIRBLKSIZ); if (preen) printf(" (ADJUSTED)\n"); Index: pass5.c =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/pass5.c,v retrieving revision 1.45 diff -u -p -r1.45 pass5.c --- pass5.c 8 Jul 2014 17:19:24 -0000 1.45 +++ pass5.c 5 Sep 2014 08:36:43 -0000 @@ -336,8 +336,8 @@ pass5(void) continue; if (cg_inosused(cg)[i] & (1 << k)) continue; - pwarn("ALLOCATED INODE %ld MARKED FREE\n", - c * fs->fs_ipg + i * 8 + k); + pwarn("ALLOCATED INODE %lld MARKED FREE\n", + ((long long)c * fs->fs_ipg + i * 8) + k); } } for (i = 0; i < blkmapsize; i++) { @@ -347,10 +347,10 @@ pass5(void) for (k = 0; k < NBBY; k++) { if ((j & (1 << k)) == 0) continue; - if (cg_inosused(cg)[i] & (1 << k)) + if (cg_blksfree(newcg)[i] & (1 << k)) continue; - pwarn("ALLOCATED FRAG %ld MARKED FREE\n", - c * fs->fs_fpg + i * 8 + k); + pwarn("ALLOCATED FRAG %lld MARKED FREE\n", + ((long long)c * fs->fs_fpg + i * 8) + k); } } } Index: setup.c =================================================================== RCS file: /cvs/src/sbin/fsck_ffs/setup.c,v retrieving revision 1.54 diff -u -p -r1.54 setup.c --- setup.c 29 May 2014 12:02:50 -0000 1.54 +++ setup.c 5 Sep 2014 08:36:43 -0000 @@ -75,7 +75,8 @@ static const int altsbtry[] = { 32, 64, int setup(char *dev) { - long cg, size, asked, i, j, bmapsize; + long cg, size, asked, i, j; + size_t bmapsize; struct disklabel *lp; off_t sizepb; struct stat statb; @@ -382,17 +383,16 @@ found: * allocate and initialize the necessary maps */ bmapsize = roundup(howmany(maxfsblock, NBBY), sizeof(int16_t)); - blockmap = calloc((unsigned)bmapsize, sizeof(char)); + blockmap = calloc(bmapsize, sizeof(char)); if (blockmap == NULL) { - printf("cannot alloc %u bytes for blockmap\n", - (unsigned)bmapsize); + printf("cannot alloc %zu bytes for blockmap\n", bmapsize); goto badsblabel; } 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))); + printf("cannot alloc %zu bytes for inostathead\n", + (unsigned)sblock.fs_ncg * sizeof(struct inostatlist)); 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.46 diff -u -p -r1.46 utilities.c --- utilities.c 24 May 2014 14:54:49 -0000 1.46 +++ utilities.c 5 Sep 2014 08:36:43 -0000 @@ -395,10 +395,11 @@ bwrite(int fd, char *buf, daddr_t blk, l /* * allocate a data block with the specified number of fragments */ -int -allocblk(long frags) +daddr_t +allocblk(int frags) { - int i, j, k, cg, baseblk; + daddr_t i, baseblk; + int j, k, cg; struct cg *cgp = &cgrp; if (frags <= 0 || frags > sblock.fs_frag) @@ -439,7 +440,7 @@ allocblk(long frags) * Free a previously allocated block */ void -freeblk(daddr_t blkno, long frags) +freeblk(daddr_t blkno, int frags) { struct inodesc idesc;