NetBSD Problem Report #50070

From prlw1@NetBSD.org  Mon Jul 20 15:55:08 2015
Return-Path: <prlw1@NetBSD.org>
Received: by mollari.NetBSD.org (Postfix, from userid 1471)
	id 5AD8DA6552; Mon, 20 Jul 2015 15:55:08 +0000 (UTC)
Message-Id: <20150720155508.5AD8DA6552@mollari.NetBSD.org>
Date: Mon, 20 Jul 2015 15:55:08 +0000 (UTC)
From: prlw1@NetBSD.org
Reply-To: prlw1@NetBSD.org
To: gnats-bugs@NetBSD.org
Subject: fsck OK but mount: incorrect super block
X-Send-Pr-Version: 3.95

>Number:         50070
>Category:       kern
>Synopsis:       fsck OK but mount: incorrect super block
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    maxv
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jul 20 16:00:00 +0000 2015
>Closed-Date:    Sat Oct 24 16:36:12 +0000 2015
>Last-Modified:  Sat Oct 24 16:36:12 +0000 2015
>Originator:     Patrick Welche
>Release:        NetBSD 7.99.20
>Organization:

>Environment:
NetBSD-7.99.20/amd64 (today's -current)
>Description:

After updating -current from 7.99.6:

# fsck -f /home
** /dev/rraid2a
** File system is already clean
** Last Mounted on /home
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
771 files, 67335 used, 48451404 free (140 frags, 6056408 blocks, 0.0% fragmentation)
# mount /home
mount_ffs: /dev/raid2a on /home: incorrect super block

ERROR: cylinder group size mismatch: fs_cgsize = 0x4800, fs->fs_cgsize = 0x4000, CGSIZE(fs) = 0x4003

http://mail-index.netbsd.org/current-users/2015/07/20/msg027763.html

file system: /dev/rraid2a
format  FFSv1
endian  little-endian
magic   11954           time    Mon Jul 20 16:51:37 2015
superblock location     8192    id      [ 50310125 72060166 ]
cylgrp  dynamic inodes  4.4BSD  sblock  FFSv2   fslevel 4
nbfree  6056408 ndir    337     nifree  12183035        nffree  140
ncg     523     size    49288608        blocks  48518739
bsize   16384   shift   14      mask    0xffffc000
fsize   2048    shift   11      mask    0xfffff800
frag    8       shift   3       fsbtodb 2
bpg     11798   fpg     94384   ipg     23296
minfree 5%      optim   time    maxcontig 4     maxbpg  4096
symlinklen 60   contigsumsize 4
maxfilesize 0x000400400402ffff
nindir  4096    inopb   128
avgfilesize 16384       avgfpdir 64
sblkno  8       cblkno  16      iblkno  24      dblkno  1480
sbsize  2048    cgsize  16384
csaddr  1480    cssize  10240
cgrotor 0       fmod    0       ronly   0       clean   0x02
...
>How-To-Repeat:

>Fix:

From Martin Husemann, we hit the else in src/sys/ufs/ffs/ffs_vfsops.c:

        /* Check the size of cylinder groups */
        fs_cgsize = ffs_fragroundup(fs, CGSIZE(fs));
        if (fs->fs_cgsize != fs_cgsize) {
                if (fs->fs_cgsize+1 == CGSIZE(fs)) {
                        printf("CGSIZE(fs) miscalculated by one - this file " 
                            "system may have been created by\n"
                            "  an old (buggy) userland, see\n"
                            "  http://www.NetBSD.org/"
                            "docs/ffsv1badsuperblock.html\n");
                } else {
                        printf("ERROR: cylinder group size mismatch: "
                            "fs_cgsize = 0x%zx, " 
                            "fs->fs_cgsize = 0x%zx, CGSIZE(fs) = 0x%zx\n",
                            (size_t)fs_cgsize, (size_t)fs->fs_cgsize,
                            (size_t)CGSIZE(fs));
                        return 0;
                }
        }

so treat as another case of ffsv1badsuperblock, and ignore the mismatch.
(Remove return 0;)

This allows mounting to succeed. (Haven't noticed any trouble in /home)

>Release-Note:

>Audit-Trail:
From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Mon, 20 Jul 2015 22:42:04 +0000

 On Mon, Jul 20, 2015 at 04:00:00PM +0000, prlw1@NetBSD.org wrote:
  > ERROR: cylinder group size mismatch: fs_cgsize = 0x4800, fs->fs_cgsize = 0x4000, CGSIZE(fs) = 0x4003
  > [...]
  > file system: /dev/rraid2a
  > bsize   16384
  > fsize   2048

 The test is spewing drivel; the maximum cgsize is one block, which is
 0x4000, so fs->fs_cgsize is correct and CGSIZE() is hallucinating.

 Would probably be a good idea to find out why, though, rather than
 just disabling the test.

 -- 
 David A. Holland
 dholland@netbsd.org

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Tue, 21 Jul 2015 10:08:42 +0200

 Can you please send the output of "dumpfs /dev/r.... | head -28"
 for your filesytem?

 Martin

From: Martin Husemann <martin@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Sun, 2 Aug 2015 14:40:14 +0000

 On Mon, Jul 20, 2015 at 10:45:01PM +0000, David Holland wrote:
 >  
 >  The test is spewing drivel; the maximum cgsize is one block, which is
 >  0x4000, so fs->fs_cgsize is correct and CGSIZE() is hallucinating.
 >  
 >  Would probably be a good idea to find out why, though, rather than
 >  just disabling the test.

 Here is a simple test program that shows it calculating bogus values (based
 on the values found in my superblock).

 Martin

 --8<--
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>

 #include <sys/param.h>
 #include <sys/types.h>
 #include </usr/src/sys/ufs/ffs/fs.h>

 int main(int argc, char **argv)
 {
 	struct fs sblock;
 	uint64_t cs;

 	memset(&sblock, 0,sizeof sblock);

 	sblock.fs_sblkno = 8;
 	sblock.fs_ncg = 610;
 	sblock.fs_bsize = 16384;
 	sblock.fs_frag = 8;
 	sblock.fs_minfree = 5;
 	sblock.fs_bmask = 0xffffc000;
 	sblock.fs_fmask = 0xfffff800;
 	sblock.fs_bshift = 14;
 	sblock.fs_fshift = 11;
 	sblock.fs_maxcontig = 4;
 	sblock.fs_maxbpg = 4096;
 	sblock.fs_fragshift = 3;
 	sblock.fs_fsbtodb = 2;
 	sblock.fs_sbsize = sizeof(sblock);
 	sblock.fs_nindir = 4096;
 	sblock.fs_inopb = 128;
 	sblock.fs_contigsumsize = 4;
 	sblock.fs_old_cpg = 1;
 	sblock.fs_ipg = 23296;
 	sblock.fs_fpg = 94368;
 	sblock.fs_sblockloc = 8192;
 	sblock.fs_id[0] = 0x4c4ad59b;
 	sblock.fs_id[1] = 0x16a2beb3;
 	sblock.fs_size = 57561588;
 	sblock.fs_dsize = 56663655;
 	sblock.fs_cssize = 10240;
 	sblock.fs_cgsize = 16384;
 	sblock.fs_qbmask = ~(uint64_t)sblock.fs_bmask;
 	sblock.fs_qfmask = ~(uint64_t)sblock.fs_fmask;

 	cs = CGSIZE(&sblock);
 	printf("CGSIZE(fs) : %" PRIu64 "\n", cs);

 	return 0;
 }

From: "J. Hannken-Illjes" <hannken@eis.cs.tu-bs.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Sun, 2 Aug 2015 17:45:29 +0200

 On 02 Aug 2015, at 16:45, Martin Husemann <martin@netbsd.org> wrote:

 > Here is a simple test program that shows it calculating bogus values (based
 > on the values found in my superblock).

 Do you remember the parameters to "newfs" and its version?

 --
 J. Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Sun, 2 Aug 2015 21:27:57 +0200

 On Sun, Aug 02, 2015 at 03:50:00PM +0000, J. Hannken-Illjes wrote:
 >  Do you remember the parameters to "newfs" and its version?

 No. I apparently installed this disk sometime July 2010, most likely
 using sysinst and -current, and whatever defaults it used back then (or
 alternatively - sorry I can't remember) manually and giving no args to
 newfs at all.

 Disklabel says:

 #        size    offset     fstype [fsize bsize cpg/sgs]
  a: 230246352         0     4.2BSD   2048 16384     0  # (Cyl.      0 - 228418)


 Martin

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Sun, 2 Aug 2015 20:19:25 +0000

 On Sun, Aug 02, 2015 at 02:45:01PM +0000, Martin Husemann wrote:
  >  	cs = CGSIZE(&sblock);
  >  	printf("CGSIZE(fs) : %" PRIu64 "\n", cs);

 I make it:
   /* base cg */     (sizeof(struct cg) + sizeof(int32_t) +         180
   /* old btotoff */ (fs)->fs_old_cpg * sizeof(int32_t) +           4
   /* old boff */    (fs)->fs_old_cpg * sizeof(u_int16_t) +         2
   /* inode map */   howmany((ipg), NBBY) +                         2912
   /* block map */   howmany((fpg), NBBY) +                         11796
   /* if present */  ((fs)->fs_contigsumsize <= 0 ? 0 :             
   /* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) +     16
   /* cluster map */ howmany(ffs_fragstoblks(fs, (fpg)), NBBY)))  + 1475
                                                                  ------
                                                                   16385
 which is one byte too large.

 I suspect the real problem here is this:

    u_int8_t cg_space[1];		/* space for cylinder group maps */
 /* actually longer */

 as that causes sizeof(struct cg) to be 176 instead of 168 (at least on
 a 64-bit platform) and the CGSIZE macro was probably not supposed to
 count that.

 (also, the fact that this padding will make the size different on
 32-bit and 64-bit machines is Bad...)

 Do we know if all accesses to the cylinder group data are via
 cg_space[]? If anything uses sizeof(cg) to index into the data we're
 probably in trouble.

 -- 
 David A. Holland
 dholland@netbsd.org

From: "J. Hannken-Illjes" <hannken@eis.cs.tu-bs.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Mon, 3 Aug 2015 12:54:23 +0200

 On 02 Aug 2015, at 22:20, David Holland <dholland-bugs@netbsd.org> wrote:

 > Do we know if all accesses to the cylinder group data are via
 > cg_space[]?

 No accesses through cg_space[], all accesses are through offset fields
 of "struct cg".

 The filesystem from martin@ has

 fs_bsize 16384
 fs_fpg 94368

 cg_old_btotoff 168
 cg_clusteroff 14900
 cg_nextfreeoff 16375

 With these values the cluster bitmap runs from 14900 to 16374.

 This matches "cg_nextfreeoff" so the file system should work as
 expected as long as "cg_nextfreeoff <= fs_bsize".

 Looks like "cg_space" is used only from userland tools (fsck_ffs,
 newfs, makefs and resize_ffs).

 > If anything uses sizeof(cg) to index into the data we're
 > probably in trouble.
 > 
 > -- 
 > David A. Holland
 > dholland@netbsd.org
 > 

 --
 J. Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)

From: "J. Hannken-Illjes" <hannken@eis.cs.tu-bs.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Mon, 3 Aug 2015 17:31:35 +0200

 This cgsize test from ffs_superblock_validate() is wrong.  Newfs aligns
 fs_cgsize to fragment size:

 	sblock.fs_cgsize = ffs_fragroundup(&sblock, CGSIZE(&sblock));

 All we should test here is

 	fs->fs_cgsize >= sizeof(struct cg)
 	fs->fs_cgsize <= fs->fs_bsize

 These tests are sufficient to read/write cylinder groups, to validate
 individual cylinder groups we should make cg_chkmagic() a function
 and add tests for all cg_*off fields there.

 --
 J. Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: "J. Hannken-Illjes" <hannken@eis.cs.tu-bs.de>,
	Maxime Villard <maxv@NetBSD.org>
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Thu, 22 Oct 2015 09:37:43 +0200

 J. Hannken-Illjes wrote:

 >  This cgsize test from ffs_superblock_validate() is wrong.  Newfs aligns
 >  fs_cgsize to fragment size:
 >  
 >  	sblock.fs_cgsize = ffs_fragroundup(&sblock, CGSIZE(&sblock));
 >  
 >  All we should test here is
 >  
 >  	fs->fs_cgsize >= sizeof(struct cg)
 >  	fs->fs_cgsize <= fs->fs_bsize

 So can we fix it, please?

 Martin

From: "J. Hannken-Illjes" <hannken@eis.cs.tu-bs.de>
To: Maxime Villard <max@M00nBSD.net>
Cc: Martin Husemann <martin@duskware.de>,
 gnats-bugs@NetBSD.org
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Thu, 22 Oct 2015 12:02:35 +0200

 On 22 Oct 2015, at 10:24, Maxime Villard <max@M00nBSD.net> wrote:

 > Le 22/10/2015 09:37, Martin Husemann a =E9crit :
 >> J. Hannken-Illjes wrote:
 >>=20
 >>> This cgsize test from ffs_superblock_validate() is wrong.  Newfs =
 aligns
 >>> fs_cgsize to fragment size:
 >>>=20
 >>> 	sblock.fs_cgsize =3D ffs_fragroundup(&sblock, CGSIZE(&sblock));
 >>>=20
 >=20
 > And so does ffs_superblock_validate(), doesn't it? Can you elaborate
 > a bit?
 >=20
 >>> All we should test here is
 >>>=20
 >>> 	fs->fs_cgsize >=3D sizeof(struct cg)
 >>> 	fs->fs_cgsize <=3D fs->fs_bsize
 >>=20
 >=20
 > The only bug I can see currently in ffs_vfsops.c is that the =
 superblock
 > is validated before ffs_oldfscompat_read() is called, which means that
 > FFSv1+!FS_FLAGS_UPDATED disks may not mount correctly. This is not the
 > case in that PR, since "fslevel 4" means FFSv1+FS_FLAGS_UPDATED.

 As already noted in this PR the first bug is to assume CGSIZE() returns
 an exact value.  It is just a guess, newfs(8) uses it as a starting
 point and reduces it to be less than fs_bsize.

 We will read cylinder groups with size fs_cgsize so this value has to
 be greater than sizeof(cg) and less or equal fs_bsize.

 If we want to check the cylinder groups, we have to check the pointers
 from struct cg against fs_cgsize and we have to do this check on every
 call to cg_chkmagic().

 --
 J. Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)

From: "Maxime Villard" <maxv@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/50070 CVS commit: src/sys/ufs/ffs
Date: Thu, 22 Oct 2015 11:31:31 +0000

 Module Name:	src
 Committed By:	maxv
 Date:		Thu Oct 22 11:31:31 UTC 2015

 Modified Files:
 	src/sys/ufs/ffs: ffs_vfsops.c

 Log Message:
 Fix PR 50070. From hannken@.


 To generate a diff of this commit:
 cvs rdiff -u -r1.335 -r1.336 src/sys/ufs/ffs/ffs_vfsops.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Maxime Villard <max@m00nbsd.net>
To: Martin Husemann <martin@duskware.de>, gnats-bugs@NetBSD.org
Cc: "J. Hannken-Illjes" <hannken@eis.cs.tu-bs.de>,
 Maxime Villard <maxv@NetBSD.org>
Subject: Re: kern/50070: fsck OK but mount: incorrect super block
Date: Thu, 22 Oct 2015 10:24:32 +0200

 Le 22/10/2015 09:37, Martin Husemann a écrit :
 > J. Hannken-Illjes wrote:
 > 
 >>  This cgsize test from ffs_superblock_validate() is wrong.  Newfs aligns
 >>  fs_cgsize to fragment size:
 >>  
 >>  	sblock.fs_cgsize = ffs_fragroundup(&sblock, CGSIZE(&sblock));
 >>  

 And so does ffs_superblock_validate(), doesn't it? Can you elaborate
 a bit?

 >>  All we should test here is
 >>  
 >>  	fs->fs_cgsize >= sizeof(struct cg)
 >>  	fs->fs_cgsize <= fs->fs_bsize
 > 

 The only bug I can see currently in ffs_vfsops.c is that the superblock
 is validated before ffs_oldfscompat_read() is called, which means that
 FFSv1+!FS_FLAGS_UPDATED disks may not mount correctly. This is not the
 case in that PR, since "fslevel 4" means FFSv1+FS_FLAGS_UPDATED.

 > So can we fix it, please?

 I guess I'll have to subscribe to netbsd-bugs@.

 > 
 > Martin
 > 

Responsible-Changed-From-To: kern-bug-people->maxv
Responsible-Changed-By: martin@NetBSD.org
Responsible-Changed-When: Fri, 23 Oct 2015 08:07:23 +0000
Responsible-Changed-Why:
Maxime commited a fix


State-Changed-From-To: open->feedback
State-Changed-By: martin@NetBSD.org
State-Changed-When: Fri, 23 Oct 2015 08:07:23 +0000
State-Changed-Why:
My affected machine now works - can you update your kernel and test again?


From: Patrick Welche <prlw1@cam.ac.uk>
To: gnats-bugs@NetBSD.org
Cc: maxv@NetBSD.org, kern-bug-people@netbsd.org, netbsd-bugs@netbsd.org,
	gnats-admin@netbsd.org, martin@NetBSD.org, prlw1@NetBSD.org
Subject: Re: kern/50070 (fsck OK but mount: incorrect super block)
Date: Sat, 24 Oct 2015 00:24:14 +0100

 On Fri, Oct 23, 2015 at 08:07:23AM +0000, martin@NetBSD.org wrote:
 > My affected machine now works - can you update your kernel and test again?

 Mine also now successfully mounts /home. Thanks!

State-Changed-From-To: feedback->closed
State-Changed-By: martin@NetBSD.org
State-Changed-When: Sat, 24 Oct 2015 16:36:12 +0000
State-Changed-Why:
Fixed


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.