diff options
-rw-r--r-- | fs/xfs/xfs_globals.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 12 | ||||
-rw-r--r-- | fs/xfs/xfs_sysctl.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_sysfs.c | 31 |
4 files changed, 52 insertions, 0 deletions
diff --git a/fs/xfs/xfs_globals.c b/fs/xfs/xfs_globals.c index 5399ef222dd7..4d41b241298f 100644 --- a/fs/xfs/xfs_globals.c +++ b/fs/xfs/xfs_globals.c | |||
@@ -43,3 +43,7 @@ xfs_param_t xfs_params = { | |||
43 | .fstrm_timer = { 1, 30*100, 3600*100}, | 43 | .fstrm_timer = { 1, 30*100, 3600*100}, |
44 | .eofb_timer = { 1, 300, 3600*24}, | 44 | .eofb_timer = { 1, 300, 3600*24}, |
45 | }; | 45 | }; |
46 | |||
47 | struct xfs_globals xfs_globals = { | ||
48 | .log_recovery_delay = 0, /* no delay by default */ | ||
49 | }; | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1fd5787add99..176c4b3609ab 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -4509,6 +4509,18 @@ xlog_recover( | |||
4509 | return -EINVAL; | 4509 | return -EINVAL; |
4510 | } | 4510 | } |
4511 | 4511 | ||
4512 | /* | ||
4513 | * Delay log recovery if the debug hook is set. This is debug | ||
4514 | * instrumention to coordinate simulation of I/O failures with | ||
4515 | * log recovery. | ||
4516 | */ | ||
4517 | if (xfs_globals.log_recovery_delay) { | ||
4518 | xfs_notice(log->l_mp, | ||
4519 | "Delaying log recovery for %d seconds.", | ||
4520 | xfs_globals.log_recovery_delay); | ||
4521 | msleep(xfs_globals.log_recovery_delay * 1000); | ||
4522 | } | ||
4523 | |||
4512 | xfs_notice(log->l_mp, "Starting recovery (logdev: %s)", | 4524 | xfs_notice(log->l_mp, "Starting recovery (logdev: %s)", |
4513 | log->l_mp->m_logname ? log->l_mp->m_logname | 4525 | log->l_mp->m_logname ? log->l_mp->m_logname |
4514 | : "internal"); | 4526 | : "internal"); |
diff --git a/fs/xfs/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h index bd8e157c20ef..ffef45375754 100644 --- a/fs/xfs/xfs_sysctl.h +++ b/fs/xfs/xfs_sysctl.h | |||
@@ -92,6 +92,11 @@ enum { | |||
92 | 92 | ||
93 | extern xfs_param_t xfs_params; | 93 | extern xfs_param_t xfs_params; |
94 | 94 | ||
95 | struct xfs_globals { | ||
96 | int log_recovery_delay; /* log recovery delay (secs) */ | ||
97 | }; | ||
98 | extern struct xfs_globals xfs_globals; | ||
99 | |||
95 | #ifdef CONFIG_SYSCTL | 100 | #ifdef CONFIG_SYSCTL |
96 | extern int xfs_sysctl_register(void); | 101 | extern int xfs_sysctl_register(void); |
97 | extern void xfs_sysctl_unregister(void); | 102 | extern void xfs_sysctl_unregister(void); |
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index 32ddf0c8c50e..aa03670851d8 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c | |||
@@ -54,7 +54,38 @@ struct kobj_type xfs_mp_ktype = { | |||
54 | #ifdef DEBUG | 54 | #ifdef DEBUG |
55 | /* debug */ | 55 | /* debug */ |
56 | 56 | ||
57 | STATIC ssize_t | ||
58 | log_recovery_delay_store( | ||
59 | const char *buf, | ||
60 | size_t count, | ||
61 | void *data) | ||
62 | { | ||
63 | int ret; | ||
64 | int val; | ||
65 | |||
66 | ret = kstrtoint(buf, 0, &val); | ||
67 | if (ret) | ||
68 | return ret; | ||
69 | |||
70 | if (val < 0 || val > 60) | ||
71 | return -EINVAL; | ||
72 | |||
73 | xfs_globals.log_recovery_delay = val; | ||
74 | |||
75 | return count; | ||
76 | } | ||
77 | |||
78 | STATIC ssize_t | ||
79 | log_recovery_delay_show( | ||
80 | char *buf, | ||
81 | void *data) | ||
82 | { | ||
83 | return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay); | ||
84 | } | ||
85 | XFS_SYSFS_ATTR_RW(log_recovery_delay); | ||
86 | |||
57 | static struct attribute *xfs_dbg_attrs[] = { | 87 | static struct attribute *xfs_dbg_attrs[] = { |
88 | ATTR_LIST(log_recovery_delay), | ||
58 | NULL, | 89 | NULL, |
59 | }; | 90 | }; |
60 | 91 | ||