hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/xfs/xfs_error.c
....@@ -4,6 +4,7 @@
44 * All Rights Reserved.
55 */
66 #include "xfs.h"
7
+#include "xfs_shared.h"
78 #include "xfs_format.h"
89 #include "xfs_fs.h"
910 #include "xfs_log_format.h"
....@@ -51,6 +52,8 @@
5152 XFS_RANDOM_BUF_LRU_REF,
5253 XFS_RANDOM_FORCE_SCRUB_REPAIR,
5354 XFS_RANDOM_FORCE_SUMMARY_RECALC,
55
+ XFS_RANDOM_IUNLINK_FALLBACK,
56
+ XFS_RANDOM_BUF_IOERROR,
5457 };
5558
5659 struct xfs_errortag_attr {
....@@ -159,6 +162,8 @@
159162 XFS_ERRORTAG_ATTR_RW(buf_lru_ref, XFS_ERRTAG_BUF_LRU_REF);
160163 XFS_ERRORTAG_ATTR_RW(force_repair, XFS_ERRTAG_FORCE_SCRUB_REPAIR);
161164 XFS_ERRORTAG_ATTR_RW(bad_summary, XFS_ERRTAG_FORCE_SUMMARY_RECALC);
165
+XFS_ERRORTAG_ATTR_RW(iunlink_fallback, XFS_ERRTAG_IUNLINK_FALLBACK);
166
+XFS_ERRORTAG_ATTR_RW(buf_ioerror, XFS_ERRTAG_BUF_IOERROR);
162167
163168 static struct attribute *xfs_errortag_attrs[] = {
164169 XFS_ERRORTAG_ATTR_LIST(noerror),
....@@ -195,6 +200,8 @@
195200 XFS_ERRORTAG_ATTR_LIST(buf_lru_ref),
196201 XFS_ERRORTAG_ATTR_LIST(force_repair),
197202 XFS_ERRORTAG_ATTR_LIST(bad_summary),
203
+ XFS_ERRORTAG_ATTR_LIST(iunlink_fallback),
204
+ XFS_ERRORTAG_ATTR_LIST(buf_ioerror),
198205 NULL,
199206 };
200207
....@@ -209,7 +216,7 @@
209216 struct xfs_mount *mp)
210217 {
211218 mp->m_errortag = kmem_zalloc(sizeof(unsigned int) * XFS_ERRTAG_MAX,
212
- KM_SLEEP | KM_MAYFAIL);
219
+ KM_MAYFAIL);
213220 if (!mp->m_errortag)
214221 return -ENOMEM;
215222
....@@ -253,7 +260,7 @@
253260
254261 xfs_warn_ratelimited(mp,
255262 "Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
256
- expression, file, line, mp->m_fsname);
263
+ expression, file, line, mp->m_super->s_id);
257264 return true;
258265 }
259266
....@@ -286,6 +293,8 @@
286293 struct xfs_mount *mp,
287294 unsigned int error_tag)
288295 {
296
+ BUILD_BUG_ON(ARRAY_SIZE(xfs_errortag_random_default) != XFS_ERRTAG_MAX);
297
+
289298 if (error_tag >= XFS_ERRTAG_MAX)
290299 return -EINVAL;
291300
....@@ -325,16 +334,40 @@
325334 const char *tag,
326335 int level,
327336 struct xfs_mount *mp,
328
- void *buf,
337
+ const void *buf,
329338 size_t bufsize,
330339 const char *filename,
331340 int linenum,
332341 xfs_failaddr_t failaddr)
333342 {
334
- if (level <= xfs_error_level)
343
+ if (buf && level <= xfs_error_level)
335344 xfs_hex_dump(buf, bufsize);
336345 xfs_error_report(tag, level, mp, filename, linenum, failaddr);
337346 xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
347
+}
348
+
349
+/*
350
+ * Complain about the kinds of metadata corruption that we can't detect from a
351
+ * verifier, such as incorrect inter-block relationship data. Does not set
352
+ * bp->b_error.
353
+ *
354
+ * Call xfs_buf_mark_corrupt, not this function.
355
+ */
356
+void
357
+xfs_buf_corruption_error(
358
+ struct xfs_buf *bp,
359
+ xfs_failaddr_t fa)
360
+{
361
+ struct xfs_mount *mp = bp->b_mount;
362
+
363
+ xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR,
364
+ "Metadata corruption detected at %pS, %s block 0x%llx",
365
+ fa, bp->b_ops->name, bp->b_bn);
366
+
367
+ xfs_alert(mp, "Unmount and run xfs_repair");
368
+
369
+ if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
370
+ xfs_stack_trace();
338371 }
339372
340373 /*
....@@ -346,18 +379,19 @@
346379 struct xfs_buf *bp,
347380 int error,
348381 const char *name,
349
- void *buf,
382
+ const void *buf,
350383 size_t bufsz,
351384 xfs_failaddr_t failaddr)
352385 {
353
- struct xfs_mount *mp = bp->b_target->bt_mount;
386
+ struct xfs_mount *mp = bp->b_mount;
354387 xfs_failaddr_t fa;
355388 int sz;
356389
357390 fa = failaddr ? failaddr : __return_address;
358391 __xfs_buf_ioerror(bp, error, fa);
359392
360
- xfs_alert(mp, "Metadata %s detected at %pS, %s block 0x%llx %s",
393
+ xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR,
394
+ "Metadata %s detected at %pS, %s block 0x%llx %s",
361395 bp->b_error == -EFSBADCRC ? "CRC error" : "corruption",
362396 fa, bp->b_ops->name, bp->b_bn, name);
363397
....@@ -397,7 +431,7 @@
397431 struct xfs_inode *ip,
398432 int error,
399433 const char *name,
400
- void *buf,
434
+ const void *buf,
401435 size_t bufsz,
402436 xfs_failaddr_t failaddr)
403437 {