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