aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2012-11-06 09:50:42 -0500
committerBen Myers <bpm@sgi.com>2012-11-08 16:25:40 -0500
commit41176a68e3f710630feace536d0277a092e206b5 (patch)
treeb1452aae0f00c37ff769e9f4620aa3936e70b837 /fs/xfs
parent40165e27617e2a98bf8588001d2f2872fae2fee2 (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')
-rw-r--r--fs/xfs/xfs_icache.c43
-rw-r--r--fs/xfs/xfs_icache.h1
-rw-r--r--fs/xfs/xfs_trace.h1
3 files changed, 45 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
1173STATIC int
1174xfs_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
1206int
1207xfs_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
1173void 1216void
1174xfs_inode_set_eofblocks_tag( 1217xfs_inode_set_eofblocks_tag(
1175 xfs_inode_t *ip) 1218 xfs_inode_t *ip)
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index 54c113478dfc..cb6b8d0eee61 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -37,6 +37,7 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
37 37
38void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip); 38void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
39void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); 39void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
40int xfs_icache_free_eofblocks(struct xfs_mount *, int);
40 41
41int xfs_sync_inode_grab(struct xfs_inode *ip); 42int xfs_sync_inode_grab(struct xfs_inode *ip);
42int xfs_inode_ag_iterator(struct xfs_mount *mp, 43int xfs_inode_ag_iterator(struct xfs_mount *mp,
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 6f46e034b766..cb5234632072 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -589,6 +589,7 @@ DEFINE_INODE_EVENT(xfs_dquot_dqdetach);
589 589
590DEFINE_INODE_EVENT(xfs_inode_set_eofblocks_tag); 590DEFINE_INODE_EVENT(xfs_inode_set_eofblocks_tag);
591DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag); 591DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag);
592DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid);
592 593
593DECLARE_EVENT_CLASS(xfs_iref_class, 594DECLARE_EVENT_CLASS(xfs_iref_class,
594 TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), 595 TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip),