* [PATCH 5/2] xfs: refactor xlog_recover_buffer_pass1
@ 2020-04-28 8:05 Christoph Hellwig
2020-04-28 15:13 ` Brian Foster
0 siblings, 1 reply; 2+ messages in thread
From: Christoph Hellwig @ 2020-04-28 8:05 UTC (permalink / raw)
To: linux-xfs
Split out a xlog_add_buffer_cancelled helper which does the low-level
manipulation of the buffer cancelation table, and in that helper call
xlog_find_buffer_cancelled instead of open coding it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/xfs/xfs_log_recover.c | 114 +++++++++++++++++++--------------------
1 file changed, 55 insertions(+), 59 deletions(-)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index fe4dad5b77a95..3bc61838266f1 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1913,65 +1913,6 @@ xlog_recover_reorder_trans(
return error;
}
-/*
- * Build up the table of buf cancel records so that we don't replay
- * cancelled data in the second pass. For buffer records that are
- * not cancel records, there is nothing to do here so we just return.
- *
- * If we get a cancel record which is already in the table, this indicates
- * that the buffer was cancelled multiple times. In order to ensure
- * that during pass 2 we keep the record in the table until we reach its
- * last occurrence in the log, we keep a reference count in the cancel
- * record in the table to tell us how many times we expect to see this
- * record during the second pass.
- */
-STATIC int
-xlog_recover_buffer_pass1(
- struct xlog *log,
- struct xlog_recover_item *item)
-{
- xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
- struct list_head *bucket;
- struct xfs_buf_cancel *bcp;
-
- 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 this isn't a cancel buffer item, then just return.
- */
- if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
- trace_xfs_log_recover_buf_not_cancel(log, buf_f);
- return 0;
- }
-
- /*
- * Insert an xfs_buf_cancel record into the hash table of them.
- * If there is already an identical record, bump its reference count.
- */
- bucket = XLOG_BUF_CANCEL_BUCKET(log, buf_f->blf_blkno);
- list_for_each_entry(bcp, bucket, bc_list) {
- if (bcp->bc_blkno == buf_f->blf_blkno &&
- bcp->bc_len == buf_f->blf_len) {
- bcp->bc_refcount++;
- trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f);
- return 0;
- }
- }
-
- bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), 0);
- bcp->bc_blkno = buf_f->blf_blkno;
- bcp->bc_len = buf_f->blf_len;
- bcp->bc_refcount = 1;
- list_add_tail(&bcp->bc_list, bucket);
-
- trace_xfs_log_recover_buf_cancel_add(log, buf_f);
- return 0;
-}
-
static struct xfs_buf_cancel *
xlog_find_buffer_cancelled(
struct xlog *log,
@@ -1993,6 +1934,35 @@ xlog_find_buffer_cancelled(
return NULL;
}
+static bool
+xlog_add_buffer_cancelled(
+ struct xlog *log,
+ xfs_daddr_t blkno,
+ uint len)
+{
+ struct xfs_buf_cancel *bcp;
+
+ /*
+ * If we find an existing cancel record, this indicates that the buffer
+ * was cancelled multiple times. To ensure that during pass 2 we keep
+ * the record in the table until we reach its last occurrence in the
+ * log, a reference count is kept to tell how many times we expect to
+ * see this record during the second pass.
+ */
+ bcp = xlog_find_buffer_cancelled(log, blkno, len);
+ if (bcp) {
+ bcp->bc_refcount++;
+ return false;
+ }
+
+ bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), 0);
+ bcp->bc_blkno = blkno;
+ bcp->bc_len = len;
+ bcp->bc_refcount = 1;
+ list_add_tail(&bcp->bc_list, XLOG_BUF_CANCEL_BUCKET(log, blkno));
+ return true;
+}
+
/*
* Check if there is and entry for blkno, len in the buffer cancel record table.
*/
@@ -2045,6 +2015,32 @@ 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
--
2.26.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 5/2] xfs: refactor xlog_recover_buffer_pass1
2020-04-28 8:05 [PATCH 5/2] xfs: refactor xlog_recover_buffer_pass1 Christoph Hellwig
@ 2020-04-28 15:13 ` Brian Foster
0 siblings, 0 replies; 2+ messages in thread
From: Brian Foster @ 2020-04-28 15:13 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-xfs
On Tue, Apr 28, 2020 at 10:05:50AM +0200, Christoph Hellwig wrote:
> Split out a xlog_add_buffer_cancelled helper which does the low-level
> manipulation of the buffer cancelation table, and in that helper call
> xlog_find_buffer_cancelled instead of open coding it.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/xfs_log_recover.c | 114 +++++++++++++++++++--------------------
> 1 file changed, 55 insertions(+), 59 deletions(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index fe4dad5b77a95..3bc61838266f1 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
...
> @@ -2045,6 +2015,32 @@ 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);
Nit, but the function call looks buried here. Also, the boolean return
seems like overkill if it's only used to control tracepoints (and
true/false for inc/ref isn't terribly intuitive anyways).
This looks cleaner to me if it's just:
if (!XFS_BLF_CANCEL) {
trace_xfs_log_recover_buf_not_cancel(log, bf);
return 0;
}
xlog_add_buffer_cancelled(log, bf->blf_blkno, bf->blf_len);
return 0;
... and let the helper invoke the buf_cancel tracepoints and return
void. Otherwise looks like a good cleanup to me.
Brian
> + 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
> --
> 2.26.1
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-04-28 15:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-28 8:05 [PATCH 5/2] xfs: refactor xlog_recover_buffer_pass1 Christoph Hellwig
2020-04-28 15:13 ` Brian Foster
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.