aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@redhat.com>2016-09-13 17:51:30 -0400
committerDave Chinner <david@fromorbit.com>2016-09-13 17:51:30 -0400
commit77169812739dd800bc3620d781a77c50c75165cc (patch)
tree7334746af19c67795c61b45287b33b1151c6d6eb /fs/xfs
parent79c350e45ebc5a718cc2d7114b45ad560069423d (diff)
xfs: normalize "infinite" retries in error configs
As it stands today, the "fail immediately" vs. "retry forever" values for max_retries and retry_timeout_seconds in the xfs metadata error configurations are not consistent. A retry_timeout_seconds of 0 means "retry forever," but a max_retries of 0 means "fail immediately." retry_timeout_seconds < 0 is disallowed, while max_retries == -1 means "retry forever." Make this consistent across the error configs, such that a value of 0 means "fail immediately" (i.e. wait 0 seconds, or retry 0 times), and a value of -1 always means "retry forever." This makes retry_timeout a signed long to accommodate the -1, even though it stores jiffies. Given our limit of a 1 day maximum timeout, this should be sufficient even at much higher HZ values than we have available today. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_buf_item.c5
-rw-r--r--fs/xfs/xfs_mount.h8
-rw-r--r--fs/xfs/xfs_sysfs.c47
3 files changed, 45 insertions, 15 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 3a279979c39d..2975cb2319f4 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -1095,7 +1095,8 @@ xfs_buf_iodone_callback_error(
1095 bp->b_last_error != bp->b_error) { 1095 bp->b_last_error != bp->b_error) {
1096 bp->b_flags |= (XBF_WRITE | XBF_DONE | XBF_WRITE_FAIL); 1096 bp->b_flags |= (XBF_WRITE | XBF_DONE | XBF_WRITE_FAIL);
1097 bp->b_last_error = bp->b_error; 1097 bp->b_last_error = bp->b_error;
1098 if (cfg->retry_timeout && !bp->b_first_retry_time) 1098 if (cfg->retry_timeout != XFS_ERR_RETRY_FOREVER &&
1099 !bp->b_first_retry_time)
1099 bp->b_first_retry_time = jiffies; 1100 bp->b_first_retry_time = jiffies;
1100 1101
1101 xfs_buf_ioerror(bp, 0); 1102 xfs_buf_ioerror(bp, 0);
@@ -1111,7 +1112,7 @@ xfs_buf_iodone_callback_error(
1111 if (cfg->max_retries != XFS_ERR_RETRY_FOREVER && 1112 if (cfg->max_retries != XFS_ERR_RETRY_FOREVER &&
1112 ++bp->b_retries > cfg->max_retries) 1113 ++bp->b_retries > cfg->max_retries)
1113 goto permanent_error; 1114 goto permanent_error;
1114 if (cfg->retry_timeout && 1115 if (cfg->retry_timeout != XFS_ERR_RETRY_FOREVER &&
1115 time_after(jiffies, cfg->retry_timeout + bp->b_first_retry_time)) 1116 time_after(jiffies, cfg->retry_timeout + bp->b_first_retry_time))
1116 goto permanent_error; 1117 goto permanent_error;
1117 1118
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index b36676cde103..efd4a5526f37 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -57,10 +57,16 @@ enum {
57 57
58#define XFS_ERR_RETRY_FOREVER -1 58#define XFS_ERR_RETRY_FOREVER -1
59 59
60/*
61 * Although retry_timeout is in jiffies which is normally an unsigned long,
62 * we limit the retry timeout to 86400 seconds, or one day. So even a
63 * signed 32-bit long is sufficient for a HZ value up to 24855. Making it
64 * signed lets us store the special "-1" value, meaning retry forever.
65 */
60struct xfs_error_cfg { 66struct xfs_error_cfg {
61 struct xfs_kobj kobj; 67 struct xfs_kobj kobj;
62 int max_retries; 68 int max_retries;
63 unsigned long retry_timeout; /* in jiffies, 0 = no timeout */ 69 long retry_timeout; /* in jiffies, -1 = infinite */
64}; 70};
65 71
66typedef struct xfs_mount { 72typedef struct xfs_mount {
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c
index 79cfd3fc5324..5f8d55d29a11 100644
--- a/fs/xfs/xfs_sysfs.c
+++ b/fs/xfs/xfs_sysfs.c
@@ -393,9 +393,15 @@ max_retries_show(
393 struct kobject *kobject, 393 struct kobject *kobject,
394 char *buf) 394 char *buf)
395{ 395{
396 int retries;
396 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 397 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
397 398
398 return snprintf(buf, PAGE_SIZE, "%d\n", cfg->max_retries); 399 if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER)
400 retries = -1;
401 else
402 retries = cfg->max_retries;
403
404 return snprintf(buf, PAGE_SIZE, "%d\n", retries);
399} 405}
400 406
401static ssize_t 407static ssize_t
@@ -415,7 +421,10 @@ max_retries_store(
415 if (val < -1) 421 if (val < -1)
416 return -EINVAL; 422 return -EINVAL;
417 423
418 cfg->max_retries = val; 424 if (val == -1)
425 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
426 else
427 cfg->max_retries = val;
419 return count; 428 return count;
420} 429}
421XFS_SYSFS_ATTR_RW(max_retries); 430XFS_SYSFS_ATTR_RW(max_retries);
@@ -425,10 +434,15 @@ retry_timeout_seconds_show(
425 struct kobject *kobject, 434 struct kobject *kobject,
426 char *buf) 435 char *buf)
427{ 436{
437 int timeout;
428 struct xfs_error_cfg *cfg = to_error_cfg(kobject); 438 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
429 439
430 return snprintf(buf, PAGE_SIZE, "%ld\n", 440 if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER)
431 jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC); 441 timeout = -1;
442 else
443 timeout = jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC;
444
445 return snprintf(buf, PAGE_SIZE, "%d\n", timeout);
432} 446}
433 447
434static ssize_t 448static ssize_t
@@ -445,11 +459,16 @@ retry_timeout_seconds_store(
445 if (ret) 459 if (ret)
446 return ret; 460 return ret;
447 461
448 /* 1 day timeout maximum */ 462 /* 1 day timeout maximum, -1 means infinite */
449 if (val < 0 || val > 86400) 463 if (val < -1 || val > 86400)
450 return -EINVAL; 464 return -EINVAL;
451 465
452 cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC); 466 if (val == -1)
467 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
468 else {
469 cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC);
470 ASSERT(msecs_to_jiffies(val * MSEC_PER_SEC) < LONG_MAX);
471 }
453 return count; 472 return count;
454} 473}
455XFS_SYSFS_ATTR_RW(retry_timeout_seconds); 474XFS_SYSFS_ATTR_RW(retry_timeout_seconds);
@@ -519,18 +538,19 @@ struct xfs_error_init {
519static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = { 538static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = {
520 { .name = "default", 539 { .name = "default",
521 .max_retries = XFS_ERR_RETRY_FOREVER, 540 .max_retries = XFS_ERR_RETRY_FOREVER,
522 .retry_timeout = 0, 541 .retry_timeout = XFS_ERR_RETRY_FOREVER,
523 }, 542 },
524 { .name = "EIO", 543 { .name = "EIO",
525 .max_retries = XFS_ERR_RETRY_FOREVER, 544 .max_retries = XFS_ERR_RETRY_FOREVER,
526 .retry_timeout = 0, 545 .retry_timeout = XFS_ERR_RETRY_FOREVER,
527 }, 546 },
528 { .name = "ENOSPC", 547 { .name = "ENOSPC",
529 .max_retries = XFS_ERR_RETRY_FOREVER, 548 .max_retries = XFS_ERR_RETRY_FOREVER,
530 .retry_timeout = 0, 549 .retry_timeout = XFS_ERR_RETRY_FOREVER,
531 }, 550 },
532 { .name = "ENODEV", 551 { .name = "ENODEV",
533 .max_retries = 0, 552 .max_retries = 0, /* We can't recover from devices disappearing */
553 .retry_timeout = 0,
534 }, 554 },
535}; 555};
536 556
@@ -561,7 +581,10 @@ xfs_error_sysfs_init_class(
561 goto out_error; 581 goto out_error;
562 582
563 cfg->max_retries = init[i].max_retries; 583 cfg->max_retries = init[i].max_retries;
564 cfg->retry_timeout = msecs_to_jiffies( 584 if (init[i].retry_timeout == XFS_ERR_RETRY_FOREVER)
585 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
586 else
587 cfg->retry_timeout = msecs_to_jiffies(
565 init[i].retry_timeout * MSEC_PER_SEC); 588 init[i].retry_timeout * MSEC_PER_SEC);
566 } 589 }
567 return 0; 590 return 0;