aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_recover.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-03 01:11:29 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 14:01:06 -0400
commitd75afeb3d302019527331520a2632b6614425b40 (patch)
tree181dec415cdae00398086764a6229d115114354d /fs/xfs/xfs_log_recover.c
parentd2e448d5fdebdcda93ed171339a3d864f65c227e (diff)
xfs: add buffer types to directory and attribute buffers
Add buffer types to the buffer log items so that log recovery can validate the buffers and calculate CRCs correctly after the buffers are recovered. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r--fs/xfs/xfs_log_recover.c254
1 files changed, 180 insertions, 74 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index d1292fd1112a..00727bc4a9b0 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -45,7 +45,14 @@
45#include "xfs_cksum.h" 45#include "xfs_cksum.h"
46#include "xfs_trace.h" 46#include "xfs_trace.h"
47#include "xfs_icache.h" 47#include "xfs_icache.h"
48
49/* Need all the magic numbers and buffer ops structures from these headers */
48#include "xfs_symlink.h" 50#include "xfs_symlink.h"
51#include "xfs_da_btree.h"
52#include "xfs_dir2_format.h"
53#include "xfs_dir2_priv.h"
54#include "xfs_attr_leaf.h"
55#include "xfs_attr_remote.h"
49 56
50STATIC int 57STATIC int
51xlog_find_zeroed( 58xlog_find_zeroed(
@@ -1860,81 +1867,30 @@ xlog_recover_do_inode_buffer(
1860} 1867}
1861 1868
1862/* 1869/*
1863 * Perform a 'normal' buffer recovery. Each logged region of the 1870 * Validate the recovered buffer is of the correct type and attach the
1864 * buffer should be copied over the corresponding region in the 1871 * appropriate buffer operations to them for writeback. Magic numbers are in a
1865 * given buffer. The bitmap in the buf log format structure indicates 1872 * few places:
1866 * where to place the logged data. 1873 * the first 16 bits of the buffer (inode buffer, dquot buffer),
1874 * the first 32 bits of the buffer (most blocks),
1875 * inside a struct xfs_da_blkinfo at the start of the buffer.
1867 */ 1876 */
1868STATIC void 1877static void
1869xlog_recover_do_reg_buffer( 1878xlog_recovery_validate_buf_type(
1870 struct xfs_mount *mp, 1879 struct xfs_mount *mp,
1871 xlog_recover_item_t *item,
1872 struct xfs_buf *bp, 1880 struct xfs_buf *bp,
1873 xfs_buf_log_format_t *buf_f) 1881 xfs_buf_log_format_t *buf_f)
1874{ 1882{
1875 int i; 1883 struct xfs_da_blkinfo *info = bp->b_addr;
1876 int bit; 1884 __uint32_t magic32;
1877 int nbits; 1885 __uint16_t magic16;
1878 int error; 1886 __uint16_t magicda;
1879 1887
1880 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f); 1888 magic32 = be32_to_cpu(*(__be32 *)bp->b_addr);
1881 1889 magic16 = be16_to_cpu(*(__be16*)bp->b_addr);
1882 bit = 0; 1890 magicda = be16_to_cpu(info->magic);
1883 i = 1; /* 0 is the buf format structure */
1884 while (1) {
1885 bit = xfs_next_bit(buf_f->blf_data_map,
1886 buf_f->blf_map_size, bit);
1887 if (bit == -1)
1888 break;
1889 nbits = xfs_contig_bits(buf_f->blf_data_map,
1890 buf_f->blf_map_size, bit);
1891 ASSERT(nbits > 0);
1892 ASSERT(item->ri_buf[i].i_addr != NULL);
1893 ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
1894 ASSERT(BBTOB(bp->b_io_length) >=
1895 ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
1896
1897 /*
1898 * Do a sanity check if this is a dquot buffer. Just checking
1899 * the first dquot in the buffer should do. XXXThis is
1900 * probably a good thing to do for other buf types also.
1901 */
1902 error = 0;
1903 if (buf_f->blf_flags &
1904 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
1905 if (item->ri_buf[i].i_addr == NULL) {
1906 xfs_alert(mp,
1907 "XFS: NULL dquot in %s.", __func__);
1908 goto next;
1909 }
1910 if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
1911 xfs_alert(mp,
1912 "XFS: dquot too small (%d) in %s.",
1913 item->ri_buf[i].i_len, __func__);
1914 goto next;
1915 }
1916 error = xfs_qm_dqcheck(mp, item->ri_buf[i].i_addr,
1917 -1, 0, XFS_QMOPT_DOWARN,
1918 "dquot_buf_recover");
1919 if (error)
1920 goto next;
1921 }
1922
1923 memcpy(xfs_buf_offset(bp,
1924 (uint)bit << XFS_BLF_SHIFT), /* dest */
1925 item->ri_buf[i].i_addr, /* source */
1926 nbits<<XFS_BLF_SHIFT); /* length */
1927 next:
1928 i++;
1929 bit += nbits;
1930 }
1931
1932 /* Shouldn't be any more regions */
1933 ASSERT(i == item->ri_total);
1934
1935 switch (buf_f->blf_flags & XFS_BLF_TYPE_MASK) { 1891 switch (buf_f->blf_flags & XFS_BLF_TYPE_MASK) {
1936 case XFS_BLF_BTREE_BUF: 1892 case XFS_BLF_BTREE_BUF:
1937 switch (be32_to_cpu(*(__be32 *)bp->b_addr)) { 1893 switch (magic32) {
1938 case XFS_ABTB_CRC_MAGIC: 1894 case XFS_ABTB_CRC_MAGIC:
1939 case XFS_ABTC_CRC_MAGIC: 1895 case XFS_ABTC_CRC_MAGIC:
1940 case XFS_ABTB_MAGIC: 1896 case XFS_ABTB_MAGIC:
@@ -1956,7 +1912,7 @@ xlog_recover_do_reg_buffer(
1956 } 1912 }
1957 break; 1913 break;
1958 case XFS_BLF_AGF_BUF: 1914 case XFS_BLF_AGF_BUF:
1959 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGF_MAGIC)) { 1915 if (magic32 != XFS_AGF_MAGIC) {
1960 xfs_warn(mp, "Bad AGF block magic!"); 1916 xfs_warn(mp, "Bad AGF block magic!");
1961 ASSERT(0); 1917 ASSERT(0);
1962 break; 1918 break;
@@ -1966,7 +1922,7 @@ xlog_recover_do_reg_buffer(
1966 case XFS_BLF_AGFL_BUF: 1922 case XFS_BLF_AGFL_BUF:
1967 if (!xfs_sb_version_hascrc(&mp->m_sb)) 1923 if (!xfs_sb_version_hascrc(&mp->m_sb))
1968 break; 1924 break;
1969 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGFL_MAGIC)) { 1925 if (magic32 != XFS_AGFL_MAGIC) {
1970 xfs_warn(mp, "Bad AGFL block magic!"); 1926 xfs_warn(mp, "Bad AGFL block magic!");
1971 ASSERT(0); 1927 ASSERT(0);
1972 break; 1928 break;
@@ -1974,7 +1930,7 @@ xlog_recover_do_reg_buffer(
1974 bp->b_ops = &xfs_agfl_buf_ops; 1930 bp->b_ops = &xfs_agfl_buf_ops;
1975 break; 1931 break;
1976 case XFS_BLF_AGI_BUF: 1932 case XFS_BLF_AGI_BUF:
1977 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_AGI_MAGIC)) { 1933 if (magic32 != XFS_AGI_MAGIC) {
1978 xfs_warn(mp, "Bad AGI block magic!"); 1934 xfs_warn(mp, "Bad AGI block magic!");
1979 ASSERT(0); 1935 ASSERT(0);
1980 break; 1936 break;
@@ -1984,7 +1940,7 @@ xlog_recover_do_reg_buffer(
1984 case XFS_BLF_UDQUOT_BUF: 1940 case XFS_BLF_UDQUOT_BUF:
1985 case XFS_BLF_PDQUOT_BUF: 1941 case XFS_BLF_PDQUOT_BUF:
1986 case XFS_BLF_GDQUOT_BUF: 1942 case XFS_BLF_GDQUOT_BUF:
1987 if (*(__be16 *)bp->b_addr != cpu_to_be16(XFS_DQUOT_MAGIC)) { 1943 if (magic16 != XFS_DQUOT_MAGIC) {
1988 xfs_warn(mp, "Bad DQUOT block magic!"); 1944 xfs_warn(mp, "Bad DQUOT block magic!");
1989 ASSERT(0); 1945 ASSERT(0);
1990 break; 1946 break;
@@ -1996,7 +1952,7 @@ xlog_recover_do_reg_buffer(
1996 * we get here with inode allocation buffers, not buffers that 1952 * we get here with inode allocation buffers, not buffers that
1997 * track unlinked list changes. 1953 * track unlinked list changes.
1998 */ 1954 */
1999 if (*(__be16 *)bp->b_addr != cpu_to_be16(XFS_DINODE_MAGIC)) { 1955 if (magic16 != XFS_DINODE_MAGIC) {
2000 xfs_warn(mp, "Bad INODE block magic!"); 1956 xfs_warn(mp, "Bad INODE block magic!");
2001 ASSERT(0); 1957 ASSERT(0);
2002 break; 1958 break;
@@ -2004,19 +1960,169 @@ xlog_recover_do_reg_buffer(
2004 bp->b_ops = &xfs_inode_buf_ops; 1960 bp->b_ops = &xfs_inode_buf_ops;
2005 break; 1961 break;
2006 case XFS_BLF_SYMLINK_BUF: 1962 case XFS_BLF_SYMLINK_BUF:
2007 if (*(__be32 *)bp->b_addr != cpu_to_be32(XFS_SYMLINK_MAGIC)) { 1963 if (magic32 != XFS_SYMLINK_MAGIC) {
2008 xfs_warn(mp, "Bad symlink block magic!"); 1964 xfs_warn(mp, "Bad symlink block magic!");
2009 ASSERT(0); 1965 ASSERT(0);
2010 break; 1966 break;
2011 } 1967 }
2012 bp->b_ops = &xfs_symlink_buf_ops; 1968 bp->b_ops = &xfs_symlink_buf_ops;
2013 break; 1969 break;
1970 case XFS_BLF_DIR_BLOCK_BUF:
1971 if (magic32 != XFS_DIR2_BLOCK_MAGIC &&
1972 magic32 != XFS_DIR3_BLOCK_MAGIC) {
1973 xfs_warn(mp, "Bad dir block magic!");
1974 ASSERT(0);
1975 break;
1976 }
1977 bp->b_ops = &xfs_dir3_block_buf_ops;
1978 break;
1979 case XFS_BLF_DIR_DATA_BUF:
1980 if (magic32 != XFS_DIR2_DATA_MAGIC &&
1981 magic32 != XFS_DIR3_DATA_MAGIC) {
1982 xfs_warn(mp, "Bad dir data magic!");
1983 ASSERT(0);
1984 break;
1985 }
1986 bp->b_ops = &xfs_dir3_data_buf_ops;
1987 break;
1988 case XFS_BLF_DIR_FREE_BUF:
1989 if (magic32 != XFS_DIR2_FREE_MAGIC &&
1990 magic32 != XFS_DIR3_FREE_MAGIC) {
1991 xfs_warn(mp, "Bad dir3 free magic!");
1992 ASSERT(0);
1993 break;
1994 }
1995 bp->b_ops = &xfs_dir3_free_buf_ops;
1996 break;
1997 case XFS_BLF_DIR_LEAF1_BUF:
1998 if (magicda != XFS_DIR2_LEAF1_MAGIC &&
1999 magicda != XFS_DIR3_LEAF1_MAGIC) {
2000 xfs_warn(mp, "Bad dir leaf1 magic!");
2001 ASSERT(0);
2002 break;
2003 }
2004 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
2005 break;
2006 case XFS_BLF_DIR_LEAFN_BUF:
2007 if (magicda != XFS_DIR2_LEAFN_MAGIC &&
2008 magicda != XFS_DIR3_LEAFN_MAGIC) {
2009 xfs_warn(mp, "Bad dir leafn magic!");
2010 ASSERT(0);
2011 break;
2012 }
2013 bp->b_ops = &xfs_dir3_leafn_buf_ops;
2014 break;
2015 case XFS_BLF_DA_NODE_BUF:
2016 if (magicda != XFS_DA_NODE_MAGIC &&
2017 magicda != XFS_DA3_NODE_MAGIC) {
2018 xfs_warn(mp, "Bad da node magic!");
2019 ASSERT(0);
2020 break;
2021 }
2022 bp->b_ops = &xfs_da3_node_buf_ops;
2023 break;
2024 case XFS_BLF_ATTR_LEAF_BUF:
2025 if (magicda != XFS_ATTR_LEAF_MAGIC &&
2026 magicda != XFS_ATTR3_LEAF_MAGIC) {
2027 xfs_warn(mp, "Bad attr leaf magic!");
2028 ASSERT(0);
2029 break;
2030 }
2031 bp->b_ops = &xfs_attr3_leaf_buf_ops;
2032 break;
2033 case XFS_BLF_ATTR_RMT_BUF:
2034 if (!xfs_sb_version_hascrc(&mp->m_sb))
2035 break;
2036 if (magicda != XFS_ATTR3_RMT_MAGIC) {
2037 xfs_warn(mp, "Bad attr remote magic!");
2038 ASSERT(0);
2039 break;
2040 }
2041 bp->b_ops = &xfs_attr3_rmt_buf_ops;
2042 break;
2014 default: 2043 default:
2015 break; 2044 break;
2016 } 2045 }
2017} 2046}
2018 2047
2019/* 2048/*
2049 * Perform a 'normal' buffer recovery. Each logged region of the
2050 * buffer should be copied over the corresponding region in the
2051 * given buffer. The bitmap in the buf log format structure indicates
2052 * where to place the logged data.
2053 */
2054STATIC void
2055xlog_recover_do_reg_buffer(
2056 struct xfs_mount *mp,
2057 xlog_recover_item_t *item,
2058 struct xfs_buf *bp,
2059 xfs_buf_log_format_t *buf_f)
2060{
2061 int i;
2062 int bit;
2063 int nbits;
2064 int error;
2065
2066 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f);
2067
2068 bit = 0;
2069 i = 1; /* 0 is the buf format structure */
2070 while (1) {
2071 bit = xfs_next_bit(buf_f->blf_data_map,
2072 buf_f->blf_map_size, bit);
2073 if (bit == -1)
2074 break;
2075 nbits = xfs_contig_bits(buf_f->blf_data_map,
2076 buf_f->blf_map_size, bit);
2077 ASSERT(nbits > 0);
2078 ASSERT(item->ri_buf[i].i_addr != NULL);
2079 ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
2080 ASSERT(BBTOB(bp->b_io_length) >=
2081 ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
2082
2083 /*
2084 * Do a sanity check if this is a dquot buffer. Just checking
2085 * the first dquot in the buffer should do. XXXThis is
2086 * probably a good thing to do for other buf types also.
2087 */
2088 error = 0;
2089 if (buf_f->blf_flags &
2090 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
2091 if (item->ri_buf[i].i_addr == NULL) {
2092 xfs_alert(mp,
2093 "XFS: NULL dquot in %s.", __func__);
2094 goto next;
2095 }
2096 if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
2097 xfs_alert(mp,
2098 "XFS: dquot too small (%d) in %s.",
2099 item->ri_buf[i].i_len, __func__);
2100 goto next;
2101 }
2102 error = xfs_qm_dqcheck(mp, item->ri_buf[i].i_addr,
2103 -1, 0, XFS_QMOPT_DOWARN,
2104 "dquot_buf_recover");
2105 if (error)
2106 goto next;
2107 }
2108
2109 memcpy(xfs_buf_offset(bp,
2110 (uint)bit << XFS_BLF_SHIFT), /* dest */
2111 item->ri_buf[i].i_addr, /* source */
2112 nbits<<XFS_BLF_SHIFT); /* length */
2113 next:
2114 i++;
2115 bit += nbits;
2116 }
2117
2118 /* Shouldn't be any more regions */
2119 ASSERT(i == item->ri_total);
2120
2121 xlog_recovery_validate_buf_type(mp, bp, buf_f);
2122
2123}
2124
2125/*
2020 * Do some primitive error checking on ondisk dquot data structures. 2126 * Do some primitive error checking on ondisk dquot data structures.
2021 */ 2127 */
2022int 2128int