summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormlelstv <mlelstv@NetBSD.org>2015-08-09 07:40:59 +0000
committermlelstv <mlelstv@NetBSD.org>2015-08-09 07:40:59 +0000
commitd3bfee14317d391ad30284cfd678bea1f2925e1b (patch)
tree40146f9d85ff44843ebc1823cf50334d38815c18
parent3fd96b8f9111b69231597589a554b1b66313343f (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.c38
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);