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);

Reply via email to