diff options
| -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); |
