Commit b394e43e995d08821588a22561c6a71a63b4ff27

Authored by Lachlan McIlroy
Committed by Tim Shimmin
1 parent 776a75fa5c

[XFS] Avoid replaying inode buffer initialisation log items if on-disk version is newer.

SGI-PV: 969656
SGI-Modid: xfs-linux-melb:xfs-kern:29676a

Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>

Showing 3 changed files with 54 additions and 3 deletions Side-by-side Diff

fs/xfs/xfs_buf_item.h
... ... @@ -52,6 +52,11 @@
52 52 #define XFS_BLI_UDQUOT_BUF 0x4
53 53 #define XFS_BLI_PDQUOT_BUF 0x8
54 54 #define XFS_BLI_GDQUOT_BUF 0x10
  55 +/*
  56 + * This flag indicates that the buffer contains newly allocated
  57 + * inodes.
  58 + */
  59 +#define XFS_BLI_INODE_NEW_BUF 0x20
55 60  
56 61 #define XFS_BLI_CHUNK 128
57 62 #define XFS_BLI_SHIFT 7
fs/xfs/xfs_log_recover.c
... ... @@ -1874,6 +1874,7 @@
1874 1874 /*ARGSUSED*/
1875 1875 STATIC void
1876 1876 xlog_recover_do_reg_buffer(
  1877 + xfs_mount_t *mp,
1877 1878 xlog_recover_item_t *item,
1878 1879 xfs_buf_t *bp,
1879 1880 xfs_buf_log_format_t *buf_f)
1880 1881  
... ... @@ -1884,7 +1885,51 @@
1884 1885 unsigned int *data_map = NULL;
1885 1886 unsigned int map_size = 0;
1886 1887 int error;
  1888 + int stale_buf = 1;
1887 1889  
  1890 + /*
  1891 + * Scan through the on-disk inode buffer and attempt to
  1892 + * determine if it has been written to since it was logged.
  1893 + *
  1894 + * - If any of the magic numbers are incorrect then the buffer is stale
  1895 + * - If any of the modes are non-zero then the buffer is not stale
  1896 + * - If all of the modes are zero and at least one of the generation
  1897 + * counts is non-zero then the buffer is stale
  1898 + *
  1899 + * If the end result is a stale buffer then the log buffer is replayed
  1900 + * otherwise it is skipped.
  1901 + *
  1902 + * This heuristic is not perfect. It can be improved by scanning the
  1903 + * entire inode chunk for evidence that any of the inode clusters have
  1904 + * been updated. To fix this problem completely we will need a major
  1905 + * architectural change to the logging system.
  1906 + */
  1907 + if (buf_f->blf_flags & XFS_BLI_INODE_NEW_BUF) {
  1908 + xfs_dinode_t *dip;
  1909 + int inodes_per_buf;
  1910 + int mode_count = 0;
  1911 + int gen_count = 0;
  1912 +
  1913 + stale_buf = 0;
  1914 + inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog;
  1915 + for (i = 0; i < inodes_per_buf; i++) {
  1916 + dip = (xfs_dinode_t *)xfs_buf_offset(bp,
  1917 + i * mp->m_sb.sb_inodesize);
  1918 + if (be16_to_cpu(dip->di_core.di_magic) !=
  1919 + XFS_DINODE_MAGIC) {
  1920 + stale_buf = 1;
  1921 + break;
  1922 + }
  1923 + if (be16_to_cpu(dip->di_core.di_mode))
  1924 + mode_count++;
  1925 + if (be16_to_cpu(dip->di_core.di_gen))
  1926 + gen_count++;
  1927 + }
  1928 +
  1929 + if (!mode_count && gen_count)
  1930 + stale_buf = 1;
  1931 + }
  1932 +
1888 1933 switch (buf_f->blf_type) {
1889 1934 case XFS_LI_BUF:
1890 1935 data_map = buf_f->blf_data_map;
... ... @@ -1917,7 +1962,7 @@
1917 1962 -1, 0, XFS_QMOPT_DOWARN,
1918 1963 "dquot_buf_recover");
1919 1964 }
1920   - if (!error)
  1965 + if (!error && stale_buf)
1921 1966 memcpy(xfs_buf_offset(bp,
1922 1967 (uint)bit << XFS_BLI_SHIFT), /* dest */
1923 1968 item->ri_buf[i].i_addr, /* source */
... ... @@ -2089,7 +2134,7 @@
2089 2134 if (log->l_quotaoffs_flag & type)
2090 2135 return;
2091 2136  
2092   - xlog_recover_do_reg_buffer(item, bp, buf_f);
  2137 + xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
2093 2138 }
2094 2139  
2095 2140 /*
... ... @@ -2190,7 +2235,7 @@
2190 2235 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
2191 2236 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
2192 2237 } else {
2193   - xlog_recover_do_reg_buffer(item, bp, buf_f);
  2238 + xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
2194 2239 }
2195 2240 if (error)
2196 2241 return XFS_ERROR(error);
fs/xfs/xfs_trans_buf.c
... ... @@ -966,6 +966,7 @@
966 966 ASSERT(atomic_read(&bip->bli_refcount) > 0);
967 967  
968 968 bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
  969 + bip->bli_format.blf_flags |= XFS_BLI_INODE_NEW_BUF;
969 970 }
970 971  
971 972