diff options
author | Tim Shimmin <tes@chook.melbourne.sgi.com> | 2007-10-01 02:39:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-01 10:59:03 -0400 |
commit | 564256c9e06d75e16d894a2cd30604bd6582cbba (patch) | |
tree | ef5505f335d401862893dd6a1bbca3e6dc3eaa88 /fs/xfs/xfs_log_recover.c | |
parent | a64314e62d89562b6fc77593648bec3acc35bf61 (diff) |
Revert "[XFS] Avoid replaying inode buffer initialisation log items if on-disk version is newer."
This reverts commit b394e43e995d08821588a22561c6a71a63b4ff27.
Lachlan McIlroy says:
It tried to fix an issue where log replay is replaying an inode cluster
initialisation transaction that should not be replayed because the inode
cluster on disk is more up to date. Since we don't log file sizes (we
rely on inode flushing to get them to disk) then we can't just replay
all the transations in the log and expect the inode to be completely
restored. We lose file size updates. Unfortunately this fix is causing
more (serious) problems than it is fixing.
SGI-PV: 969656
SGI-Modid: xfs-linux-melb:xfs-kern:29804a
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 51 |
1 files changed, 3 insertions, 48 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 7174991f4bef..8ae6e8e5f3db 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1874,7 +1874,6 @@ xlog_recover_do_inode_buffer( | |||
1874 | /*ARGSUSED*/ | 1874 | /*ARGSUSED*/ |
1875 | STATIC void | 1875 | STATIC void |
1876 | xlog_recover_do_reg_buffer( | 1876 | xlog_recover_do_reg_buffer( |
1877 | xfs_mount_t *mp, | ||
1878 | xlog_recover_item_t *item, | 1877 | xlog_recover_item_t *item, |
1879 | xfs_buf_t *bp, | 1878 | xfs_buf_t *bp, |
1880 | xfs_buf_log_format_t *buf_f) | 1879 | xfs_buf_log_format_t *buf_f) |
@@ -1885,50 +1884,6 @@ xlog_recover_do_reg_buffer( | |||
1885 | unsigned int *data_map = NULL; | 1884 | unsigned int *data_map = NULL; |
1886 | unsigned int map_size = 0; | 1885 | unsigned int map_size = 0; |
1887 | int error; | 1886 | int error; |
1888 | int stale_buf = 1; | ||
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 (dip->di_core.di_mode) | ||
1924 | mode_count++; | ||
1925 | if (dip->di_core.di_gen) | ||
1926 | gen_count++; | ||
1927 | } | ||
1928 | |||
1929 | if (!mode_count && gen_count) | ||
1930 | stale_buf = 1; | ||
1931 | } | ||
1932 | 1887 | ||
1933 | switch (buf_f->blf_type) { | 1888 | switch (buf_f->blf_type) { |
1934 | case XFS_LI_BUF: | 1889 | case XFS_LI_BUF: |
@@ -1962,7 +1917,7 @@ xlog_recover_do_reg_buffer( | |||
1962 | -1, 0, XFS_QMOPT_DOWARN, | 1917 | -1, 0, XFS_QMOPT_DOWARN, |
1963 | "dquot_buf_recover"); | 1918 | "dquot_buf_recover"); |
1964 | } | 1919 | } |
1965 | if (!error && stale_buf) | 1920 | if (!error) |
1966 | memcpy(xfs_buf_offset(bp, | 1921 | memcpy(xfs_buf_offset(bp, |
1967 | (uint)bit << XFS_BLI_SHIFT), /* dest */ | 1922 | (uint)bit << XFS_BLI_SHIFT), /* dest */ |
1968 | item->ri_buf[i].i_addr, /* source */ | 1923 | item->ri_buf[i].i_addr, /* source */ |
@@ -2134,7 +2089,7 @@ xlog_recover_do_dquot_buffer( | |||
2134 | if (log->l_quotaoffs_flag & type) | 2089 | if (log->l_quotaoffs_flag & type) |
2135 | return; | 2090 | return; |
2136 | 2091 | ||
2137 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); | 2092 | xlog_recover_do_reg_buffer(item, bp, buf_f); |
2138 | } | 2093 | } |
2139 | 2094 | ||
2140 | /* | 2095 | /* |
@@ -2235,7 +2190,7 @@ xlog_recover_do_buffer_trans( | |||
2235 | (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { | 2190 | (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { |
2236 | xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); | 2191 | xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); |
2237 | } else { | 2192 | } else { |
2238 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); | 2193 | xlog_recover_do_reg_buffer(item, bp, buf_f); |
2239 | } | 2194 | } |
2240 | if (error) | 2195 | if (error) |
2241 | return XFS_ERROR(error); | 2196 | return XFS_ERROR(error); |