aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2009-08-17 23:44:03 -0400
committerJoel Becker <joel.becker@oracle.com>2009-09-22 23:09:46 -0400
commit7540c1a77b26bc2f9d86a0bfbe6597b05ec5f93d (patch)
tree4b0414f74d265cfe496d5e5f39c6c6d240f6e713 /fs
parentce9c5a54c0f06b0efb4db8720a0616cc6aa0e5b2 (diff)
ocfs2: Don't merge in 1st refcount ops of reflink.
Actually the whole reflink will touch refcount tree 2 times: 1. It will add the clusters in the extent record to the tree if it isn't refcounted before. 2. It will add 1 refcount to these clusters when it add these extent records to the tree. So actually we shouldn't do merge in the 1st operation since the 2nd one will soon be called and we may have to split it again. Do a merge first and split soon is a waste of time. So we only merge in the 2nd round. This is done by adding a new internal __ocfs2_increase_refcount and call it with "not-merge" for 1st refcount operation in reflink. This also has a side-effect that we don't need to worry too much about the metadata allocation in the 2nd round since it will only merge and no split will happen for those records. Signed-off-by: Tao Ma <tao.ma@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/refcounttree.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index dc57d066f794..47df8c5cd3c5 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -1147,7 +1147,7 @@ static void ocfs2_refcount_rec_merge(struct ocfs2_refcount_block *rb,
1147static int ocfs2_change_refcount_rec(handle_t *handle, 1147static int ocfs2_change_refcount_rec(handle_t *handle,
1148 struct ocfs2_caching_info *ci, 1148 struct ocfs2_caching_info *ci,
1149 struct buffer_head *ref_leaf_bh, 1149 struct buffer_head *ref_leaf_bh,
1150 int index, int change) 1150 int index, int merge, int change)
1151{ 1151{
1152 int ret; 1152 int ret;
1153 struct ocfs2_refcount_block *rb = 1153 struct ocfs2_refcount_block *rb =
@@ -1176,7 +1176,7 @@ static int ocfs2_change_refcount_rec(handle_t *handle,
1176 } 1176 }
1177 1177
1178 le16_add_cpu(&rl->rl_used, -1); 1178 le16_add_cpu(&rl->rl_used, -1);
1179 } else 1179 } else if (merge)
1180 ocfs2_refcount_rec_merge(rb, index); 1180 ocfs2_refcount_rec_merge(rb, index);
1181 1181
1182 ret = ocfs2_journal_dirty(handle, ref_leaf_bh); 1182 ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
@@ -1652,7 +1652,7 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,
1652 struct buffer_head *ref_root_bh, 1652 struct buffer_head *ref_root_bh,
1653 struct buffer_head *ref_leaf_bh, 1653 struct buffer_head *ref_leaf_bh,
1654 struct ocfs2_refcount_rec *rec, 1654 struct ocfs2_refcount_rec *rec,
1655 int index, 1655 int index, int merge,
1656 struct ocfs2_alloc_context *meta_ac) 1656 struct ocfs2_alloc_context *meta_ac)
1657{ 1657{
1658 int ret; 1658 int ret;
@@ -1710,7 +1710,8 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,
1710 1710
1711 le16_add_cpu(&rf_list->rl_used, 1); 1711 le16_add_cpu(&rf_list->rl_used, 1);
1712 1712
1713 ocfs2_refcount_rec_merge(rb, index); 1713 if (merge)
1714 ocfs2_refcount_rec_merge(rb, index);
1714 1715
1715 ret = ocfs2_journal_dirty(handle, ref_leaf_bh); 1716 ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
1716 if (ret) { 1717 if (ret) {
@@ -1744,7 +1745,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
1744 struct buffer_head *ref_root_bh, 1745 struct buffer_head *ref_root_bh,
1745 struct buffer_head *ref_leaf_bh, 1746 struct buffer_head *ref_leaf_bh,
1746 struct ocfs2_refcount_rec *split_rec, 1747 struct ocfs2_refcount_rec *split_rec,
1747 int index, 1748 int index, int merge,
1748 struct ocfs2_alloc_context *meta_ac, 1749 struct ocfs2_alloc_context *meta_ac,
1749 struct ocfs2_cached_dealloc_ctxt *dealloc) 1750 struct ocfs2_cached_dealloc_ctxt *dealloc)
1750{ 1751{
@@ -1882,7 +1883,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
1882 le32_to_cpu(split_rec->r_refcount), 1883 le32_to_cpu(split_rec->r_refcount),
1883 (unsigned long long)ref_leaf_bh->b_blocknr, index); 1884 (unsigned long long)ref_leaf_bh->b_blocknr, index);
1884 1885
1885 ocfs2_refcount_rec_merge(rb, index); 1886 if (merge)
1887 ocfs2_refcount_rec_merge(rb, index);
1886 } 1888 }
1887 1889
1888 ret = ocfs2_journal_dirty(handle, ref_leaf_bh); 1890 ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
@@ -1894,12 +1896,12 @@ out:
1894 return ret; 1896 return ret;
1895} 1897}
1896 1898
1897int ocfs2_increase_refcount(handle_t *handle, 1899static int __ocfs2_increase_refcount(handle_t *handle,
1898 struct ocfs2_caching_info *ci, 1900 struct ocfs2_caching_info *ci,
1899 struct buffer_head *ref_root_bh, 1901 struct buffer_head *ref_root_bh,
1900 u64 cpos, u32 len, 1902 u64 cpos, u32 len, int merge,
1901 struct ocfs2_alloc_context *meta_ac, 1903 struct ocfs2_alloc_context *meta_ac,
1902 struct ocfs2_cached_dealloc_ctxt *dealloc) 1904 struct ocfs2_cached_dealloc_ctxt *dealloc)
1903{ 1905{
1904 int ret = 0, index; 1906 int ret = 0, index;
1905 struct buffer_head *ref_leaf_bh = NULL; 1907 struct buffer_head *ref_leaf_bh = NULL;
@@ -1937,7 +1939,8 @@ int ocfs2_increase_refcount(handle_t *handle,
1937 "count %u\n", (unsigned long long)cpos, set_len, 1939 "count %u\n", (unsigned long long)cpos, set_len,
1938 le32_to_cpu(rec.r_refcount)); 1940 le32_to_cpu(rec.r_refcount));
1939 ret = ocfs2_change_refcount_rec(handle, ci, 1941 ret = ocfs2_change_refcount_rec(handle, ci,
1940 ref_leaf_bh, index, 1); 1942 ref_leaf_bh, index,
1943 merge, 1);
1941 if (ret) { 1944 if (ret) {
1942 mlog_errno(ret); 1945 mlog_errno(ret);
1943 goto out; 1946 goto out;
@@ -1950,7 +1953,8 @@ int ocfs2_increase_refcount(handle_t *handle,
1950 set_len); 1953 set_len);
1951 ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh, 1954 ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh,
1952 ref_leaf_bh, 1955 ref_leaf_bh,
1953 &rec, index, meta_ac); 1956 &rec, index,
1957 merge, meta_ac);
1954 if (ret) { 1958 if (ret) {
1955 mlog_errno(ret); 1959 mlog_errno(ret);
1956 goto out; 1960 goto out;
@@ -1968,7 +1972,7 @@ int ocfs2_increase_refcount(handle_t *handle,
1968 set_len, le32_to_cpu(rec.r_refcount)); 1972 set_len, le32_to_cpu(rec.r_refcount));
1969 ret = ocfs2_split_refcount_rec(handle, ci, 1973 ret = ocfs2_split_refcount_rec(handle, ci,
1970 ref_root_bh, ref_leaf_bh, 1974 ref_root_bh, ref_leaf_bh,
1971 &rec, index, 1975 &rec, index, merge,
1972 meta_ac, dealloc); 1976 meta_ac, dealloc);
1973 if (ret) { 1977 if (ret) {
1974 mlog_errno(ret); 1978 mlog_errno(ret);
@@ -2061,6 +2065,18 @@ out:
2061 return ret; 2065 return ret;
2062} 2066}
2063 2067
2068int ocfs2_increase_refcount(handle_t *handle,
2069 struct ocfs2_caching_info *ci,
2070 struct buffer_head *ref_root_bh,
2071 u64 cpos, u32 len,
2072 struct ocfs2_alloc_context *meta_ac,
2073 struct ocfs2_cached_dealloc_ctxt *dealloc)
2074{
2075 return __ocfs2_increase_refcount(handle, ci, ref_root_bh,
2076 cpos, len, 1,
2077 meta_ac, dealloc);
2078}
2079
2064static int ocfs2_decrease_refcount_rec(handle_t *handle, 2080static int ocfs2_decrease_refcount_rec(handle_t *handle,
2065 struct ocfs2_caching_info *ci, 2081 struct ocfs2_caching_info *ci,
2066 struct buffer_head *ref_root_bh, 2082 struct buffer_head *ref_root_bh,
@@ -2081,7 +2097,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
2081 if (cpos == le64_to_cpu(rec->r_cpos) && 2097 if (cpos == le64_to_cpu(rec->r_cpos) &&
2082 len == le32_to_cpu(rec->r_clusters)) 2098 len == le32_to_cpu(rec->r_clusters))
2083 ret = ocfs2_change_refcount_rec(handle, ci, 2099 ret = ocfs2_change_refcount_rec(handle, ci,
2084 ref_leaf_bh, index, -1); 2100 ref_leaf_bh, index, 1, -1);
2085 else { 2101 else {
2086 struct ocfs2_refcount_rec split = *rec; 2102 struct ocfs2_refcount_rec split = *rec;
2087 split.r_cpos = cpu_to_le64(cpos); 2103 split.r_cpos = cpu_to_le64(cpos);
@@ -2097,7 +2113,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
2097 le32_to_cpu(rec->r_clusters)); 2113 le32_to_cpu(rec->r_clusters));
2098 ret = ocfs2_split_refcount_rec(handle, ci, 2114 ret = ocfs2_split_refcount_rec(handle, ci,
2099 ref_root_bh, ref_leaf_bh, 2115 ref_root_bh, ref_leaf_bh,
2100 &split, index, 2116 &split, index, 1,
2101 meta_ac, dealloc); 2117 meta_ac, dealloc);
2102 } 2118 }
2103 2119
@@ -3631,9 +3647,9 @@ int ocfs2_add_refcount_flag(struct inode *inode,
3631 goto out_commit; 3647 goto out_commit;
3632 } 3648 }
3633 3649
3634 ret = ocfs2_increase_refcount(handle, ref_ci, ref_root_bh, 3650 ret = __ocfs2_increase_refcount(handle, ref_ci, ref_root_bh,
3635 p_cluster, num_clusters, 3651 p_cluster, num_clusters, 0,
3636 meta_ac, dealloc); 3652 meta_ac, dealloc);
3637 if (ret) { 3653 if (ret) {
3638 mlog_errno(ret); 3654 mlog_errno(ret);
3639 goto out_commit; 3655 goto out_commit;