summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf_item.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2020-06-29 14:49:15 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-07-07 07:15:07 -0700
commit3536b61e74aa232d0ae42cff57b80278724f209c (patch)
treef1e8dc6878a8650a83c7e5dae3e396e12262a5da /fs/xfs/xfs_buf_item.c
parent428947e9d525ae3a03dbdce4cdbcb2afe020732d (diff)
downloadlinux-stable-3536b61e74aa232d0ae42cff57b80278724f209c.tar.gz
linux-stable-3536b61e74aa232d0ae42cff57b80278724f209c.tar.bz2
linux-stable-3536b61e74aa232d0ae42cff57b80278724f209c.zip
xfs: unwind log item error flagging
When an buffer IO error occurs, we want to mark all the log items attached to the buffer as failed. Open code the error handling loop so that we can modify the flagging for the different types of objects directly and independently of each other. This also allows us to remove the ->iop_error method from the log item operations. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_buf_item.c')
-rw-r--r--fs/xfs/xfs_buf_item.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index f80fc5bd3bff..d61f20b989cd 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -12,6 +12,7 @@
#include "xfs_bit.h"
#include "xfs_mount.h"
#include "xfs_trans.h"
+#include "xfs_trans_priv.h"
#include "xfs_buf_item.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
@@ -956,37 +957,6 @@ xfs_buf_item_relse(
}
/*
- * Invoke the error state callback for each log item affected by the failed I/O.
- *
- * If a metadata buffer write fails with a non-permanent error, the buffer is
- * eventually resubmitted and so the completion callbacks are not run. The error
- * state may need to be propagated to the log items attached to the buffer,
- * however, so the next AIL push of the item knows hot to handle it correctly.
- */
-STATIC void
-xfs_buf_do_callbacks_fail(
- struct xfs_buf *bp)
-{
- struct xfs_ail *ailp = bp->b_mount->m_ail;
- struct xfs_log_item *lip;
-
- /*
- * Buffer log item errors are handled directly by xfs_buf_item_push()
- * and xfs_buf_iodone_callback_error, and they have no IO error
- * callbacks. Check only for items in b_li_list.
- */
- if (list_empty(&bp->b_li_list))
- return;
-
- spin_lock(&ailp->ail_lock);
- list_for_each_entry(lip, &bp->b_li_list, li_bio_list) {
- if (lip->li_ops->iop_error)
- lip->li_ops->iop_error(lip, bp);
- }
- spin_unlock(&ailp->ail_lock);
-}
-
-/*
* Decide if we're going to retry the write after a failure, and prepare
* the buffer for retrying the write.
*/
@@ -1165,6 +1135,7 @@ xfs_buf_inode_iodone(
struct xfs_buf *bp)
{
if (bp->b_error) {
+ struct xfs_log_item *lip;
int ret = xfs_buf_iodone_error(bp);
if (ret == XBF_IOERROR_FINISH)
@@ -1172,7 +1143,11 @@ xfs_buf_inode_iodone(
if (ret == XBF_IOERROR_DONE)
return;
ASSERT(ret == XBF_IOERROR_FAIL);
- xfs_buf_do_callbacks_fail(bp);
+ spin_lock(&bp->b_mount->m_ail->ail_lock);
+ list_for_each_entry(lip, &bp->b_li_list, li_bio_list) {
+ xfs_set_li_failed(lip, bp);
+ }
+ spin_unlock(&bp->b_mount->m_ail->ail_lock);
xfs_buf_ioerror(bp, 0);
xfs_buf_relse(bp);
return;
@@ -1193,6 +1168,7 @@ xfs_buf_dquot_iodone(
struct xfs_buf *bp)
{
if (bp->b_error) {
+ struct xfs_log_item *lip;
int ret = xfs_buf_iodone_error(bp);
if (ret == XBF_IOERROR_FINISH)
@@ -1200,7 +1176,11 @@ xfs_buf_dquot_iodone(
if (ret == XBF_IOERROR_DONE)
return;
ASSERT(ret == XBF_IOERROR_FAIL);
- xfs_buf_do_callbacks_fail(bp);
+ spin_lock(&bp->b_mount->m_ail->ail_lock);
+ list_for_each_entry(lip, &bp->b_li_list, li_bio_list) {
+ xfs_set_li_failed(lip, bp);
+ }
+ spin_unlock(&bp->b_mount->m_ail->ail_lock);
xfs_buf_ioerror(bp, 0);
xfs_buf_relse(bp);
return;
@@ -1232,7 +1212,7 @@ xfs_buf_iodone(
if (ret == XBF_IOERROR_DONE)
return;
ASSERT(ret == XBF_IOERROR_FAIL);
- xfs_buf_do_callbacks_fail(bp);
+ ASSERT(list_empty(&bp->b_li_list));
xfs_buf_ioerror(bp, 0);
xfs_buf_relse(bp);
return;