diff options
author | Mark Fasheh <mfasheh@suse.com> | 2008-11-12 18:16:38 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:34:19 -0500 |
commit | fecc01126d7a244b7e9b563c80663ffdca35343b (patch) | |
tree | dbc9144a0f4b6e6997928b2fa2ddeb483f8fd2d7 | |
parent | 85db90e77806d48a19fda77dabe8897d369a1710 (diff) |
ocfs2: turn __ocfs2_remove_inode_range() into ocfs2_remove_btree_range()
This patch genericizes the high level handling of extent removal.
ocfs2_remove_btree_range() is nearly identical to
__ocfs2_remove_inode_range(), except that extent tree operations have been
used where necessary. We update ocfs2_remove_inode_range() to use the
generic helper. Now extent tree based structures have an easy way to
truncate ranges.
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Acked-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r-- | fs/ocfs2/alloc.c | 72 | ||||
-rw-r--r-- | fs/ocfs2/alloc.h | 5 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 85 |
3 files changed, 82 insertions, 80 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 4614614084dd..5592a2f6335b 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -5255,6 +5255,78 @@ out: | |||
5255 | return ret; | 5255 | return ret; |
5256 | } | 5256 | } |
5257 | 5257 | ||
5258 | int ocfs2_remove_btree_range(struct inode *inode, | ||
5259 | struct ocfs2_extent_tree *et, | ||
5260 | u32 cpos, u32 phys_cpos, u32 len, | ||
5261 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
5262 | { | ||
5263 | int ret; | ||
5264 | u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); | ||
5265 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
5266 | struct inode *tl_inode = osb->osb_tl_inode; | ||
5267 | handle_t *handle; | ||
5268 | struct ocfs2_alloc_context *meta_ac = NULL; | ||
5269 | |||
5270 | ret = ocfs2_lock_allocators(inode, et, 0, 1, NULL, &meta_ac); | ||
5271 | if (ret) { | ||
5272 | mlog_errno(ret); | ||
5273 | return ret; | ||
5274 | } | ||
5275 | |||
5276 | mutex_lock(&tl_inode->i_mutex); | ||
5277 | |||
5278 | if (ocfs2_truncate_log_needs_flush(osb)) { | ||
5279 | ret = __ocfs2_flush_truncate_log(osb); | ||
5280 | if (ret < 0) { | ||
5281 | mlog_errno(ret); | ||
5282 | goto out; | ||
5283 | } | ||
5284 | } | ||
5285 | |||
5286 | handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); | ||
5287 | if (IS_ERR(handle)) { | ||
5288 | ret = PTR_ERR(handle); | ||
5289 | mlog_errno(ret); | ||
5290 | goto out; | ||
5291 | } | ||
5292 | |||
5293 | ret = ocfs2_journal_access(handle, inode, et->et_root_bh, | ||
5294 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
5295 | if (ret) { | ||
5296 | mlog_errno(ret); | ||
5297 | goto out; | ||
5298 | } | ||
5299 | |||
5300 | ret = ocfs2_remove_extent(inode, et, cpos, len, handle, meta_ac, | ||
5301 | dealloc); | ||
5302 | if (ret) { | ||
5303 | mlog_errno(ret); | ||
5304 | goto out_commit; | ||
5305 | } | ||
5306 | |||
5307 | ocfs2_et_update_clusters(inode, et, -len); | ||
5308 | |||
5309 | ret = ocfs2_journal_dirty(handle, et->et_root_bh); | ||
5310 | if (ret) { | ||
5311 | mlog_errno(ret); | ||
5312 | goto out_commit; | ||
5313 | } | ||
5314 | |||
5315 | ret = ocfs2_truncate_log_append(osb, handle, phys_blkno, len); | ||
5316 | if (ret) | ||
5317 | mlog_errno(ret); | ||
5318 | |||
5319 | out_commit: | ||
5320 | ocfs2_commit_trans(osb, handle); | ||
5321 | out: | ||
5322 | mutex_unlock(&tl_inode->i_mutex); | ||
5323 | |||
5324 | if (meta_ac) | ||
5325 | ocfs2_free_alloc_context(meta_ac); | ||
5326 | |||
5327 | return ret; | ||
5328 | } | ||
5329 | |||
5258 | int ocfs2_truncate_log_needs_flush(struct ocfs2_super *osb) | 5330 | int ocfs2_truncate_log_needs_flush(struct ocfs2_super *osb) |
5259 | { | 5331 | { |
5260 | struct buffer_head *tl_bh = osb->osb_tl_bh; | 5332 | struct buffer_head *tl_bh = osb->osb_tl_bh; |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 3eb735eedae6..0fbf8fc55a49 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -110,6 +110,11 @@ int ocfs2_remove_extent(struct inode *inode, | |||
110 | u32 cpos, u32 len, handle_t *handle, | 110 | u32 cpos, u32 len, handle_t *handle, |
111 | struct ocfs2_alloc_context *meta_ac, | 111 | struct ocfs2_alloc_context *meta_ac, |
112 | struct ocfs2_cached_dealloc_ctxt *dealloc); | 112 | struct ocfs2_cached_dealloc_ctxt *dealloc); |
113 | int ocfs2_remove_btree_range(struct inode *inode, | ||
114 | struct ocfs2_extent_tree *et, | ||
115 | u32 cpos, u32 phys_cpos, u32 len, | ||
116 | struct ocfs2_cached_dealloc_ctxt *dealloc); | ||
117 | |||
113 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 118 | int ocfs2_num_free_extents(struct ocfs2_super *osb, |
114 | struct inode *inode, | 119 | struct inode *inode, |
115 | struct ocfs2_extent_tree *et); | 120 | struct ocfs2_extent_tree *et); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index e2570a3bc2b2..360549161e20 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1226,83 +1226,6 @@ out: | |||
1226 | return ret; | 1226 | return ret; |
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | static int __ocfs2_remove_inode_range(struct inode *inode, | ||
1230 | struct buffer_head *di_bh, | ||
1231 | u32 cpos, u32 phys_cpos, u32 len, | ||
1232 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
1233 | { | ||
1234 | int ret; | ||
1235 | u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); | ||
1236 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1237 | struct inode *tl_inode = osb->osb_tl_inode; | ||
1238 | handle_t *handle; | ||
1239 | struct ocfs2_alloc_context *meta_ac = NULL; | ||
1240 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
1241 | struct ocfs2_extent_tree et; | ||
1242 | |||
1243 | ocfs2_init_dinode_extent_tree(&et, inode, di_bh); | ||
1244 | |||
1245 | ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac); | ||
1246 | if (ret) { | ||
1247 | mlog_errno(ret); | ||
1248 | return ret; | ||
1249 | } | ||
1250 | |||
1251 | mutex_lock(&tl_inode->i_mutex); | ||
1252 | |||
1253 | if (ocfs2_truncate_log_needs_flush(osb)) { | ||
1254 | ret = __ocfs2_flush_truncate_log(osb); | ||
1255 | if (ret < 0) { | ||
1256 | mlog_errno(ret); | ||
1257 | goto out; | ||
1258 | } | ||
1259 | } | ||
1260 | |||
1261 | handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); | ||
1262 | if (IS_ERR(handle)) { | ||
1263 | ret = PTR_ERR(handle); | ||
1264 | mlog_errno(ret); | ||
1265 | goto out; | ||
1266 | } | ||
1267 | |||
1268 | ret = ocfs2_journal_access(handle, inode, di_bh, | ||
1269 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
1270 | if (ret) { | ||
1271 | mlog_errno(ret); | ||
1272 | goto out; | ||
1273 | } | ||
1274 | |||
1275 | ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, meta_ac, | ||
1276 | dealloc); | ||
1277 | if (ret) { | ||
1278 | mlog_errno(ret); | ||
1279 | goto out_commit; | ||
1280 | } | ||
1281 | |||
1282 | OCFS2_I(inode)->ip_clusters -= len; | ||
1283 | di->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters); | ||
1284 | |||
1285 | ret = ocfs2_journal_dirty(handle, di_bh); | ||
1286 | if (ret) { | ||
1287 | mlog_errno(ret); | ||
1288 | goto out_commit; | ||
1289 | } | ||
1290 | |||
1291 | ret = ocfs2_truncate_log_append(osb, handle, phys_blkno, len); | ||
1292 | if (ret) | ||
1293 | mlog_errno(ret); | ||
1294 | |||
1295 | out_commit: | ||
1296 | ocfs2_commit_trans(osb, handle); | ||
1297 | out: | ||
1298 | mutex_unlock(&tl_inode->i_mutex); | ||
1299 | |||
1300 | if (meta_ac) | ||
1301 | ocfs2_free_alloc_context(meta_ac); | ||
1302 | |||
1303 | return ret; | ||
1304 | } | ||
1305 | |||
1306 | /* | 1229 | /* |
1307 | * Truncate a byte range, avoiding pages within partial clusters. This | 1230 | * Truncate a byte range, avoiding pages within partial clusters. This |
1308 | * preserves those pages for the zeroing code to write to. | 1231 | * preserves those pages for the zeroing code to write to. |
@@ -1402,7 +1325,9 @@ static int ocfs2_remove_inode_range(struct inode *inode, | |||
1402 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1325 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1403 | struct ocfs2_cached_dealloc_ctxt dealloc; | 1326 | struct ocfs2_cached_dealloc_ctxt dealloc; |
1404 | struct address_space *mapping = inode->i_mapping; | 1327 | struct address_space *mapping = inode->i_mapping; |
1328 | struct ocfs2_extent_tree et; | ||
1405 | 1329 | ||
1330 | ocfs2_init_dinode_extent_tree(&et, inode, di_bh); | ||
1406 | ocfs2_init_dealloc_ctxt(&dealloc); | 1331 | ocfs2_init_dealloc_ctxt(&dealloc); |
1407 | 1332 | ||
1408 | if (byte_len == 0) | 1333 | if (byte_len == 0) |
@@ -1458,9 +1383,9 @@ static int ocfs2_remove_inode_range(struct inode *inode, | |||
1458 | 1383 | ||
1459 | /* Only do work for non-holes */ | 1384 | /* Only do work for non-holes */ |
1460 | if (phys_cpos != 0) { | 1385 | if (phys_cpos != 0) { |
1461 | ret = __ocfs2_remove_inode_range(inode, di_bh, cpos, | 1386 | ret = ocfs2_remove_btree_range(inode, &et, cpos, |
1462 | phys_cpos, alloc_size, | 1387 | phys_cpos, alloc_size, |
1463 | &dealloc); | 1388 | &dealloc); |
1464 | if (ret) { | 1389 | if (ret) { |
1465 | mlog_errno(ret); | 1390 | mlog_errno(ret); |
1466 | goto out; | 1391 | goto out; |