aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_buf.c12
-rw-r--r--fs/xfs/xfs_buf.h20
-rw-r--r--fs/xfs/xfs_buf_item.c121
-rw-r--r--fs/xfs/xfs_mount.c22
-rw-r--r--fs/xfs/xfs_mount.h34
-rw-r--r--fs/xfs/xfs_sysfs.c291
-rw-r--r--fs/xfs/xfs_sysfs.h3
-rw-r--r--fs/xfs/xfs_trace.h1
8 files changed, 450 insertions, 54 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 9a2191b91137..e71cfbd5acb3 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1100,22 +1100,18 @@ xfs_bwrite(
1100 return error; 1100 return error;
1101} 1101}
1102 1102
1103STATIC void 1103static void
1104xfs_buf_bio_end_io( 1104xfs_buf_bio_end_io(
1105 struct bio *bio) 1105 struct bio *bio)
1106{ 1106{
1107 xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; 1107 struct xfs_buf *bp = (struct xfs_buf *)bio->bi_private;
1108 1108
1109 /* 1109 /*
1110 * don't overwrite existing errors - otherwise we can lose errors on 1110 * don't overwrite existing errors - otherwise we can lose errors on
1111 * buffers that require multiple bios to complete. 1111 * buffers that require multiple bios to complete.
1112 */ 1112 */
1113 if (bio->bi_error) { 1113 if (bio->bi_error)
1114 spin_lock(&bp->b_lock); 1114 cmpxchg(&bp->b_io_error, 0, bio->bi_error);
1115 if (!bp->b_io_error)
1116 bp->b_io_error = bio->bi_error;
1117 spin_unlock(&bp->b_lock);
1118 }
1119 1115
1120 if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) 1116 if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
1121 invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); 1117 invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp));
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 4eb89bd4ee73..8bfb974f0772 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -183,6 +183,26 @@ typedef struct xfs_buf {
183 unsigned int b_page_count; /* size of page array */ 183 unsigned int b_page_count; /* size of page array */
184 unsigned int b_offset; /* page offset in first page */ 184 unsigned int b_offset; /* page offset in first page */
185 int b_error; /* error code on I/O */ 185 int b_error; /* error code on I/O */
186
187 /*
188 * async write failure retry count. Initialised to zero on the first
189 * failure, then when it exceeds the maximum configured without a
190 * success the write is considered to be failed permanently and the
191 * iodone handler will take appropriate action.
192 *
193 * For retry timeouts, we record the jiffie of the first failure. This
194 * means that we can change the retry timeout for buffers already under
195 * I/O and thus avoid getting stuck in a retry loop with a long timeout.
196 *
197 * last_error is used to ensure that we are getting repeated errors, not
198 * different errors. e.g. a block device might change ENOSPC to EIO when
199 * a failure timeout occurs, so we want to re-initialise the error
200 * retry behaviour appropriately when that happens.
201 */
202 int b_retries;
203 unsigned long b_first_retry_time; /* in jiffies */
204 int b_last_error;
205
186 const struct xfs_buf_ops *b_ops; 206 const struct xfs_buf_ops *b_ops;
187 207
188#ifdef XFS_BUF_LOCK_TRACKING 208#ifdef XFS_BUF_LOCK_TRACKING
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 99e91a0e554e..34257992934c 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -1042,35 +1042,22 @@ xfs_buf_do_callbacks(
1042 } 1042 }
1043} 1043}
1044 1044
1045/* 1045static bool
1046 * This is the iodone() function for buffers which have had callbacks 1046xfs_buf_iodone_callback_error(
1047 * attached to them by xfs_buf_attach_iodone(). It should remove each
1048 * log item from the buffer's list and call the callback of each in turn.
1049 * When done, the buffer's fsprivate field is set to NULL and the buffer
1050 * is unlocked with a call to iodone().
1051 */
1052void
1053xfs_buf_iodone_callbacks(
1054 struct xfs_buf *bp) 1047 struct xfs_buf *bp)
1055{ 1048{
1056 struct xfs_log_item *lip = bp->b_fspriv; 1049 struct xfs_log_item *lip = bp->b_fspriv;
1057 struct xfs_mount *mp = lip->li_mountp; 1050 struct xfs_mount *mp = lip->li_mountp;
1058 static ulong lasttime; 1051 static ulong lasttime;
1059 static xfs_buftarg_t *lasttarg; 1052 static xfs_buftarg_t *lasttarg;
1060 1053 struct xfs_error_cfg *cfg;
1061 if (likely(!bp->b_error))
1062 goto do_callbacks;
1063 1054
1064 /* 1055 /*
1065 * If we've already decided to shutdown the filesystem because of 1056 * If we've already decided to shutdown the filesystem because of
1066 * I/O errors, there's no point in giving this a retry. 1057 * I/O errors, there's no point in giving this a retry.
1067 */ 1058 */
1068 if (XFS_FORCED_SHUTDOWN(mp)) { 1059 if (XFS_FORCED_SHUTDOWN(mp))
1069 xfs_buf_stale(bp); 1060 goto out_stale;
1070 bp->b_flags |= XBF_DONE;
1071 trace_xfs_buf_item_iodone(bp, _RET_IP_);
1072 goto do_callbacks;
1073 }
1074 1061
1075 if (bp->b_target != lasttarg || 1062 if (bp->b_target != lasttarg ||
1076 time_after(jiffies, (lasttime + 5*HZ))) { 1063 time_after(jiffies, (lasttime + 5*HZ))) {
@@ -1079,45 +1066,93 @@ xfs_buf_iodone_callbacks(
1079 } 1066 }
1080 lasttarg = bp->b_target; 1067 lasttarg = bp->b_target;
1081 1068
1069 /* synchronous writes will have callers process the error */
1070 if (!(bp->b_flags & XBF_ASYNC))
1071 goto out_stale;
1072
1073 trace_xfs_buf_item_iodone_async(bp, _RET_IP_);
1074 ASSERT(bp->b_iodone != NULL);
1075
1082 /* 1076 /*
1083 * If the write was asynchronous then no one will be looking for the 1077 * If the write was asynchronous then no one will be looking for the
1084 * error. Clear the error state and write the buffer out again. 1078 * error. If this is the first failure of this type, clear the error
1085 * 1079 * state and write the buffer out again. This means we always retry an
1086 * XXX: This helps against transient write errors, but we need to find 1080 * async write failure at least once, but we also need to set the buffer
1087 * a way to shut the filesystem down if the writes keep failing. 1081 * up to behave correctly now for repeated failures.
1088 *
1089 * In practice we'll shut the filesystem down soon as non-transient
1090 * errors tend to affect the whole device and a failing log write
1091 * will make us give up. But we really ought to do better here.
1092 */ 1082 */
1093 if (bp->b_flags & XBF_ASYNC) { 1083 if (!(bp->b_flags & (XBF_STALE|XBF_WRITE_FAIL)) ||
1094 ASSERT(bp->b_iodone != NULL); 1084 bp->b_last_error != bp->b_error) {
1085 bp->b_flags |= (XBF_WRITE | XBF_ASYNC |
1086 XBF_DONE | XBF_WRITE_FAIL);
1087 bp->b_last_error = bp->b_error;
1088 bp->b_retries = 0;
1089 bp->b_first_retry_time = jiffies;
1090
1091 xfs_buf_ioerror(bp, 0);
1092 xfs_buf_submit(bp);
1093 return true;
1094 }
1095 1095
1096 trace_xfs_buf_item_iodone_async(bp, _RET_IP_); 1096 /*
1097 * Repeated failure on an async write. Take action according to the
1098 * error configuration we have been set up to use.
1099 */
1100 cfg = xfs_error_get_cfg(mp, XFS_ERR_METADATA, bp->b_error);
1097 1101
1098 xfs_buf_ioerror(bp, 0); /* errno of 0 unsets the flag */ 1102 if (cfg->max_retries != XFS_ERR_RETRY_FOREVER &&
1103 ++bp->b_retries > cfg->max_retries)
1104 goto permanent_error;
1105 if (cfg->retry_timeout &&
1106 time_after(jiffies, cfg->retry_timeout + bp->b_first_retry_time))
1107 goto permanent_error;
1099 1108
1100 if (!(bp->b_flags & (XBF_STALE|XBF_WRITE_FAIL))) { 1109 /* At unmount we may treat errors differently */
1101 bp->b_flags |= XBF_WRITE | XBF_ASYNC | 1110 if ((mp->m_flags & XFS_MOUNT_UNMOUNTING) && mp->m_fail_unmount)
1102 XBF_DONE | XBF_WRITE_FAIL; 1111 goto permanent_error;
1103 xfs_buf_submit(bp);
1104 } else {
1105 xfs_buf_relse(bp);
1106 }
1107 1112
1108 return; 1113 /* still a transient error, higher layers will retry */
1109 } 1114 xfs_buf_ioerror(bp, 0);
1115 xfs_buf_relse(bp);
1116 return true;
1110 1117
1111 /* 1118 /*
1112 * If the write of the buffer was synchronous, we want to make 1119 * Permanent error - we need to trigger a shutdown if we haven't already
1113 * sure to return the error to the caller of xfs_bwrite(). 1120 * to indicate that inconsistency will result from this action.
1114 */ 1121 */
1122permanent_error:
1123 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1124out_stale:
1115 xfs_buf_stale(bp); 1125 xfs_buf_stale(bp);
1116 bp->b_flags |= XBF_DONE; 1126 bp->b_flags |= XBF_DONE;
1117
1118 trace_xfs_buf_error_relse(bp, _RET_IP_); 1127 trace_xfs_buf_error_relse(bp, _RET_IP_);
1128 return false;
1129}
1130
1131/*
1132 * This is the iodone() function for buffers which have had callbacks attached
1133 * to them by xfs_buf_attach_iodone(). We need to iterate the items on the
1134 * callback list, mark the buffer as having no more callbacks and then push the
1135 * buffer through IO completion processing.
1136 */
1137void
1138xfs_buf_iodone_callbacks(
1139 struct xfs_buf *bp)
1140{
1141 /*
1142 * If there is an error, process it. Some errors require us
1143 * to run callbacks after failure processing is done so we
1144 * detect that and take appropriate action.
1145 */
1146 if (bp->b_error && xfs_buf_iodone_callback_error(bp))
1147 return;
1148
1149 /*
1150 * Successful IO or permanent error. Either way, we can clear the
1151 * retry state here in preparation for the next error that may occur.
1152 */
1153 bp->b_last_error = 0;
1154 bp->b_retries = 0;
1119 1155
1120do_callbacks:
1121 xfs_buf_do_callbacks(bp); 1156 xfs_buf_do_callbacks(bp);
1122 bp->b_fspriv = NULL; 1157 bp->b_fspriv = NULL;
1123 bp->b_iodone = NULL; 1158 bp->b_iodone = NULL;
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 654799f716fc..3b67b1470664 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -680,6 +680,9 @@ xfs_mountfs(
680 680
681 xfs_set_maxicount(mp); 681 xfs_set_maxicount(mp);
682 682
683 /* enable fail_at_unmount as default */
684 mp->m_fail_unmount = 1;
685
683 error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, NULL, mp->m_fsname); 686 error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, NULL, mp->m_fsname);
684 if (error) 687 if (error)
685 goto out; 688 goto out;
@@ -689,10 +692,15 @@ xfs_mountfs(
689 if (error) 692 if (error)
690 goto out_remove_sysfs; 693 goto out_remove_sysfs;
691 694
692 error = xfs_uuid_mount(mp); 695 error = xfs_error_sysfs_init(mp);
693 if (error) 696 if (error)
694 goto out_del_stats; 697 goto out_del_stats;
695 698
699
700 error = xfs_uuid_mount(mp);
701 if (error)
702 goto out_remove_error_sysfs;
703
696 /* 704 /*
697 * Set the minimum read and write sizes 705 * Set the minimum read and write sizes
698 */ 706 */
@@ -956,6 +964,7 @@ xfs_mountfs(
956 cancel_delayed_work_sync(&mp->m_reclaim_work); 964 cancel_delayed_work_sync(&mp->m_reclaim_work);
957 xfs_reclaim_inodes(mp, SYNC_WAIT); 965 xfs_reclaim_inodes(mp, SYNC_WAIT);
958 out_log_dealloc: 966 out_log_dealloc:
967 mp->m_flags |= XFS_MOUNT_UNMOUNTING;
959 xfs_log_mount_cancel(mp); 968 xfs_log_mount_cancel(mp);
960 out_fail_wait: 969 out_fail_wait:
961 if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) 970 if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp)
@@ -967,6 +976,8 @@ xfs_mountfs(
967 xfs_da_unmount(mp); 976 xfs_da_unmount(mp);
968 out_remove_uuid: 977 out_remove_uuid:
969 xfs_uuid_unmount(mp); 978 xfs_uuid_unmount(mp);
979 out_remove_error_sysfs:
980 xfs_error_sysfs_del(mp);
970 out_del_stats: 981 out_del_stats:
971 xfs_sysfs_del(&mp->m_stats.xs_kobj); 982 xfs_sysfs_del(&mp->m_stats.xs_kobj);
972 out_remove_sysfs: 983 out_remove_sysfs:
@@ -1005,6 +1016,14 @@ xfs_unmountfs(
1005 xfs_log_force(mp, XFS_LOG_SYNC); 1016 xfs_log_force(mp, XFS_LOG_SYNC);
1006 1017
1007 /* 1018 /*
1019 * We now need to tell the world we are unmounting. This will allow
1020 * us to detect that the filesystem is going away and we should error
1021 * out anything that we have been retrying in the background. This will
1022 * prevent neverending retries in AIL pushing from hanging the unmount.
1023 */
1024 mp->m_flags |= XFS_MOUNT_UNMOUNTING;
1025
1026 /*
1008 * Flush all pending changes from the AIL. 1027 * Flush all pending changes from the AIL.
1009 */ 1028 */
1010 xfs_ail_push_all_sync(mp->m_ail); 1029 xfs_ail_push_all_sync(mp->m_ail);
@@ -1055,6 +1074,7 @@ xfs_unmountfs(
1055#endif 1074#endif
1056 xfs_free_perag(mp); 1075 xfs_free_perag(mp);
1057 1076
1077 xfs_error_sysfs_del(mp);
1058 xfs_sysfs_del(&mp->m_stats.xs_kobj); 1078 xfs_sysfs_del(&mp->m_stats.xs_kobj);
1059 xfs_sysfs_del(&mp->m_kobj); 1079 xfs_sysfs_del(&mp->m_kobj);
1060} 1080}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index bac6b3435591..9063a9c7b2fe 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -37,6 +37,32 @@ enum {
37 XFS_LOWSP_MAX, 37 XFS_LOWSP_MAX,
38}; 38};
39 39
40/*
41 * Error Configuration
42 *
43 * Error classes define the subsystem the configuration belongs to.
44 * Error numbers define the errors that are configurable.
45 */
46enum {
47 XFS_ERR_METADATA,
48 XFS_ERR_CLASS_MAX,
49};
50enum {
51 XFS_ERR_DEFAULT,
52 XFS_ERR_EIO,
53 XFS_ERR_ENOSPC,
54 XFS_ERR_ENODEV,
55 XFS_ERR_ERRNO_MAX,
56};
57
58#define XFS_ERR_RETRY_FOREVER -1
59
60struct xfs_error_cfg {
61 struct xfs_kobj kobj;
62 int max_retries;
63 unsigned long retry_timeout; /* in jiffies, 0 = no timeout */
64};
65
40typedef struct xfs_mount { 66typedef struct xfs_mount {
41 struct super_block *m_super; 67 struct super_block *m_super;
42 xfs_tid_t m_tid; /* next unused tid for fs */ 68 xfs_tid_t m_tid; /* next unused tid for fs */
@@ -127,6 +153,9 @@ typedef struct xfs_mount {
127 int64_t m_low_space[XFS_LOWSP_MAX]; 153 int64_t m_low_space[XFS_LOWSP_MAX];
128 /* low free space thresholds */ 154 /* low free space thresholds */
129 struct xfs_kobj m_kobj; 155 struct xfs_kobj m_kobj;
156 struct xfs_kobj m_error_kobj;
157 struct xfs_kobj m_error_meta_kobj;
158 struct xfs_error_cfg m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX];
130 struct xstats m_stats; /* per-fs stats */ 159 struct xstats m_stats; /* per-fs stats */
131 160
132 struct workqueue_struct *m_buf_workqueue; 161 struct workqueue_struct *m_buf_workqueue;
@@ -148,6 +177,7 @@ typedef struct xfs_mount {
148 */ 177 */
149 __uint32_t m_generation; 178 __uint32_t m_generation;
150 179
180 bool m_fail_unmount;
151#ifdef DEBUG 181#ifdef DEBUG
152 /* 182 /*
153 * DEBUG mode instrumentation to test and/or trigger delayed allocation 183 * DEBUG mode instrumentation to test and/or trigger delayed allocation
@@ -166,6 +196,7 @@ typedef struct xfs_mount {
166#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops 196#define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops
167 must be synchronous except 197 must be synchronous except
168 for space allocations */ 198 for space allocations */
199#define XFS_MOUNT_UNMOUNTING (1ULL << 1) /* filesystem is unmounting */
169#define XFS_MOUNT_WAS_CLEAN (1ULL << 3) 200#define XFS_MOUNT_WAS_CLEAN (1ULL << 3)
170#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem 201#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
171 operations, typically for 202 operations, typically for
@@ -364,4 +395,7 @@ extern void xfs_set_low_space_thresholds(struct xfs_mount *);
364int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, 395int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb,
365 xfs_off_t count_fsb); 396 xfs_off_t count_fsb);
366 397
398struct xfs_error_cfg * xfs_error_get_cfg(struct xfs_mount *mp,
399 int error_class, int error);
400
367#endif /* __XFS_MOUNT_H__ */ 401#endif /* __XFS_MOUNT_H__ */
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c
index 6ced4f143494..4c2c55086208 100644
--- a/fs/xfs/xfs_sysfs.c
+++ b/fs/xfs/xfs_sysfs.c
@@ -17,10 +17,11 @@
17 */ 17 */
18 18
19#include "xfs.h" 19#include "xfs.h"
20#include "xfs_sysfs.h" 20#include "xfs_shared.h"
21#include "xfs_format.h" 21#include "xfs_format.h"
22#include "xfs_log_format.h" 22#include "xfs_log_format.h"
23#include "xfs_trans_resv.h" 23#include "xfs_trans_resv.h"
24#include "xfs_sysfs.h"
24#include "xfs_log.h" 25#include "xfs_log.h"
25#include "xfs_log_priv.h" 26#include "xfs_log_priv.h"
26#include "xfs_stats.h" 27#include "xfs_stats.h"
@@ -362,3 +363,291 @@ struct kobj_type xfs_log_ktype = {
362 .sysfs_ops = &xfs_sysfs_ops, 363 .sysfs_ops = &xfs_sysfs_ops,
363 .default_attrs = xfs_log_attrs, 364 .default_attrs = xfs_log_attrs,
364}; 365};
366
367/*
368 * Metadata IO error configuration
369 *
370 * The sysfs structure here is:
371 * ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
372 *
373 * where <class> allows us to discriminate between data IO and metadata IO,
374 * and any other future type of IO (e.g. special inode or directory error
375 * handling) we care to support.
376 */
377static inline struct xfs_error_cfg *
378to_error_cfg(struct kobject *kobject)
379{
380 struct xfs_kobj *kobj = to_kobj(kobject);
381 return container_of(kobj, struct xfs_error_cfg, kobj);
382}
383
384static inline struct xfs_mount *
385err_to_mp(struct kobject *kobject)
386{
387 struct xfs_kobj *kobj = to_kobj(kobject);
388 return container_of(kobj, struct xfs_mount, m_error_kobj);
389}
390
391static ssize_t
392max_retries_show(
393 struct kobject *kobject,
394 char *buf)
395{
396 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
397
398 return snprintf(buf, PAGE_SIZE, "%d\n", cfg->max_retries);
399}
400
401static ssize_t
402max_retries_store(
403 struct kobject *kobject,
404 const char *buf,
405 size_t count)
406{
407 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
408 int ret;
409 int val;
410
411 ret = kstrtoint(buf, 0, &val);
412 if (ret)
413 return ret;
414
415 if (val < -1)
416 return -EINVAL;
417
418 cfg->max_retries = val;
419 return count;
420}
421XFS_SYSFS_ATTR_RW(max_retries);
422
423static ssize_t
424retry_timeout_seconds_show(
425 struct kobject *kobject,
426 char *buf)
427{
428 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
429
430 return snprintf(buf, PAGE_SIZE, "%ld\n",
431 jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC);
432}
433
434static ssize_t
435retry_timeout_seconds_store(
436 struct kobject *kobject,
437 const char *buf,
438 size_t count)
439{
440 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
441 int ret;
442 int val;
443
444 ret = kstrtoint(buf, 0, &val);
445 if (ret)
446 return ret;
447
448 /* 1 day timeout maximum */
449 if (val < 0 || val > 86400)
450 return -EINVAL;
451
452 cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC);
453 return count;
454}
455XFS_SYSFS_ATTR_RW(retry_timeout_seconds);
456
457static ssize_t
458fail_at_unmount_show(
459 struct kobject *kobject,
460 char *buf)
461{
462 struct xfs_mount *mp = err_to_mp(kobject);
463
464 return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_fail_unmount);
465}
466
467static ssize_t
468fail_at_unmount_store(
469 struct kobject *kobject,
470 const char *buf,
471 size_t count)
472{
473 struct xfs_mount *mp = err_to_mp(kobject);
474 int ret;
475 int val;
476
477 ret = kstrtoint(buf, 0, &val);
478 if (ret)
479 return ret;
480
481 if (val < 0 || val > 1)
482 return -EINVAL;
483
484 mp->m_fail_unmount = val;
485 return count;
486}
487XFS_SYSFS_ATTR_RW(fail_at_unmount);
488
489static struct attribute *xfs_error_attrs[] = {
490 ATTR_LIST(max_retries),
491 ATTR_LIST(retry_timeout_seconds),
492 NULL,
493};
494
495
496struct kobj_type xfs_error_cfg_ktype = {
497 .release = xfs_sysfs_release,
498 .sysfs_ops = &xfs_sysfs_ops,
499 .default_attrs = xfs_error_attrs,
500};
501
502struct kobj_type xfs_error_ktype = {
503 .release = xfs_sysfs_release,
504 .sysfs_ops = &xfs_sysfs_ops,
505};
506
507/*
508 * Error initialization tables. These need to be ordered in the same
509 * order as the enums used to index the array. All class init tables need to
510 * define a "default" behaviour as the first entry, all other entries can be
511 * empty.
512 */
513struct xfs_error_init {
514 char *name;
515 int max_retries;
516 int retry_timeout; /* in seconds */
517};
518
519static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = {
520 { .name = "default",
521 .max_retries = XFS_ERR_RETRY_FOREVER,
522 .retry_timeout = 0,
523 },
524 { .name = "EIO",
525 .max_retries = XFS_ERR_RETRY_FOREVER,
526 .retry_timeout = 0,
527 },
528 { .name = "ENOSPC",
529 .max_retries = XFS_ERR_RETRY_FOREVER,
530 .retry_timeout = 0,
531 },
532 { .name = "ENODEV",
533 .max_retries = 0,
534 },
535};
536
537static int
538xfs_error_sysfs_init_class(
539 struct xfs_mount *mp,
540 int class,
541 const char *parent_name,
542 struct xfs_kobj *parent_kobj,
543 const struct xfs_error_init init[])
544{
545 struct xfs_error_cfg *cfg;
546 int error;
547 int i;
548
549 ASSERT(class < XFS_ERR_CLASS_MAX);
550
551 error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype,
552 &mp->m_error_kobj, parent_name);
553 if (error)
554 return error;
555
556 for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) {
557 cfg = &mp->m_error_cfg[class][i];
558 error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype,
559 parent_kobj, init[i].name);
560 if (error)
561 goto out_error;
562
563 cfg->max_retries = init[i].max_retries;
564 cfg->retry_timeout = msecs_to_jiffies(
565 init[i].retry_timeout * MSEC_PER_SEC);
566 }
567 return 0;
568
569out_error:
570 /* unwind the entries that succeeded */
571 for (i--; i >= 0; i--) {
572 cfg = &mp->m_error_cfg[class][i];
573 xfs_sysfs_del(&cfg->kobj);
574 }
575 xfs_sysfs_del(parent_kobj);
576 return error;
577}
578
579int
580xfs_error_sysfs_init(
581 struct xfs_mount *mp)
582{
583 int error;
584
585 /* .../xfs/<dev>/error/ */
586 error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
587 &mp->m_kobj, "error");
588 if (error)
589 return error;
590
591 error = sysfs_create_file(&mp->m_error_kobj.kobject,
592 ATTR_LIST(fail_at_unmount));
593
594 if (error)
595 goto out_error;
596
597 /* .../xfs/<dev>/error/metadata/ */
598 error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA,
599 "metadata", &mp->m_error_meta_kobj,
600 xfs_error_meta_init);
601 if (error)
602 goto out_error;
603
604 return 0;
605
606out_error:
607 xfs_sysfs_del(&mp->m_error_kobj);
608 return error;
609}
610
611void
612xfs_error_sysfs_del(
613 struct xfs_mount *mp)
614{
615 struct xfs_error_cfg *cfg;
616 int i, j;
617
618 for (i = 0; i < XFS_ERR_CLASS_MAX; i++) {
619 for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) {
620 cfg = &mp->m_error_cfg[i][j];
621
622 xfs_sysfs_del(&cfg->kobj);
623 }
624 }
625 xfs_sysfs_del(&mp->m_error_meta_kobj);
626 xfs_sysfs_del(&mp->m_error_kobj);
627}
628
629struct xfs_error_cfg *
630xfs_error_get_cfg(
631 struct xfs_mount *mp,
632 int error_class,
633 int error)
634{
635 struct xfs_error_cfg *cfg;
636
637 switch (error) {
638 case EIO:
639 cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO];
640 break;
641 case ENOSPC:
642 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC];
643 break;
644 case ENODEV:
645 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV];
646 break;
647 default:
648 cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT];
649 break;
650 }
651
652 return cfg;
653}
diff --git a/fs/xfs/xfs_sysfs.h b/fs/xfs/xfs_sysfs.h
index be692e59938d..d04637181ef2 100644
--- a/fs/xfs/xfs_sysfs.h
+++ b/fs/xfs/xfs_sysfs.h
@@ -58,4 +58,7 @@ xfs_sysfs_del(
58 wait_for_completion(&kobj->complete); 58 wait_for_completion(&kobj->complete);
59} 59}
60 60
61int xfs_error_sysfs_init(struct xfs_mount *mp);
62void xfs_error_sysfs_del(struct xfs_mount *mp);
63
61#endif /* __XFS_SYSFS_H__ */ 64#endif /* __XFS_SYSFS_H__ */
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 840d52e38f10..ea94ee0fe5ea 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -364,7 +364,6 @@ DEFINE_BUF_EVENT(xfs_buf_delwri_split);
364DEFINE_BUF_EVENT(xfs_buf_get_uncached); 364DEFINE_BUF_EVENT(xfs_buf_get_uncached);
365DEFINE_BUF_EVENT(xfs_bdstrat_shut); 365DEFINE_BUF_EVENT(xfs_bdstrat_shut);
366DEFINE_BUF_EVENT(xfs_buf_item_relse); 366DEFINE_BUF_EVENT(xfs_buf_item_relse);
367DEFINE_BUF_EVENT(xfs_buf_item_iodone);
368DEFINE_BUF_EVENT(xfs_buf_item_iodone_async); 367DEFINE_BUF_EVENT(xfs_buf_item_iodone_async);
369DEFINE_BUF_EVENT(xfs_buf_error_relse); 368DEFINE_BUF_EVENT(xfs_buf_error_relse);
370DEFINE_BUF_EVENT(xfs_buf_wait_buftarg); 369DEFINE_BUF_EVENT(xfs_buf_wait_buftarg);