|
@@ -3556,107 +3556,43 @@ corrupt_out:
|
|
|
|
|
|
|
|
|
/*
|
|
|
- * 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;
|
|
|
- }
|
|
|
- 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;
|
|
|
- }
|
|
|
+ again:
|
|
|
+ XFS_MOUNT_ILOCK(mp);
|
|
|
+ ip = mp->m_inodes;
|
|
|
+ if (ip == NULL)
|
|
|
+ goto out;
|
|
|
|
|
|
- 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)))) {
|
|
|
+ do {
|
|
|
+ /* Make sure we skip markers inserted by sync */
|
|
|
+ if (ip->i_mount == NULL) {
|
|
|
+ ip = ip->i_mnext;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- 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);
|
|
|
+ xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
|
|
|
+ goto again;
|
|
|
+ }
|
|
|
|
|
|
- vn_purge(vp, &vmap);
|
|
|
+ ASSERT(vn_count(vp) == 0);
|
|
|
|
|
|
- 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;
|
|
|
- }
|
|
|
- }
|
|
|
+ ip = ip->i_mnext;
|
|
|
+ } while (ip != mp->m_inodes);
|
|
|
+ out:
|
|
|
XFS_MOUNT_IUNLOCK(mp);
|
|
|
- return !busy;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/*
|
|
|
* xfs_iaccess: check accessibility of inode for mode.
|
|
|
*/
|