if (!ip->i_update_core && (ip->i_itemp == NULL)) {
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_iflock(ip);
+ xfs_iflags_set(ip, XFS_IRECLAIMABLE);
return xfs_finish_reclaim(ip, 1, XFS_IFLUSH_DELWRI_ELSE_SYNC);
} else {
xfs_mount_t *mp = ip->i_mount;
XFS_MOUNT_ILOCK(mp);
spin_lock(&ip->i_flags_lock);
__xfs_iflags_set(ip, XFS_IRECLAIMABLE);
- VFS_I(ip)->i_private = NULL;
- ip->i_vnode = NULL;
spin_unlock(&ip->i_flags_lock);
list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
XFS_MOUNT_IUNLOCK(mp);
int sync_mode)
{
xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino);
- struct inode *vp = VFS_I(ip);
-
- if (vp && VN_BAD(vp))
- goto reclaim;
/* The hash lock here protects a thread in xfs_iget_core from
* racing with us on linking the inode back with a vnode.
write_lock(&pag->pag_ici_lock);
spin_lock(&ip->i_flags_lock);
if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
- (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) {
+ !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) {
spin_unlock(&ip->i_flags_lock);
write_unlock(&pag->pag_ici_lock);
if (locked) {
* In the case of a forced shutdown we rely on xfs_iflush() to
* wait for the inode to be unpinned before returning an error.
*/
- if (xfs_iflush(ip, sync_mode) == 0) {
+ if (!is_bad_inode(VFS_I(ip)) && xfs_iflush(ip, sync_mode) == 0) {
/* synchronize with xfs_iflush_done */
xfs_iflock(ip);
xfs_ifunlock(ip);
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
-
- reclaim:
xfs_ireclaim(ip);
return 0;
}
int
-xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
+xfs_finish_reclaim_all(
+ xfs_mount_t *mp,
+ int noblock,
+ int mode)
{
- int purged;
xfs_inode_t *ip, *n;
- int done = 0;
- while (!done) {
- purged = 0;
- XFS_MOUNT_ILOCK(mp);
- list_for_each_entry_safe(ip, n, &mp->m_del_inodes, i_reclaim) {
- if (noblock) {
- if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0)
- continue;
- if (xfs_ipincount(ip) ||
- !xfs_iflock_nowait(ip)) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- continue;
- }
+restart:
+ XFS_MOUNT_ILOCK(mp);
+ list_for_each_entry_safe(ip, n, &mp->m_del_inodes, i_reclaim) {
+ if (noblock) {
+ if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0)
+ continue;
+ if (xfs_ipincount(ip) ||
+ !xfs_iflock_nowait(ip)) {
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ continue;
}
- XFS_MOUNT_IUNLOCK(mp);
- if (xfs_finish_reclaim(ip, noblock,
- XFS_IFLUSH_DELWRI_ELSE_ASYNC))
- delay(1);
- purged = 1;
- break;
}
-
- done = !purged;
+ XFS_MOUNT_IUNLOCK(mp);
+ if (xfs_finish_reclaim(ip, noblock, mode))
+ delay(1);
+ goto restart;
}
-
XFS_MOUNT_IUNLOCK(mp);
return 0;
}