NetBSD-Bugs archive

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

Re: bin/50108: fsck_ffs fails replaying wapbl journal on filesystem with 4k sectors



The following reply was made to PR bin/50108; it has been noted by GNATS.

From: mlelstv%serpens.de@localhost (Michael van Elst)
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: bin/50108: fsck_ffs fails replaying wapbl journal on filesystem with 4k sectors
Date: Sun, 2 Aug 2015 10:45:07 +0000 (UTC)

 dholland-bugs%netbsd.org@localhost (David Holland) writes:
 
 > If you (or someone) can catch this in the debugger and then trace the
 > provenance of that 367616 my guess is that it's been multiplied by the
 > wrong thing.
 
 > Although this is not trivial; for the moment I can't tell for sure if
 > wapbl_read and wapbl_write are supposed to be getting block numbers in
 > frags or device-level blocks or DEV_BSIZE blocks
 
 It depends on wether it is kernel (DEV_BSIZE) or userland (sector size).
 
 The fsck_ffs output shows that the journal blocks can be read
 successfully. The write however failed, and assuming this is
 a unit problem and the real block is 91904 or even 45952, it's
 a block inside the filesystem.
 
 Writes to blocks inside the filesystem using wapl_write are
 caused by replaying the journal... and the block numbers that
 appear inside the journal are written by the kernel using
 its DEV_BSIZE units. When replayed by fsck_ffs in userland
 however, these are interpreted as sector size units.
 
 You can dump the journal with:
 
 dumpfs -sjv vnd0a
 
 This should show a block with 'daddr 367616' in the journal.
 
 
 There are 4 places in the kernel code in vfs_wapbl.c (also used by
 fsck_ffs) that retrieve block numbers from the journal.
 
 wapbl_blkhash_ins(wr, wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen), *offp);
 wapbl_blkhash_rem(wr, wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen));
 
 and twice in the disabled verify function:
 wapbl_blkhash_get(wr, wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen));
 
 
 Unfortunately there is no magic to transparently get the right
 unit conversion here.
 
 You could replace
 
 	wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen)
 
 with
 
 	wapbl_block_daddr(wc, i, j, fsblklen)
 
 for something like:
 
 daddr_t
 wapbl_block_daddr(struct wapbl_wc_blocklist *wc, int i, int j, int blen)
 {
 #ifdef _KERNEL
 	return wc->wc_blocks[i].wc_daddr + btodb(j * blen);
 #else
 	return dbtob(wc->wc_blocks[i].wc_daddr) / blen + j;
 #endif
 }
 
 
 
 -- 
 -- 
                                 Michael van Elst
 Internet: mlelstv%serpens.de@localhost
                                 "A potential Snark may lurk in every tree."
 


Home | Main Index | Thread Index | Old Index