diff options
| author | mlelstv <mlelstv@NetBSD.org> | 2015-08-09 07:40:59 +0000 |
|---|---|---|
| committer | mlelstv <mlelstv@NetBSD.org> | 2015-08-09 07:40:59 +0000 |
| commit | d3bfee14317d391ad30284cfd678bea1f2925e1b (patch) | |
| tree | 40146f9d85ff44843ebc1823cf50334d38815c18 | |
| parent | 3fd96b8f9111b69231597589a554b1b66313343f (diff) | |
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
| -rw-r--r-- | sys/kern/vfs_wapbl.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/sys/kern/vfs_wapbl.c b/sys/kern/vfs_wapbl.c index 244805388e6..c3046d64445 100644 --- a/sys/kern/vfs_wapbl.c +++ b/sys/kern/vfs_wapbl.c @@ -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 *wr) } #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_replay *wr, off_t *offp) */ 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 wapbl_replay *wr) */ 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 *wr, struct vnode *fsdevvp) 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 *wr, struct vnode *fsdevvp) 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); |
