|
29 | 29 | #include "xfs_error.h"
|
30 | 30 | #include "xfs_trace.h"
|
31 | 31 | #include "xfs_log.h"
|
| 32 | +#include "xfs_inode.h" |
32 | 33 |
|
33 | 34 |
|
34 | 35 | kmem_zone_t *xfs_buf_item_zone;
|
@@ -1054,6 +1055,31 @@ xfs_buf_do_callbacks(
|
1054 | 1055 | }
|
1055 | 1056 | }
|
1056 | 1057 |
|
| 1058 | +/* |
| 1059 | + * Invoke the error state callback for each log item affected by the failed I/O. |
| 1060 | + * |
| 1061 | + * If a metadata buffer write fails with a non-permanent error, the buffer is |
| 1062 | + * eventually resubmitted and so the completion callbacks are not run. The error |
| 1063 | + * state may need to be propagated to the log items attached to the buffer, |
| 1064 | + * however, so the next AIL push of the item knows hot to handle it correctly. |
| 1065 | + */ |
| 1066 | +STATIC void |
| 1067 | +xfs_buf_do_callbacks_fail( |
| 1068 | + struct xfs_buf *bp) |
| 1069 | +{ |
| 1070 | + struct xfs_log_item *next; |
| 1071 | + struct xfs_log_item *lip = bp->b_fspriv; |
| 1072 | + struct xfs_ail *ailp = lip->li_ailp; |
| 1073 | + |
| 1074 | + spin_lock(&ailp->xa_lock); |
| 1075 | + for (; lip; lip = next) { |
| 1076 | + next = lip->li_bio_list; |
| 1077 | + if (lip->li_ops->iop_error) |
| 1078 | + lip->li_ops->iop_error(lip, bp); |
| 1079 | + } |
| 1080 | + spin_unlock(&ailp->xa_lock); |
| 1081 | +} |
| 1082 | + |
1057 | 1083 | static bool
|
1058 | 1084 | xfs_buf_iodone_callback_error(
|
1059 | 1085 | struct xfs_buf *bp)
|
@@ -1123,7 +1149,11 @@ xfs_buf_iodone_callback_error(
|
1123 | 1149 | if ((mp->m_flags & XFS_MOUNT_UNMOUNTING) && mp->m_fail_unmount)
|
1124 | 1150 | goto permanent_error;
|
1125 | 1151 |
|
1126 |
| - /* still a transient error, higher layers will retry */ |
| 1152 | + /* |
| 1153 | + * Still a transient error, run IO completion failure callbacks and let |
| 1154 | + * the higher layers retry the buffer. |
| 1155 | + */ |
| 1156 | + xfs_buf_do_callbacks_fail(bp); |
1127 | 1157 | xfs_buf_ioerror(bp, 0);
|
1128 | 1158 | xfs_buf_relse(bp);
|
1129 | 1159 | return true;
|
|
0 commit comments