| @@ -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 */ |
1915 | static int | | 1915 | static int |
1916 | wapbl_write_blocks(struct wapbl *wl, off_t *offp) | | 1916 | wapbl_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 | |
1986 | static int | | 2005 | static int |
1987 | wapbl_write_revocations(struct wapbl *wl, off_t *offp) | | 2006 | wapbl_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; |