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.c246
1 files changed, 239 insertions, 7 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index d1dba7ce75ae..93f03ec17eec 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -29,6 +29,7 @@
29#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
30#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
31#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
32#include "xfs_btree.h"
32#include "xfs_dinode.h" 33#include "xfs_dinode.h"
33#include "xfs_inode.h" 34#include "xfs_inode.h"
34#include "xfs_inode_item.h" 35#include "xfs_inode_item.h"
@@ -45,6 +46,14 @@
45#include "xfs_trace.h" 46#include "xfs_trace.h"
46#include "xfs_icache.h" 47#include "xfs_icache.h"
47 48
49/* Need all the magic numbers and buffer ops structures from these headers */
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"
56
48STATIC int 57STATIC int
49xlog_find_zeroed( 58xlog_find_zeroed(
50 struct xlog *, 59 struct xlog *,
@@ -1785,6 +1794,7 @@ xlog_recover_do_inode_buffer(
1785 xfs_agino_t *buffer_nextp; 1794 xfs_agino_t *buffer_nextp;
1786 1795
1787 trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); 1796 trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
1797 bp->b_ops = &xfs_inode_buf_ops;
1788 1798
1789 inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog; 1799 inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog;
1790 for (i = 0; i < inodes_per_buf; i++) { 1800 for (i = 0; i < inodes_per_buf; i++) {
@@ -1857,6 +1867,201 @@ xlog_recover_do_inode_buffer(
1857} 1867}
1858 1868
1859/* 1869/*
1870 * Validate the recovered buffer is of the correct type and attach the
1871 * appropriate buffer operations to them for writeback. Magic numbers are in a
1872 * few places:
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.
1876 */
1877static void
1878xlog_recovery_validate_buf_type(
1879 struct xfs_mount *mp,
1880 struct xfs_buf *bp,
1881 xfs_buf_log_format_t *buf_f)
1882{
1883 struct xfs_da_blkinfo *info = bp->b_addr;
1884 __uint32_t magic32;
1885 __uint16_t magic16;
1886 __uint16_t magicda;
1887
1888 magic32 = be32_to_cpu(*(__be32 *)bp->b_addr);
1889 magic16 = be16_to_cpu(*(__be16*)bp->b_addr);
1890 magicda = be16_to_cpu(info->magic);
1891 switch (xfs_blft_from_flags(buf_f)) {
1892 case XFS_BLFT_BTREE_BUF:
1893 switch (magic32) {
1894 case XFS_ABTB_CRC_MAGIC:
1895 case XFS_ABTC_CRC_MAGIC:
1896 case XFS_ABTB_MAGIC:
1897 case XFS_ABTC_MAGIC:
1898 bp->b_ops = &xfs_allocbt_buf_ops;
1899 break;
1900 case XFS_IBT_CRC_MAGIC:
1901 case XFS_IBT_MAGIC:
1902 bp->b_ops = &xfs_inobt_buf_ops;
1903 break;
1904 case XFS_BMAP_CRC_MAGIC:
1905 case XFS_BMAP_MAGIC:
1906 bp->b_ops = &xfs_bmbt_buf_ops;
1907 break;
1908 default:
1909 xfs_warn(mp, "Bad btree block magic!");
1910 ASSERT(0);
1911 break;
1912 }
1913 break;
1914 case XFS_BLFT_AGF_BUF:
1915 if (magic32 != XFS_AGF_MAGIC) {
1916 xfs_warn(mp, "Bad AGF block magic!");
1917 ASSERT(0);
1918 break;
1919 }
1920 bp->b_ops = &xfs_agf_buf_ops;
1921 break;
1922 case XFS_BLFT_AGFL_BUF:
1923 if (!xfs_sb_version_hascrc(&mp->m_sb))
1924 break;
1925 if (magic32 != XFS_AGFL_MAGIC) {
1926 xfs_warn(mp, "Bad AGFL block magic!");
1927 ASSERT(0);
1928 break;
1929 }
1930 bp->b_ops = &xfs_agfl_buf_ops;
1931 break;
1932 case XFS_BLFT_AGI_BUF:
1933 if (magic32 != XFS_AGI_MAGIC) {
1934 xfs_warn(mp, "Bad AGI block magic!");
1935 ASSERT(0);
1936 break;
1937 }
1938 bp->b_ops = &xfs_agi_buf_ops;
1939 break;
1940 case XFS_BLFT_UDQUOT_BUF:
1941 case XFS_BLFT_PDQUOT_BUF:
1942 case XFS_BLFT_GDQUOT_BUF:
1943#ifdef CONFIG_XFS_QUOTA
1944 if (magic16 != XFS_DQUOT_MAGIC) {
1945 xfs_warn(mp, "Bad DQUOT block magic!");
1946 ASSERT(0);
1947 break;
1948 }
1949 bp->b_ops = &xfs_dquot_buf_ops;
1950#else
1951 xfs_alert(mp,
1952 "Trying to recover dquots without QUOTA support built in!");
1953 ASSERT(0);
1954#endif
1955 break;
1956 case XFS_BLFT_DINO_BUF:
1957 /*
1958 * we get here with inode allocation buffers, not buffers that
1959 * track unlinked list changes.
1960 */
1961 if (magic16 != XFS_DINODE_MAGIC) {
1962 xfs_warn(mp, "Bad INODE block magic!");
1963 ASSERT(0);
1964 break;
1965 }
1966 bp->b_ops = &xfs_inode_buf_ops;
1967 break;
1968 case XFS_BLFT_SYMLINK_BUF:
1969 if (magic32 != XFS_SYMLINK_MAGIC) {
1970 xfs_warn(mp, "Bad symlink block magic!");
1971 ASSERT(0);
1972 break;
1973 }
1974 bp->b_ops = &xfs_symlink_buf_ops;
1975 break;
1976 case XFS_BLFT_DIR_BLOCK_BUF:
1977 if (magic32 != XFS_DIR2_BLOCK_MAGIC &&
1978 magic32 != XFS_DIR3_BLOCK_MAGIC) {
1979 xfs_warn(mp, "Bad dir block magic!");
1980 ASSERT(0);
1981 break;
1982 }
1983 bp->b_ops = &xfs_dir3_block_buf_ops;
1984 break;
1985 case XFS_BLFT_DIR_DATA_BUF:
1986 if (magic32 != XFS_DIR2_DATA_MAGIC &&
1987 magic32 != XFS_DIR3_DATA_MAGIC) {
1988 xfs_warn(mp, "Bad dir data magic!");
1989 ASSERT(0);
1990 break;
1991 }
1992 bp->b_ops = &xfs_dir3_data_buf_ops;
1993 break;
1994 case XFS_BLFT_DIR_FREE_BUF:
1995 if (magic32 != XFS_DIR2_FREE_MAGIC &&
1996 magic32 != XFS_DIR3_FREE_MAGIC) {
1997 xfs_warn(mp, "Bad dir3 free magic!");
1998 ASSERT(0);
1999 break;
2000 }
2001 bp->b_ops = &xfs_dir3_free_buf_ops;
2002 break;
2003 case XFS_BLFT_DIR_LEAF1_BUF:
2004 if (magicda != XFS_DIR2_LEAF1_MAGIC &&
2005 magicda != XFS_DIR3_LEAF1_MAGIC) {
2006 xfs_warn(mp, "Bad dir leaf1 magic!");
2007 ASSERT(0);
2008 break;
2009 }
2010 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
2011 break;
2012 case XFS_BLFT_DIR_LEAFN_BUF:
2013 if (magicda != XFS_DIR2_LEAFN_MAGIC &&
2014 magicda != XFS_DIR3_LEAFN_MAGIC) {
2015 xfs_warn(mp, "Bad dir leafn magic!");
2016 ASSERT(0);
2017 break;
2018 }
2019 bp->b_ops = &xfs_dir3_leafn_buf_ops;
2020 break;
2021 case XFS_BLFT_DA_NODE_BUF:
2022 if (magicda != XFS_DA_NODE_MAGIC &&
2023 magicda != XFS_DA3_NODE_MAGIC) {
2024 xfs_warn(mp, "Bad da node magic!");
2025 ASSERT(0);
2026 break;
2027 }
2028 bp->b_ops = &xfs_da3_node_buf_ops;
2029 break;
2030 case XFS_BLFT_ATTR_LEAF_BUF:
2031 if (magicda != XFS_ATTR_LEAF_MAGIC &&
2032 magicda != XFS_ATTR3_LEAF_MAGIC) {
2033 xfs_warn(mp, "Bad attr leaf magic!");
2034 ASSERT(0);
2035 break;
2036 }
2037 bp->b_ops = &xfs_attr3_leaf_buf_ops;
2038 break;
2039 case XFS_BLFT_ATTR_RMT_BUF:
2040 if (!xfs_sb_version_hascrc(&mp->m_sb))
2041 break;
2042 if (magic32 != XFS_ATTR3_RMT_MAGIC) {
2043 xfs_warn(mp, "Bad attr remote magic!");
2044 ASSERT(0);
2045 break;
2046 }
2047 bp->b_ops = &xfs_attr3_rmt_buf_ops;
2048 break;
2049 case XFS_BLFT_SB_BUF:
2050 if (magic32 != XFS_SB_MAGIC) {
2051 xfs_warn(mp, "Bad SB block magic!");
2052 ASSERT(0);
2053 break;
2054 }
2055 bp->b_ops = &xfs_sb_buf_ops;
2056 break;
2057 default:
2058 xfs_warn(mp, "Unknown buffer type %d!",
2059 xfs_blft_from_flags(buf_f));
2060 break;
2061 }
2062}
2063
2064/*
1860 * Perform a 'normal' buffer recovery. Each logged region of the 2065 * Perform a 'normal' buffer recovery. Each logged region of the
1861 * buffer should be copied over the corresponding region in the 2066 * buffer should be copied over the corresponding region in the
1862 * given buffer. The bitmap in the buf log format structure indicates 2067 * given buffer. The bitmap in the buf log format structure indicates
@@ -1928,6 +2133,8 @@ xlog_recover_do_reg_buffer(
1928 2133
1929 /* Shouldn't be any more regions */ 2134 /* Shouldn't be any more regions */
1930 ASSERT(i == item->ri_total); 2135 ASSERT(i == item->ri_total);
2136
2137 xlog_recovery_validate_buf_type(mp, bp, buf_f);
1931} 2138}
1932 2139
1933/* 2140/*
@@ -2213,6 +2420,7 @@ xlog_recover_inode_pass2(
2213 int attr_index; 2420 int attr_index;
2214 uint fields; 2421 uint fields;
2215 xfs_icdinode_t *dicp; 2422 xfs_icdinode_t *dicp;
2423 uint isize;
2216 int need_free = 0; 2424 int need_free = 0;
2217 2425
2218 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) { 2426 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
@@ -2238,7 +2446,7 @@ xlog_recover_inode_pass2(
2238 trace_xfs_log_recover_inode_recover(log, in_f); 2446 trace_xfs_log_recover_inode_recover(log, in_f);
2239 2447
2240 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 0, 2448 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 0,
2241 NULL); 2449 &xfs_inode_buf_ops);
2242 if (!bp) { 2450 if (!bp) {
2243 error = ENOMEM; 2451 error = ENOMEM;
2244 goto error; 2452 goto error;
@@ -2349,7 +2557,8 @@ xlog_recover_inode_pass2(
2349 error = EFSCORRUPTED; 2557 error = EFSCORRUPTED;
2350 goto error; 2558 goto error;
2351 } 2559 }
2352 if (unlikely(item->ri_buf[1].i_len > sizeof(struct xfs_icdinode))) { 2560 isize = xfs_icdinode_size(dicp->di_version);
2561 if (unlikely(item->ri_buf[1].i_len > isize)) {
2353 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)", 2562 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
2354 XFS_ERRLEVEL_LOW, mp, dicp); 2563 XFS_ERRLEVEL_LOW, mp, dicp);
2355 xfs_buf_relse(bp); 2564 xfs_buf_relse(bp);
@@ -2361,13 +2570,13 @@ xlog_recover_inode_pass2(
2361 } 2570 }
2362 2571
2363 /* The core is in in-core format */ 2572 /* The core is in in-core format */
2364 xfs_dinode_to_disk(dip, item->ri_buf[1].i_addr); 2573 xfs_dinode_to_disk(dip, dicp);
2365 2574
2366 /* the rest is in on-disk format */ 2575 /* the rest is in on-disk format */
2367 if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) { 2576 if (item->ri_buf[1].i_len > isize) {
2368 memcpy((xfs_caddr_t) dip + sizeof(struct xfs_icdinode), 2577 memcpy((char *)dip + isize,
2369 item->ri_buf[1].i_addr + sizeof(struct xfs_icdinode), 2578 item->ri_buf[1].i_addr + isize,
2370 item->ri_buf[1].i_len - sizeof(struct xfs_icdinode)); 2579 item->ri_buf[1].i_len - isize);
2371 } 2580 }
2372 2581
2373 fields = in_f->ilf_fields; 2582 fields = in_f->ilf_fields;
@@ -2451,6 +2660,9 @@ xlog_recover_inode_pass2(
2451 } 2660 }
2452 2661
2453write_inode_buffer: 2662write_inode_buffer:
2663 /* re-generate the checksum. */
2664 xfs_dinode_calc_crc(log->l_mp, dip);
2665
2454 ASSERT(bp->b_target->bt_mount == mp); 2666 ASSERT(bp->b_target->bt_mount == mp);
2455 bp->b_iodone = xlog_recover_iodone; 2667 bp->b_iodone = xlog_recover_iodone;
2456 xfs_buf_delwri_queue(bp, buffer_list); 2668 xfs_buf_delwri_queue(bp, buffer_list);
@@ -2948,6 +3160,7 @@ xlog_recover_process_efi(
2948 * This will pull the EFI from the AIL and 3160 * This will pull the EFI from the AIL and
2949 * free the memory associated with it. 3161 * free the memory associated with it.
2950 */ 3162 */
3163 set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
2951 xfs_efi_release(efip, efip->efi_format.efi_nextents); 3164 xfs_efi_release(efip, efip->efi_format.efi_nextents);
2952 return XFS_ERROR(EIO); 3165 return XFS_ERROR(EIO);
2953 } 3166 }
@@ -3751,6 +3964,25 @@ xlog_recover(
3751 return error; 3964 return error;
3752 } 3965 }
3753 3966
3967 /*
3968 * Version 5 superblock log feature mask validation. We know the
3969 * log is dirty so check if there are any unknown log features
3970 * in what we need to recover. If there are unknown features
3971 * (e.g. unsupported transactions, then simply reject the
3972 * attempt at recovery before touching anything.
3973 */
3974 if (XFS_SB_VERSION_NUM(&log->l_mp->m_sb) == XFS_SB_VERSION_5 &&
3975 xfs_sb_has_incompat_log_feature(&log->l_mp->m_sb,
3976 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)) {
3977 xfs_warn(log->l_mp,
3978"Superblock has unknown incompatible log features (0x%x) enabled.\n"
3979"The log can not be fully and/or safely recovered by this kernel.\n"
3980"Please recover the log on a kernel that supports the unknown features.",
3981 (log->l_mp->m_sb.sb_features_log_incompat &
3982 XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN));
3983 return EINVAL;
3984 }
3985
3754 xfs_notice(log->l_mp, "Starting recovery (logdev: %s)", 3986 xfs_notice(log->l_mp, "Starting recovery (logdev: %s)",
3755 log->l_mp->m_logname ? log->l_mp->m_logname 3987 log->l_mp->m_logname ? log->l_mp->m_logname
3756 : "internal"); 3988 : "internal");