.. | .. |
---|
4 | 4 | * All Rights Reserved. |
---|
5 | 5 | */ |
---|
6 | 6 | #include "xfs.h" |
---|
| 7 | +#include "xfs_shared.h" |
---|
7 | 8 | #include "xfs_format.h" |
---|
8 | 9 | #include "xfs_fs.h" |
---|
9 | 10 | #include "xfs_log_format.h" |
---|
.. | .. |
---|
51 | 52 | XFS_RANDOM_BUF_LRU_REF, |
---|
52 | 53 | XFS_RANDOM_FORCE_SCRUB_REPAIR, |
---|
53 | 54 | XFS_RANDOM_FORCE_SUMMARY_RECALC, |
---|
| 55 | + XFS_RANDOM_IUNLINK_FALLBACK, |
---|
| 56 | + XFS_RANDOM_BUF_IOERROR, |
---|
54 | 57 | }; |
---|
55 | 58 | |
---|
56 | 59 | struct xfs_errortag_attr { |
---|
.. | .. |
---|
159 | 162 | XFS_ERRORTAG_ATTR_RW(buf_lru_ref, XFS_ERRTAG_BUF_LRU_REF); |
---|
160 | 163 | XFS_ERRORTAG_ATTR_RW(force_repair, XFS_ERRTAG_FORCE_SCRUB_REPAIR); |
---|
161 | 164 | 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); |
---|
162 | 167 | |
---|
163 | 168 | static struct attribute *xfs_errortag_attrs[] = { |
---|
164 | 169 | XFS_ERRORTAG_ATTR_LIST(noerror), |
---|
.. | .. |
---|
195 | 200 | XFS_ERRORTAG_ATTR_LIST(buf_lru_ref), |
---|
196 | 201 | XFS_ERRORTAG_ATTR_LIST(force_repair), |
---|
197 | 202 | XFS_ERRORTAG_ATTR_LIST(bad_summary), |
---|
| 203 | + XFS_ERRORTAG_ATTR_LIST(iunlink_fallback), |
---|
| 204 | + XFS_ERRORTAG_ATTR_LIST(buf_ioerror), |
---|
198 | 205 | NULL, |
---|
199 | 206 | }; |
---|
200 | 207 | |
---|
.. | .. |
---|
209 | 216 | struct xfs_mount *mp) |
---|
210 | 217 | { |
---|
211 | 218 | mp->m_errortag = kmem_zalloc(sizeof(unsigned int) * XFS_ERRTAG_MAX, |
---|
212 | | - KM_SLEEP | KM_MAYFAIL); |
---|
| 219 | + KM_MAYFAIL); |
---|
213 | 220 | if (!mp->m_errortag) |
---|
214 | 221 | return -ENOMEM; |
---|
215 | 222 | |
---|
.. | .. |
---|
253 | 260 | |
---|
254 | 261 | xfs_warn_ratelimited(mp, |
---|
255 | 262 | "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); |
---|
257 | 264 | return true; |
---|
258 | 265 | } |
---|
259 | 266 | |
---|
.. | .. |
---|
286 | 293 | struct xfs_mount *mp, |
---|
287 | 294 | unsigned int error_tag) |
---|
288 | 295 | { |
---|
| 296 | + BUILD_BUG_ON(ARRAY_SIZE(xfs_errortag_random_default) != XFS_ERRTAG_MAX); |
---|
| 297 | + |
---|
289 | 298 | if (error_tag >= XFS_ERRTAG_MAX) |
---|
290 | 299 | return -EINVAL; |
---|
291 | 300 | |
---|
.. | .. |
---|
325 | 334 | const char *tag, |
---|
326 | 335 | int level, |
---|
327 | 336 | struct xfs_mount *mp, |
---|
328 | | - void *buf, |
---|
| 337 | + const void *buf, |
---|
329 | 338 | size_t bufsize, |
---|
330 | 339 | const char *filename, |
---|
331 | 340 | int linenum, |
---|
332 | 341 | xfs_failaddr_t failaddr) |
---|
333 | 342 | { |
---|
334 | | - if (level <= xfs_error_level) |
---|
| 343 | + if (buf && level <= xfs_error_level) |
---|
335 | 344 | xfs_hex_dump(buf, bufsize); |
---|
336 | 345 | xfs_error_report(tag, level, mp, filename, linenum, failaddr); |
---|
337 | 346 | 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(); |
---|
338 | 371 | } |
---|
339 | 372 | |
---|
340 | 373 | /* |
---|
.. | .. |
---|
346 | 379 | struct xfs_buf *bp, |
---|
347 | 380 | int error, |
---|
348 | 381 | const char *name, |
---|
349 | | - void *buf, |
---|
| 382 | + const void *buf, |
---|
350 | 383 | size_t bufsz, |
---|
351 | 384 | xfs_failaddr_t failaddr) |
---|
352 | 385 | { |
---|
353 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 386 | + struct xfs_mount *mp = bp->b_mount; |
---|
354 | 387 | xfs_failaddr_t fa; |
---|
355 | 388 | int sz; |
---|
356 | 389 | |
---|
357 | 390 | fa = failaddr ? failaddr : __return_address; |
---|
358 | 391 | __xfs_buf_ioerror(bp, error, fa); |
---|
359 | 392 | |
---|
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", |
---|
361 | 395 | bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", |
---|
362 | 396 | fa, bp->b_ops->name, bp->b_bn, name); |
---|
363 | 397 | |
---|
.. | .. |
---|
397 | 431 | struct xfs_inode *ip, |
---|
398 | 432 | int error, |
---|
399 | 433 | const char *name, |
---|
400 | | - void *buf, |
---|
| 434 | + const void *buf, |
---|
401 | 435 | size_t bufsz, |
---|
402 | 436 | xfs_failaddr_t failaddr) |
---|
403 | 437 | { |
---|