Module Name: src Committed By: mlelstv Date: Sun Aug 9 07:40:59 UTC 2015
Modified Files: src/sys/kern: vfs_wapbl.c Log Message: Refactor disk address calculation from physical block numbers in the journal into a function. Make that function work correctly with sector sizes != DEV_BSIZE when compiled outside the kernel (i.e. fsck_ffs). Fixes PR bin/45933 To generate a diff of this commit: cvs rdiff -u -r1.61 -r1.62 src/sys/kern/vfs_wapbl.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_wapbl.c diff -u src/sys/kern/vfs_wapbl.c:1.61 src/sys/kern/vfs_wapbl.c:1.62 --- src/sys/kern/vfs_wapbl.c:1.61 Sat Oct 18 08:33:29 2014 +++ src/sys/kern/vfs_wapbl.c Sun Aug 9 07:40:59 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_wapbl.c,v 1.61 2014/10/18 08:33:29 snj Exp $ */ +/* $NetBSD: vfs_wapbl.c,v 1.62 2015/08/09 07:40:59 mlelstv Exp $ */ /*- * Copyright (c) 2003, 2008, 2009 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #define WAPBL_INTERNAL #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.61 2014/10/18 08:33:29 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.62 2015/08/09 07:40:59 mlelstv Exp $"); #include <sys/param.h> #include <sys/bitops.h> @@ -2603,6 +2603,32 @@ wapbl_replay_isopen1(struct wapbl_replay } #endif +/* + * calculate the disk address for the i'th block in the wc_blockblist + * offset by j blocks of size blen. + * + * wc_daddr is always a kernel disk address in DEV_BSIZE units that + * was written to the journal. + * + * The kernel needs that address plus the offset in DEV_BSIZE units. + * + * Userland needs that address plus the offset in blen units. + * + */ +static daddr_t +wapbl_block_daddr(struct wapbl_wc_blocklist *wc, int i, int j, int blen) +{ + daddr_t pbn; + +#ifdef _KERNEL + pbn = wc->wc_blocks[i].wc_daddr + btodb(j * blen); +#else + pbn = dbtob(wc->wc_blocks[i].wc_daddr) / blen + j; +#endif + + return pbn; +} + static void wapbl_replay_process_blocks(struct wapbl_replay *wr, off_t *offp) { @@ -2617,7 +2643,7 @@ wapbl_replay_process_blocks(struct wapbl */ n = wc->wc_blocks[i].wc_dlen >> wr->wr_fs_dev_bshift; for (j = 0; j < n; j++) { - wapbl_blkhash_ins(wr, wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen), + wapbl_blkhash_ins(wr, wapbl_block_daddr(wc, i, j, fsblklen), *offp); wapbl_circ_advance(wr, fsblklen, offp); } @@ -2638,7 +2664,7 @@ wapbl_replay_process_revocations(struct */ n = wc->wc_blocks[i].wc_dlen >> wr->wr_fs_dev_bshift; for (j = 0; j < n; j++) - wapbl_blkhash_rem(wr, wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen)); + wapbl_blkhash_rem(wr, wapbl_block_daddr(wc, i, j, fsblklen)); } } @@ -2774,7 +2800,7 @@ wapbl_replay_verify(struct wapbl_replay for (j = 0; j < n; j++) { struct wapbl_blk *wb = wapbl_blkhash_get(wr, - wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen)); + wapbl_block_daddr(wc, i, j, fsblklen)); if (wb && (wb->wb_off == off)) { foundcnt++; error = @@ -2818,7 +2844,7 @@ wapbl_replay_verify(struct wapbl_replay for (j = 0; j < n; j++) { struct wapbl_blk *wb = wapbl_blkhash_get(wr, - wc->wc_blocks[i].wc_daddr + btodb(j * fsblklen)); + wapbl_block_daddr(wc, i, j, fsblklen)); if (wb && (wb->wb_off == off)) { wapbl_blkhash_rem(wr, wb->wb_blk);