aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_inode.c110
-rw-r--r--fs/xfs/xfs_inode.h7
-rw-r--r--fs/xfs/xfs_mount.c2
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 */
3562int 3561void
3563xfs_iflush_all( 3562xfs_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 *);
520void xfs_iunpin(xfs_inode_t *); 515void xfs_iunpin(xfs_inode_t *);
521int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); 516int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
522int xfs_iflush(xfs_inode_t *, uint); 517int xfs_iflush(xfs_inode_t *, uint);
523int xfs_iflush_all(struct xfs_mount *, int); 518void xfs_iflush_all(struct xfs_mount *);
524int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); 519int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *);
525uint xfs_iroundup(uint); 520uint xfs_iroundup(uint);
526void xfs_ichgtime(xfs_inode_t *, int); 521void 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);