aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/alloc.c
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2009-08-17 23:29:12 -0400
committerJoel Becker <joel.becker@oracle.com>2009-09-22 23:09:35 -0400
commitbcbbb24a6a5c5b3e7b8e5284e0bfa23f45c32377 (patch)
treee45a6cfd75cd8005fdf280c2f5f57c09186249dd /fs/ocfs2/alloc.c
parent1aa75fea64bc26bda9be9b1b20ae253d7a481877 (diff)
ocfs2: Decrement refcount when truncating refcounted extents.
Add 'Decrement refcount for delete' in to the normal truncate process. So for a refcounted extent record, call refcount rec decrementation instead of cluster free. Signed-off-by: Tao Ma <tao.ma@oracle.com>
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r--fs/ocfs2/alloc.c76
1 files changed, 69 insertions, 7 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 96f8ca6b3aba..03438a677933 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -49,6 +49,7 @@
49#include "super.h" 49#include "super.h"
50#include "uptodate.h" 50#include "uptodate.h"
51#include "xattr.h" 51#include "xattr.h"
52#include "refcounttree.h"
52 53
53#include "buffer_head_io.h" 54#include "buffer_head_io.h"
54 55
@@ -6673,7 +6674,7 @@ out:
6673 */ 6674 */
6674static int ocfs2_trim_tree(struct inode *inode, struct ocfs2_path *path, 6675static int ocfs2_trim_tree(struct inode *inode, struct ocfs2_path *path,
6675 handle_t *handle, struct ocfs2_truncate_context *tc, 6676 handle_t *handle, struct ocfs2_truncate_context *tc,
6676 u32 clusters_to_del, u64 *delete_start) 6677 u32 clusters_to_del, u64 *delete_start, u8 *flags)
6677{ 6678{
6678 int ret, i, index = path->p_tree_depth; 6679 int ret, i, index = path->p_tree_depth;
6679 u32 new_edge = 0; 6680 u32 new_edge = 0;
@@ -6683,6 +6684,7 @@ static int ocfs2_trim_tree(struct inode *inode, struct ocfs2_path *path,
6683 struct ocfs2_extent_rec *rec; 6684 struct ocfs2_extent_rec *rec;
6684 6685
6685 *delete_start = 0; 6686 *delete_start = 0;
6687 *flags = 0;
6686 6688
6687 while (index >= 0) { 6689 while (index >= 0) {
6688 bh = path->p_node[index].bh; 6690 bh = path->p_node[index].bh;
@@ -6770,6 +6772,7 @@ find_tail_record:
6770 *delete_start = le64_to_cpu(rec->e_blkno) 6772 *delete_start = le64_to_cpu(rec->e_blkno)
6771 + ocfs2_clusters_to_blocks(inode->i_sb, 6773 + ocfs2_clusters_to_blocks(inode->i_sb,
6772 le16_to_cpu(rec->e_leaf_clusters)); 6774 le16_to_cpu(rec->e_leaf_clusters));
6775 *flags = rec->e_flags;
6773 6776
6774 /* 6777 /*
6775 * If it's now empty, remove this record. 6778 * If it's now empty, remove this record.
@@ -6869,7 +6872,8 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
6869 struct buffer_head *fe_bh, 6872 struct buffer_head *fe_bh,
6870 handle_t *handle, 6873 handle_t *handle,
6871 struct ocfs2_truncate_context *tc, 6874 struct ocfs2_truncate_context *tc,
6872 struct ocfs2_path *path) 6875 struct ocfs2_path *path,
6876 struct ocfs2_alloc_context *meta_ac)
6873{ 6877{
6874 int status; 6878 int status;
6875 struct ocfs2_dinode *fe; 6879 struct ocfs2_dinode *fe;
@@ -6877,6 +6881,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
6877 struct ocfs2_extent_list *el; 6881 struct ocfs2_extent_list *el;
6878 struct buffer_head *last_eb_bh = NULL; 6882 struct buffer_head *last_eb_bh = NULL;
6879 u64 delete_blk = 0; 6883 u64 delete_blk = 0;
6884 u8 rec_flags;
6880 6885
6881 fe = (struct ocfs2_dinode *) fe_bh->b_data; 6886 fe = (struct ocfs2_dinode *) fe_bh->b_data;
6882 6887
@@ -6932,7 +6937,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
6932 inode->i_blocks = ocfs2_inode_sector_count(inode); 6937 inode->i_blocks = ocfs2_inode_sector_count(inode);
6933 6938
6934 status = ocfs2_trim_tree(inode, path, handle, tc, 6939 status = ocfs2_trim_tree(inode, path, handle, tc,
6935 clusters_to_del, &delete_blk); 6940 clusters_to_del, &delete_blk, &rec_flags);
6936 if (status) { 6941 if (status) {
6937 mlog_errno(status); 6942 mlog_errno(status);
6938 goto bail; 6943 goto bail;
@@ -6964,8 +6969,16 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
6964 } 6969 }
6965 6970
6966 if (delete_blk) { 6971 if (delete_blk) {
6967 status = ocfs2_truncate_log_append(osb, handle, delete_blk, 6972 if (rec_flags & OCFS2_EXT_REFCOUNTED)
6968 clusters_to_del); 6973 status = ocfs2_decrease_refcount(inode, handle,
6974 ocfs2_blocks_to_clusters(osb->sb,
6975 delete_blk),
6976 clusters_to_del, meta_ac,
6977 &tc->tc_dealloc);
6978 else
6979 status = ocfs2_truncate_log_append(osb, handle,
6980 delete_blk,
6981 clusters_to_del);
6969 if (status < 0) { 6982 if (status < 0) {
6970 mlog_errno(status); 6983 mlog_errno(status);
6971 goto bail; 6984 goto bail;
@@ -7383,11 +7396,14 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
7383{ 7396{
7384 int status, i, credits, tl_sem = 0; 7397 int status, i, credits, tl_sem = 0;
7385 u32 clusters_to_del, new_highest_cpos, range; 7398 u32 clusters_to_del, new_highest_cpos, range;
7399 u64 blkno = 0;
7386 struct ocfs2_extent_list *el; 7400 struct ocfs2_extent_list *el;
7387 handle_t *handle = NULL; 7401 handle_t *handle = NULL;
7388 struct inode *tl_inode = osb->osb_tl_inode; 7402 struct inode *tl_inode = osb->osb_tl_inode;
7389 struct ocfs2_path *path = NULL; 7403 struct ocfs2_path *path = NULL;
7390 struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data; 7404 struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data;
7405 struct ocfs2_alloc_context *meta_ac = NULL;
7406 struct ocfs2_refcount_tree *ref_tree = NULL;
7391 7407
7392 mlog_entry_void(); 7408 mlog_entry_void();
7393 7409
@@ -7413,6 +7429,8 @@ start:
7413 goto bail; 7429 goto bail;
7414 } 7430 }
7415 7431
7432 credits = 0;
7433
7416 /* 7434 /*
7417 * Truncate always works against the rightmost tree branch. 7435 * Truncate always works against the rightmost tree branch.
7418 */ 7436 */
@@ -7453,10 +7471,15 @@ start:
7453 clusters_to_del = 0; 7471 clusters_to_del = 0;
7454 } else if (le32_to_cpu(el->l_recs[i].e_cpos) >= new_highest_cpos) { 7472 } else if (le32_to_cpu(el->l_recs[i].e_cpos) >= new_highest_cpos) {
7455 clusters_to_del = ocfs2_rec_clusters(el, &el->l_recs[i]); 7473 clusters_to_del = ocfs2_rec_clusters(el, &el->l_recs[i]);
7474 blkno = le64_to_cpu(el->l_recs[i].e_blkno);
7456 } else if (range > new_highest_cpos) { 7475 } else if (range > new_highest_cpos) {
7457 clusters_to_del = (ocfs2_rec_clusters(el, &el->l_recs[i]) + 7476 clusters_to_del = (ocfs2_rec_clusters(el, &el->l_recs[i]) +
7458 le32_to_cpu(el->l_recs[i].e_cpos)) - 7477 le32_to_cpu(el->l_recs[i].e_cpos)) -
7459 new_highest_cpos; 7478 new_highest_cpos;
7479 blkno = le64_to_cpu(el->l_recs[i].e_blkno) +
7480 ocfs2_clusters_to_blocks(inode->i_sb,
7481 ocfs2_rec_clusters(el, &el->l_recs[i]) -
7482 clusters_to_del);
7460 } else { 7483 } else {
7461 status = 0; 7484 status = 0;
7462 goto bail; 7485 goto bail;
@@ -7465,6 +7488,29 @@ start:
7465 mlog(0, "clusters_to_del = %u in this pass, tail blk=%llu\n", 7488 mlog(0, "clusters_to_del = %u in this pass, tail blk=%llu\n",
7466 clusters_to_del, (unsigned long long)path_leaf_bh(path)->b_blocknr); 7489 clusters_to_del, (unsigned long long)path_leaf_bh(path)->b_blocknr);
7467 7490
7491 if (el->l_recs[i].e_flags & OCFS2_EXT_REFCOUNTED && clusters_to_del) {
7492 BUG_ON(!(OCFS2_I(inode)->ip_dyn_features &
7493 OCFS2_HAS_REFCOUNT_FL));
7494
7495 status = ocfs2_lock_refcount_tree(osb,
7496 le64_to_cpu(di->i_refcount_loc),
7497 1, &ref_tree, NULL);
7498 if (status) {
7499 mlog_errno(status);
7500 goto bail;
7501 }
7502
7503 status = ocfs2_prepare_refcount_change_for_del(inode, fe_bh,
7504 blkno,
7505 clusters_to_del,
7506 &credits,
7507 &meta_ac);
7508 if (status < 0) {
7509 mlog_errno(status);
7510 goto bail;
7511 }
7512 }
7513
7468 mutex_lock(&tl_inode->i_mutex); 7514 mutex_lock(&tl_inode->i_mutex);
7469 tl_sem = 1; 7515 tl_sem = 1;
7470 /* ocfs2_truncate_log_needs_flush guarantees us at least one 7516 /* ocfs2_truncate_log_needs_flush guarantees us at least one
@@ -7478,7 +7524,7 @@ start:
7478 } 7524 }
7479 } 7525 }
7480 7526
7481 credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del, 7527 credits += ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del,
7482 (struct ocfs2_dinode *)fe_bh->b_data, 7528 (struct ocfs2_dinode *)fe_bh->b_data,
7483 el); 7529 el);
7484 handle = ocfs2_start_trans(osb, credits); 7530 handle = ocfs2_start_trans(osb, credits);
@@ -7490,7 +7536,7 @@ start:
7490 } 7536 }
7491 7537
7492 status = ocfs2_do_truncate(osb, clusters_to_del, inode, fe_bh, handle, 7538 status = ocfs2_do_truncate(osb, clusters_to_del, inode, fe_bh, handle,
7493 tc, path); 7539 tc, path, meta_ac);
7494 if (status < 0) { 7540 if (status < 0) {
7495 mlog_errno(status); 7541 mlog_errno(status);
7496 goto bail; 7542 goto bail;
@@ -7504,6 +7550,16 @@ start:
7504 7550
7505 ocfs2_reinit_path(path, 1); 7551 ocfs2_reinit_path(path, 1);
7506 7552
7553 if (meta_ac) {
7554 ocfs2_free_alloc_context(meta_ac);
7555 meta_ac = NULL;
7556 }
7557
7558 if (ref_tree) {
7559 ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
7560 ref_tree = NULL;
7561 }
7562
7507 /* 7563 /*
7508 * The check above will catch the case where we've truncated 7564 * The check above will catch the case where we've truncated
7509 * away all allocation. 7565 * away all allocation.
@@ -7520,6 +7576,12 @@ bail:
7520 if (handle) 7576 if (handle)
7521 ocfs2_commit_trans(osb, handle); 7577 ocfs2_commit_trans(osb, handle);
7522 7578
7579 if (meta_ac)
7580 ocfs2_free_alloc_context(meta_ac);
7581
7582 if (ref_tree)
7583 ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
7584
7523 ocfs2_run_deallocs(osb, &tc->tc_dealloc); 7585 ocfs2_run_deallocs(osb, &tc->tc_dealloc);
7524 7586
7525 ocfs2_free_path(path); 7587 ocfs2_free_path(path);