Hello,
on a clean FFS2 filesystem I am getting this false error on very large
files (length >= 1 TB). This example is from i386.
# /sbin/fsck -nf /dev/rsd5a
** /dev/rsd5a (NO WRITE)
** File system is already clean
** Last Mounted on /mnt
** Phase 1 - Check Blocks and Sizes
INCORRECT BLOCK COUNT I=5 (-1364564224 should be -1364564224)
CORRECT? no
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
158 files, 395514676 used, 576642036 free (300 frags, 72080217 blocks, 0.0%
fragmentation)
# /bin/ls -li /mnt/vnd00
5 -r-------- 1 root wheel 1500000026624 Jun 22 18:48 /mnt/vnd00
There are two problems:
1. inodesc.id_entryno can't hold the data found in ufs2_dinode.di_blocks
when operating on FFS2.
2. unsigned long long variable is being printed out as %ld
Please verify the patch below carefully to be sure that I don't cause more
harm than what I fix.
Tested on i386 and *clean* FFS1 and FFS2 file systems only.
Regards,
David
Index: sbin/fsck_ffs/fsck.h
===================================================================
RCS file: /cvs/src/sbin/fsck_ffs/fsck.h,v
retrieving revision 1.29
diff -u -p -u -r1.29 fsck.h
--- sbin/fsck_ffs/fsck.h 9 May 2014 13:19:34 -0000 1.29
+++ sbin/fsck_ffs/fsck.h 4 Sep 2014 15:36:36 -0000
@@ -170,7 +170,7 @@ struct inodesc {
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 */
+ u_int64_t id_entryno; /* for DATA nodes, current entry number */
char id_type; /* type of descriptor, DATA or ADDR */
};
/* file types */
Index: sbin/fsck_ffs/pass1.c
===================================================================
RCS file: /cvs/src/sbin/fsck_ffs/pass1.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 pass1.c
--- sbin/fsck_ffs/pass1.c 11 Jun 2013 16:42:04 -0000 1.38
+++ sbin/fsck_ffs/pass1.c 4 Sep 2014 15:36:37 -0000
@@ -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 (%llu should be %llu)",
+ (unsigned long long)inumber, (unsigned long long)DIP(dp,
di_blocks),
+ (unsigned long long)idesc->id_entryno);
if (preen)
printf(" (CORRECTED)\n");
else if (reply("CORRECT") == 0)