xfs: refactor log recovery item dispatch for pass1 commit functions

Move the pass1 commit code into the per-item source code files and use
the dispatch function to call them.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Darrick J. Wong 2020-05-01 16:00:46 -07:00
parent 8ea5682d07
commit 3304a4fabd
4 changed files with 64 additions and 89 deletions

View File

@ -34,6 +34,9 @@ struct xlog_recover_item_ops {
/* Start readahead for pass2, if provided. */
void (*ra_pass2)(struct xlog *log, struct xlog_recover_item *item);
/* Do whatever work we need to do for pass1, if provided. */
int (*commit_pass1)(struct xlog *log, struct xlog_recover_item *item);
};
extern const struct xlog_recover_item_ops xlog_icreate_item_ops;
@ -97,5 +100,6 @@ struct xlog_recover {
void xlog_buf_readahead(struct xlog *log, xfs_daddr_t blkno, uint len,
const struct xfs_buf_ops *ops);
bool xlog_add_buffer_cancelled(struct xlog *log, xfs_daddr_t blkno, uint len);
#endif /* __XFS_LOG_RECOVER_H__ */

View File

@ -56,8 +56,35 @@ xlog_recover_buf_ra_pass2(
xlog_buf_readahead(log, buf_f->blf_blkno, buf_f->blf_len, NULL);
}
/*
* Build up the table of buf cancel records so that we don't replay cancelled
* data in the second pass.
*/
static int
xlog_recover_buf_commit_pass1(
struct xlog *log,
struct xlog_recover_item *item)
{
struct xfs_buf_log_format *bf = item->ri_buf[0].i_addr;
if (!xfs_buf_log_check_iovec(&item->ri_buf[0])) {
xfs_err(log->l_mp, "bad buffer log item size (%d)",
item->ri_buf[0].i_len);
return -EFSCORRUPTED;
}
if (!(bf->blf_flags & XFS_BLF_CANCEL))
trace_xfs_log_recover_buf_not_cancel(log, bf);
else if (xlog_add_buffer_cancelled(log, bf->blf_blkno, bf->blf_len))
trace_xfs_log_recover_buf_cancel_add(log, bf);
else
trace_xfs_log_recover_buf_cancel_ref_inc(log, bf);
return 0;
}
const struct xlog_recover_item_ops xlog_buf_item_ops = {
.item_type = XFS_LI_BUF,
.reorder = xlog_recover_buf_reorder,
.ra_pass2 = xlog_recover_buf_ra_pass2,
.commit_pass1 = xlog_recover_buf_commit_pass1,
};

View File

@ -58,6 +58,34 @@ const struct xlog_recover_item_ops xlog_dquot_item_ops = {
.ra_pass2 = xlog_recover_dquot_ra_pass2,
};
/*
* Recover QUOTAOFF records. We simply make a note of it in the xlog
* structure, so that we know not to do any dquot item or dquot buffer recovery,
* of that type.
*/
STATIC int
xlog_recover_quotaoff_commit_pass1(
struct xlog *log,
struct xlog_recover_item *item)
{
struct xfs_qoff_logformat *qoff_f = item->ri_buf[0].i_addr;
ASSERT(qoff_f);
/*
* The logitem format's flag tells us if this was user quotaoff,
* group/project quotaoff or both.
*/
if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
log->l_quotaoffs_flag |= XFS_DQ_USER;
if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)
log->l_quotaoffs_flag |= XFS_DQ_PROJ;
if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
log->l_quotaoffs_flag |= XFS_DQ_GROUP;
return 0;
}
const struct xlog_recover_item_ops xlog_quotaoff_item_ops = {
.item_type = XFS_LI_QUOTAOFF,
.commit_pass1 = xlog_recover_quotaoff_commit_pass1,
};

View File

@ -1953,7 +1953,7 @@ xlog_find_buffer_cancelled(
return NULL;
}
static bool
bool
xlog_add_buffer_cancelled(
struct xlog *log,
xfs_daddr_t blkno,
@ -2034,32 +2034,6 @@ xlog_buf_readahead(
xfs_buf_readahead(log->l_mp->m_ddev_targp, blkno, len, ops);
}
/*
* Build up the table of buf cancel records so that we don't replay cancelled
* data in the second pass.
*/
static int
xlog_recover_buffer_pass1(
struct xlog *log,
struct xlog_recover_item *item)
{
struct xfs_buf_log_format *bf = item->ri_buf[0].i_addr;
if (!xfs_buf_log_check_iovec(&item->ri_buf[0])) {
xfs_err(log->l_mp, "bad buffer log item size (%d)",
item->ri_buf[0].i_len);
return -EFSCORRUPTED;
}
if (!(bf->blf_flags & XFS_BLF_CANCEL))
trace_xfs_log_recover_buf_not_cancel(log, bf);
else if (xlog_add_buffer_cancelled(log, bf->blf_blkno, bf->blf_len))
trace_xfs_log_recover_buf_cancel_add(log, bf);
else
trace_xfs_log_recover_buf_cancel_ref_inc(log, bf);
return 0;
}
/*
* Perform recovery for a buffer full of inodes. In these buffers, the only
* data which should be recovered is that which corresponds to the
@ -3197,33 +3171,6 @@ error:
return error;
}
/*
* Recover QUOTAOFF records. We simply make a note of it in the xlog
* structure, so that we know not to do any dquot item or dquot buffer recovery,
* of that type.
*/
STATIC int
xlog_recover_quotaoff_pass1(
struct xlog *log,
struct xlog_recover_item *item)
{
xfs_qoff_logformat_t *qoff_f = item->ri_buf[0].i_addr;
ASSERT(qoff_f);
/*
* The logitem format's flag tells us if this was user quotaoff,
* group/project quotaoff or both.
*/
if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
log->l_quotaoffs_flag |= XFS_DQ_USER;
if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)
log->l_quotaoffs_flag |= XFS_DQ_PROJ;
if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
log->l_quotaoffs_flag |= XFS_DQ_GROUP;
return 0;
}
/*
* Recover a dquot record
*/
@ -3890,40 +3837,6 @@ xlog_recover_do_icreate_pass2(
length, be32_to_cpu(icl->icl_gen));
}
STATIC int
xlog_recover_commit_pass1(
struct xlog *log,
struct xlog_recover *trans,
struct xlog_recover_item *item)
{
trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS1);
switch (ITEM_TYPE(item)) {
case XFS_LI_BUF:
return xlog_recover_buffer_pass1(log, item);
case XFS_LI_QUOTAOFF:
return xlog_recover_quotaoff_pass1(log, item);
case XFS_LI_INODE:
case XFS_LI_EFI:
case XFS_LI_EFD:
case XFS_LI_DQUOT:
case XFS_LI_ICREATE:
case XFS_LI_RUI:
case XFS_LI_RUD:
case XFS_LI_CUI:
case XFS_LI_CUD:
case XFS_LI_BUI:
case XFS_LI_BUD:
/* nothing to do in pass 1 */
return 0;
default:
xfs_warn(log->l_mp, "%s: invalid item type (%d)",
__func__, ITEM_TYPE(item));
ASSERT(0);
return -EFSCORRUPTED;
}
}
STATIC int
xlog_recover_commit_pass2(
struct xlog *log,
@ -4021,9 +3934,12 @@ xlog_recover_commit_trans(
return error;
list_for_each_entry_safe(item, next, &trans->r_itemq, ri_list) {
trace_xfs_log_recover_item_recover(log, trans, item, pass);
switch (pass) {
case XLOG_RECOVER_PASS1:
error = xlog_recover_commit_pass1(log, trans, item);
if (item->ri_ops->commit_pass1)
error = item->ri_ops->commit_pass1(log, item);
break;
case XLOG_RECOVER_PASS2:
if (item->ri_ops->ra_pass2)