diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_inode.c | 110 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 2 |
3 files changed, 25 insertions, 94 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 | */ |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 2c9a7c4dabdf..54d9e54c7c95 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -412,11 +412,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n); | |||
412 | #define XFS_IFLUSH_DELWRI 5 | 412 | #define XFS_IFLUSH_DELWRI 5 |
413 | 413 | ||
414 | /* | 414 | /* |
415 | * Flags for xfs_iflush_all. | ||
416 | */ | ||
417 | #define XFS_FLUSH_ALL 0x1 | ||
418 | |||
419 | /* | ||
420 | * Flags for xfs_itruncate_start(). | 415 | * Flags for xfs_itruncate_start(). |
421 | */ | 416 | */ |
422 | #define XFS_ITRUNC_DEFINITE 0x1 | 417 | #define XFS_ITRUNC_DEFINITE 0x1 |
@@ -520,7 +515,7 @@ void xfs_ipin(xfs_inode_t *); | |||
520 | void xfs_iunpin(xfs_inode_t *); | 515 | void xfs_iunpin(xfs_inode_t *); |
521 | int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); | 516 | int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); |
522 | int xfs_iflush(xfs_inode_t *, uint); | 517 | int xfs_iflush(xfs_inode_t *, uint); |
523 | int xfs_iflush_all(struct xfs_mount *, int); | 518 | void xfs_iflush_all(struct xfs_mount *); |
524 | int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); | 519 | int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); |
525 | uint xfs_iroundup(uint); | 520 | uint xfs_iroundup(uint); |
526 | void xfs_ichgtime(xfs_inode_t *, int); | 521 | void xfs_ichgtime(xfs_inode_t *, int); |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f618f6d6381c..5b363fcf8665 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1082,7 +1082,7 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1082 | int64_t fsid; | 1082 | int64_t fsid; |
1083 | #endif | 1083 | #endif |
1084 | 1084 | ||
1085 | xfs_iflush_all(mp, XFS_FLUSH_ALL); | 1085 | xfs_iflush_all(mp); |
1086 | 1086 | ||
1087 | XFS_QM_DQPURGEALL(mp, | 1087 | XFS_QM_DQPURGEALL(mp, |
1088 | XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING); | 1088 | XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING); |