| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: vfs_wapbl.c,v 1.47 2011/09/01 09:03:43 christos Exp $ */ | | 1 | /* $NetBSD: vfs_wapbl.c,v 1.48 2011/12/02 12:38:59 yamt Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2003, 2008, 2009 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2003, 2008, 2009 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.47 2011/09/01 09:03:43 christos Exp $"); | | 39 | __KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.48 2011/12/02 12:38:59 yamt Exp $"); |
40 | | | 40 | |
41 | #include <sys/param.h> | | 41 | #include <sys/param.h> |
42 | #include <sys/bitops.h> | | 42 | #include <sys/bitops.h> |
43 | | | 43 | |
44 | #ifdef _KERNEL | | 44 | #ifdef _KERNEL |
45 | #include <sys/param.h> | | 45 | #include <sys/param.h> |
46 | #include <sys/namei.h> | | 46 | #include <sys/namei.h> |
47 | #include <sys/proc.h> | | 47 | #include <sys/proc.h> |
48 | #include <sys/sysctl.h> | | 48 | #include <sys/sysctl.h> |
49 | #include <sys/uio.h> | | 49 | #include <sys/uio.h> |
50 | #include <sys/vnode.h> | | 50 | #include <sys/vnode.h> |
51 | #include <sys/file.h> | | 51 | #include <sys/file.h> |
52 | #include <sys/malloc.h> | | 52 | #include <sys/malloc.h> |
| @@ -1893,87 +1893,108 @@ wapbl_transaction_len(struct wapbl *wl) | | | @@ -1893,87 +1893,108 @@ wapbl_transaction_len(struct wapbl *wl) |
1893 | sizeof(((struct wapbl_wc_blocklist *)0)->wc_blocks[0]); | | 1893 | sizeof(((struct wapbl_wc_blocklist *)0)->wc_blocks[0]); |
1894 | | | 1894 | |
1895 | KASSERT(bph > 0); | | 1895 | KASSERT(bph > 0); |
1896 | | | 1896 | |
1897 | len = wl->wl_bcount; | | 1897 | len = wl->wl_bcount; |
1898 | len += howmany(wl->wl_bufcount, bph) * blocklen; | | 1898 | len += howmany(wl->wl_bufcount, bph) * blocklen; |
1899 | len += howmany(wl->wl_dealloccnt, bph) * blocklen; | | 1899 | len += howmany(wl->wl_dealloccnt, bph) * blocklen; |
1900 | len += wapbl_transaction_inodes_len(wl); | | 1900 | len += wapbl_transaction_inodes_len(wl); |
1901 | | | 1901 | |
1902 | return len; | | 1902 | return len; |
1903 | } | | 1903 | } |
1904 | | | 1904 | |
1905 | /* | | 1905 | /* |
| | | 1906 | * wapbl_cache_sync: issue DIOCCACHESYNC |
| | | 1907 | */ |
| | | 1908 | static int |
| | | 1909 | wapbl_cache_sync(struct wapbl *wl, const char *msg) |
| | | 1910 | { |
| | | 1911 | const bool verbose = wapbl_verbose_commit >= 2; |
| | | 1912 | struct bintime start_time; |
| | | 1913 | int force = 1; |
| | | 1914 | int error; |
| | | 1915 | |
| | | 1916 | if (!wapbl_flush_disk_cache) { |
| | | 1917 | return 0; |
| | | 1918 | } |
| | | 1919 | if (verbose) { |
| | | 1920 | bintime(&start_time); |
| | | 1921 | } |
| | | 1922 | error = VOP_IOCTL(wl->wl_devvp, DIOCCACHESYNC, &force, |
| | | 1923 | FWRITE, FSCRED); |
| | | 1924 | if (error) { |
| | | 1925 | WAPBL_PRINTF(WAPBL_PRINT_ERROR, |
| | | 1926 | ("wapbl_cache_sync: DIOCCACHESYNC on dev 0x%x " |
| | | 1927 | "returned %d\n", wl->wl_devvp->v_rdev, error)); |
| | | 1928 | } |
| | | 1929 | if (verbose) { |
| | | 1930 | struct bintime d; |
| | | 1931 | struct timespec ts; |
| | | 1932 | |
| | | 1933 | bintime(&d); |
| | | 1934 | bintime_sub(&d, &start_time); |
| | | 1935 | bintime2timespec(&d, &ts); |
| | | 1936 | printf("wapbl_cache_sync: %s: dev 0x%jx %ju.%09lu\n", |
| | | 1937 | msg, (uintmax_t)wl->wl_devvp->v_rdev, |
| | | 1938 | (uintmax_t)ts.tv_sec, ts.tv_nsec); |
| | | 1939 | } |
| | | 1940 | return error; |
| | | 1941 | } |
| | | 1942 | |
| | | 1943 | /* |
1906 | * Perform commit operation | | 1944 | * Perform commit operation |
1907 | * | | 1945 | * |
1908 | * Note that generation number incrementation needs to | | 1946 | * Note that generation number incrementation needs to |
1909 | * be protected against racing with other invocations | | 1947 | * be protected against racing with other invocations |
1910 | * of wapbl_commit. This is ok since this routine | | 1948 | * of wapbl_write_commit. This is ok since this routine |
1911 | * is only invoked from wapbl_flush | | 1949 | * is only invoked from wapbl_flush |
1912 | */ | | 1950 | */ |
1913 | static int | | 1951 | static int |
1914 | wapbl_write_commit(struct wapbl *wl, off_t head, off_t tail) | | 1952 | wapbl_write_commit(struct wapbl *wl, off_t head, off_t tail) |
1915 | { | | 1953 | { |
1916 | struct wapbl_wc_header *wc = wl->wl_wc_header; | | 1954 | struct wapbl_wc_header *wc = wl->wl_wc_header; |
1917 | struct timespec ts; | | 1955 | struct timespec ts; |
1918 | int error; | | 1956 | int error; |
1919 | int force = 1; | | | |
1920 | daddr_t pbn; | | 1957 | daddr_t pbn; |
1921 | | | 1958 | |
1922 | if (wapbl_flush_disk_cache) { | | 1959 | /* XXX Calc checksum here, instead we do this for now */ |
1923 | /* XXX Calc checksum here, instead we do this for now */ | | 1960 | wapbl_cache_sync(wl, "1"); |
1924 | error = VOP_IOCTL(wl->wl_devvp, DIOCCACHESYNC, &force, | | | |
1925 | FWRITE, FSCRED); | | | |
1926 | if (error) { | | | |
1927 | WAPBL_PRINTF(WAPBL_PRINT_ERROR, | | | |
1928 | ("wapbl_write_commit: DIOCCACHESYNC on dev 0x%x " | | | |
1929 | "returned %d\n", wl->wl_devvp->v_rdev, error)); | | | |
1930 | } | | | |
1931 | } | | | |
1932 | | | 1961 | |
1933 | wc->wc_head = head; | | 1962 | wc->wc_head = head; |
1934 | wc->wc_tail = tail; | | 1963 | wc->wc_tail = tail; |
1935 | wc->wc_checksum = 0; | | 1964 | wc->wc_checksum = 0; |
1936 | wc->wc_version = 1; | | 1965 | wc->wc_version = 1; |
1937 | getnanotime(&ts); | | 1966 | getnanotime(&ts); |
1938 | wc->wc_time = ts.tv_sec; | | 1967 | wc->wc_time = ts.tv_sec; |
1939 | wc->wc_timensec = ts.tv_nsec; | | 1968 | wc->wc_timensec = ts.tv_nsec; |
1940 | | | 1969 | |
1941 | WAPBL_PRINTF(WAPBL_PRINT_WRITE, | | 1970 | WAPBL_PRINTF(WAPBL_PRINT_WRITE, |
1942 | ("wapbl_write_commit: head = %"PRIdMAX "tail = %"PRIdMAX"\n", | | 1971 | ("wapbl_write_commit: head = %"PRIdMAX "tail = %"PRIdMAX"\n", |
1943 | (intmax_t)head, (intmax_t)tail)); | | 1972 | (intmax_t)head, (intmax_t)tail)); |
1944 | | | 1973 | |
1945 | /* | | 1974 | /* |
1946 | * XXX if generation will rollover, then first zero | | 1975 | * XXX if generation will rollover, then first zero |
1947 | * over second commit header before trying to write both headers. | | 1976 | * over second commit header before trying to write both headers. |
1948 | */ | | 1977 | */ |
1949 | | | 1978 | |
1950 | pbn = wl->wl_logpbn + (wc->wc_generation % 2); | | 1979 | pbn = wl->wl_logpbn + (wc->wc_generation % 2); |
1951 | #ifdef _KERNEL | | 1980 | #ifdef _KERNEL |
1952 | pbn = btodb(pbn << wc->wc_log_dev_bshift); | | 1981 | pbn = btodb(pbn << wc->wc_log_dev_bshift); |
1953 | #endif | | 1982 | #endif |
1954 | error = wapbl_write(wc, wc->wc_len, wl->wl_devvp, pbn); | | 1983 | error = wapbl_write(wc, wc->wc_len, wl->wl_devvp, pbn); |
1955 | if (error) | | 1984 | if (error) |
1956 | return error; | | 1985 | return error; |
1957 | | | 1986 | |
1958 | if (wapbl_flush_disk_cache) { | | 1987 | wapbl_cache_sync(wl, "2"); |
1959 | error = VOP_IOCTL(wl->wl_devvp, DIOCCACHESYNC, &force, | | | |
1960 | FWRITE, FSCRED); | | | |
1961 | if (error) { | | | |
1962 | WAPBL_PRINTF(WAPBL_PRINT_ERROR, | | | |
1963 | ("wapbl_write_commit: DIOCCACHESYNC on dev 0x%x " | | | |
1964 | "returned %d\n", wl->wl_devvp->v_rdev, error)); | | | |
1965 | } | | | |
1966 | } | | | |
1967 | | | 1988 | |
1968 | /* | | 1989 | /* |
1969 | * If the generation number was zero, write it out a second time. | | 1990 | * If the generation number was zero, write it out a second time. |
1970 | * This handles initialization and generation number rollover | | 1991 | * This handles initialization and generation number rollover |
1971 | */ | | 1992 | */ |
1972 | if (wc->wc_generation++ == 0) { | | 1993 | if (wc->wc_generation++ == 0) { |
1973 | error = wapbl_write_commit(wl, head, tail); | | 1994 | error = wapbl_write_commit(wl, head, tail); |
1974 | /* | | 1995 | /* |
1975 | * This panic should be able to be removed if we do the | | 1996 | * This panic should be able to be removed if we do the |
1976 | * zero'ing mentioned above, and we are certain to roll | | 1997 | * zero'ing mentioned above, and we are certain to roll |
1977 | * back generation number on failure. | | 1998 | * back generation number on failure. |
1978 | */ | | 1999 | */ |
1979 | if (error) | | 2000 | if (error) |