Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 165117
b: refs/heads/master
c: 6ae23c5
h: refs/heads/master
i:
  165115: ad7dd75
v: v3
  • Loading branch information
Tao Ma authored and Joel Becker committed Sep 23, 2009
1 parent fa118de commit 45f9af9
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6f70fa519976a379d72781d927cf8e5f5b05ec86
refs/heads/master: 6ae23c5555176c5b23480c9c578ff27437085ba5
2 changes: 1 addition & 1 deletion trunk/fs/ocfs2/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6974,7 +6974,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
ocfs2_blocks_to_clusters(osb->sb,
delete_blk),
clusters_to_del, meta_ac,
&tc->tc_dealloc);
&tc->tc_dealloc, 1);
else
status = ocfs2_truncate_log_append(osb, handle,
delete_blk,
Expand Down
104 changes: 78 additions & 26 deletions trunk/fs/ocfs2/refcounttree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2076,17 +2076,19 @@ static int __ocfs2_decrease_refcount(handle_t *handle,
struct buffer_head *ref_root_bh,
u64 cpos, u32 len,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc)
struct ocfs2_cached_dealloc_ctxt *dealloc,
int delete)
{
int ret = 0, index = 0;
struct ocfs2_refcount_rec rec;
unsigned int r_count = 0, r_len;
struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
struct buffer_head *ref_leaf_bh = NULL;

mlog(0, "Tree owner %llu, decrease refcount start %llu, len %u\n",
mlog(0, "Tree owner %llu, decrease refcount start %llu, "
"len %u, delete %u\n",
(unsigned long long)ocfs2_metadata_cache_owner(ci),
(unsigned long long)cpos, len);
(unsigned long long)cpos, len, delete);

while (len) {
ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
Expand All @@ -2099,6 +2101,8 @@ static int __ocfs2_decrease_refcount(handle_t *handle,

r_count = le32_to_cpu(rec.r_refcount);
BUG_ON(r_count == 0);
if (!delete)
BUG_ON(r_count > 1);

r_len = min((u64)(cpos + len), le64_to_cpu(rec.r_cpos) +
le32_to_cpu(rec.r_clusters)) - cpos;
Expand All @@ -2112,7 +2116,7 @@ static int __ocfs2_decrease_refcount(handle_t *handle,
goto out;
}

if (le32_to_cpu(rec.r_refcount) == 1) {
if (le32_to_cpu(rec.r_refcount) == 1 && delete) {
ret = ocfs2_cache_cluster_dealloc(dealloc,
ocfs2_clusters_to_blocks(sb, cpos),
r_len);
Expand All @@ -2137,7 +2141,8 @@ static int __ocfs2_decrease_refcount(handle_t *handle,
int ocfs2_decrease_refcount(struct inode *inode,
handle_t *handle, u32 cpos, u32 len,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc)
struct ocfs2_cached_dealloc_ctxt *dealloc,
int delete)
{
int ret;
u64 ref_blkno;
Expand Down Expand Up @@ -2167,7 +2172,7 @@ int ocfs2_decrease_refcount(struct inode *inode,
}

ret = __ocfs2_decrease_refcount(handle, &tree->rf_ci, ref_root_bh,
cpos, len, meta_ac, dealloc);
cpos, len, meta_ac, dealloc, delete);
if (ret)
mlog_errno(ret);
out:
Expand Down Expand Up @@ -2974,10 +2979,16 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
u32 cpos, u32 p_cluster,
u32 num_clusters, unsigned int e_flags)
{
int ret, credits = 0;
int ret, delete, index, credits = 0;
u32 new_bit, new_len;
unsigned int set_len;
struct ocfs2_super *osb = OCFS2_SB(sb);
handle_t *handle;
struct buffer_head *ref_leaf_bh = NULL;
struct ocfs2_refcount_rec rec;

mlog(0, "cpos %u, p_cluster %u, num_clusters %u, e_flags %u\n",
cpos, p_cluster, num_clusters, e_flags);

ret = ocfs2_lock_refcount_allocators(sb, p_cluster, num_clusters,
&context->di_et,
Expand All @@ -2998,35 +3009,75 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
}

while (num_clusters) {
ret = __ocfs2_claim_clusters(osb, handle, context->data_ac,
1, num_clusters,
&new_bit, &new_len);
ret = ocfs2_get_refcount_rec(context->ref_ci,
context->ref_root_bh,
p_cluster, num_clusters,
&rec, &index, &ref_leaf_bh);
if (ret) {
mlog_errno(ret);
goto out_commit;
}

ret = ocfs2_replace_clusters(handle, context,
cpos, p_cluster, new_bit,
new_len, e_flags);
BUG_ON(!rec.r_refcount);
set_len = min((u64)p_cluster + num_clusters,
le64_to_cpu(rec.r_cpos) +
le32_to_cpu(rec.r_clusters)) - p_cluster;

/*
* There are many different situation here.
* 1. If refcount == 1, remove the flag and don't COW.
* 2. If refcount > 1, allocate clusters.
* Here we may not allocate r_len once at a time, so continue
* until we reach num_clusters.
*/
if (le32_to_cpu(rec.r_refcount) == 1) {
delete = 0;
ret = ocfs2_clear_ext_refcount(handle, &context->di_et,
cpos, p_cluster,
set_len, e_flags,
context->meta_ac,
&context->dealloc);
if (ret) {
mlog_errno(ret);
goto out_commit;
}
} else {
delete = 1;

ret = __ocfs2_claim_clusters(osb, handle,
context->data_ac,
1, set_len,
&new_bit, &new_len);
if (ret) {
mlog_errno(ret);
goto out_commit;
}

ret = ocfs2_replace_clusters(handle, context,
cpos, p_cluster, new_bit,
new_len, e_flags);
if (ret) {
mlog_errno(ret);
goto out_commit;
}
set_len = new_len;
}

ret = __ocfs2_decrease_refcount(handle, context->ref_ci,
context->ref_root_bh,
p_cluster, set_len,
context->meta_ac,
&context->dealloc, delete);
if (ret) {
mlog_errno(ret);
goto out_commit;
}

cpos += new_len;
p_cluster += new_len;
num_clusters -= new_len;
}

ret = __ocfs2_decrease_refcount(handle, context->ref_ci,
context->ref_root_bh,
p_cluster, num_clusters,
context->meta_ac,
&context->dealloc);
if (ret) {
mlog_errno(ret);
goto out_commit;
cpos += set_len;
p_cluster += set_len;
num_clusters -= set_len;
brelse(ref_leaf_bh);
ref_leaf_bh = NULL;
}

/*
Expand All @@ -3049,6 +3100,7 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
ocfs2_free_alloc_context(context->meta_ac);
context->meta_ac = NULL;
}
brelse(ref_leaf_bh);

return ret;
}
Expand Down
3 changes: 2 additions & 1 deletion trunk/fs/ocfs2/refcounttree.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ void ocfs2_unlock_refcount_tree(struct ocfs2_super *osb,
int ocfs2_decrease_refcount(struct inode *inode,
handle_t *handle, u32 cpos, u32 len,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc);
struct ocfs2_cached_dealloc_ctxt *dealloc,
int delete);
int ocfs2_prepare_refcount_change_for_del(struct inode *inode,
struct buffer_head *di_bh,
u64 phys_blkno,
Expand Down

0 comments on commit 45f9af9

Please sign in to comment.