summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf_item.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_buf_item.c')
-rw-r--r--fs/xfs/xfs_buf_item.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index b8d0cd4adb81..0d95c59f7c68 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -1085,6 +1085,9 @@ xfs_buf_iodone_callback_error(
bp->b_flags |= (XBF_WRITE | XBF_ASYNC |
XBF_DONE | XBF_WRITE_FAIL);
bp->b_last_error = bp->b_error;
+ bp->b_retries = 0;
+ bp->b_first_retry_time = jiffies;
+
xfs_buf_ioerror(bp, 0);
xfs_buf_submit(bp);
return true;
@@ -1095,8 +1098,13 @@ xfs_buf_iodone_callback_error(
* error configuration we have been set up to use.
*/
cfg = xfs_error_get_cfg(mp, XFS_ERR_METADATA, bp->b_error);
- if (!cfg->max_retries)
- goto permanent_error;
+
+ if (cfg->max_retries != XFS_ERR_RETRY_FOREVER &&
+ ++bp->b_retries > cfg->max_retries)
+ goto permanent_error;
+ if (cfg->retry_timeout &&
+ time_after(jiffies, cfg->retry_timeout + bp->b_first_retry_time))
+ goto permanent_error;
/* still a transient error, higher layers will retry */
xfs_buf_ioerror(bp, 0);
@@ -1139,6 +1147,7 @@ xfs_buf_iodone_callbacks(
* retry state here in preparation for the next error that may occur.
*/
bp->b_last_error = 0;
+ bp->b_retries = 0;
xfs_buf_do_callbacks(bp);
bp->b_fspriv = NULL;