diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 66cefb274385..dfcbd98d1599 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -855,7 +855,36 @@ out: | |||
855 | reclaim: | 855 | reclaim: |
856 | xfs_ifunlock(ip); | 856 | xfs_ifunlock(ip); |
857 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 857 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
858 | xfs_ireclaim(ip); | 858 | |
859 | XFS_STATS_INC(xs_ig_reclaims); | ||
860 | /* | ||
861 | * Remove the inode from the per-AG radix tree. | ||
862 | * | ||
863 | * Because radix_tree_delete won't complain even if the item was never | ||
864 | * added to the tree assert that it's been there before to catch | ||
865 | * problems with the inode life time early on. | ||
866 | */ | ||
867 | write_lock(&pag->pag_ici_lock); | ||
868 | if (!radix_tree_delete(&pag->pag_ici_root, | ||
869 | XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino))) | ||
870 | ASSERT(0); | ||
871 | write_unlock(&pag->pag_ici_lock); | ||
872 | |||
873 | /* | ||
874 | * Here we do an (almost) spurious inode lock in order to coordinate | ||
875 | * with inode cache radix tree lookups. This is because the lookup | ||
876 | * can reference the inodes in the cache without taking references. | ||
877 | * | ||
878 | * We make that OK here by ensuring that we wait until the inode is | ||
879 | * unlocked after the lookup before we go ahead and free it. We get | ||
880 | * both the ilock and the iolock because the code may need to drop the | ||
881 | * ilock one but will still hold the iolock. | ||
882 | */ | ||
883 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
884 | xfs_qm_dqdetach(ip); | ||
885 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
886 | |||
887 | xfs_inode_free(ip); | ||
859 | return error; | 888 | return error; |
860 | 889 | ||
861 | } | 890 | } |