NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/45933: fsck_ffs can't find wapbl journal on 4k-block disks



>Number:         45933
>Category:       bin
>Synopsis:       fsck_ffs can't find wapbl journal on 4k-block disks
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Feb 06 03:30:00 +0000 2012
>Originator:     David Krinsky
>Release:        NetBSD 5.99.59
>Organization:
>Environment:
        
        
System: NetBSD foundation.krinsky.net 5.99.59 NetBSD 5.99.59 
(NEWBANTHA_XEN3_DOM0) #0: Thu Jan 12 20:56:21 EST 2012 
root%foundation.krinsky.net@localhost:/usr/obj/sys/arch/amd64/compile/NEWBANTHA_XEN3_DOM0
 amd64
Architecture: x86_64
Machine: amd64

fsck_ffs ident:
     $NetBSD: crt0-common.c,v 1.7 2011/06/30 20:07:35 matt Exp $
     $NetBSD: crt0.S,v 1.3 2011/07/01 02:59:05 joerg Exp $
     $NetBSD: crti.S,v 1.1 2010/08/07 18:01:35 joerg Exp $
     $NetBSD: crtbegin.S,v 1.2 2010/11/30 18:37:59 joerg Exp $
     $NetBSD: dir.c,v 1.53 2011/03/06 17:08:16 bouyer Exp $
     $NetBSD: inode.c,v 1.64 2011/03/06 17:08:16 bouyer Exp $
     $NetBSD: main.c,v 1.80 2011/08/29 14:34:59 joerg Exp $
     $NetBSD: pass1.c,v 1.49 2011/08/14 12:32:01 christos Exp $
     $NetBSD: pass1b.c,v 1.22 2011/03/06 17:08:16 bouyer Exp $
     $NetBSD: pass2.c,v 1.48 2011/08/14 12:32:01 christos Exp $
     $NetBSD: pass3.c,v 1.20 2011/03/06 17:08:16 bouyer Exp $
     $NetBSD: pass4.c,v 1.26 2011/03/06 17:08:16 bouyer Exp $
     $NetBSD: pass5.c,v 1.49 2011/08/14 12:32:01 christos Exp $
     $NetBSD: fsutil.c,v 1.20 2011/06/09 19:57:50 christos Exp $
     $NetBSD: setup.c,v 1.94 2011/08/14 12:32:01 christos Exp $
     $NetBSD: utilities.c,v 1.60 2011/06/09 19:57:52 christos Exp $
     $NetBSD: ffs_bswap.c,v 1.35 2011/03/06 17:08:38 bouyer Exp $
     $NetBSD: ffs_subr.c,v 1.47 2011/08/14 12:37:09 christos Exp $
     $NetBSD: ffs_tables.c,v 1.9 2005/12/11 12:25:25 christos Exp $
     $NetBSD: ffs_appleufs.c,v 1.12 2011/11/19 22:51:31 tls Exp $
     $NetBSD: partutil.c,v 1.11 2011/11/13 22:04:51 christos Exp $
     $NetBSD: quota2_subr.c,v 1.4 2011/06/07 14:56:13 bouyer Exp $
     $NetBSD: progress.c,v 1.5 2009/04/11 06:48:36 lukem Exp $
     $NetBSD: vfs_wapbl.c,v 1.48 2011/12/02 12:38:59 yamt Exp $
     $NetBSD: wapbl.c,v 1.5 2010/03/06 11:31:40 mlelstv Exp $
     $NetBSD: crtend.S,v 1.1 2010/08/07 18:01:34 joerg Exp $
     $NetBSD: crtn.S,v 1.1 2010/08/07 18:01:35 joerg Exp $

>Description:

When attempting to fsck an FFSv2 filesystem that had been mounted with "-o log"
but then not cleanly unmounted, fsck_ffs fails to find and read the journal if
the filesystem is on a device with a sector size of 4K:

    foundation# fsck /dev/mapper/rvgr00-wapbltest
    ** /dev/mapper/rvgr00-wapbltest

    CANNOT READ: BLK 8388608
    CONTINUE? [yn] y

    THE FOLLOWING DISK SECTORS COULD NOT BE READ: 67108864 (8388608), 67108865 
(8388608),
    Unrecognized wapbl magic: 0x00000000
    UNABLE TO READ JOURNAL FOR REPLAY
    CONTINUE? [yn] 

(This example is from a 4096 MiB FFSv2 filesystem located on a 4160
MiB LVM logical volume, which is ultimately resident on a RAID1
RAIDframe array of two 2TB Seagate Barracuda Green drives--which have
4K disk sectors.  But I've observed the same thing on filesystems
created on the same drive directly with no RAID or LVM.  Note also
that the only crashes I've experienced to trigger this have been by
killing a Xen DomU with xm destroy, but the problem doesn't appear
Xen-related; the DomUs, like the Dom0 above, are running recent
versions of -current for amd64.)

Block 8388608 is the correct location of the WAPBL journal in 512-byte blocks;
manually doing 

    dd if=/dev/mapper/rvgr00-wapbltest of=/tmp/whatever bs=512 count=131072 
skip=8388608

succeeds, and /tmp/whatever is not just zeroes.
        
>How-To-Repeat:
    - Create an FFSv2 filesystem on a device with 4K blocks (I have been 
leaving space 
        for a WAPBL journal after the filesystem but it seems unlikely that 
this is
        necessary.)
    - mount -o log /dev/{filesystem} /mnt
    - Crash
    - fsck /dev/{filesystem}

>Fix:

The problem appears to be that check_wapbl() in sbin/fsck_ffs/wapbl.c calls
wapbl_replay_start with addr=8388608 and blksize=512, as apparently specified 
in the
superblock:

(gdb) bt
#0  bread (fd=5, buf=0x7f7ff7b1e000 "", blk=8388608, size=1024)
    at /usr/src/sbin/fsck_ffs/utilities.c:342
#1  0x000000000041cf82 in wapbl_read (data=0x7f7ff7b1e000, len=1024, devvp=0x0, 
pbn=8388608)
    at /usr/src/sbin/fsck_ffs/wapbl.c:84
#2  0x000000000041c426 in wapbl_replay_start (wrp=0x624850, vp=0x0, 
off=8388608, 
    count=131072, blksize=512) at /usr/src/sys/kern/vfs_wapbl.c:2421
#3  0x000000000041d4c3 in check_wapbl () at /usr/src/sbin/fsck_ffs/wapbl.c:210
#4  0x0000000000411d68 in setup (dev=0x7f7ff7b01060 
"/dev/mapper/rvgr00-wapbltest", 
    origdev=0x7f7ff7b01060 "/dev/mapper/rvgr00-wapbltest")
    at /usr/src/sbin/fsck_ffs/setup.c:185
#5  0x0000000000408f35 in checkfilesys (
    filesys=0x7f7ff7b01060 "/dev/mapper/rvgr00-wapbltest", 
    origfs=0x7f7ff7b01060 "/dev/mapper/rvgr00-wapbltest", child=0)
    at /usr/src/sbin/fsck_ffs/main.c:306
#6  0x0000000000408de7 in main (argc=0, argv=0x7f7fffffdc60)
    at /usr/src/sbin/fsck_ffs/main.c:245
(gdb) fr 3
#3  0x000000000041d4c3 in check_wapbl () at /usr/src/sbin/fsck_ffs/wapbl.c:210
210                                     error = wapbl_replay_start(
(gdb) l
205                                     sbdirty();
206                                     ret = FSCK_EXIT_CHECK_FAILED;
207                                     break;
208                             }
209                             if (sblock->fs_flags & FS_DOWAPBL) {
210                                     error = wapbl_replay_start(
211                                         &wapbl_replay, 0, addr, count, 
blksize);
212                                     if (error) {
213                                             pfatal(
214                                                "UNABLE TO READ JOURNAL FOR 
REPLAY");
(gdb) p addr
$23 = 8388608
(gdb) p blksize
$24 = 512

But then wapbl_replay_start doesn't pass this information on to wapbl_read--it 
just
calls wapbl_read with the address in 512-byte blocks (as "pbn") without 
specifying
the blocksize:

(gdb) fr 2
#2  0x000000000041c426 in wapbl_replay_start (wrp=0x624850, vp=0x0, 
off=8388608, 
    count=131072, blksize=512) at /usr/src/sys/kern/vfs_wapbl.c:2421
2421            error = wapbl_read(scratch, 2<<log_dev_bshift, devvp, pbn);
(gdb) l
2416    
2417            pbn = logpbn;
2418    #ifdef _KERNEL
2419            pbn = btodb(pbn << log_dev_bshift);
2420    #endif
2421            error = wapbl_read(scratch, 2<<log_dev_bshift, devvp, pbn);
2422            if (error)
2423                    goto errout;
2424    
2425            wch = (struct wapbl_wc_header *)scratch;
(gdb) p pbn
$25 = 8388608

and the ultimate result is that bread tries to pread from a block way beyond 
the end of the
partition (i.e., 4096*pbn bytes into the partition instead of 512*pbn bytes), 
because
dev_bsize == 4096:

(gdb) fr 0
#0  bread (fd=5, buf=0x7f7ff7b1e000 "", blk=8388608, size=1024)
    at /usr/src/sbin/fsck_ffs/utilities.c:344
344             if ((pread(fd, buf, (int)size, offset) == size) &&
(gdb) l
339             int i, errs;
340             off_t offset;
341     
342             offset = blk;
343             offset *= dev_bsize;
344             if ((pread(fd, buf, (int)size, offset) == size) &&
345                 read_wapbl(buf, size, blk) == 0)
346                     return (0);
347             rwerror("READ", blk);
348             errs = 0;
(gdb) p offset
$37 = 34359738368
(gdb) p blk
$38 = 8388608
(gdb) p dev_bsize
$39 = 4096

I am not sufficiently familiar with this code to tell whether the cleanest 
solution
is to pass the blocksize further down, to recalculate pbn in terms of the larger
correct blocksize, to make sure the location of the log is stored in units that 
match
the device, or something else.

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index