aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_recover.c
diff options
context:
space:
mode:
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