diff options
author | Christoph Hellwig <hch@sgi.com> | 2005-06-21 01:37:17 -0400 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-06-21 01:37:17 -0400 |
commit | efa8027804b2bd8eb7d4b41a1f5b738c36e44e8c (patch) | |
tree | 763b870f05c5a8e41fddcfe77f56f3ba5cfcf191 /fs/xfs/xfs_inode.c | |
parent | ba0f32d46049e2b625dabd33c7964f8ca2cd7651 (diff) |
[XFS] rewrite xfs_iflush_all
SGI-PV: 936890
SGI-Modid: xfs-linux:xfs-kern:193349a
Signed-off-by: Christoph Hellwig <hch@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 110 |
1 files changed, 23 insertions, 87 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 99421638e860..a2c723baff06 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -3556,107 +3556,43 @@ corrupt_out: | |||
3556 | 3556 | ||
3557 | 3557 | ||
3558 | /* | 3558 | /* |
3559 | * Flush all inactive inodes in mp. Return true if no user references | 3559 | * Flush all inactive inodes in mp. |
3560 | * were found, false otherwise. | ||
3561 | */ | 3560 | */ |
3562 | int | 3561 | void |
3563 | xfs_iflush_all( | 3562 | xfs_iflush_all( |
3564 | xfs_mount_t *mp, | 3563 | xfs_mount_t *mp) |
3565 | int flag) | ||
3566 | { | 3564 | { |
3567 | int busy; | ||
3568 | int done; | ||
3569 | int purged; | ||
3570 | xfs_inode_t *ip; | 3565 | xfs_inode_t *ip; |
3571 | vmap_t vmap; | ||
3572 | vnode_t *vp; | 3566 | vnode_t *vp; |
3573 | 3567 | ||
3574 | busy = done = 0; | 3568 | again: |
3575 | while (!done) { | 3569 | XFS_MOUNT_ILOCK(mp); |
3576 | purged = 0; | 3570 | ip = mp->m_inodes; |
3577 | XFS_MOUNT_ILOCK(mp); | 3571 | if (ip == NULL) |
3578 | ip = mp->m_inodes; | 3572 | goto out; |
3579 | if (ip == NULL) { | ||
3580 | break; | ||
3581 | } | ||
3582 | do { | ||
3583 | /* Make sure we skip markers inserted by sync */ | ||
3584 | if (ip->i_mount == NULL) { | ||
3585 | ip = ip->i_mnext; | ||
3586 | continue; | ||
3587 | } | ||
3588 | |||
3589 | /* | ||
3590 | * It's up to our caller to purge the root | ||
3591 | * and quota vnodes later. | ||
3592 | */ | ||
3593 | vp = XFS_ITOV_NULL(ip); | ||
3594 | |||
3595 | if (!vp) { | ||
3596 | XFS_MOUNT_IUNLOCK(mp); | ||
3597 | xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); | ||
3598 | purged = 1; | ||
3599 | break; | ||
3600 | } | ||
3601 | 3573 | ||
3602 | if (vn_count(vp) != 0) { | 3574 | do { |
3603 | if (vn_count(vp) == 1 && | 3575 | /* Make sure we skip markers inserted by sync */ |
3604 | (ip == mp->m_rootip || | 3576 | if (ip->i_mount == NULL) { |
3605 | (mp->m_quotainfo && | 3577 | ip = ip->i_mnext; |
3606 | (ip->i_ino == mp->m_sb.sb_uquotino || | 3578 | continue; |
3607 | ip->i_ino == mp->m_sb.sb_gquotino)))) { | 3579 | } |
3608 | 3580 | ||
3609 | ip = ip->i_mnext; | 3581 | vp = XFS_ITOV_NULL(ip); |
3610 | continue; | 3582 | if (!vp) { |
3611 | } | ||
3612 | if (!(flag & XFS_FLUSH_ALL)) { | ||
3613 | busy = 1; | ||
3614 | done = 1; | ||
3615 | break; | ||
3616 | } | ||
3617 | /* | ||
3618 | * Ignore busy inodes but continue flushing | ||
3619 | * others. | ||
3620 | */ | ||
3621 | ip = ip->i_mnext; | ||
3622 | continue; | ||
3623 | } | ||
3624 | /* | ||
3625 | * Sample vp mapping while holding mp locked on MP | ||
3626 | * systems, so we don't purge a reclaimed or | ||
3627 | * nonexistent vnode. We break from the loop | ||
3628 | * since we know that we modify | ||
3629 | * it by pulling ourselves from it in xfs_reclaim() | ||
3630 | * called via vn_purge() below. Set ip to the next | ||
3631 | * entry in the list anyway so we'll know below | ||
3632 | * whether we reached the end or not. | ||
3633 | */ | ||
3634 | VMAP(vp, vmap); | ||
3635 | XFS_MOUNT_IUNLOCK(mp); | 3583 | XFS_MOUNT_IUNLOCK(mp); |
3584 | xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); | ||
3585 | goto again; | ||
3586 | } | ||
3636 | 3587 | ||
3637 | vn_purge(vp, &vmap); | 3588 | ASSERT(vn_count(vp) == 0); |
3638 | 3589 | ||
3639 | purged = 1; | 3590 | ip = ip->i_mnext; |
3640 | break; | 3591 | } while (ip != mp->m_inodes); |
3641 | } while (ip != mp->m_inodes); | 3592 | out: |
3642 | /* | ||
3643 | * We need to distinguish between when we exit the loop | ||
3644 | * after a purge and when we simply hit the end of the | ||
3645 | * list. We can't use the (ip == mp->m_inodes) test, | ||
3646 | * because when we purge an inode at the start of the list | ||
3647 | * the next inode on the list becomes mp->m_inodes. That | ||
3648 | * would cause such a test to bail out early. The purged | ||
3649 | * variable tells us how we got out of the loop. | ||
3650 | */ | ||
3651 | if (!purged) { | ||
3652 | done = 1; | ||
3653 | } | ||
3654 | } | ||
3655 | XFS_MOUNT_IUNLOCK(mp); | 3593 | XFS_MOUNT_IUNLOCK(mp); |
3656 | return !busy; | ||
3657 | } | 3594 | } |
3658 | 3595 | ||
3659 | |||
3660 | /* | 3596 | /* |
3661 | * xfs_iaccess: check accessibility of inode for mode. | 3597 | * xfs_iaccess: check accessibility of inode for mode. |
3662 | */ | 3598 | */ |