aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/move_extent.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2014-11-02 16:36:05 -0500
committerOlof Johansson <olof@lixom.net>2014-11-02 16:37:07 -0500
commit4257412db57900e43716d0b7ddd4f4a51e6ed2f4 (patch)
tree759963245a484422e9ad2639cb223b53f844ff15 /fs/ext4/move_extent.c
parentcc040ba269ae6972face1dc7376ab3eaab9f64c8 (diff)
parent4b91f7f3c8b20e073b7bfc098625b37f99789508 (diff)
Merge tag 'fixes-against-v3.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into fixes
Merge "omap fixes against v3.18-rc2" from Tony Lindgren: Few fixes for omaps to enable NAND BCH so devices won't produce errors when booted with omap2plus_defconfig, and reduce bloat by making IPV6 a loadable module. Also let's add a warning about legacy boot being deprecated for omap3. We now have things working with device tree, and only omap3 is still booting in legacy mode. So hopefully this warning will help move the remaining legacy mode users to boot with device tree. As the total reduction of code and static data is somewhere around 20000 lines of code once we remove omap3 legacy mode booting, we really do want to make omap3 to boot also in device tree mode only over the next few merge cycles. * tag 'fixes-against-v3.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (407 commits) ARM: OMAP2+: Warn about deprecated legacy booting mode ARM: omap2plus_defconfig: Fix errors with NAND BCH ARM: omap2plus_defconfig: Fix bloat caused by having ipv6 built-in + Linux 3.18-rc2 Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'fs/ext4/move_extent.c')
-rw-r--r--fs/ext4/move_extent.c1068
1 files changed, 123 insertions, 945 deletions
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 671a74b14fd7..9f2311bc9c4f 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -27,120 +27,26 @@
27 * @lblock: logical block number to find an extent path 27 * @lblock: logical block number to find an extent path
28 * @path: pointer to an extent path pointer (for output) 28 * @path: pointer to an extent path pointer (for output)
29 * 29 *
30 * ext4_ext_find_extent wrapper. Return 0 on success, or a negative error value 30 * ext4_find_extent wrapper. Return 0 on success, or a negative error value
31 * on failure. 31 * on failure.
32 */ 32 */
33static inline int 33static inline int
34get_ext_path(struct inode *inode, ext4_lblk_t lblock, 34get_ext_path(struct inode *inode, ext4_lblk_t lblock,
35 struct ext4_ext_path **orig_path) 35 struct ext4_ext_path **ppath)
36{ 36{
37 int ret = 0;
38 struct ext4_ext_path *path; 37 struct ext4_ext_path *path;
39 38
40 path = ext4_ext_find_extent(inode, lblock, *orig_path, EXT4_EX_NOCACHE); 39 path = ext4_find_extent(inode, lblock, ppath, EXT4_EX_NOCACHE);
41 if (IS_ERR(path)) 40 if (IS_ERR(path))
42 ret = PTR_ERR(path); 41 return PTR_ERR(path);
43 else if (path[ext_depth(inode)].p_ext == NULL) 42 if (path[ext_depth(inode)].p_ext == NULL) {
44 ret = -ENODATA; 43 ext4_ext_drop_refs(path);
45 else 44 kfree(path);
46 *orig_path = path; 45 *ppath = NULL;
47 46 return -ENODATA;
48 return ret;
49}
50
51/**
52 * copy_extent_status - Copy the extent's initialization status
53 *
54 * @src: an extent for getting initialize status
55 * @dest: an extent to be set the status
56 */
57static void
58copy_extent_status(struct ext4_extent *src, struct ext4_extent *dest)
59{
60 if (ext4_ext_is_unwritten(src))
61 ext4_ext_mark_unwritten(dest);
62 else
63 dest->ee_len = cpu_to_le16(ext4_ext_get_actual_len(dest));
64}
65
66/**
67 * mext_next_extent - Search for the next extent and set it to "extent"
68 *
69 * @inode: inode which is searched
70 * @path: this will obtain data for the next extent
71 * @extent: pointer to the next extent we have just gotten
72 *
73 * Search the next extent in the array of ext4_ext_path structure (@path)
74 * and set it to ext4_extent structure (@extent). In addition, the member of
75 * @path (->p_ext) also points the next extent. Return 0 on success, 1 if
76 * ext4_ext_path structure refers to the last extent, or a negative error
77 * value on failure.
78 */
79int
80mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
81 struct ext4_extent **extent)
82{
83 struct ext4_extent_header *eh;
84 int ppos, leaf_ppos = path->p_depth;
85
86 ppos = leaf_ppos;
87 if (EXT_LAST_EXTENT(path[ppos].p_hdr) > path[ppos].p_ext) {
88 /* leaf block */
89 *extent = ++path[ppos].p_ext;
90 path[ppos].p_block = ext4_ext_pblock(path[ppos].p_ext);
91 return 0;
92 }
93
94 while (--ppos >= 0) {
95 if (EXT_LAST_INDEX(path[ppos].p_hdr) >
96 path[ppos].p_idx) {
97 int cur_ppos = ppos;
98
99 /* index block */
100 path[ppos].p_idx++;
101 path[ppos].p_block = ext4_idx_pblock(path[ppos].p_idx);
102 if (path[ppos+1].p_bh)
103 brelse(path[ppos+1].p_bh);
104 path[ppos+1].p_bh =
105 sb_bread(inode->i_sb, path[ppos].p_block);
106 if (!path[ppos+1].p_bh)
107 return -EIO;
108 path[ppos+1].p_hdr =
109 ext_block_hdr(path[ppos+1].p_bh);
110
111 /* Halfway index block */
112 while (++cur_ppos < leaf_ppos) {
113 path[cur_ppos].p_idx =
114 EXT_FIRST_INDEX(path[cur_ppos].p_hdr);
115 path[cur_ppos].p_block =
116 ext4_idx_pblock(path[cur_ppos].p_idx);
117 if (path[cur_ppos+1].p_bh)
118 brelse(path[cur_ppos+1].p_bh);
119 path[cur_ppos+1].p_bh = sb_bread(inode->i_sb,
120 path[cur_ppos].p_block);
121 if (!path[cur_ppos+1].p_bh)
122 return -EIO;
123 path[cur_ppos+1].p_hdr =
124 ext_block_hdr(path[cur_ppos+1].p_bh);
125 }
126
127 path[leaf_ppos].p_ext = *extent = NULL;
128
129 eh = path[leaf_ppos].p_hdr;
130 if (le16_to_cpu(eh->eh_entries) == 0)
131 /* empty leaf is found */
132 return -ENODATA;
133
134 /* leaf block */
135 path[leaf_ppos].p_ext = *extent =
136 EXT_FIRST_EXTENT(path[leaf_ppos].p_hdr);
137 path[leaf_ppos].p_block =
138 ext4_ext_pblock(path[leaf_ppos].p_ext);
139 return 0;
140 }
141 } 47 }
142 /* We found the last extent */ 48 *ppath = path;
143 return 1; 49 return 0;
144} 50}
145 51
146/** 52/**
@@ -178,417 +84,6 @@ ext4_double_up_write_data_sem(struct inode *orig_inode,
178} 84}
179 85
180/** 86/**
181 * mext_insert_across_blocks - Insert extents across leaf block
182 *
183 * @handle: journal handle
184 * @orig_inode: original inode
185 * @o_start: first original extent to be changed
186 * @o_end: last original extent to be changed
187 * @start_ext: first new extent to be inserted
188 * @new_ext: middle of new extent to be inserted
189 * @end_ext: last new extent to be inserted
190 *
191 * Allocate a new leaf block and insert extents into it. Return 0 on success,
192 * or a negative error value on failure.
193 */
194static int
195mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
196 struct ext4_extent *o_start, struct ext4_extent *o_end,
197 struct ext4_extent *start_ext, struct ext4_extent *new_ext,
198 struct ext4_extent *end_ext)
199{
200 struct ext4_ext_path *orig_path = NULL;
201 ext4_lblk_t eblock = 0;
202 int new_flag = 0;
203 int end_flag = 0;
204 int err = 0;
205
206 if (start_ext->ee_len && new_ext->ee_len && end_ext->ee_len) {
207 if (o_start == o_end) {
208
209 /* start_ext new_ext end_ext
210 * donor |---------|-----------|--------|
211 * orig |------------------------------|
212 */
213 end_flag = 1;
214 } else {
215
216 /* start_ext new_ext end_ext
217 * donor |---------|----------|---------|
218 * orig |---------------|--------------|
219 */
220 o_end->ee_block = end_ext->ee_block;
221 o_end->ee_len = end_ext->ee_len;
222 ext4_ext_store_pblock(o_end, ext4_ext_pblock(end_ext));
223 }
224
225 o_start->ee_len = start_ext->ee_len;
226 eblock = le32_to_cpu(start_ext->ee_block);
227 new_flag = 1;
228
229 } else if (start_ext->ee_len && new_ext->ee_len &&
230 !end_ext->ee_len && o_start == o_end) {
231
232 /* start_ext new_ext
233 * donor |--------------|---------------|
234 * orig |------------------------------|
235 */
236 o_start->ee_len = start_ext->ee_len;
237 eblock = le32_to_cpu(start_ext->ee_block);
238 new_flag = 1;
239
240 } else if (!start_ext->ee_len && new_ext->ee_len &&
241 end_ext->ee_len && o_start == o_end) {
242
243 /* new_ext end_ext
244 * donor |--------------|---------------|
245 * orig |------------------------------|
246 */
247 o_end->ee_block = end_ext->ee_block;
248 o_end->ee_len = end_ext->ee_len;
249 ext4_ext_store_pblock(o_end, ext4_ext_pblock(end_ext));
250
251 /*
252 * Set 0 to the extent block if new_ext was
253 * the first block.
254 */
255 if (new_ext->ee_block)
256 eblock = le32_to_cpu(new_ext->ee_block);
257
258 new_flag = 1;
259 } else {
260 ext4_debug("ext4 move extent: Unexpected insert case\n");
261 return -EIO;
262 }
263
264 if (new_flag) {
265 err = get_ext_path(orig_inode, eblock, &orig_path);
266 if (err)
267 goto out;
268
269 if (ext4_ext_insert_extent(handle, orig_inode,
270 orig_path, new_ext, 0))
271 goto out;
272 }
273
274 if (end_flag) {
275 err = get_ext_path(orig_inode,
276 le32_to_cpu(end_ext->ee_block) - 1, &orig_path);
277 if (err)
278 goto out;
279
280 if (ext4_ext_insert_extent(handle, orig_inode,
281 orig_path, end_ext, 0))
282 goto out;
283 }
284out:
285 if (orig_path) {
286 ext4_ext_drop_refs(orig_path);
287 kfree(orig_path);
288 }
289
290 return err;
291
292}
293
294/**
295 * mext_insert_inside_block - Insert new extent to the extent block
296 *
297 * @o_start: first original extent to be moved
298 * @o_end: last original extent to be moved
299 * @start_ext: first new extent to be inserted
300 * @new_ext: middle of new extent to be inserted
301 * @end_ext: last new extent to be inserted
302 * @eh: extent header of target leaf block
303 * @range_to_move: used to decide how to insert extent
304 *
305 * Insert extents into the leaf block. The extent (@o_start) is overwritten
306 * by inserted extents.
307 */
308static void
309mext_insert_inside_block(struct ext4_extent *o_start,
310 struct ext4_extent *o_end,
311 struct ext4_extent *start_ext,
312 struct ext4_extent *new_ext,
313 struct ext4_extent *end_ext,
314 struct ext4_extent_header *eh,
315 int range_to_move)
316{
317 int i = 0;
318 unsigned long len;
319
320 /* Move the existing extents */
321 if (range_to_move && o_end < EXT_LAST_EXTENT(eh)) {
322 len = (unsigned long)(EXT_LAST_EXTENT(eh) + 1) -
323 (unsigned long)(o_end + 1);
324 memmove(o_end + 1 + range_to_move, o_end + 1, len);
325 }
326
327 /* Insert start entry */
328 if (start_ext->ee_len)
329 o_start[i++].ee_len = start_ext->ee_len;
330
331 /* Insert new entry */
332 if (new_ext->ee_len) {
333 o_start[i] = *new_ext;
334 ext4_ext_store_pblock(&o_start[i++], ext4_ext_pblock(new_ext));
335 }
336
337 /* Insert end entry */
338 if (end_ext->ee_len)
339 o_start[i] = *end_ext;
340
341 /* Increment the total entries counter on the extent block */
342 le16_add_cpu(&eh->eh_entries, range_to_move);
343}
344
345/**
346 * mext_insert_extents - Insert new extent
347 *
348 * @handle: journal handle
349 * @orig_inode: original inode
350 * @orig_path: path indicates first extent to be changed
351 * @o_start: first original extent to be changed
352 * @o_end: last original extent to be changed
353 * @start_ext: first new extent to be inserted
354 * @new_ext: middle of new extent to be inserted
355 * @end_ext: last new extent to be inserted
356 *
357 * Call the function to insert extents. If we cannot add more extents into
358 * the leaf block, we call mext_insert_across_blocks() to create a
359 * new leaf block. Otherwise call mext_insert_inside_block(). Return 0
360 * on success, or a negative error value on failure.
361 */
362static int
363mext_insert_extents(handle_t *handle, struct inode *orig_inode,
364 struct ext4_ext_path *orig_path,
365 struct ext4_extent *o_start,
366 struct ext4_extent *o_end,
367 struct ext4_extent *start_ext,
368 struct ext4_extent *new_ext,
369 struct ext4_extent *end_ext)
370{
371 struct ext4_extent_header *eh;
372 unsigned long need_slots, slots_range;
373 int range_to_move, depth, ret;
374
375 /*
376 * The extents need to be inserted
377 * start_extent + new_extent + end_extent.
378 */
379 need_slots = (start_ext->ee_len ? 1 : 0) + (end_ext->ee_len ? 1 : 0) +
380 (new_ext->ee_len ? 1 : 0);
381
382 /* The number of slots between start and end */
383 slots_range = ((unsigned long)(o_end + 1) - (unsigned long)o_start + 1)
384 / sizeof(struct ext4_extent);
385
386 /* Range to move the end of extent */
387 range_to_move = need_slots - slots_range;
388 depth = orig_path->p_depth;
389 orig_path += depth;
390 eh = orig_path->p_hdr;
391
392 if (depth) {
393 /* Register to journal */
394 BUFFER_TRACE(orig_path->p_bh, "get_write_access");
395 ret = ext4_journal_get_write_access(handle, orig_path->p_bh);
396 if (ret)
397 return ret;
398 }
399
400 /* Expansion */
401 if (range_to_move > 0 &&
402 (range_to_move > le16_to_cpu(eh->eh_max)
403 - le16_to_cpu(eh->eh_entries))) {
404
405 ret = mext_insert_across_blocks(handle, orig_inode, o_start,
406 o_end, start_ext, new_ext, end_ext);
407 if (ret < 0)
408 return ret;
409 } else
410 mext_insert_inside_block(o_start, o_end, start_ext, new_ext,
411 end_ext, eh, range_to_move);
412
413 return ext4_ext_dirty(handle, orig_inode, orig_path);
414}
415
416/**
417 * mext_leaf_block - Move one leaf extent block into the inode.
418 *
419 * @handle: journal handle
420 * @orig_inode: original inode
421 * @orig_path: path indicates first extent to be changed
422 * @dext: donor extent
423 * @from: start offset on the target file
424 *
425 * In order to insert extents into the leaf block, we must divide the extent
426 * in the leaf block into three extents. The one is located to be inserted
427 * extents, and the others are located around it.
428 *
429 * Therefore, this function creates structures to save extents of the leaf
430 * block, and inserts extents by calling mext_insert_extents() with
431 * created extents. Return 0 on success, or a negative error value on failure.
432 */
433static int
434mext_leaf_block(handle_t *handle, struct inode *orig_inode,
435 struct ext4_ext_path *orig_path, struct ext4_extent *dext,
436 ext4_lblk_t *from)
437{
438 struct ext4_extent *oext, *o_start, *o_end, *prev_ext;
439 struct ext4_extent new_ext, start_ext, end_ext;
440 ext4_lblk_t new_ext_end;
441 int oext_alen, new_ext_alen, end_ext_alen;
442 int depth = ext_depth(orig_inode);
443 int ret;
444
445 start_ext.ee_block = end_ext.ee_block = 0;
446 o_start = o_end = oext = orig_path[depth].p_ext;
447 oext_alen = ext4_ext_get_actual_len(oext);
448 start_ext.ee_len = end_ext.ee_len = 0;
449
450 new_ext.ee_block = cpu_to_le32(*from);
451 ext4_ext_store_pblock(&new_ext, ext4_ext_pblock(dext));
452 new_ext.ee_len = dext->ee_len;
453 new_ext_alen = ext4_ext_get_actual_len(&new_ext);
454 new_ext_end = le32_to_cpu(new_ext.ee_block) + new_ext_alen - 1;
455
456 /*
457 * Case: original extent is first
458 * oext |--------|
459 * new_ext |--|
460 * start_ext |--|
461 */
462 if (le32_to_cpu(oext->ee_block) < le32_to_cpu(new_ext.ee_block) &&
463 le32_to_cpu(new_ext.ee_block) <
464 le32_to_cpu(oext->ee_block) + oext_alen) {
465 start_ext.ee_len = cpu_to_le16(le32_to_cpu(new_ext.ee_block) -
466 le32_to_cpu(oext->ee_block));
467 start_ext.ee_block = oext->ee_block;
468 copy_extent_status(oext, &start_ext);
469 } else if (oext > EXT_FIRST_EXTENT(orig_path[depth].p_hdr)) {
470 prev_ext = oext - 1;
471 /*
472 * We can merge new_ext into previous extent,
473 * if these are contiguous and same extent type.
474 */
475 if (ext4_can_extents_be_merged(orig_inode, prev_ext,
476 &new_ext)) {
477 o_start = prev_ext;
478 start_ext.ee_len = cpu_to_le16(
479 ext4_ext_get_actual_len(prev_ext) +
480 new_ext_alen);
481 start_ext.ee_block = oext->ee_block;
482 copy_extent_status(prev_ext, &start_ext);
483 new_ext.ee_len = 0;
484 }
485 }
486
487 /*
488 * Case: new_ext_end must be less than oext
489 * oext |-----------|
490 * new_ext |-------|
491 */
492 if (le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end) {
493 EXT4_ERROR_INODE(orig_inode,
494 "new_ext_end(%u) should be less than or equal to "
495 "oext->ee_block(%u) + oext_alen(%d) - 1",
496 new_ext_end, le32_to_cpu(oext->ee_block),
497 oext_alen);
498 ret = -EIO;
499 goto out;
500 }
501
502 /*
503 * Case: new_ext is smaller than original extent
504 * oext |---------------|
505 * new_ext |-----------|
506 * end_ext |---|
507 */
508 if (le32_to_cpu(oext->ee_block) <= new_ext_end &&
509 new_ext_end < le32_to_cpu(oext->ee_block) + oext_alen - 1) {
510 end_ext.ee_len =
511 cpu_to_le16(le32_to_cpu(oext->ee_block) +
512 oext_alen - 1 - new_ext_end);
513 copy_extent_status(oext, &end_ext);
514 end_ext_alen = ext4_ext_get_actual_len(&end_ext);
515 ext4_ext_store_pblock(&end_ext,
516 (ext4_ext_pblock(o_end) + oext_alen - end_ext_alen));
517 end_ext.ee_block =
518 cpu_to_le32(le32_to_cpu(o_end->ee_block) +
519 oext_alen - end_ext_alen);
520 }
521
522 ret = mext_insert_extents(handle, orig_inode, orig_path, o_start,
523 o_end, &start_ext, &new_ext, &end_ext);
524out:
525 return ret;
526}
527
528/**
529 * mext_calc_swap_extents - Calculate extents for extent swapping.
530 *
531 * @tmp_dext: the extent that will belong to the original inode
532 * @tmp_oext: the extent that will belong to the donor inode
533 * @orig_off: block offset of original inode
534 * @donor_off: block offset of donor inode
535 * @max_count: the maximum length of extents
536 *
537 * Return 0 on success, or a negative error value on failure.
538 */
539static int
540mext_calc_swap_extents(struct ext4_extent *tmp_dext,
541 struct ext4_extent *tmp_oext,
542 ext4_lblk_t orig_off, ext4_lblk_t donor_off,
543 ext4_lblk_t max_count)
544{
545 ext4_lblk_t diff, orig_diff;
546 struct ext4_extent dext_old, oext_old;
547
548 BUG_ON(orig_off != donor_off);
549
550 /* original and donor extents have to cover the same block offset */
551 if (orig_off < le32_to_cpu(tmp_oext->ee_block) ||
552 le32_to_cpu(tmp_oext->ee_block) +
553 ext4_ext_get_actual_len(tmp_oext) - 1 < orig_off)
554 return -ENODATA;
555
556 if (orig_off < le32_to_cpu(tmp_dext->ee_block) ||
557 le32_to_cpu(tmp_dext->ee_block) +
558 ext4_ext_get_actual_len(tmp_dext) - 1 < orig_off)
559 return -ENODATA;
560
561 dext_old = *tmp_dext;
562 oext_old = *tmp_oext;
563
564 /* When tmp_dext is too large, pick up the target range. */
565 diff = donor_off - le32_to_cpu(tmp_dext->ee_block);
566
567 ext4_ext_store_pblock(tmp_dext, ext4_ext_pblock(tmp_dext) + diff);
568 le32_add_cpu(&tmp_dext->ee_block, diff);
569 le16_add_cpu(&tmp_dext->ee_len, -diff);
570
571 if (max_count < ext4_ext_get_actual_len(tmp_dext))
572 tmp_dext->ee_len = cpu_to_le16(max_count);
573
574 orig_diff = orig_off - le32_to_cpu(tmp_oext->ee_block);
575 ext4_ext_store_pblock(tmp_oext, ext4_ext_pblock(tmp_oext) + orig_diff);
576
577 /* Adjust extent length if donor extent is larger than orig */
578 if (ext4_ext_get_actual_len(tmp_dext) >
579 ext4_ext_get_actual_len(tmp_oext) - orig_diff)
580 tmp_dext->ee_len = cpu_to_le16(le16_to_cpu(tmp_oext->ee_len) -
581 orig_diff);
582
583 tmp_oext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(tmp_dext));
584
585 copy_extent_status(&oext_old, tmp_dext);
586 copy_extent_status(&dext_old, tmp_oext);
587
588 return 0;
589}
590
591/**
592 * mext_check_coverage - Check that all extents in range has the same type 87 * mext_check_coverage - Check that all extents in range has the same type
593 * 88 *
594 * @inode: inode in question 89 * @inode: inode in question
@@ -619,171 +114,25 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
619 } 114 }
620 ret = 1; 115 ret = 1;
621out: 116out:
622 if (path) { 117 ext4_ext_drop_refs(path);
623 ext4_ext_drop_refs(path); 118 kfree(path);
624 kfree(path);
625 }
626 return ret; 119 return ret;
627} 120}
628 121
629/** 122/**
630 * mext_replace_branches - Replace original extents with new extents
631 *
632 * @handle: journal handle
633 * @orig_inode: original inode
634 * @donor_inode: donor inode
635 * @from: block offset of orig_inode
636 * @count: block count to be replaced
637 * @err: pointer to save return value
638 *
639 * Replace original inode extents and donor inode extents page by page.
640 * We implement this replacement in the following three steps:
641 * 1. Save the block information of original and donor inodes into
642 * dummy extents.
643 * 2. Change the block information of original inode to point at the
644 * donor inode blocks.
645 * 3. Change the block information of donor inode to point at the saved
646 * original inode blocks in the dummy extents.
647 *
648 * Return replaced block count.
649 */
650static int
651mext_replace_branches(handle_t *handle, struct inode *orig_inode,
652 struct inode *donor_inode, ext4_lblk_t from,
653 ext4_lblk_t count, int *err)
654{
655 struct ext4_ext_path *orig_path = NULL;
656 struct ext4_ext_path *donor_path = NULL;
657 struct ext4_extent *oext, *dext;
658 struct ext4_extent tmp_dext, tmp_oext;
659 ext4_lblk_t orig_off = from, donor_off = from;
660 int depth;
661 int replaced_count = 0;
662 int dext_alen;
663
664 *err = ext4_es_remove_extent(orig_inode, from, count);
665 if (*err)
666 goto out;
667
668 *err = ext4_es_remove_extent(donor_inode, from, count);
669 if (*err)
670 goto out;
671
672 /* Get the original extent for the block "orig_off" */
673 *err = get_ext_path(orig_inode, orig_off, &orig_path);
674 if (*err)
675 goto out;
676
677 /* Get the donor extent for the head */
678 *err = get_ext_path(donor_inode, donor_off, &donor_path);
679 if (*err)
680 goto out;
681 depth = ext_depth(orig_inode);
682 oext = orig_path[depth].p_ext;
683 tmp_oext = *oext;
684
685 depth = ext_depth(donor_inode);
686 dext = donor_path[depth].p_ext;
687 if (unlikely(!dext))
688 goto missing_donor_extent;
689 tmp_dext = *dext;
690
691 *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
692 donor_off, count);
693 if (*err)
694 goto out;
695
696 /* Loop for the donor extents */
697 while (1) {
698 /* The extent for donor must be found. */
699 if (unlikely(!dext)) {
700 missing_donor_extent:
701 EXT4_ERROR_INODE(donor_inode,
702 "The extent for donor must be found");
703 *err = -EIO;
704 goto out;
705 } else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
706 EXT4_ERROR_INODE(donor_inode,
707 "Donor offset(%u) and the first block of donor "
708 "extent(%u) should be equal",
709 donor_off,
710 le32_to_cpu(tmp_dext.ee_block));
711 *err = -EIO;
712 goto out;
713 }
714
715 /* Set donor extent to orig extent */
716 *err = mext_leaf_block(handle, orig_inode,
717 orig_path, &tmp_dext, &orig_off);
718 if (*err)
719 goto out;
720
721 /* Set orig extent to donor extent */
722 *err = mext_leaf_block(handle, donor_inode,
723 donor_path, &tmp_oext, &donor_off);
724 if (*err)
725 goto out;
726
727 dext_alen = ext4_ext_get_actual_len(&tmp_dext);
728 replaced_count += dext_alen;
729 donor_off += dext_alen;
730 orig_off += dext_alen;
731
732 BUG_ON(replaced_count > count);
733 /* Already moved the expected blocks */
734 if (replaced_count >= count)
735 break;
736
737 if (orig_path)
738 ext4_ext_drop_refs(orig_path);
739 *err = get_ext_path(orig_inode, orig_off, &orig_path);
740 if (*err)
741 goto out;
742 depth = ext_depth(orig_inode);
743 oext = orig_path[depth].p_ext;
744 tmp_oext = *oext;
745
746 if (donor_path)
747 ext4_ext_drop_refs(donor_path);
748 *err = get_ext_path(donor_inode, donor_off, &donor_path);
749 if (*err)
750 goto out;
751 depth = ext_depth(donor_inode);
752 dext = donor_path[depth].p_ext;
753 tmp_dext = *dext;
754
755 *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
756 donor_off, count - replaced_count);
757 if (*err)
758 goto out;
759 }
760
761out:
762 if (orig_path) {
763 ext4_ext_drop_refs(orig_path);
764 kfree(orig_path);
765 }
766 if (donor_path) {
767 ext4_ext_drop_refs(donor_path);
768 kfree(donor_path);
769 }
770
771 return replaced_count;
772}
773
774/**
775 * mext_page_double_lock - Grab and lock pages on both @inode1 and @inode2 123 * mext_page_double_lock - Grab and lock pages on both @inode1 and @inode2
776 * 124 *
777 * @inode1: the inode structure 125 * @inode1: the inode structure
778 * @inode2: the inode structure 126 * @inode2: the inode structure
779 * @index: page index 127 * @index1: page index
128 * @index2: page index
780 * @page: result page vector 129 * @page: result page vector
781 * 130 *
782 * Grab two locked pages for inode's by inode order 131 * Grab two locked pages for inode's by inode order
783 */ 132 */
784static int 133static int
785mext_page_double_lock(struct inode *inode1, struct inode *inode2, 134mext_page_double_lock(struct inode *inode1, struct inode *inode2,
786 pgoff_t index, struct page *page[2]) 135 pgoff_t index1, pgoff_t index2, struct page *page[2])
787{ 136{
788 struct address_space *mapping[2]; 137 struct address_space *mapping[2];
789 unsigned fl = AOP_FLAG_NOFS; 138 unsigned fl = AOP_FLAG_NOFS;
@@ -793,15 +142,18 @@ mext_page_double_lock(struct inode *inode1, struct inode *inode2,
793 mapping[0] = inode1->i_mapping; 142 mapping[0] = inode1->i_mapping;
794 mapping[1] = inode2->i_mapping; 143 mapping[1] = inode2->i_mapping;
795 } else { 144 } else {
145 pgoff_t tmp = index1;
146 index1 = index2;
147 index2 = tmp;
796 mapping[0] = inode2->i_mapping; 148 mapping[0] = inode2->i_mapping;
797 mapping[1] = inode1->i_mapping; 149 mapping[1] = inode1->i_mapping;
798 } 150 }
799 151
800 page[0] = grab_cache_page_write_begin(mapping[0], index, fl); 152 page[0] = grab_cache_page_write_begin(mapping[0], index1, fl);
801 if (!page[0]) 153 if (!page[0])
802 return -ENOMEM; 154 return -ENOMEM;
803 155
804 page[1] = grab_cache_page_write_begin(mapping[1], index, fl); 156 page[1] = grab_cache_page_write_begin(mapping[1], index2, fl);
805 if (!page[1]) { 157 if (!page[1]) {
806 unlock_page(page[0]); 158 unlock_page(page[0]);
807 page_cache_release(page[0]); 159 page_cache_release(page[0]);
@@ -893,25 +245,27 @@ out:
893 * @o_filp: file structure of original file 245 * @o_filp: file structure of original file
894 * @donor_inode: donor inode 246 * @donor_inode: donor inode
895 * @orig_page_offset: page index on original file 247 * @orig_page_offset: page index on original file
248 * @donor_page_offset: page index on donor file
896 * @data_offset_in_page: block index where data swapping starts 249 * @data_offset_in_page: block index where data swapping starts
897 * @block_len_in_page: the number of blocks to be swapped 250 * @block_len_in_page: the number of blocks to be swapped
898 * @unwritten: orig extent is unwritten or not 251 * @unwritten: orig extent is unwritten or not
899 * @err: pointer to save return value 252 * @err: pointer to save return value
900 * 253 *
901 * Save the data in original inode blocks and replace original inode extents 254 * Save the data in original inode blocks and replace original inode extents
902 * with donor inode extents by calling mext_replace_branches(). 255 * with donor inode extents by calling ext4_swap_extents().
903 * Finally, write out the saved data in new original inode blocks. Return 256 * Finally, write out the saved data in new original inode blocks. Return
904 * replaced block count. 257 * replaced block count.
905 */ 258 */
906static int 259static int
907move_extent_per_page(struct file *o_filp, struct inode *donor_inode, 260move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
908 pgoff_t orig_page_offset, int data_offset_in_page, 261 pgoff_t orig_page_offset, pgoff_t donor_page_offset,
909 int block_len_in_page, int unwritten, int *err) 262 int data_offset_in_page,
263 int block_len_in_page, int unwritten, int *err)
910{ 264{
911 struct inode *orig_inode = file_inode(o_filp); 265 struct inode *orig_inode = file_inode(o_filp);
912 struct page *pagep[2] = {NULL, NULL}; 266 struct page *pagep[2] = {NULL, NULL};
913 handle_t *handle; 267 handle_t *handle;
914 ext4_lblk_t orig_blk_offset; 268 ext4_lblk_t orig_blk_offset, donor_blk_offset;
915 unsigned long blocksize = orig_inode->i_sb->s_blocksize; 269 unsigned long blocksize = orig_inode->i_sb->s_blocksize;
916 unsigned int w_flags = 0; 270 unsigned int w_flags = 0;
917 unsigned int tmp_data_size, data_size, replaced_size; 271 unsigned int tmp_data_size, data_size, replaced_size;
@@ -939,6 +293,9 @@ again:
939 orig_blk_offset = orig_page_offset * blocks_per_page + 293 orig_blk_offset = orig_page_offset * blocks_per_page +
940 data_offset_in_page; 294 data_offset_in_page;
941 295
296 donor_blk_offset = donor_page_offset * blocks_per_page +
297 data_offset_in_page;
298
942 /* Calculate data_size */ 299 /* Calculate data_size */
943 if ((orig_blk_offset + block_len_in_page - 1) == 300 if ((orig_blk_offset + block_len_in_page - 1) ==
944 ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) { 301 ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) {
@@ -959,7 +316,7 @@ again:
959 replaced_size = data_size; 316 replaced_size = data_size;
960 317
961 *err = mext_page_double_lock(orig_inode, donor_inode, orig_page_offset, 318 *err = mext_page_double_lock(orig_inode, donor_inode, orig_page_offset,
962 pagep); 319 donor_page_offset, pagep);
963 if (unlikely(*err < 0)) 320 if (unlikely(*err < 0))
964 goto stop_journal; 321 goto stop_journal;
965 /* 322 /*
@@ -978,7 +335,7 @@ again:
978 if (*err) 335 if (*err)
979 goto drop_data_sem; 336 goto drop_data_sem;
980 337
981 unwritten &= mext_check_coverage(donor_inode, orig_blk_offset, 338 unwritten &= mext_check_coverage(donor_inode, donor_blk_offset,
982 block_len_in_page, 1, err); 339 block_len_in_page, 1, err);
983 if (*err) 340 if (*err)
984 goto drop_data_sem; 341 goto drop_data_sem;
@@ -994,9 +351,10 @@ again:
994 *err = -EBUSY; 351 *err = -EBUSY;
995 goto drop_data_sem; 352 goto drop_data_sem;
996 } 353 }
997 replaced_count = mext_replace_branches(handle, orig_inode, 354 replaced_count = ext4_swap_extents(handle, orig_inode,
998 donor_inode, orig_blk_offset, 355 donor_inode, orig_blk_offset,
999 block_len_in_page, err); 356 donor_blk_offset,
357 block_len_in_page, 1, err);
1000 drop_data_sem: 358 drop_data_sem:
1001 ext4_double_up_write_data_sem(orig_inode, donor_inode); 359 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1002 goto unlock_pages; 360 goto unlock_pages;
@@ -1014,9 +372,9 @@ data_copy:
1014 goto unlock_pages; 372 goto unlock_pages;
1015 } 373 }
1016 ext4_double_down_write_data_sem(orig_inode, donor_inode); 374 ext4_double_down_write_data_sem(orig_inode, donor_inode);
1017 replaced_count = mext_replace_branches(handle, orig_inode, donor_inode, 375 replaced_count = ext4_swap_extents(handle, orig_inode, donor_inode,
1018 orig_blk_offset, 376 orig_blk_offset, donor_blk_offset,
1019 block_len_in_page, err); 377 block_len_in_page, 1, err);
1020 ext4_double_up_write_data_sem(orig_inode, donor_inode); 378 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1021 if (*err) { 379 if (*err) {
1022 if (replaced_count) { 380 if (replaced_count) {
@@ -1061,9 +419,9 @@ repair_branches:
1061 * Try to swap extents to it's original places 419 * Try to swap extents to it's original places
1062 */ 420 */
1063 ext4_double_down_write_data_sem(orig_inode, donor_inode); 421 ext4_double_down_write_data_sem(orig_inode, donor_inode);
1064 replaced_count = mext_replace_branches(handle, donor_inode, orig_inode, 422 replaced_count = ext4_swap_extents(handle, donor_inode, orig_inode,
1065 orig_blk_offset, 423 orig_blk_offset, donor_blk_offset,
1066 block_len_in_page, &err2); 424 block_len_in_page, 0, &err2);
1067 ext4_double_up_write_data_sem(orig_inode, donor_inode); 425 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1068 if (replaced_count != block_len_in_page) { 426 if (replaced_count != block_len_in_page) {
1069 EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset), 427 EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset),
@@ -1093,10 +451,14 @@ mext_check_arguments(struct inode *orig_inode,
1093 struct inode *donor_inode, __u64 orig_start, 451 struct inode *donor_inode, __u64 orig_start,
1094 __u64 donor_start, __u64 *len) 452 __u64 donor_start, __u64 *len)
1095{ 453{
1096 ext4_lblk_t orig_blocks, donor_blocks; 454 __u64 orig_eof, donor_eof;
1097 unsigned int blkbits = orig_inode->i_blkbits; 455 unsigned int blkbits = orig_inode->i_blkbits;
1098 unsigned int blocksize = 1 << blkbits; 456 unsigned int blocksize = 1 << blkbits;
1099 457
458 orig_eof = (i_size_read(orig_inode) + blocksize - 1) >> blkbits;
459 donor_eof = (i_size_read(donor_inode) + blocksize - 1) >> blkbits;
460
461
1100 if (donor_inode->i_mode & (S_ISUID|S_ISGID)) { 462 if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
1101 ext4_debug("ext4 move extent: suid or sgid is set" 463 ext4_debug("ext4 move extent: suid or sgid is set"
1102 " to donor file [ino:orig %lu, donor %lu]\n", 464 " to donor file [ino:orig %lu, donor %lu]\n",
@@ -1112,7 +474,7 @@ mext_check_arguments(struct inode *orig_inode,
1112 ext4_debug("ext4 move extent: The argument files should " 474 ext4_debug("ext4 move extent: The argument files should "
1113 "not be swapfile [ino:orig %lu, donor %lu]\n", 475 "not be swapfile [ino:orig %lu, donor %lu]\n",
1114 orig_inode->i_ino, donor_inode->i_ino); 476 orig_inode->i_ino, donor_inode->i_ino);
1115 return -EINVAL; 477 return -EBUSY;
1116 } 478 }
1117 479
1118 /* Ext4 move extent supports only extent based file */ 480 /* Ext4 move extent supports only extent based file */
@@ -1132,67 +494,28 @@ mext_check_arguments(struct inode *orig_inode,
1132 } 494 }
1133 495
1134 /* Start offset should be same */ 496 /* Start offset should be same */
1135 if (orig_start != donor_start) { 497 if ((orig_start & ~(PAGE_MASK >> orig_inode->i_blkbits)) !=
498 (donor_start & ~(PAGE_MASK >> orig_inode->i_blkbits))) {
1136 ext4_debug("ext4 move extent: orig and donor's start " 499 ext4_debug("ext4 move extent: orig and donor's start "
1137 "offset are not same [ino:orig %lu, donor %lu]\n", 500 "offset are not alligned [ino:orig %lu, donor %lu]\n",
1138 orig_inode->i_ino, donor_inode->i_ino); 501 orig_inode->i_ino, donor_inode->i_ino);
1139 return -EINVAL; 502 return -EINVAL;
1140 } 503 }
1141 504
1142 if ((orig_start >= EXT_MAX_BLOCKS) || 505 if ((orig_start >= EXT_MAX_BLOCKS) ||
506 (donor_start >= EXT_MAX_BLOCKS) ||
1143 (*len > EXT_MAX_BLOCKS) || 507 (*len > EXT_MAX_BLOCKS) ||
508 (donor_start + *len >= EXT_MAX_BLOCKS) ||
1144 (orig_start + *len >= EXT_MAX_BLOCKS)) { 509 (orig_start + *len >= EXT_MAX_BLOCKS)) {
1145 ext4_debug("ext4 move extent: Can't handle over [%u] blocks " 510 ext4_debug("ext4 move extent: Can't handle over [%u] blocks "
1146 "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCKS, 511 "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCKS,
1147 orig_inode->i_ino, donor_inode->i_ino); 512 orig_inode->i_ino, donor_inode->i_ino);
1148 return -EINVAL; 513 return -EINVAL;
1149 } 514 }
1150 515 if (orig_eof < orig_start + *len - 1)
1151 if (orig_inode->i_size > donor_inode->i_size) { 516 *len = orig_eof - orig_start;
1152 donor_blocks = (donor_inode->i_size + blocksize - 1) >> blkbits; 517 if (donor_eof < donor_start + *len - 1)
1153 /* TODO: eliminate this artificial restriction */ 518 *len = donor_eof - donor_start;
1154 if (orig_start >= donor_blocks) {
1155 ext4_debug("ext4 move extent: orig start offset "
1156 "[%llu] should be less than donor file blocks "
1157 "[%u] [ino:orig %lu, donor %lu]\n",
1158 orig_start, donor_blocks,
1159 orig_inode->i_ino, donor_inode->i_ino);
1160 return -EINVAL;
1161 }
1162
1163 /* TODO: eliminate this artificial restriction */
1164 if (orig_start + *len > donor_blocks) {
1165 ext4_debug("ext4 move extent: End offset [%llu] should "
1166 "be less than donor file blocks [%u]."
1167 "So adjust length from %llu to %llu "
1168 "[ino:orig %lu, donor %lu]\n",
1169 orig_start + *len, donor_blocks,
1170 *len, donor_blocks - orig_start,
1171 orig_inode->i_ino, donor_inode->i_ino);
1172 *len = donor_blocks - orig_start;
1173 }
1174 } else {
1175 orig_blocks = (orig_inode->i_size + blocksize - 1) >> blkbits;
1176 if (orig_start >= orig_blocks) {
1177 ext4_debug("ext4 move extent: start offset [%llu] "
1178 "should be less than original file blocks "
1179 "[%u] [ino:orig %lu, donor %lu]\n",
1180 orig_start, orig_blocks,
1181 orig_inode->i_ino, donor_inode->i_ino);
1182 return -EINVAL;
1183 }
1184
1185 if (orig_start + *len > orig_blocks) {
1186 ext4_debug("ext4 move extent: Adjust length "
1187 "from %llu to %llu. Because it should be "
1188 "less than original file blocks "
1189 "[ino:orig %lu, donor %lu]\n",
1190 *len, orig_blocks - orig_start,
1191 orig_inode->i_ino, donor_inode->i_ino);
1192 *len = orig_blocks - orig_start;
1193 }
1194 }
1195
1196 if (!*len) { 519 if (!*len) {
1197 ext4_debug("ext4 move extent: len should not be 0 " 520 ext4_debug("ext4 move extent: len should not be 0 "
1198 "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino, 521 "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
@@ -1208,60 +531,26 @@ mext_check_arguments(struct inode *orig_inode,
1208 * 531 *
1209 * @o_filp: file structure of the original file 532 * @o_filp: file structure of the original file
1210 * @d_filp: file structure of the donor file 533 * @d_filp: file structure of the donor file
1211 * @orig_start: start offset in block for orig 534 * @orig_blk: start offset in block for orig
1212 * @donor_start: start offset in block for donor 535 * @donor_blk: start offset in block for donor
1213 * @len: the number of blocks to be moved 536 * @len: the number of blocks to be moved
1214 * @moved_len: moved block length 537 * @moved_len: moved block length
1215 * 538 *
1216 * This function returns 0 and moved block length is set in moved_len 539 * This function returns 0 and moved block length is set in moved_len
1217 * if succeed, otherwise returns error value. 540 * if succeed, otherwise returns error value.
1218 * 541 *
1219 * Note: ext4_move_extents() proceeds the following order.
1220 * 1:ext4_move_extents() calculates the last block number of moving extent
1221 * function by the start block number (orig_start) and the number of blocks
1222 * to be moved (len) specified as arguments.
1223 * If the {orig, donor}_start points a hole, the extent's start offset
1224 * pointed by ext_cur (current extent), holecheck_path, orig_path are set
1225 * after hole behind.
1226 * 2:Continue step 3 to step 5, until the holecheck_path points to last_extent
1227 * or the ext_cur exceeds the block_end which is last logical block number.
1228 * 3:To get the length of continues area, call mext_next_extent()
1229 * specified with the ext_cur (initial value is holecheck_path) re-cursive,
1230 * until find un-continuous extent, the start logical block number exceeds
1231 * the block_end or the extent points to the last extent.
1232 * 4:Exchange the original inode data with donor inode data
1233 * from orig_page_offset to seq_end_page.
1234 * The start indexes of data are specified as arguments.
1235 * That of the original inode is orig_page_offset,
1236 * and the donor inode is also orig_page_offset
1237 * (To easily handle blocksize != pagesize case, the offset for the
1238 * donor inode is block unit).
1239 * 5:Update holecheck_path and orig_path to points a next proceeding extent,
1240 * then returns to step 2.
1241 * 6:Release holecheck_path, orig_path and set the len to moved_len
1242 * which shows the number of moved blocks.
1243 * The moved_len is useful for the command to calculate the file offset
1244 * for starting next move extent ioctl.
1245 * 7:Return 0 on success, or a negative error value on failure.
1246 */ 542 */
1247int 543int
1248ext4_move_extents(struct file *o_filp, struct file *d_filp, 544ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
1249 __u64 orig_start, __u64 donor_start, __u64 len, 545 __u64 donor_blk, __u64 len, __u64 *moved_len)
1250 __u64 *moved_len)
1251{ 546{
1252 struct inode *orig_inode = file_inode(o_filp); 547 struct inode *orig_inode = file_inode(o_filp);
1253 struct inode *donor_inode = file_inode(d_filp); 548 struct inode *donor_inode = file_inode(d_filp);
1254 struct ext4_ext_path *orig_path = NULL, *holecheck_path = NULL; 549 struct ext4_ext_path *path = NULL;
1255 struct ext4_extent *ext_prev, *ext_cur, *ext_dummy;
1256 ext4_lblk_t block_start = orig_start;
1257 ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
1258 ext4_lblk_t rest_blocks;
1259 pgoff_t orig_page_offset = 0, seq_end_page;
1260 int ret, depth, last_extent = 0;
1261 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits; 550 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
1262 int data_offset_in_page; 551 ext4_lblk_t o_end, o_start = orig_blk;
1263 int block_len_in_page; 552 ext4_lblk_t d_start = donor_blk;
1264 int unwritten; 553 int ret;
1265 554
1266 if (orig_inode->i_sb != donor_inode->i_sb) { 555 if (orig_inode->i_sb != donor_inode->i_sb) {
1267 ext4_debug("ext4 move extent: The argument files " 556 ext4_debug("ext4 move extent: The argument files "
@@ -1303,121 +592,58 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1303 /* Protect extent tree against block allocations via delalloc */ 592 /* Protect extent tree against block allocations via delalloc */
1304 ext4_double_down_write_data_sem(orig_inode, donor_inode); 593 ext4_double_down_write_data_sem(orig_inode, donor_inode);
1305 /* Check the filesystem environment whether move_extent can be done */ 594 /* Check the filesystem environment whether move_extent can be done */
1306 ret = mext_check_arguments(orig_inode, donor_inode, orig_start, 595 ret = mext_check_arguments(orig_inode, donor_inode, orig_blk,
1307 donor_start, &len); 596 donor_blk, &len);
1308 if (ret) 597 if (ret)
1309 goto out; 598 goto out;
599 o_end = o_start + len;
1310 600
1311 file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits; 601 while (o_start < o_end) {
1312 block_end = block_start + len - 1; 602 struct ext4_extent *ex;
1313 if (file_end < block_end) 603 ext4_lblk_t cur_blk, next_blk;
1314 len -= block_end - file_end; 604 pgoff_t orig_page_index, donor_page_index;
605 int offset_in_page;
606 int unwritten, cur_len;
1315 607
1316 ret = get_ext_path(orig_inode, block_start, &orig_path); 608 ret = get_ext_path(orig_inode, o_start, &path);
1317 if (ret) 609 if (ret)
1318 goto out;
1319
1320 /* Get path structure to check the hole */
1321 ret = get_ext_path(orig_inode, block_start, &holecheck_path);
1322 if (ret)
1323 goto out;
1324
1325 depth = ext_depth(orig_inode);
1326 ext_cur = holecheck_path[depth].p_ext;
1327
1328 /*
1329 * Get proper starting location of block replacement if block_start was
1330 * within the hole.
1331 */
1332 if (le32_to_cpu(ext_cur->ee_block) +
1333 ext4_ext_get_actual_len(ext_cur) - 1 < block_start) {
1334 /*
1335 * The hole exists between extents or the tail of
1336 * original file.
1337 */
1338 last_extent = mext_next_extent(orig_inode,
1339 holecheck_path, &ext_cur);
1340 if (last_extent < 0) {
1341 ret = last_extent;
1342 goto out;
1343 }
1344 last_extent = mext_next_extent(orig_inode, orig_path,
1345 &ext_dummy);
1346 if (last_extent < 0) {
1347 ret = last_extent;
1348 goto out; 610 goto out;
1349 } 611 ex = path[path->p_depth].p_ext;
1350 seq_start = le32_to_cpu(ext_cur->ee_block); 612 next_blk = ext4_ext_next_allocated_block(path);
1351 } else if (le32_to_cpu(ext_cur->ee_block) > block_start) 613 cur_blk = le32_to_cpu(ex->ee_block);
1352 /* The hole exists at the beginning of original file. */ 614 cur_len = ext4_ext_get_actual_len(ex);
1353 seq_start = le32_to_cpu(ext_cur->ee_block); 615 /* Check hole before the start pos */
1354 else 616 if (cur_blk + cur_len - 1 < o_start) {
1355 seq_start = block_start; 617 if (next_blk == EXT_MAX_BLOCKS) {
1356 618 o_start = o_end;
1357 /* No blocks within the specified range. */ 619 ret = -ENODATA;
1358 if (le32_to_cpu(ext_cur->ee_block) > block_end) { 620 goto out;
1359 ext4_debug("ext4 move extent: The specified range of file " 621 }
1360 "may be the hole\n"); 622 d_start += next_blk - o_start;
1361 ret = -EINVAL; 623 o_start = next_blk;
1362 goto out;
1363 }
1364
1365 /* Adjust start blocks */
1366 add_blocks = min(le32_to_cpu(ext_cur->ee_block) +
1367 ext4_ext_get_actual_len(ext_cur), block_end + 1) -
1368 max(le32_to_cpu(ext_cur->ee_block), block_start);
1369
1370 while (!last_extent && le32_to_cpu(ext_cur->ee_block) <= block_end) {
1371 seq_blocks += add_blocks;
1372
1373 /* Adjust tail blocks */
1374 if (seq_start + seq_blocks - 1 > block_end)
1375 seq_blocks = block_end - seq_start + 1;
1376
1377 ext_prev = ext_cur;
1378 last_extent = mext_next_extent(orig_inode, holecheck_path,
1379 &ext_cur);
1380 if (last_extent < 0) {
1381 ret = last_extent;
1382 break;
1383 }
1384 add_blocks = ext4_ext_get_actual_len(ext_cur);
1385
1386 /*
1387 * Extend the length of contiguous block (seq_blocks)
1388 * if extents are contiguous.
1389 */
1390 if (ext4_can_extents_be_merged(orig_inode,
1391 ext_prev, ext_cur) &&
1392 block_end >= le32_to_cpu(ext_cur->ee_block) &&
1393 !last_extent)
1394 continue; 624 continue;
1395 625 /* Check hole after the start pos */
1396 /* Is original extent is unwritten */ 626 } else if (cur_blk > o_start) {
1397 unwritten = ext4_ext_is_unwritten(ext_prev); 627 /* Skip hole */
1398 628 d_start += cur_blk - o_start;
1399 data_offset_in_page = seq_start % blocks_per_page; 629 o_start = cur_blk;
1400 630 /* Extent inside requested range ?*/
1401 /* 631 if (cur_blk >= o_end)
1402 * Calculate data blocks count that should be swapped 632 goto out;
1403 * at the first page. 633 } else { /* in_range(o_start, o_blk, o_len) */
1404 */ 634 cur_len += cur_blk - o_start;
1405 if (data_offset_in_page + seq_blocks > blocks_per_page) {
1406 /* Swapped blocks are across pages */
1407 block_len_in_page =
1408 blocks_per_page - data_offset_in_page;
1409 } else {
1410 /* Swapped blocks are in a page */
1411 block_len_in_page = seq_blocks;
1412 } 635 }
1413 636 unwritten = ext4_ext_is_unwritten(ex);
1414 orig_page_offset = seq_start >> 637 if (o_end - o_start < cur_len)
1415 (PAGE_CACHE_SHIFT - orig_inode->i_blkbits); 638 cur_len = o_end - o_start;
1416 seq_end_page = (seq_start + seq_blocks - 1) >> 639
1417 (PAGE_CACHE_SHIFT - orig_inode->i_blkbits); 640 orig_page_index = o_start >> (PAGE_CACHE_SHIFT -
1418 seq_start = le32_to_cpu(ext_cur->ee_block); 641 orig_inode->i_blkbits);
1419 rest_blocks = seq_blocks; 642 donor_page_index = d_start >> (PAGE_CACHE_SHIFT -
1420 643 donor_inode->i_blkbits);
644 offset_in_page = o_start % blocks_per_page;
645 if (cur_len > blocks_per_page- offset_in_page)
646 cur_len = blocks_per_page - offset_in_page;
1421 /* 647 /*
1422 * Up semaphore to avoid following problems: 648 * Up semaphore to avoid following problems:
1423 * a. transaction deadlock among ext4_journal_start, 649 * a. transaction deadlock among ext4_journal_start,
@@ -1426,77 +652,29 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1426 * in move_extent_per_page 652 * in move_extent_per_page
1427 */ 653 */
1428 ext4_double_up_write_data_sem(orig_inode, donor_inode); 654 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1429 655 /* Swap original branches with new branches */
1430 while (orig_page_offset <= seq_end_page) { 656 move_extent_per_page(o_filp, donor_inode,
1431 657 orig_page_index, donor_page_index,
1432 /* Swap original branches with new branches */ 658 offset_in_page, cur_len,
1433 block_len_in_page = move_extent_per_page( 659 unwritten, &ret);
1434 o_filp, donor_inode,
1435 orig_page_offset,
1436 data_offset_in_page,
1437 block_len_in_page,
1438 unwritten, &ret);
1439
1440 /* Count how many blocks we have exchanged */
1441 *moved_len += block_len_in_page;
1442 if (ret < 0)
1443 break;
1444 if (*moved_len > len) {
1445 EXT4_ERROR_INODE(orig_inode,
1446 "We replaced blocks too much! "
1447 "sum of replaced: %llu requested: %llu",
1448 *moved_len, len);
1449 ret = -EIO;
1450 break;
1451 }
1452
1453 orig_page_offset++;
1454 data_offset_in_page = 0;
1455 rest_blocks -= block_len_in_page;
1456 if (rest_blocks > blocks_per_page)
1457 block_len_in_page = blocks_per_page;
1458 else
1459 block_len_in_page = rest_blocks;
1460 }
1461
1462 ext4_double_down_write_data_sem(orig_inode, donor_inode); 660 ext4_double_down_write_data_sem(orig_inode, donor_inode);
1463 if (ret < 0) 661 if (ret < 0)
1464 break; 662 break;
1465 663 o_start += cur_len;
1466 /* Decrease buffer counter */ 664 d_start += cur_len;
1467 if (holecheck_path)
1468 ext4_ext_drop_refs(holecheck_path);
1469 ret = get_ext_path(orig_inode, seq_start, &holecheck_path);
1470 if (ret)
1471 break;
1472 depth = holecheck_path->p_depth;
1473
1474 /* Decrease buffer counter */
1475 if (orig_path)
1476 ext4_ext_drop_refs(orig_path);
1477 ret = get_ext_path(orig_inode, seq_start, &orig_path);
1478 if (ret)
1479 break;
1480
1481 ext_cur = holecheck_path[depth].p_ext;
1482 add_blocks = ext4_ext_get_actual_len(ext_cur);
1483 seq_blocks = 0;
1484
1485 } 665 }
666 *moved_len = o_start - orig_blk;
667 if (*moved_len > len)
668 *moved_len = len;
669
1486out: 670out:
1487 if (*moved_len) { 671 if (*moved_len) {
1488 ext4_discard_preallocations(orig_inode); 672 ext4_discard_preallocations(orig_inode);
1489 ext4_discard_preallocations(donor_inode); 673 ext4_discard_preallocations(donor_inode);
1490 } 674 }
1491 675
1492 if (orig_path) { 676 ext4_ext_drop_refs(path);
1493 ext4_ext_drop_refs(orig_path); 677 kfree(path);
1494 kfree(orig_path);
1495 }
1496 if (holecheck_path) {
1497 ext4_ext_drop_refs(holecheck_path);
1498 kfree(holecheck_path);
1499 }
1500 ext4_double_up_write_data_sem(orig_inode, donor_inode); 678 ext4_double_up_write_data_sem(orig_inode, donor_inode);
1501 ext4_inode_resume_unlocked_dio(orig_inode); 679 ext4_inode_resume_unlocked_dio(orig_inode);
1502 ext4_inode_resume_unlocked_dio(donor_inode); 680 ext4_inode_resume_unlocked_dio(donor_inode);