[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>
This commit is contained in:
Christoph Hellwig 2005-06-21 15:37:17 +10:00 committed by Nathan Scott
parent ba0f32d460
commit efa8027804
3 changed files with 27 additions and 96 deletions

View file

@ -3556,106 +3556,42 @@ xfs_iflush_int(
/*
* Flush all inactive inodes in mp. Return true if no user references
* were found, false otherwise.
* Flush all inactive inodes in mp.
*/
int
void
xfs_iflush_all(
xfs_mount_t *mp,
int flag)
xfs_mount_t *mp)
{
int busy;
int done;
int purged;
xfs_inode_t *ip;
vmap_t vmap;
vnode_t *vp;
busy = done = 0;
while (!done) {
purged = 0;
XFS_MOUNT_ILOCK(mp);
ip = mp->m_inodes;
if (ip == NULL) {
break;
again:
XFS_MOUNT_ILOCK(mp);
ip = mp->m_inodes;
if (ip == NULL)
goto out;
do {
/* Make sure we skip markers inserted by sync */
if (ip->i_mount == NULL) {
ip = ip->i_mnext;
continue;
}
do {
/* Make sure we skip markers inserted by sync */
if (ip->i_mount == NULL) {
ip = ip->i_mnext;
continue;
}
/*
* It's up to our caller to purge the root
* and quota vnodes later.
*/
vp = XFS_ITOV_NULL(ip);
if (!vp) {
XFS_MOUNT_IUNLOCK(mp);
xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
purged = 1;
break;
}
if (vn_count(vp) != 0) {
if (vn_count(vp) == 1 &&
(ip == mp->m_rootip ||
(mp->m_quotainfo &&
(ip->i_ino == mp->m_sb.sb_uquotino ||
ip->i_ino == mp->m_sb.sb_gquotino)))) {
ip = ip->i_mnext;
continue;
}
if (!(flag & XFS_FLUSH_ALL)) {
busy = 1;
done = 1;
break;
}
/*
* Ignore busy inodes but continue flushing
* others.
*/
ip = ip->i_mnext;
continue;
}
/*
* Sample vp mapping while holding mp locked on MP
* systems, so we don't purge a reclaimed or
* nonexistent vnode. We break from the loop
* since we know that we modify
* it by pulling ourselves from it in xfs_reclaim()
* called via vn_purge() below. Set ip to the next
* entry in the list anyway so we'll know below
* whether we reached the end or not.
*/
VMAP(vp, vmap);
vp = XFS_ITOV_NULL(ip);
if (!vp) {
XFS_MOUNT_IUNLOCK(mp);
vn_purge(vp, &vmap);
purged = 1;
break;
} while (ip != mp->m_inodes);
/*
* We need to distinguish between when we exit the loop
* after a purge and when we simply hit the end of the
* list. We can't use the (ip == mp->m_inodes) test,
* because when we purge an inode at the start of the list
* the next inode on the list becomes mp->m_inodes. That
* would cause such a test to bail out early. The purged
* variable tells us how we got out of the loop.
*/
if (!purged) {
done = 1;
xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
goto again;
}
}
XFS_MOUNT_IUNLOCK(mp);
return !busy;
}
ASSERT(vn_count(vp) == 0);
ip = ip->i_mnext;
} while (ip != mp->m_inodes);
out:
XFS_MOUNT_IUNLOCK(mp);
}
/*
* xfs_iaccess: check accessibility of inode for mode.

View file

@ -411,11 +411,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
#define XFS_IFLUSH_ASYNC 4
#define XFS_IFLUSH_DELWRI 5
/*
* Flags for xfs_iflush_all.
*/
#define XFS_FLUSH_ALL 0x1
/*
* Flags for xfs_itruncate_start().
*/
@ -520,7 +515,7 @@ void xfs_ipin(xfs_inode_t *);
void xfs_iunpin(xfs_inode_t *);
int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
int xfs_iflush(xfs_inode_t *, uint);
int xfs_iflush_all(struct xfs_mount *, int);
void xfs_iflush_all(struct xfs_mount *);
int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *);
uint xfs_iroundup(uint);
void xfs_ichgtime(xfs_inode_t *, int);

View file

@ -1082,7 +1082,7 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
int64_t fsid;
#endif
xfs_iflush_all(mp, XFS_FLUSH_ALL);
xfs_iflush_all(mp);
XFS_QM_DQPURGEALL(mp,
XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING);