|
30 | 30 | #include "xfs_trans.h" |
31 | 31 | #include "xfs_sb.h" |
32 | 32 | #include "xfs_inode.h" |
| 33 | +#include "xfs_icache.h" |
| 34 | +#include "xfs_itable.h" |
33 | 35 | #include "xfs_alloc.h" |
34 | 36 | #include "xfs_alloc_btree.h" |
35 | 37 | #include "xfs_bmap.h" |
@@ -488,3 +490,55 @@ xfs_scrub_checkpoint_log( |
488 | 490 | xfs_ail_push_all_sync(mp->m_ail); |
489 | 491 | return 0; |
490 | 492 | } |
| 493 | + |
| 494 | +/* |
| 495 | + * Given an inode and the scrub control structure, grab either the |
| 496 | + * inode referenced in the control structure or the inode passed in. |
| 497 | + * The inode is not locked. |
| 498 | + */ |
| 499 | +int |
| 500 | +xfs_scrub_get_inode( |
| 501 | + struct xfs_scrub_context *sc, |
| 502 | + struct xfs_inode *ip_in) |
| 503 | +{ |
| 504 | + struct xfs_mount *mp = sc->mp; |
| 505 | + struct xfs_inode *ip = NULL; |
| 506 | + int error; |
| 507 | + |
| 508 | + /* |
| 509 | + * If userspace passed us an AG number or a generation number |
| 510 | + * without an inode number, they haven't got a clue so bail out |
| 511 | + * immediately. |
| 512 | + */ |
| 513 | + if (sc->sm->sm_agno || (sc->sm->sm_gen && !sc->sm->sm_ino)) |
| 514 | + return -EINVAL; |
| 515 | + |
| 516 | + /* We want to scan the inode we already had opened. */ |
| 517 | + if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) { |
| 518 | + sc->ip = ip_in; |
| 519 | + return 0; |
| 520 | + } |
| 521 | + |
| 522 | + /* Look up the inode, see if the generation number matches. */ |
| 523 | + if (xfs_internal_inum(mp, sc->sm->sm_ino)) |
| 524 | + return -ENOENT; |
| 525 | + error = xfs_iget(mp, NULL, sc->sm->sm_ino, |
| 526 | + XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE, 0, &ip); |
| 527 | + if (error == -ENOENT || error == -EINVAL) { |
| 528 | + /* inode doesn't exist... */ |
| 529 | + return -ENOENT; |
| 530 | + } else if (error) { |
| 531 | + trace_xfs_scrub_op_error(sc, |
| 532 | + XFS_INO_TO_AGNO(mp, sc->sm->sm_ino), |
| 533 | + XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino), |
| 534 | + error, __return_address); |
| 535 | + return error; |
| 536 | + } |
| 537 | + if (VFS_I(ip)->i_generation != sc->sm->sm_gen) { |
| 538 | + iput(VFS_I(ip)); |
| 539 | + return -ENOENT; |
| 540 | + } |
| 541 | + |
| 542 | + sc->ip = ip; |
| 543 | + return 0; |
| 544 | +} |
0 commit comments