summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_buf_item.c
diff options
context:
space:
mode:
authorCarlos Maiolino <cmaiolino@redhat.com>2016-05-18 11:08:15 +1000
committerDave Chinner <david@fromorbit.com>2016-05-18 11:08:15 +1000
commita5ea70d25d76950e11690110b526374307d05d81 (patch)
tree8b131bde696d1ed8e887f4ebcd0a82059ad2eba4 /fs/xfs/xfs_buf_item.c
parentef6a50fbb1bba7951aa23adcfb40e99ca72dc51c (diff)
xfs: add configuration of error failure speed
On reception of an error, we can fail immediately, perform some bound amount of retries or retry indefinitely. The current behaviour we have is to retry forever. However, we'd like the ability to choose how long the filesystem should try after an error, it can either fail immediately, retry a few times, or retry forever. This is implemented by using max_retries sysfs attribute, to hold the amount of times we allow the filesystem to retry after an error. Being -1 a special case where the filesystem will retry indefinitely. Add both a maximum retry count and a retry timeout so that we can bound by time and/or physical IO attempts. Finally, plumb these into xfs_buf_iodone error processing so that the error behaviour follows the selected configuration. Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
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;