diff options
author | Brian Foster <bfoster@redhat.com> | 2012-11-06 09:50:42 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-11-08 16:25:40 -0500 |
commit | 41176a68e3f710630feace536d0277a092e206b5 (patch) | |
tree | b1452aae0f00c37ff769e9f4620aa3936e70b837 /fs/xfs/xfs_icache.c | |
parent | 40165e27617e2a98bf8588001d2f2872fae2fee2 (diff) |
xfs: create function to scan and clear EOFBLOCKS inodes
xfs_inodes_free_eofblocks() implements scanning functionality for
EOFBLOCKS inodes. It uses the AG iterator to walk the tagged inodes
and free post-EOF blocks via the xfs_inode_free_eofblocks() execute
function. The scan can be invoked in best-effort mode or wait
(force) mode.
A best-effort scan (default) handles all inodes that do not have a
dirty cache and we successfully acquire the io lock via trylock. In
wait mode, we continue to cycle through an AG until all inodes are
handled.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_icache.c')
-rw-r--r-- | fs/xfs/xfs_icache.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 2a96dc48ebe6..d115cb44b103 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -1170,6 +1170,49 @@ xfs_reclaim_inodes_count( | |||
1170 | return reclaimable; | 1170 | return reclaimable; |
1171 | } | 1171 | } |
1172 | 1172 | ||
1173 | STATIC int | ||
1174 | xfs_inode_free_eofblocks( | ||
1175 | struct xfs_inode *ip, | ||
1176 | struct xfs_perag *pag, | ||
1177 | int flags, | ||
1178 | void *args) | ||
1179 | { | ||
1180 | int ret; | ||
1181 | |||
1182 | if (!xfs_can_free_eofblocks(ip, false)) { | ||
1183 | /* inode could be preallocated or append-only */ | ||
1184 | trace_xfs_inode_free_eofblocks_invalid(ip); | ||
1185 | xfs_inode_clear_eofblocks_tag(ip); | ||
1186 | return 0; | ||
1187 | } | ||
1188 | |||
1189 | /* | ||
1190 | * If the mapping is dirty the operation can block and wait for some | ||
1191 | * time. Unless we are waiting, skip it. | ||
1192 | */ | ||
1193 | if (!(flags & SYNC_WAIT) && | ||
1194 | mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY)) | ||
1195 | return 0; | ||
1196 | |||
1197 | ret = xfs_free_eofblocks(ip->i_mount, ip, true); | ||
1198 | |||
1199 | /* don't revisit the inode if we're not waiting */ | ||
1200 | if (ret == EAGAIN && !(flags & SYNC_WAIT)) | ||
1201 | ret = 0; | ||
1202 | |||
1203 | return ret; | ||
1204 | } | ||
1205 | |||
1206 | int | ||
1207 | xfs_icache_free_eofblocks( | ||
1208 | struct xfs_mount *mp, | ||
1209 | int flags) | ||
1210 | { | ||
1211 | ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0); | ||
1212 | return xfs_inode_ag_iterator_tag(mp, xfs_inode_free_eofblocks, flags, | ||
1213 | NULL, XFS_ICI_EOFBLOCKS_TAG); | ||
1214 | } | ||
1215 | |||
1173 | void | 1216 | void |
1174 | xfs_inode_set_eofblocks_tag( | 1217 | xfs_inode_set_eofblocks_tag( |
1175 | xfs_inode_t *ip) | 1218 | xfs_inode_t *ip) |