1 From: Tao Ma <tao.ma@oracle.com>
2 Subject: [PATCH 04/16] ocfs2: Make high level btree extend code generic
3 Patch-mainline: 2.6.28?
6 Factor out the non-inode specifics of ocfs2_do_extend_allocation() into a more generic
7 function, ocfs2_do_cluster_allocation(). ocfs2_do_extend_allocation calls
8 ocfs2_do_cluster_allocation() now, but the latter can be used for other
11 Signed-off-by: Tao Ma <tao.ma@oracle.com>
12 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
14 fs/ocfs2/alloc.c | 110 ++++++++++++++++++++++++++++++++++++++++++++
15 fs/ocfs2/alloc.h | 17 ++++++
16 fs/ocfs2/aops.c | 8 +--
18 fs/ocfs2/file.c | 136 ++++++++++---------------------------------------------
19 fs/ocfs2/file.h | 26 ++++------
20 fs/ocfs2/namei.c | 8 +--
21 7 files changed, 176 insertions(+), 135 deletions(-)
23 --- a/fs/ocfs2/alloc.c
24 +++ b/fs/ocfs2/alloc.c
25 @@ -4302,6 +4302,116 @@ bail:
30 + * Allcate and add clusters into the extent b-tree.
31 + * The new clusters(clusters_to_add) will be inserted at logical_offset.
32 + * The extent b-tree's root is root_el and it should be in root_bh, and
33 + * it is not limited to the file storage. Any extent tree can use this
34 + * function if it implements the proper ocfs2_extent_tree.
36 +int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
37 + struct inode *inode,
38 + u32 *logical_offset,
39 + u32 clusters_to_add,
41 + struct buffer_head *root_bh,
42 + struct ocfs2_extent_list *root_el,
44 + struct ocfs2_alloc_context *data_ac,
45 + struct ocfs2_alloc_context *meta_ac,
46 + enum ocfs2_alloc_restarted *reason_ret,
47 + enum ocfs2_extent_tree_type type)
51 + enum ocfs2_alloc_restarted reason = RESTART_NONE;
52 + u32 bit_off, num_bits;
56 + BUG_ON(!clusters_to_add);
59 + flags = OCFS2_EXT_UNWRITTEN;
61 + free_extents = ocfs2_num_free_extents(osb, inode, root_bh, type);
62 + if (free_extents < 0) {
63 + status = free_extents;
68 + /* there are two cases which could cause us to EAGAIN in the
69 + * we-need-more-metadata case:
70 + * 1) we haven't reserved *any*
71 + * 2) we are so fragmented, we've needed to add metadata too
73 + if (!free_extents && !meta_ac) {
74 + mlog(0, "we haven't reserved any metadata!\n");
76 + reason = RESTART_META;
78 + } else if ((!free_extents)
79 + && (ocfs2_alloc_context_bits_left(meta_ac)
80 + < ocfs2_extend_meta_needed(root_el))) {
81 + mlog(0, "filesystem is really fragmented...\n");
83 + reason = RESTART_META;
87 + status = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
88 + clusters_to_add, &bit_off, &num_bits);
90 + if (status != -ENOSPC)
95 + BUG_ON(num_bits > clusters_to_add);
97 + /* reserve our write early -- insert_extent may update the inode */
98 + status = ocfs2_journal_access(handle, inode, root_bh,
99 + OCFS2_JOURNAL_ACCESS_WRITE);
101 + mlog_errno(status);
105 + block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
106 + mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
107 + num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
108 + status = ocfs2_insert_extent(osb, handle, inode, root_bh,
109 + *logical_offset, block, num_bits,
110 + flags, meta_ac, type);
112 + mlog_errno(status);
116 + status = ocfs2_journal_dirty(handle, root_bh);
118 + mlog_errno(status);
122 + clusters_to_add -= num_bits;
123 + *logical_offset += num_bits;
125 + if (clusters_to_add) {
126 + mlog(0, "need to alloc once more, wanted = %u\n",
129 + reason = RESTART_TRANS;
135 + *reason_ret = reason;
139 static void ocfs2_make_right_split_rec(struct super_block *sb,
140 struct ocfs2_extent_rec *split_rec,
142 --- a/fs/ocfs2/alloc.h
143 +++ b/fs/ocfs2/alloc.h
144 @@ -41,6 +41,23 @@ int ocfs2_insert_extent(struct ocfs2_sup
146 struct ocfs2_alloc_context *meta_ac,
147 enum ocfs2_extent_tree_type et_type);
148 +enum ocfs2_alloc_restarted {
153 +int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb,
154 + struct inode *inode,
155 + u32 *logical_offset,
156 + u32 clusters_to_add,
157 + int mark_unwritten,
158 + struct buffer_head *root_bh,
159 + struct ocfs2_extent_list *root_el,
161 + struct ocfs2_alloc_context *data_ac,
162 + struct ocfs2_alloc_context *meta_ac,
163 + enum ocfs2_alloc_restarted *reason_ret,
164 + enum ocfs2_extent_tree_type type);
165 struct ocfs2_cached_dealloc_ctxt;
166 int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh,
167 handle_t *handle, u32 cpos, u32 len, u32 phys,
168 --- a/fs/ocfs2/aops.c
169 +++ b/fs/ocfs2/aops.c
170 @@ -1255,10 +1255,10 @@ static int ocfs2_write_cluster(struct ad
171 * any additional semaphores or cluster locks.
174 - ret = ocfs2_do_extend_allocation(OCFS2_SB(inode->i_sb), inode,
175 - &tmp_pos, 1, 0, wc->w_di_bh,
176 - wc->w_handle, data_ac,
178 + ret = ocfs2_add_inode_data(OCFS2_SB(inode->i_sb), inode,
179 + &tmp_pos, 1, 0, wc->w_di_bh,
180 + wc->w_handle, data_ac,
183 * This shouldn't happen because we must have already
184 * calculated the correct meta data allocation required. The
187 @@ -1383,9 +1383,9 @@ static int ocfs2_do_extend_dir(struct su
189 u32 offset = OCFS2_I(dir)->ip_clusters;
191 - status = ocfs2_do_extend_allocation(OCFS2_SB(sb), dir, &offset,
192 - 1, 0, parent_fe_bh, handle,
193 - data_ac, meta_ac, NULL);
194 + status = ocfs2_add_inode_data(OCFS2_SB(sb), dir, &offset,
195 + 1, 0, parent_fe_bh, handle,
196 + data_ac, meta_ac, NULL);
197 BUG_ON(status == -EAGAIN);
200 --- a/fs/ocfs2/file.c
201 +++ b/fs/ocfs2/file.c
202 @@ -488,7 +488,7 @@ bail:
206 - * extend allocation only here.
207 + * extend file allocation only here.
208 * we'll update all the disk stuff, and oip->alloc_size
210 * expect stuff to be locked, a transaction started and enough data /
211 @@ -497,107 +497,25 @@ bail:
212 * Will return -EAGAIN, and a reason if a restart is needed.
213 * If passed in, *reason will always be set, even in error.
215 -int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
216 - struct inode *inode,
217 - u32 *logical_offset,
218 - u32 clusters_to_add,
219 - int mark_unwritten,
220 - struct buffer_head *fe_bh,
222 - struct ocfs2_alloc_context *data_ac,
223 - struct ocfs2_alloc_context *meta_ac,
224 - enum ocfs2_alloc_restarted *reason_ret)
225 +int ocfs2_add_inode_data(struct ocfs2_super *osb,
226 + struct inode *inode,
227 + u32 *logical_offset,
228 + u32 clusters_to_add,
229 + int mark_unwritten,
230 + struct buffer_head *fe_bh,
232 + struct ocfs2_alloc_context *data_ac,
233 + struct ocfs2_alloc_context *meta_ac,
234 + enum ocfs2_alloc_restarted *reason_ret)
238 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
239 - enum ocfs2_alloc_restarted reason = RESTART_NONE;
240 - u32 bit_off, num_bits;
244 - BUG_ON(!clusters_to_add);
246 - if (mark_unwritten)
247 - flags = OCFS2_EXT_UNWRITTEN;
249 - free_extents = ocfs2_num_free_extents(osb, inode, fe_bh,
250 - OCFS2_DINODE_EXTENT);
251 - if (free_extents < 0) {
252 - status = free_extents;
253 - mlog_errno(status);
257 - /* there are two cases which could cause us to EAGAIN in the
258 - * we-need-more-metadata case:
259 - * 1) we haven't reserved *any*
260 - * 2) we are so fragmented, we've needed to add metadata too
262 - if (!free_extents && !meta_ac) {
263 - mlog(0, "we haven't reserved any metadata!\n");
265 - reason = RESTART_META;
267 - } else if ((!free_extents)
268 - && (ocfs2_alloc_context_bits_left(meta_ac)
269 - < ocfs2_extend_meta_needed(&fe->id2.i_list))) {
270 - mlog(0, "filesystem is really fragmented...\n");
272 - reason = RESTART_META;
276 - status = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
277 - clusters_to_add, &bit_off, &num_bits);
279 - if (status != -ENOSPC)
280 - mlog_errno(status);
284 - BUG_ON(num_bits > clusters_to_add);
286 - /* reserve our write early -- insert_extent may update the inode */
287 - status = ocfs2_journal_access(handle, inode, fe_bh,
288 - OCFS2_JOURNAL_ACCESS_WRITE);
290 - mlog_errno(status);
294 - block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
295 - mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
296 - num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
297 - status = ocfs2_insert_extent(osb, handle, inode, fe_bh,
298 - *logical_offset, block, num_bits,
299 - flags, meta_ac, OCFS2_DINODE_EXTENT);
301 - mlog_errno(status);
304 + struct ocfs2_extent_list *el = &fe->id2.i_list;
306 - status = ocfs2_journal_dirty(handle, fe_bh);
308 - mlog_errno(status);
312 - clusters_to_add -= num_bits;
313 - *logical_offset += num_bits;
315 - if (clusters_to_add) {
316 - mlog(0, "need to alloc once more, clusters = %u, wanted = "
317 - "%u\n", fe->i_clusters, clusters_to_add);
319 - reason = RESTART_TRANS;
325 - *reason_ret = reason;
327 + return ocfs2_add_clusters_in_btree(osb, inode, logical_offset,
328 + clusters_to_add, mark_unwritten,
330 + data_ac, meta_ac, reason_ret,
331 + OCFS2_DINODE_EXTENT);
334 static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
335 @@ -676,16 +594,16 @@ restarted_transaction:
337 prev_clusters = OCFS2_I(inode)->ip_clusters;
339 - status = ocfs2_do_extend_allocation(osb,
349 + status = ocfs2_add_inode_data(osb,
359 if ((status < 0) && (status != -EAGAIN)) {
360 if (status != -ENOSPC)
362 --- a/fs/ocfs2/file.h
363 +++ b/fs/ocfs2/file.h
364 @@ -31,6 +31,7 @@ extern const struct file_operations ocfs
365 extern const struct inode_operations ocfs2_file_iops;
366 extern const struct inode_operations ocfs2_special_file_iops;
367 struct ocfs2_alloc_context;
368 +enum ocfs2_alloc_restarted;
370 struct ocfs2_file_private {
371 struct file *fp_file;
372 @@ -38,21 +39,16 @@ struct ocfs2_file_private {
373 struct ocfs2_lock_res fp_flock;
376 -enum ocfs2_alloc_restarted {
381 -int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
382 - struct inode *inode,
383 - u32 *logical_offset,
384 - u32 clusters_to_add,
385 - int mark_unwritten,
386 - struct buffer_head *fe_bh,
388 - struct ocfs2_alloc_context *data_ac,
389 - struct ocfs2_alloc_context *meta_ac,
390 - enum ocfs2_alloc_restarted *reason_ret);
391 +int ocfs2_add_inode_data(struct ocfs2_super *osb,
392 + struct inode *inode,
393 + u32 *logical_offset,
394 + u32 clusters_to_add,
395 + int mark_unwritten,
396 + struct buffer_head *fe_bh,
398 + struct ocfs2_alloc_context *data_ac,
399 + struct ocfs2_alloc_context *meta_ac,
400 + enum ocfs2_alloc_restarted *reason_ret);
401 int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size,
403 int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
404 --- a/fs/ocfs2/namei.c
405 +++ b/fs/ocfs2/namei.c
406 @@ -1598,10 +1598,10 @@ static int ocfs2_symlink(struct inode *d
409 inode->i_op = &ocfs2_symlink_inode_operations;
410 - status = ocfs2_do_extend_allocation(osb, inode, &offset, 1, 0,
412 - handle, data_ac, NULL,
414 + status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0,
416 + handle, data_ac, NULL,
419 if (status != -ENOSPC && status != -EINTR) {