Mon Nov 17 19:31:47 2008 UTC ()
Ensure that block records are correctly padded.


(joerg)
diff -r1.6 -r1.7 src/sys/kern/vfs_wapbl.c
diff -r1.6 -r1.7 src/sys/sys/wapbl.h

cvs diff -r1.6 -r1.7 src/sys/kern/vfs_wapbl.c (expand / switch to unified diff)

--- src/sys/kern/vfs_wapbl.c 2008/11/11 08:29:58 1.6
+++ src/sys/kern/vfs_wapbl.c 2008/11/17 19:31:47 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_wapbl.c,v 1.6 2008/11/11 08:29:58 joerg Exp $ */ 1/* $NetBSD: vfs_wapbl.c,v 1.7 2008/11/17 19:31:47 joerg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003,2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003,2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc. 8 * by Wasabi Systems, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -26,27 +26,27 @@ @@ -26,27 +26,27 @@
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * This implements file system independent write ahead filesystem logging. 33 * This implements file system independent write ahead filesystem logging.
34 */ 34 */
35 35
36#define WAPBL_INTERNAL 36#define WAPBL_INTERNAL
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.6 2008/11/11 08:29:58 joerg Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.7 2008/11/17 19:31:47 joerg Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42 42
43#ifdef _KERNEL 43#ifdef _KERNEL
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/namei.h> 45#include <sys/namei.h>
46#include <sys/proc.h> 46#include <sys/proc.h>
47#include <sys/uio.h> 47#include <sys/uio.h>
48#include <sys/vnode.h> 48#include <sys/vnode.h>
49#include <sys/file.h> 49#include <sys/file.h>
50#include <sys/malloc.h> 50#include <sys/malloc.h>
51#include <sys/resourcevar.h> 51#include <sys/resourcevar.h>
52#include <sys/conf.h> 52#include <sys/conf.h>
@@ -1912,26 +1912,27 @@ wapbl_write_commit(struct wapbl *wl, off @@ -1912,26 +1912,27 @@ wapbl_write_commit(struct wapbl *wl, off
1912} 1912}
1913 1913
1914/* Returns new offset value */ 1914/* Returns new offset value */
1915static int 1915static int
1916wapbl_write_blocks(struct wapbl *wl, off_t *offp) 1916wapbl_write_blocks(struct wapbl *wl, off_t *offp)
1917{ 1917{
1918 struct wapbl_wc_blocklist *wc = 1918 struct wapbl_wc_blocklist *wc =
1919 (struct wapbl_wc_blocklist *)wl->wl_wc_scratch; 1919 (struct wapbl_wc_blocklist *)wl->wl_wc_scratch;
1920 int blocklen = 1<<wl->wl_log_dev_bshift; 1920 int blocklen = 1<<wl->wl_log_dev_bshift;
1921 int bph; 1921 int bph;
1922 struct buf *bp; 1922 struct buf *bp;
1923 off_t off = *offp; 1923 off_t off = *offp;
1924 int error; 1924 int error;
 1925 size_t padding;
1925 1926
1926 KASSERT(rw_write_held(&wl->wl_rwlock)); 1927 KASSERT(rw_write_held(&wl->wl_rwlock));
1927 1928
1928 bph = (blocklen - offsetof(struct wapbl_wc_blocklist, wc_blocks)) / 1929 bph = (blocklen - offsetof(struct wapbl_wc_blocklist, wc_blocks)) /
1929 sizeof(((struct wapbl_wc_blocklist *)0)->wc_blocks[0]); 1930 sizeof(((struct wapbl_wc_blocklist *)0)->wc_blocks[0]);
1930 1931
1931 bp = LIST_FIRST(&wl->wl_bufs); 1932 bp = LIST_FIRST(&wl->wl_bufs);
1932 1933
1933 while (bp) { 1934 while (bp) {
1934 int cnt; 1935 int cnt;
1935 struct buf *obp = bp; 1936 struct buf *obp = bp;
1936 1937
1937 KASSERT(bp->b_flags & B_LOCKED); 1938 KASSERT(bp->b_flags & B_LOCKED);
@@ -1952,42 +1953,60 @@ wapbl_write_blocks(struct wapbl *wl, off @@ -1952,42 +1953,60 @@ wapbl_write_blocks(struct wapbl *wl, off
1952 * bwrite when the vnode lock should already be held 1953 * bwrite when the vnode lock should already be held
1953 * by the invoking code. 1954 * by the invoking code.
1954 */ 1955 */
1955 KASSERT((bp->b_vp->v_type == VBLK) || 1956 KASSERT((bp->b_vp->v_type == VBLK) ||
1956 (bp->b_blkno != bp->b_lblkno)); 1957 (bp->b_blkno != bp->b_lblkno));
1957 KASSERT(bp->b_blkno > 0); 1958 KASSERT(bp->b_blkno > 0);
1958 1959
1959 wc->wc_blocks[wc->wc_blkcount].wc_daddr = bp->b_blkno; 1960 wc->wc_blocks[wc->wc_blkcount].wc_daddr = bp->b_blkno;
1960 wc->wc_blocks[wc->wc_blkcount].wc_dlen = bp->b_bcount; 1961 wc->wc_blocks[wc->wc_blkcount].wc_dlen = bp->b_bcount;
1961 wc->wc_len += bp->b_bcount; 1962 wc->wc_len += bp->b_bcount;
1962 wc->wc_blkcount++; 1963 wc->wc_blkcount++;
1963 bp = LIST_NEXT(bp, b_wapbllist); 1964 bp = LIST_NEXT(bp, b_wapbllist);
1964 } 1965 }
 1966 if (wc->wc_len % blocklen != 0) {
 1967 printf("Padding WAPBL record...");
 1968 padding = blocklen - wc->wc_len % blocklen;
 1969 wc->wc_len += padding;
 1970 } else {
 1971 padding = 0;
 1972 }
 1973
1965 WAPBL_PRINTF(WAPBL_PRINT_WRITE, 1974 WAPBL_PRINTF(WAPBL_PRINT_WRITE,
1966 ("wapbl_write_blocks: len = %u off = %"PRIdMAX"\n", 1975 ("wapbl_write_blocks: len = %u (padding %zu) off = %"PRIdMAX"\n",
1967 wc->wc_len, (intmax_t)off)); 1976 wc->wc_len, padding, (intmax_t)off));
1968 1977
1969 error = wapbl_circ_write(wl, wc, blocklen, &off); 1978 error = wapbl_circ_write(wl, wc, blocklen, &off);
1970 if (error) 1979 if (error)
1971 return error; 1980 return error;
1972 bp = obp; 1981 bp = obp;
1973 cnt = 0; 1982 cnt = 0;
1974 while (bp && (cnt++ < bph)) { 1983 while (bp && (cnt++ < bph)) {
1975 error = wapbl_circ_write(wl, bp->b_data, 1984 error = wapbl_circ_write(wl, bp->b_data,
1976 bp->b_bcount, &off); 1985 bp->b_bcount, &off);
1977 if (error) 1986 if (error)
1978 return error; 1987 return error;
1979 bp = LIST_NEXT(bp, b_wapbllist); 1988 bp = LIST_NEXT(bp, b_wapbllist);
1980 } 1989 }
 1990 if (padding) {
 1991 void *zero;
 1992
 1993 zero = wapbl_malloc(padding);
 1994 memset(zero, 0, padding);
 1995 error = wapbl_circ_write(wl, zero, padding, &off);
 1996 wapbl_free(zero);
 1997 if (error)
 1998 return error;
 1999 }
1981 } 2000 }
1982 *offp = off; 2001 *offp = off;
1983 return 0; 2002 return 0;
1984} 2003}
1985 2004
1986static int 2005static int
1987wapbl_write_revocations(struct wapbl *wl, off_t *offp) 2006wapbl_write_revocations(struct wapbl *wl, off_t *offp)
1988{ 2007{
1989 struct wapbl_wc_blocklist *wc = 2008 struct wapbl_wc_blocklist *wc =
1990 (struct wapbl_wc_blocklist *)wl->wl_wc_scratch; 2009 (struct wapbl_wc_blocklist *)wl->wl_wc_scratch;
1991 int i; 2010 int i;
1992 int blocklen = 1<<wl->wl_log_dev_bshift; 2011 int blocklen = 1<<wl->wl_log_dev_bshift;
1993 int bph; 2012 int bph;

cvs diff -r1.6 -r1.7 src/sys/sys/wapbl.h (expand / switch to unified diff)

--- src/sys/sys/wapbl.h 2008/11/15 10:04:31 1.6
+++ src/sys/sys/wapbl.h 2008/11/17 19:31:47 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: wapbl.h,v 1.6 2008/11/15 10:04:31 joerg Exp $ */ 1/* $NetBSD: wapbl.h,v 1.7 2008/11/17 19:31:47 joerg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003,2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003,2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc. 8 * by Wasabi Systems, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -87,29 +87,26 @@ extern int wapbl_debug_print; @@ -87,29 +87,26 @@ extern int wapbl_debug_print;
87 *  87 *
88 * The journal consists of a header followed by a circular buffer 88 * The journal consists of a header followed by a circular buffer
89 * region. The circular data area is described by the header 89 * region. The circular data area is described by the header
90 * wc_circ_off, wc_circ_size, wc_head and wc_tail fields as bytes 90 * wc_circ_off, wc_circ_size, wc_head and wc_tail fields as bytes
91 * from the start of the journal header. New records are inserted 91 * from the start of the journal header. New records are inserted
92 * at wc_head and the oldest valid record can be found at wc_tail. 92 * at wc_head and the oldest valid record can be found at wc_tail.
93 * When ((wc_head == wc_tail) && (wc_head == 0)), the journal is empty. 93 * When ((wc_head == wc_tail) && (wc_head == 0)), the journal is empty.
94 * The condition of ((wc_head == wc_tail) && (wc_head != 0)) 94 * The condition of ((wc_head == wc_tail) && (wc_head != 0))
95 * indicates a full journal, although this condition is rare. 95 * indicates a full journal, although this condition is rare.
96 * 96 *
97 * The journal header as well as its records are marked by a 32bit 97 * The journal header as well as its records are marked by a 32bit
98 * type tag and length for ease of parsing. Journal records are 98 * type tag and length for ease of parsing. Journal records are
99 * padded so as to fall on journal device block boundaries. 99 * padded so as to fall on journal device block boundaries.
100 * (XXX i think there is currently a bug wrt WC_BLOCKS not ending 
101 * correctly on a journal device block boundary. this would need 
102 * to be fixed if the journal blocksize does not match filesystem.) 
103 */ 100 */
104 101
105/* 102/*
106 * The following are the 4 record types used by the journal: 103 * The following are the 4 record types used by the journal:
107 * Each tag indicates journal data organized by one of the 104 * Each tag indicates journal data organized by one of the
108 * structures used below. 105 * structures used below.
109 */ 106 */
110enum { 107enum {
111 WAPBL_WC_HEADER = 0x5741424c, /* "WABL", struct wapbl_wc_header */ 108 WAPBL_WC_HEADER = 0x5741424c, /* "WABL", struct wapbl_wc_header */
112 WAPBL_WC_INODES, /* struct wapbl_wc_inodelist */ 109 WAPBL_WC_INODES, /* struct wapbl_wc_inodelist */
113 WAPBL_WC_REVOCATIONS, /* struct wapbl_wc_blocklist */ 110 WAPBL_WC_REVOCATIONS, /* struct wapbl_wc_blocklist */
114 WAPBL_WC_BLOCKS, /* struct wapbl_wc_blocklist */ 111 WAPBL_WC_BLOCKS, /* struct wapbl_wc_blocklist */
115}; 112};