diff options
author | Brian Foster <bfoster@redhat.com> | 2012-11-06 09:50:39 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-11-08 16:20:38 -0500 |
commit | a454f7428ffa03c8e1321124d9074101b7290be6 (patch) | |
tree | 8dc1cdfb38dc100f844821e3122b0d4ec017f903 /fs/xfs | |
parent | 27b52867925e3aaed090063c1c58a7537e6373f3 (diff) |
xfs: support a tag-based inode_ag_iterator
Genericize xfs_inode_ag_walk() to support an optional radix tree tag
and args argument for the execute function. Create a new wrapper
called xfs_inode_ag_iterator_tag() that performs a tag based walk
of perag's and inodes.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_icache.c | 56 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.h | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_qm_syscalls.c | 5 |
3 files changed, 59 insertions, 11 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index f9afc5ff0482..2a96dc48ebe6 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -516,8 +516,11 @@ xfs_inode_ag_walk( | |||
516 | struct xfs_mount *mp, | 516 | struct xfs_mount *mp, |
517 | struct xfs_perag *pag, | 517 | struct xfs_perag *pag, |
518 | int (*execute)(struct xfs_inode *ip, | 518 | int (*execute)(struct xfs_inode *ip, |
519 | struct xfs_perag *pag, int flags), | 519 | struct xfs_perag *pag, int flags, |
520 | int flags) | 520 | void *args), |
521 | int flags, | ||
522 | void *args, | ||
523 | int tag) | ||
521 | { | 524 | { |
522 | uint32_t first_index; | 525 | uint32_t first_index; |
523 | int last_error = 0; | 526 | int last_error = 0; |
@@ -536,9 +539,17 @@ restart: | |||
536 | int i; | 539 | int i; |
537 | 540 | ||
538 | rcu_read_lock(); | 541 | rcu_read_lock(); |
539 | nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, | 542 | |
543 | if (tag == -1) | ||
544 | nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, | ||
540 | (void **)batch, first_index, | 545 | (void **)batch, first_index, |
541 | XFS_LOOKUP_BATCH); | 546 | XFS_LOOKUP_BATCH); |
547 | else | ||
548 | nr_found = radix_tree_gang_lookup_tag( | ||
549 | &pag->pag_ici_root, | ||
550 | (void **) batch, first_index, | ||
551 | XFS_LOOKUP_BATCH, tag); | ||
552 | |||
542 | if (!nr_found) { | 553 | if (!nr_found) { |
543 | rcu_read_unlock(); | 554 | rcu_read_unlock(); |
544 | break; | 555 | break; |
@@ -579,7 +590,7 @@ restart: | |||
579 | for (i = 0; i < nr_found; i++) { | 590 | for (i = 0; i < nr_found; i++) { |
580 | if (!batch[i]) | 591 | if (!batch[i]) |
581 | continue; | 592 | continue; |
582 | error = execute(batch[i], pag, flags); | 593 | error = execute(batch[i], pag, flags, args); |
583 | IRELE(batch[i]); | 594 | IRELE(batch[i]); |
584 | if (error == EAGAIN) { | 595 | if (error == EAGAIN) { |
585 | skipped++; | 596 | skipped++; |
@@ -608,8 +619,10 @@ int | |||
608 | xfs_inode_ag_iterator( | 619 | xfs_inode_ag_iterator( |
609 | struct xfs_mount *mp, | 620 | struct xfs_mount *mp, |
610 | int (*execute)(struct xfs_inode *ip, | 621 | int (*execute)(struct xfs_inode *ip, |
611 | struct xfs_perag *pag, int flags), | 622 | struct xfs_perag *pag, int flags, |
612 | int flags) | 623 | void *args), |
624 | int flags, | ||
625 | void *args) | ||
613 | { | 626 | { |
614 | struct xfs_perag *pag; | 627 | struct xfs_perag *pag; |
615 | int error = 0; | 628 | int error = 0; |
@@ -619,7 +632,36 @@ xfs_inode_ag_iterator( | |||
619 | ag = 0; | 632 | ag = 0; |
620 | while ((pag = xfs_perag_get(mp, ag))) { | 633 | while ((pag = xfs_perag_get(mp, ag))) { |
621 | ag = pag->pag_agno + 1; | 634 | ag = pag->pag_agno + 1; |
622 | error = xfs_inode_ag_walk(mp, pag, execute, flags); | 635 | error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1); |
636 | xfs_perag_put(pag); | ||
637 | if (error) { | ||
638 | last_error = error; | ||
639 | if (error == EFSCORRUPTED) | ||
640 | break; | ||
641 | } | ||
642 | } | ||
643 | return XFS_ERROR(last_error); | ||
644 | } | ||
645 | |||
646 | int | ||
647 | xfs_inode_ag_iterator_tag( | ||
648 | struct xfs_mount *mp, | ||
649 | int (*execute)(struct xfs_inode *ip, | ||
650 | struct xfs_perag *pag, int flags, | ||
651 | void *args), | ||
652 | int flags, | ||
653 | void *args, | ||
654 | int tag) | ||
655 | { | ||
656 | struct xfs_perag *pag; | ||
657 | int error = 0; | ||
658 | int last_error = 0; | ||
659 | xfs_agnumber_t ag; | ||
660 | |||
661 | ag = 0; | ||
662 | while ((pag = xfs_perag_get_tag(mp, ag, tag))) { | ||
663 | ag = pag->pag_agno + 1; | ||
664 | error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag); | ||
623 | xfs_perag_put(pag); | 665 | xfs_perag_put(pag); |
624 | if (error) { | 666 | if (error) { |
625 | last_error = error; | 667 | last_error = error; |
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index db3613075dc6..54c113478dfc 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h | |||
@@ -40,7 +40,12 @@ void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); | |||
40 | 40 | ||
41 | int xfs_sync_inode_grab(struct xfs_inode *ip); | 41 | int xfs_sync_inode_grab(struct xfs_inode *ip); |
42 | int xfs_inode_ag_iterator(struct xfs_mount *mp, | 42 | int xfs_inode_ag_iterator(struct xfs_mount *mp, |
43 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), | 43 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, |
44 | int flags); | 44 | int flags, void *args), |
45 | int flags, void *args); | ||
46 | int xfs_inode_ag_iterator_tag(struct xfs_mount *mp, | ||
47 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, | ||
48 | int flags, void *args), | ||
49 | int flags, void *args, int tag); | ||
45 | 50 | ||
46 | #endif | 51 | #endif |
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 7a9071f8855f..5f53e75409b8 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c | |||
@@ -846,7 +846,8 @@ STATIC int | |||
846 | xfs_dqrele_inode( | 846 | xfs_dqrele_inode( |
847 | struct xfs_inode *ip, | 847 | struct xfs_inode *ip, |
848 | struct xfs_perag *pag, | 848 | struct xfs_perag *pag, |
849 | int flags) | 849 | int flags, |
850 | void *args) | ||
850 | { | 851 | { |
851 | /* skip quota inodes */ | 852 | /* skip quota inodes */ |
852 | if (ip == ip->i_mount->m_quotainfo->qi_uquotaip || | 853 | if (ip == ip->i_mount->m_quotainfo->qi_uquotaip || |
@@ -882,5 +883,5 @@ xfs_qm_dqrele_all_inodes( | |||
882 | uint flags) | 883 | uint flags) |
883 | { | 884 | { |
884 | ASSERT(mp->m_quotainfo); | 885 | ASSERT(mp->m_quotainfo); |
885 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags); | 886 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL); |
886 | } | 887 | } |