diff options
author | Tristan Ye <tristan.ye@oracle.com> | 2011-03-18 02:35:32 -0400 |
---|---|---|
committer | Tristan Ye <tristan.ye@oracle.com> | 2011-05-25 03:17:09 -0400 |
commit | de474ee8bbc315b0e6772cebdb24b335f82cf95d (patch) | |
tree | 04426cf07865f7f456eb2f8154d96b2ef403cee9 /fs/ocfs2 | |
parent | 028ba5df63fa9fc18045bc1e9b48cdd43727e1c5 (diff) |
Ocfs2/move_extents: lock allocators and reserve metadata blocks and data clusters for extents moving.
ocfs2_lock_allocators_move_extents() was like the common ocfs2_lock_allocators(),
to lock metadata and data alloctors during extents moving, reserve appropriate
metadata blocks and data clusters, also performa a best- effort to calculate the
credits for journal transaction in one run of movement.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/move_extents.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index 6311c15356f7..e5ce1495dc77 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c | |||
@@ -54,3 +54,64 @@ struct ocfs2_move_extents_context { | |||
54 | struct ocfs2_alloc_context *data_ac; | 54 | struct ocfs2_alloc_context *data_ac; |
55 | struct ocfs2_cached_dealloc_ctxt dealloc; | 55 | struct ocfs2_cached_dealloc_ctxt dealloc; |
56 | }; | 56 | }; |
57 | |||
58 | /* | ||
59 | * lock allocators, and reserving appropriate number of bits for | ||
60 | * meta blocks and data clusters. | ||
61 | * | ||
62 | * in some cases, we don't need to reserve clusters, just let data_ac | ||
63 | * be NULL. | ||
64 | */ | ||
65 | static int ocfs2_lock_allocators_move_extents(struct inode *inode, | ||
66 | struct ocfs2_extent_tree *et, | ||
67 | u32 clusters_to_move, | ||
68 | u32 extents_to_split, | ||
69 | struct ocfs2_alloc_context **meta_ac, | ||
70 | struct ocfs2_alloc_context **data_ac, | ||
71 | int extra_blocks, | ||
72 | int *credits) | ||
73 | { | ||
74 | int ret, num_free_extents; | ||
75 | unsigned int max_recs_needed = 2 * extents_to_split + clusters_to_move; | ||
76 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
77 | |||
78 | num_free_extents = ocfs2_num_free_extents(osb, et); | ||
79 | if (num_free_extents < 0) { | ||
80 | ret = num_free_extents; | ||
81 | mlog_errno(ret); | ||
82 | goto out; | ||
83 | } | ||
84 | |||
85 | if (!num_free_extents || | ||
86 | (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed)) | ||
87 | extra_blocks += ocfs2_extend_meta_needed(et->et_root_el); | ||
88 | |||
89 | ret = ocfs2_reserve_new_metadata_blocks(osb, extra_blocks, meta_ac); | ||
90 | if (ret) { | ||
91 | mlog_errno(ret); | ||
92 | goto out; | ||
93 | } | ||
94 | |||
95 | if (data_ac) { | ||
96 | ret = ocfs2_reserve_clusters(osb, clusters_to_move, data_ac); | ||
97 | if (ret) { | ||
98 | mlog_errno(ret); | ||
99 | goto out; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | *credits += ocfs2_calc_extend_credits(osb->sb, et->et_root_el, | ||
104 | clusters_to_move + 2); | ||
105 | |||
106 | mlog(0, "reserve metadata_blocks: %d, data_clusters: %u, credits: %d\n", | ||
107 | extra_blocks, clusters_to_move, *credits); | ||
108 | out: | ||
109 | if (ret) { | ||
110 | if (*meta_ac) { | ||
111 | ocfs2_free_alloc_context(*meta_ac); | ||
112 | *meta_ac = NULL; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | return ret; | ||
117 | } | ||