Revert "[XFS] Avoid replaying inode buffer initialisation log items if on-disk version is newer."
This reverts commit b394e43e99
.
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>
This commit is contained in:
parent
a64314e62d
commit
564256c9e0
|
@ -52,11 +52,6 @@ typedef struct xfs_buf_log_format_t {
|
|||
#define XFS_BLI_UDQUOT_BUF 0x4
|
||||
#define XFS_BLI_PDQUOT_BUF 0x8
|
||||
#define XFS_BLI_GDQUOT_BUF 0x10
|
||||
/*
|
||||
* This flag indicates that the buffer contains newly allocated
|
||||
* inodes.
|
||||
*/
|
||||
#define XFS_BLI_INODE_NEW_BUF 0x20
|
||||
|
||||
#define XFS_BLI_CHUNK 128
|
||||
#define XFS_BLI_SHIFT 7
|
||||
|
|
|
@ -1874,7 +1874,6 @@ xlog_recover_do_inode_buffer(
|
|||
/*ARGSUSED*/
|
||||
STATIC void
|
||||
xlog_recover_do_reg_buffer(
|
||||
xfs_mount_t *mp,
|
||||
xlog_recover_item_t *item,
|
||||
xfs_buf_t *bp,
|
||||
xfs_buf_log_format_t *buf_f)
|
||||
|
@ -1885,50 +1884,6 @@ xlog_recover_do_reg_buffer(
|
|||
unsigned int *data_map = NULL;
|
||||
unsigned int map_size = 0;
|
||||
int error;
|
||||
int stale_buf = 1;
|
||||
|
||||
/*
|
||||
* Scan through the on-disk inode buffer and attempt to
|
||||
* determine if it has been written to since it was logged.
|
||||
*
|
||||
* - If any of the magic numbers are incorrect then the buffer is stale
|
||||
* - If any of the modes are non-zero then the buffer is not stale
|
||||
* - If all of the modes are zero and at least one of the generation
|
||||
* counts is non-zero then the buffer is stale
|
||||
*
|
||||
* If the end result is a stale buffer then the log buffer is replayed
|
||||
* otherwise it is skipped.
|
||||
*
|
||||
* This heuristic is not perfect. It can be improved by scanning the
|
||||
* entire inode chunk for evidence that any of the inode clusters have
|
||||
* been updated. To fix this problem completely we will need a major
|
||||
* architectural change to the logging system.
|
||||
*/
|
||||
if (buf_f->blf_flags & XFS_BLI_INODE_NEW_BUF) {
|
||||
xfs_dinode_t *dip;
|
||||
int inodes_per_buf;
|
||||
int mode_count = 0;
|
||||
int gen_count = 0;
|
||||
|
||||
stale_buf = 0;
|
||||
inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog;
|
||||
for (i = 0; i < inodes_per_buf; i++) {
|
||||
dip = (xfs_dinode_t *)xfs_buf_offset(bp,
|
||||
i * mp->m_sb.sb_inodesize);
|
||||
if (be16_to_cpu(dip->di_core.di_magic) !=
|
||||
XFS_DINODE_MAGIC) {
|
||||
stale_buf = 1;
|
||||
break;
|
||||
}
|
||||
if (dip->di_core.di_mode)
|
||||
mode_count++;
|
||||
if (dip->di_core.di_gen)
|
||||
gen_count++;
|
||||
}
|
||||
|
||||
if (!mode_count && gen_count)
|
||||
stale_buf = 1;
|
||||
}
|
||||
|
||||
switch (buf_f->blf_type) {
|
||||
case XFS_LI_BUF:
|
||||
|
@ -1962,7 +1917,7 @@ xlog_recover_do_reg_buffer(
|
|||
-1, 0, XFS_QMOPT_DOWARN,
|
||||
"dquot_buf_recover");
|
||||
}
|
||||
if (!error && stale_buf)
|
||||
if (!error)
|
||||
memcpy(xfs_buf_offset(bp,
|
||||
(uint)bit << XFS_BLI_SHIFT), /* dest */
|
||||
item->ri_buf[i].i_addr, /* source */
|
||||
|
@ -2134,7 +2089,7 @@ xlog_recover_do_dquot_buffer(
|
|||
if (log->l_quotaoffs_flag & type)
|
||||
return;
|
||||
|
||||
xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
|
||||
xlog_recover_do_reg_buffer(item, bp, buf_f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2235,7 +2190,7 @@ xlog_recover_do_buffer_trans(
|
|||
(XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
|
||||
xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
|
||||
} else {
|
||||
xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
|
||||
xlog_recover_do_reg_buffer(item, bp, buf_f);
|
||||
}
|
||||
if (error)
|
||||
return XFS_ERROR(error);
|
||||
|
|
|
@ -966,7 +966,6 @@ xfs_trans_inode_alloc_buf(
|
|||
ASSERT(atomic_read(&bip->bli_refcount) > 0);
|
||||
|
||||
bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
|
||||
bip->bli_format.blf_flags |= XFS_BLI_INODE_NEW_BUF;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue