diff options
Diffstat (limited to 'fs/xfs/xfs_buf_item.c')
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 13 |
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; |