1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/fs.h>
17#include <linux/quotaops.h>
18#include <linux/slab.h>
19#include "ext4_jbd2.h"
20#include "ext4.h"
21
22
23
24
25
26
27
28
29
30
31
32static inline int
33get_ext_path(struct inode *inode, ext4_lblk_t lblock,
34 struct ext4_ext_path **path)
35{
36 int ret = 0;
37
38 *path = ext4_ext_find_extent(inode, lblock, *path);
39 if (IS_ERR(*path)) {
40 ret = PTR_ERR(*path);
41 *path = NULL;
42 } else if ((*path)[ext_depth(inode)].p_ext == NULL)
43 ret = -ENODATA;
44
45 return ret;
46}
47
48
49
50
51
52
53
54static void
55copy_extent_status(struct ext4_extent *src, struct ext4_extent *dest)
56{
57 if (ext4_ext_is_uninitialized(src))
58 ext4_ext_mark_uninitialized(dest);
59 else
60 dest->ee_len = cpu_to_le16(ext4_ext_get_actual_len(dest));
61}
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76static int
77mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
78 struct ext4_extent **extent)
79{
80 struct ext4_extent_header *eh;
81 int ppos, leaf_ppos = path->p_depth;
82
83 ppos = leaf_ppos;
84 if (EXT_LAST_EXTENT(path[ppos].p_hdr) > path[ppos].p_ext) {
85
86 *extent = ++path[ppos].p_ext;
87 path[ppos].p_block = ext4_ext_pblock(path[ppos].p_ext);
88 return 0;
89 }
90
91 while (--ppos >= 0) {
92 if (EXT_LAST_INDEX(path[ppos].p_hdr) >
93 path[ppos].p_idx) {
94 int cur_ppos = ppos;
95
96
97 path[ppos].p_idx++;
98 path[ppos].p_block = ext4_idx_pblock(path[ppos].p_idx);
99 if (path[ppos+1].p_bh)
100 brelse(path[ppos+1].p_bh);
101 path[ppos+1].p_bh =
102 sb_bread(inode->i_sb, path[ppos].p_block);
103 if (!path[ppos+1].p_bh)
104 return -EIO;
105 path[ppos+1].p_hdr =
106 ext_block_hdr(path[ppos+1].p_bh);
107
108
109 while (++cur_ppos < leaf_ppos) {
110 path[cur_ppos].p_idx =
111 EXT_FIRST_INDEX(path[cur_ppos].p_hdr);
112 path[cur_ppos].p_block =
113 ext4_idx_pblock(path[cur_ppos].p_idx);
114 if (path[cur_ppos+1].p_bh)
115 brelse(path[cur_ppos+1].p_bh);
116 path[cur_ppos+1].p_bh = sb_bread(inode->i_sb,
117 path[cur_ppos].p_block);
118 if (!path[cur_ppos+1].p_bh)
119 return -EIO;
120 path[cur_ppos+1].p_hdr =
121 ext_block_hdr(path[cur_ppos+1].p_bh);
122 }
123
124 path[leaf_ppos].p_ext = *extent = NULL;
125
126 eh = path[leaf_ppos].p_hdr;
127 if (le16_to_cpu(eh->eh_entries) == 0)
128
129 return -ENODATA;
130
131
132 path[leaf_ppos].p_ext = *extent =
133 EXT_FIRST_EXTENT(path[leaf_ppos].p_hdr);
134 path[leaf_ppos].p_block =
135 ext4_ext_pblock(path[leaf_ppos].p_ext);
136 return 0;
137 }
138 }
139
140 return 1;
141}
142
143
144
145
146
147
148static void
149double_down_write_data_sem(struct inode *first, struct inode *second)
150{
151 if (first < second) {
152 down_write(&EXT4_I(first)->i_data_sem);
153 down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
154 } else {
155 down_write(&EXT4_I(second)->i_data_sem);
156 down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
157
158 }
159}
160
161
162
163
164
165
166
167
168static void
169double_up_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
170{
171 up_write(&EXT4_I(orig_inode)->i_data_sem);
172 up_write(&EXT4_I(donor_inode)->i_data_sem);
173}
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189static int
190mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
191 struct ext4_extent *o_start, struct ext4_extent *o_end,
192 struct ext4_extent *start_ext, struct ext4_extent *new_ext,
193 struct ext4_extent *end_ext)
194{
195 struct ext4_ext_path *orig_path = NULL;
196 ext4_lblk_t eblock = 0;
197 int new_flag = 0;
198 int end_flag = 0;
199 int err = 0;
200
201 if (start_ext->ee_len && new_ext->ee_len && end_ext->ee_len) {
202 if (o_start == o_end) {
203
204
205
206
207
208 end_flag = 1;
209 } else {
210
211
212
213
214
215 o_end->ee_block = end_ext->ee_block;
216 o_end->ee_len = end_ext->ee_len;
217 ext4_ext_store_pblock(o_end, ext4_ext_pblock(end_ext));
218 }
219
220 o_start->ee_len = start_ext->ee_len;
221 eblock = le32_to_cpu(start_ext->ee_block);
222 new_flag = 1;
223
224 } else if (start_ext->ee_len && new_ext->ee_len &&
225 !end_ext->ee_len && o_start == o_end) {
226
227
228
229
230
231 o_start->ee_len = start_ext->ee_len;
232 eblock = le32_to_cpu(start_ext->ee_block);
233 new_flag = 1;
234
235 } else if (!start_ext->ee_len && new_ext->ee_len &&
236 end_ext->ee_len && o_start == o_end) {
237
238
239
240
241
242 o_end->ee_block = end_ext->ee_block;
243 o_end->ee_len = end_ext->ee_len;
244 ext4_ext_store_pblock(o_end, ext4_ext_pblock(end_ext));
245
246
247
248
249
250 if (new_ext->ee_block)
251 eblock = le32_to_cpu(new_ext->ee_block);
252
253 new_flag = 1;
254 } else {
255 ext4_debug("ext4 move extent: Unexpected insert case\n");
256 return -EIO;
257 }
258
259 if (new_flag) {
260 err = get_ext_path(orig_inode, eblock, &orig_path);
261 if (err)
262 goto out;
263
264 if (ext4_ext_insert_extent(handle, orig_inode,
265 orig_path, new_ext, 0))
266 goto out;
267 }
268
269 if (end_flag) {
270 err = get_ext_path(orig_inode,
271 le32_to_cpu(end_ext->ee_block) - 1, &orig_path);
272 if (err)
273 goto out;
274
275 if (ext4_ext_insert_extent(handle, orig_inode,
276 orig_path, end_ext, 0))
277 goto out;
278 }
279out:
280 if (orig_path) {
281 ext4_ext_drop_refs(orig_path);
282 kfree(orig_path);
283 }
284
285 return err;
286
287}
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303static void
304mext_insert_inside_block(struct ext4_extent *o_start,
305 struct ext4_extent *o_end,
306 struct ext4_extent *start_ext,
307 struct ext4_extent *new_ext,
308 struct ext4_extent *end_ext,
309 struct ext4_extent_header *eh,
310 int range_to_move)
311{
312 int i = 0;
313 unsigned long len;
314
315
316 if (range_to_move && o_end < EXT_LAST_EXTENT(eh)) {
317 len = (unsigned long)(EXT_LAST_EXTENT(eh) + 1) -
318 (unsigned long)(o_end + 1);
319 memmove(o_end + 1 + range_to_move, o_end + 1, len);
320 }
321
322
323 if (start_ext->ee_len)
324 o_start[i++].ee_len = start_ext->ee_len;
325
326
327 if (new_ext->ee_len) {
328 o_start[i] = *new_ext;
329 ext4_ext_store_pblock(&o_start[i++], ext4_ext_pblock(new_ext));
330 }
331
332
333 if (end_ext->ee_len)
334 o_start[i] = *end_ext;
335
336
337 le16_add_cpu(&eh->eh_entries, range_to_move);
338}
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357static int
358mext_insert_extents(handle_t *handle, struct inode *orig_inode,
359 struct ext4_ext_path *orig_path,
360 struct ext4_extent *o_start,
361 struct ext4_extent *o_end,
362 struct ext4_extent *start_ext,
363 struct ext4_extent *new_ext,
364 struct ext4_extent *end_ext)
365{
366 struct ext4_extent_header *eh;
367 unsigned long need_slots, slots_range;
368 int range_to_move, depth, ret;
369
370
371
372
373
374 need_slots = (start_ext->ee_len ? 1 : 0) + (end_ext->ee_len ? 1 : 0) +
375 (new_ext->ee_len ? 1 : 0);
376
377
378 slots_range = ((unsigned long)(o_end + 1) - (unsigned long)o_start + 1)
379 / sizeof(struct ext4_extent);
380
381
382 range_to_move = need_slots - slots_range;
383 depth = orig_path->p_depth;
384 orig_path += depth;
385 eh = orig_path->p_hdr;
386
387 if (depth) {
388
389 ret = ext4_journal_get_write_access(handle, orig_path->p_bh);
390 if (ret)
391 return ret;
392 }
393
394
395 if (range_to_move > 0 &&
396 (range_to_move > le16_to_cpu(eh->eh_max)
397 - le16_to_cpu(eh->eh_entries))) {
398
399 ret = mext_insert_across_blocks(handle, orig_inode, o_start,
400 o_end, start_ext, new_ext, end_ext);
401 if (ret < 0)
402 return ret;
403 } else
404 mext_insert_inside_block(o_start, o_end, start_ext, new_ext,
405 end_ext, eh, range_to_move);
406
407 if (depth) {
408 ret = ext4_handle_dirty_metadata(handle, orig_inode,
409 orig_path->p_bh);
410 if (ret)
411 return ret;
412 } else {
413 ret = ext4_mark_inode_dirty(handle, orig_inode);
414 if (ret < 0)
415 return ret;
416 }
417
418 return 0;
419}
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438static int
439mext_leaf_block(handle_t *handle, struct inode *orig_inode,
440 struct ext4_ext_path *orig_path, struct ext4_extent *dext,
441 ext4_lblk_t *from)
442{
443 struct ext4_extent *oext, *o_start, *o_end, *prev_ext;
444 struct ext4_extent new_ext, start_ext, end_ext;
445 ext4_lblk_t new_ext_end;
446 int oext_alen, new_ext_alen, end_ext_alen;
447 int depth = ext_depth(orig_inode);
448 int ret;
449
450 start_ext.ee_block = end_ext.ee_block = 0;
451 o_start = o_end = oext = orig_path[depth].p_ext;
452 oext_alen = ext4_ext_get_actual_len(oext);
453 start_ext.ee_len = end_ext.ee_len = 0;
454
455 new_ext.ee_block = cpu_to_le32(*from);
456 ext4_ext_store_pblock(&new_ext, ext4_ext_pblock(dext));
457 new_ext.ee_len = dext->ee_len;
458 new_ext_alen = ext4_ext_get_actual_len(&new_ext);
459 new_ext_end = le32_to_cpu(new_ext.ee_block) + new_ext_alen - 1;
460
461
462
463
464
465
466
467 if (le32_to_cpu(oext->ee_block) < le32_to_cpu(new_ext.ee_block) &&
468 le32_to_cpu(new_ext.ee_block) <
469 le32_to_cpu(oext->ee_block) + oext_alen) {
470 start_ext.ee_len = cpu_to_le16(le32_to_cpu(new_ext.ee_block) -
471 le32_to_cpu(oext->ee_block));
472 start_ext.ee_block = oext->ee_block;
473 copy_extent_status(oext, &start_ext);
474 } else if (oext > EXT_FIRST_EXTENT(orig_path[depth].p_hdr)) {
475 prev_ext = oext - 1;
476
477
478
479
480 if (ext4_can_extents_be_merged(orig_inode, prev_ext,
481 &new_ext)) {
482 o_start = prev_ext;
483 start_ext.ee_len = cpu_to_le16(
484 ext4_ext_get_actual_len(prev_ext) +
485 new_ext_alen);
486 start_ext.ee_block = oext->ee_block;
487 copy_extent_status(prev_ext, &start_ext);
488 new_ext.ee_len = 0;
489 }
490 }
491
492
493
494
495
496
497 if (le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end) {
498 EXT4_ERROR_INODE(orig_inode,
499 "new_ext_end(%u) should be less than or equal to "
500 "oext->ee_block(%u) + oext_alen(%d) - 1",
501 new_ext_end, le32_to_cpu(oext->ee_block),
502 oext_alen);
503 ret = -EIO;
504 goto out;
505 }
506
507
508
509
510
511
512
513 if (le32_to_cpu(oext->ee_block) <= new_ext_end &&
514 new_ext_end < le32_to_cpu(oext->ee_block) + oext_alen - 1) {
515 end_ext.ee_len =
516 cpu_to_le16(le32_to_cpu(oext->ee_block) +
517 oext_alen - 1 - new_ext_end);
518 copy_extent_status(oext, &end_ext);
519 end_ext_alen = ext4_ext_get_actual_len(&end_ext);
520 ext4_ext_store_pblock(&end_ext,
521 (ext4_ext_pblock(o_end) + oext_alen - end_ext_alen));
522 end_ext.ee_block =
523 cpu_to_le32(le32_to_cpu(o_end->ee_block) +
524 oext_alen - end_ext_alen);
525 }
526
527 ret = mext_insert_extents(handle, orig_inode, orig_path, o_start,
528 o_end, &start_ext, &new_ext, &end_ext);
529out:
530 return ret;
531}
532
533
534
535
536
537
538
539
540
541
542
543
544static int
545mext_calc_swap_extents(struct ext4_extent *tmp_dext,
546 struct ext4_extent *tmp_oext,
547 ext4_lblk_t orig_off, ext4_lblk_t donor_off,
548 ext4_lblk_t max_count)
549{
550 ext4_lblk_t diff, orig_diff;
551 struct ext4_extent dext_old, oext_old;
552
553 BUG_ON(orig_off != donor_off);
554
555
556 if (orig_off < le32_to_cpu(tmp_oext->ee_block) ||
557 le32_to_cpu(tmp_oext->ee_block) +
558 ext4_ext_get_actual_len(tmp_oext) - 1 < orig_off)
559 return -ENODATA;
560
561 if (orig_off < le32_to_cpu(tmp_dext->ee_block) ||
562 le32_to_cpu(tmp_dext->ee_block) +
563 ext4_ext_get_actual_len(tmp_dext) - 1 < orig_off)
564 return -ENODATA;
565
566 dext_old = *tmp_dext;
567 oext_old = *tmp_oext;
568
569
570 diff = donor_off - le32_to_cpu(tmp_dext->ee_block);
571
572 ext4_ext_store_pblock(tmp_dext, ext4_ext_pblock(tmp_dext) + diff);
573 tmp_dext->ee_block =
574 cpu_to_le32(le32_to_cpu(tmp_dext->ee_block) + diff);
575 tmp_dext->ee_len = cpu_to_le16(le16_to_cpu(tmp_dext->ee_len) - diff);
576
577 if (max_count < ext4_ext_get_actual_len(tmp_dext))
578 tmp_dext->ee_len = cpu_to_le16(max_count);
579
580 orig_diff = orig_off - le32_to_cpu(tmp_oext->ee_block);
581 ext4_ext_store_pblock(tmp_oext, ext4_ext_pblock(tmp_oext) + orig_diff);
582
583
584 if (ext4_ext_get_actual_len(tmp_dext) >
585 ext4_ext_get_actual_len(tmp_oext) - orig_diff)
586 tmp_dext->ee_len = cpu_to_le16(le16_to_cpu(tmp_oext->ee_len) -
587 orig_diff);
588
589 tmp_oext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(tmp_dext));
590
591 copy_extent_status(&oext_old, tmp_dext);
592 copy_extent_status(&dext_old, tmp_oext);
593
594 return 0;
595}
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618static int
619mext_replace_branches(handle_t *handle, struct inode *orig_inode,
620 struct inode *donor_inode, ext4_lblk_t from,
621 ext4_lblk_t count, int *err)
622{
623 struct ext4_ext_path *orig_path = NULL;
624 struct ext4_ext_path *donor_path = NULL;
625 struct ext4_extent *oext, *dext;
626 struct ext4_extent tmp_dext, tmp_oext;
627 ext4_lblk_t orig_off = from, donor_off = from;
628 int depth;
629 int replaced_count = 0;
630 int dext_alen;
631
632
633 double_down_write_data_sem(orig_inode, donor_inode);
634
635
636 *err = get_ext_path(orig_inode, orig_off, &orig_path);
637 if (*err)
638 goto out;
639
640
641 *err = get_ext_path(donor_inode, donor_off, &donor_path);
642 if (*err)
643 goto out;
644 depth = ext_depth(orig_inode);
645 oext = orig_path[depth].p_ext;
646 tmp_oext = *oext;
647
648 depth = ext_depth(donor_inode);
649 dext = donor_path[depth].p_ext;
650 tmp_dext = *dext;
651
652 *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
653 donor_off, count);
654 if (*err)
655 goto out;
656
657
658 while (1) {
659
660 if (!dext) {
661 EXT4_ERROR_INODE(donor_inode,
662 "The extent for donor must be found");
663 *err = -EIO;
664 goto out;
665 } else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
666 EXT4_ERROR_INODE(donor_inode,
667 "Donor offset(%u) and the first block of donor "
668 "extent(%u) should be equal",
669 donor_off,
670 le32_to_cpu(tmp_dext.ee_block));
671 *err = -EIO;
672 goto out;
673 }
674
675
676 *err = mext_leaf_block(handle, orig_inode,
677 orig_path, &tmp_dext, &orig_off);
678 if (*err)
679 goto out;
680
681
682 *err = mext_leaf_block(handle, donor_inode,
683 donor_path, &tmp_oext, &donor_off);
684 if (*err)
685 goto out;
686
687 dext_alen = ext4_ext_get_actual_len(&tmp_dext);
688 replaced_count += dext_alen;
689 donor_off += dext_alen;
690 orig_off += dext_alen;
691
692
693 if (replaced_count >= count)
694 break;
695
696 if (orig_path)
697 ext4_ext_drop_refs(orig_path);
698 *err = get_ext_path(orig_inode, orig_off, &orig_path);
699 if (*err)
700 goto out;
701 depth = ext_depth(orig_inode);
702 oext = orig_path[depth].p_ext;
703 tmp_oext = *oext;
704
705 if (donor_path)
706 ext4_ext_drop_refs(donor_path);
707 *err = get_ext_path(donor_inode, donor_off, &donor_path);
708 if (*err)
709 goto out;
710 depth = ext_depth(donor_inode);
711 dext = donor_path[depth].p_ext;
712 tmp_dext = *dext;
713
714 *err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
715 donor_off, count - replaced_count);
716 if (*err)
717 goto out;
718 }
719
720out:
721 if (orig_path) {
722 ext4_ext_drop_refs(orig_path);
723 kfree(orig_path);
724 }
725 if (donor_path) {
726 ext4_ext_drop_refs(donor_path);
727 kfree(donor_path);
728 }
729
730 ext4_ext_invalidate_cache(orig_inode);
731 ext4_ext_invalidate_cache(donor_inode);
732
733 double_up_write_data_sem(orig_inode, donor_inode);
734
735 return replaced_count;
736}
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754static int
755move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
756 pgoff_t orig_page_offset, int data_offset_in_page,
757 int block_len_in_page, int uninit, int *err)
758{
759 struct inode *orig_inode = o_filp->f_dentry->d_inode;
760 struct address_space *mapping = orig_inode->i_mapping;
761 struct buffer_head *bh;
762 struct page *page = NULL;
763 const struct address_space_operations *a_ops = mapping->a_ops;
764 handle_t *handle;
765 ext4_lblk_t orig_blk_offset;
766 long long offs = orig_page_offset << PAGE_CACHE_SHIFT;
767 unsigned long blocksize = orig_inode->i_sb->s_blocksize;
768 unsigned int w_flags = 0;
769 unsigned int tmp_data_size, data_size, replaced_size;
770 void *fsdata;
771 int i, jblocks;
772 int err2 = 0;
773 int replaced_count = 0;
774 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
775
776
777
778
779
780 jblocks = ext4_writepage_trans_blocks(orig_inode) * 2;
781 handle = ext4_journal_start(orig_inode, jblocks);
782 if (IS_ERR(handle)) {
783 *err = PTR_ERR(handle);
784 return 0;
785 }
786
787 if (segment_eq(get_fs(), KERNEL_DS))
788 w_flags |= AOP_FLAG_UNINTERRUPTIBLE;
789
790 orig_blk_offset = orig_page_offset * blocks_per_page +
791 data_offset_in_page;
792
793
794
795
796
797
798
799 if (uninit) {
800 replaced_count = mext_replace_branches(handle, orig_inode,
801 donor_inode, orig_blk_offset,
802 block_len_in_page, err);
803 goto out2;
804 }
805
806 offs = (long long)orig_blk_offset << orig_inode->i_blkbits;
807
808
809 if ((orig_blk_offset + block_len_in_page - 1) ==
810 ((orig_inode->i_size - 1) >> orig_inode->i_blkbits)) {
811
812 tmp_data_size = orig_inode->i_size & (blocksize - 1);
813
814
815
816
817 if (tmp_data_size == 0)
818 tmp_data_size = blocksize;
819
820 data_size = tmp_data_size +
821 ((block_len_in_page - 1) << orig_inode->i_blkbits);
822 } else
823 data_size = block_len_in_page << orig_inode->i_blkbits;
824
825 replaced_size = data_size;
826
827 *err = a_ops->write_begin(o_filp, mapping, offs, data_size, w_flags,
828 &page, &fsdata);
829 if (unlikely(*err < 0))
830 goto out;
831
832 if (!PageUptodate(page)) {
833 mapping->a_ops->readpage(o_filp, page);
834 lock_page(page);
835 }
836
837
838
839
840
841
842
843
844 wait_on_page_writeback(page);
845
846
847 try_to_release_page(page, 0);
848
849 replaced_count = mext_replace_branches(handle, orig_inode, donor_inode,
850 orig_blk_offset, block_len_in_page,
851 &err2);
852 if (err2) {
853 if (replaced_count) {
854 block_len_in_page = replaced_count;
855 replaced_size =
856 block_len_in_page << orig_inode->i_blkbits;
857 } else
858 goto out;
859 }
860
861 if (!page_has_buffers(page))
862 create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0);
863
864 bh = page_buffers(page);
865 for (i = 0; i < data_offset_in_page; i++)
866 bh = bh->b_this_page;
867
868 for (i = 0; i < block_len_in_page; i++) {
869 *err = ext4_get_block(orig_inode,
870 (sector_t)(orig_blk_offset + i), bh, 0);
871 if (*err < 0)
872 goto out;
873
874 if (bh->b_this_page != NULL)
875 bh = bh->b_this_page;
876 }
877
878 *err = a_ops->write_end(o_filp, mapping, offs, data_size, replaced_size,
879 page, fsdata);
880 page = NULL;
881
882out:
883 if (unlikely(page)) {
884 if (PageLocked(page))
885 unlock_page(page);
886 page_cache_release(page);
887 ext4_journal_stop(handle);
888 }
889out2:
890 ext4_journal_stop(handle);
891
892 if (err2)
893 *err = err2;
894
895 return replaced_count;
896}
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911static int
912mext_check_arguments(struct inode *orig_inode,
913 struct inode *donor_inode, __u64 orig_start,
914 __u64 donor_start, __u64 *len)
915{
916 ext4_lblk_t orig_blocks, donor_blocks;
917 unsigned int blkbits = orig_inode->i_blkbits;
918 unsigned int blocksize = 1 << blkbits;
919
920 if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
921 ext4_debug("ext4 move extent: suid or sgid is set"
922 " to donor file [ino:orig %lu, donor %lu]\n",
923 orig_inode->i_ino, donor_inode->i_ino);
924 return -EINVAL;
925 }
926
927 if (IS_IMMUTABLE(donor_inode) || IS_APPEND(donor_inode))
928 return -EPERM;
929
930
931 if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) {
932 ext4_debug("ext4 move extent: The argument files should "
933 "not be swapfile [ino:orig %lu, donor %lu]\n",
934 orig_inode->i_ino, donor_inode->i_ino);
935 return -EINVAL;
936 }
937
938
939 if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
940 ext4_debug("ext4 move extent: orig file is not extents "
941 "based file [ino:orig %lu]\n", orig_inode->i_ino);
942 return -EOPNOTSUPP;
943 } else if (!(ext4_test_inode_flag(donor_inode, EXT4_INODE_EXTENTS))) {
944 ext4_debug("ext4 move extent: donor file is not extents "
945 "based file [ino:donor %lu]\n", donor_inode->i_ino);
946 return -EOPNOTSUPP;
947 }
948
949 if ((!orig_inode->i_size) || (!donor_inode->i_size)) {
950 ext4_debug("ext4 move extent: File size is 0 byte\n");
951 return -EINVAL;
952 }
953
954
955 if (orig_start != donor_start) {
956 ext4_debug("ext4 move extent: orig and donor's start "
957 "offset are not same [ino:orig %lu, donor %lu]\n",
958 orig_inode->i_ino, donor_inode->i_ino);
959 return -EINVAL;
960 }
961
962 if ((orig_start >= EXT_MAX_BLOCKS) ||
963 (donor_start >= EXT_MAX_BLOCKS) ||
964 (*len > EXT_MAX_BLOCKS) ||
965 (orig_start + *len >= EXT_MAX_BLOCKS)) {
966 ext4_debug("ext4 move extent: Can't handle over [%u] blocks "
967 "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCKS,
968 orig_inode->i_ino, donor_inode->i_ino);
969 return -EINVAL;
970 }
971
972 if (orig_inode->i_size > donor_inode->i_size) {
973 donor_blocks = (donor_inode->i_size + blocksize - 1) >> blkbits;
974
975 if (orig_start >= donor_blocks) {
976 ext4_debug("ext4 move extent: orig start offset "
977 "[%llu] should be less than donor file blocks "
978 "[%u] [ino:orig %lu, donor %lu]\n",
979 orig_start, donor_blocks,
980 orig_inode->i_ino, donor_inode->i_ino);
981 return -EINVAL;
982 }
983
984
985 if (orig_start + *len > donor_blocks) {
986 ext4_debug("ext4 move extent: End offset [%llu] should "
987 "be less than donor file blocks [%u]."
988 "So adjust length from %llu to %llu "
989 "[ino:orig %lu, donor %lu]\n",
990 orig_start + *len, donor_blocks,
991 *len, donor_blocks - orig_start,
992 orig_inode->i_ino, donor_inode->i_ino);
993 *len = donor_blocks - orig_start;
994 }
995 } else {
996 orig_blocks = (orig_inode->i_size + blocksize - 1) >> blkbits;
997 if (orig_start >= orig_blocks) {
998 ext4_debug("ext4 move extent: start offset [%llu] "
999 "should be less than original file blocks "
1000 "[%u] [ino:orig %lu, donor %lu]\n",
1001 orig_start, orig_blocks,
1002 orig_inode->i_ino, donor_inode->i_ino);
1003 return -EINVAL;
1004 }
1005
1006 if (orig_start + *len > orig_blocks) {
1007 ext4_debug("ext4 move extent: Adjust length "
1008 "from %llu to %llu. Because it should be "
1009 "less than original file blocks "
1010 "[ino:orig %lu, donor %lu]\n",
1011 *len, orig_blocks - orig_start,
1012 orig_inode->i_ino, donor_inode->i_ino);
1013 *len = orig_blocks - orig_start;
1014 }
1015 }
1016
1017 if (!*len) {
1018 ext4_debug("ext4 move extent: len should not be 0 "
1019 "[ino:orig %lu, donor %lu]\n", orig_inode->i_ino,
1020 donor_inode->i_ino);
1021 return -EINVAL;
1022 }
1023
1024 return 0;
1025}
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035static void
1036mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
1037{
1038 BUG_ON(inode1 == inode2);
1039 if (inode1 < inode2) {
1040 mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
1041 mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
1042 } else {
1043 mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
1044 mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
1045 }
1046}
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056static void
1057mext_inode_double_unlock(struct inode *inode1, struct inode *inode2)
1058{
1059 mutex_unlock(&inode1->i_mutex);
1060 mutex_unlock(&inode2->i_mutex);
1061}
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104int
1105ext4_move_extents(struct file *o_filp, struct file *d_filp,
1106 __u64 orig_start, __u64 donor_start, __u64 len,
1107 __u64 *moved_len)
1108{
1109 struct inode *orig_inode = o_filp->f_dentry->d_inode;
1110 struct inode *donor_inode = d_filp->f_dentry->d_inode;
1111 struct ext4_ext_path *orig_path = NULL, *holecheck_path = NULL;
1112 struct ext4_extent *ext_prev, *ext_cur, *ext_dummy;
1113 ext4_lblk_t block_start = orig_start;
1114 ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
1115 ext4_lblk_t rest_blocks;
1116 pgoff_t orig_page_offset = 0, seq_end_page;
1117 int ret, depth, last_extent = 0;
1118 int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
1119 int data_offset_in_page;
1120 int block_len_in_page;
1121 int uninit;
1122
1123 if (orig_inode->i_sb != donor_inode->i_sb) {
1124 ext4_debug("ext4 move extent: The argument files "
1125 "should be in same FS [ino:orig %lu, donor %lu]\n",
1126 orig_inode->i_ino, donor_inode->i_ino);
1127 return -EINVAL;
1128 }
1129
1130
1131 if (orig_inode == donor_inode) {
1132 ext4_debug("ext4 move extent: The argument files should not "
1133 "be same inode [ino:orig %lu, donor %lu]\n",
1134 orig_inode->i_ino, donor_inode->i_ino);
1135 return -EINVAL;
1136 }
1137
1138
1139 if (!S_ISREG(orig_inode->i_mode) || !S_ISREG(donor_inode->i_mode)) {
1140 ext4_debug("ext4 move extent: The argument files should be "
1141 "regular file [ino:orig %lu, donor %lu]\n",
1142 orig_inode->i_ino, donor_inode->i_ino);
1143 return -EINVAL;
1144 }
1145
1146
1147 if (ext4_should_journal_data(orig_inode) ||
1148 ext4_should_journal_data(donor_inode)) {
1149 return -EINVAL;
1150 }
1151
1152 mext_inode_double_lock(orig_inode, donor_inode);
1153
1154
1155 double_down_write_data_sem(orig_inode, donor_inode);
1156
1157 ret = mext_check_arguments(orig_inode, donor_inode, orig_start,
1158 donor_start, &len);
1159 if (ret)
1160 goto out;
1161
1162 file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits;
1163 block_end = block_start + len - 1;
1164 if (file_end < block_end)
1165 len -= block_end - file_end;
1166
1167 ret = get_ext_path(orig_inode, block_start, &orig_path);
1168 if (ret)
1169 goto out;
1170
1171
1172 ret = get_ext_path(orig_inode, block_start, &holecheck_path);
1173 if (ret)
1174 goto out;
1175
1176 depth = ext_depth(orig_inode);
1177 ext_cur = holecheck_path[depth].p_ext;
1178
1179
1180
1181
1182
1183 if (le32_to_cpu(ext_cur->ee_block) +
1184 ext4_ext_get_actual_len(ext_cur) - 1 < block_start) {
1185
1186
1187
1188
1189 last_extent = mext_next_extent(orig_inode,
1190 holecheck_path, &ext_cur);
1191 if (last_extent < 0) {
1192 ret = last_extent;
1193 goto out;
1194 }
1195 last_extent = mext_next_extent(orig_inode, orig_path,
1196 &ext_dummy);
1197 if (last_extent < 0) {
1198 ret = last_extent;
1199 goto out;
1200 }
1201 seq_start = le32_to_cpu(ext_cur->ee_block);
1202 } else if (le32_to_cpu(ext_cur->ee_block) > block_start)
1203
1204 seq_start = le32_to_cpu(ext_cur->ee_block);
1205 else
1206 seq_start = block_start;
1207
1208
1209 if (le32_to_cpu(ext_cur->ee_block) > block_end) {
1210 ext4_debug("ext4 move extent: The specified range of file "
1211 "may be the hole\n");
1212 ret = -EINVAL;
1213 goto out;
1214 }
1215
1216
1217 add_blocks = min(le32_to_cpu(ext_cur->ee_block) +
1218 ext4_ext_get_actual_len(ext_cur), block_end + 1) -
1219 max(le32_to_cpu(ext_cur->ee_block), block_start);
1220
1221 while (!last_extent && le32_to_cpu(ext_cur->ee_block) <= block_end) {
1222 seq_blocks += add_blocks;
1223
1224
1225 if (seq_start + seq_blocks - 1 > block_end)
1226 seq_blocks = block_end - seq_start + 1;
1227
1228 ext_prev = ext_cur;
1229 last_extent = mext_next_extent(orig_inode, holecheck_path,
1230 &ext_cur);
1231 if (last_extent < 0) {
1232 ret = last_extent;
1233 break;
1234 }
1235 add_blocks = ext4_ext_get_actual_len(ext_cur);
1236
1237
1238
1239
1240
1241 if (ext4_can_extents_be_merged(orig_inode,
1242 ext_prev, ext_cur) &&
1243 block_end >= le32_to_cpu(ext_cur->ee_block) &&
1244 !last_extent)
1245 continue;
1246
1247
1248 uninit = ext4_ext_is_uninitialized(ext_prev);
1249
1250 data_offset_in_page = seq_start % blocks_per_page;
1251
1252
1253
1254
1255
1256 if (data_offset_in_page + seq_blocks > blocks_per_page) {
1257
1258 block_len_in_page =
1259 blocks_per_page - data_offset_in_page;
1260 } else {
1261
1262 block_len_in_page = seq_blocks;
1263 }
1264
1265 orig_page_offset = seq_start >>
1266 (PAGE_CACHE_SHIFT - orig_inode->i_blkbits);
1267 seq_end_page = (seq_start + seq_blocks - 1) >>
1268 (PAGE_CACHE_SHIFT - orig_inode->i_blkbits);
1269 seq_start = le32_to_cpu(ext_cur->ee_block);
1270 rest_blocks = seq_blocks;
1271
1272
1273
1274
1275
1276
1277
1278
1279 double_up_write_data_sem(orig_inode, donor_inode);
1280
1281 while (orig_page_offset <= seq_end_page) {
1282
1283
1284 block_len_in_page = move_extent_per_page(
1285 o_filp, donor_inode,
1286 orig_page_offset,
1287 data_offset_in_page,
1288 block_len_in_page, uninit,
1289 &ret);
1290
1291
1292 *moved_len += block_len_in_page;
1293 if (ret < 0)
1294 break;
1295 if (*moved_len > len) {
1296 EXT4_ERROR_INODE(orig_inode,
1297 "We replaced blocks too much! "
1298 "sum of replaced: %llu requested: %llu",
1299 *moved_len, len);
1300 ret = -EIO;
1301 break;
1302 }
1303
1304 orig_page_offset++;
1305 data_offset_in_page = 0;
1306 rest_blocks -= block_len_in_page;
1307 if (rest_blocks > blocks_per_page)
1308 block_len_in_page = blocks_per_page;
1309 else
1310 block_len_in_page = rest_blocks;
1311 }
1312
1313 double_down_write_data_sem(orig_inode, donor_inode);
1314 if (ret < 0)
1315 break;
1316
1317
1318 if (holecheck_path)
1319 ext4_ext_drop_refs(holecheck_path);
1320 ret = get_ext_path(orig_inode, seq_start, &holecheck_path);
1321 if (ret)
1322 break;
1323 depth = holecheck_path->p_depth;
1324
1325
1326 if (orig_path)
1327 ext4_ext_drop_refs(orig_path);
1328 ret = get_ext_path(orig_inode, seq_start, &orig_path);
1329 if (ret)
1330 break;
1331
1332 ext_cur = holecheck_path[depth].p_ext;
1333 add_blocks = ext4_ext_get_actual_len(ext_cur);
1334 seq_blocks = 0;
1335
1336 }
1337out:
1338 if (*moved_len) {
1339 ext4_discard_preallocations(orig_inode);
1340 ext4_discard_preallocations(donor_inode);
1341 }
1342
1343 if (orig_path) {
1344 ext4_ext_drop_refs(orig_path);
1345 kfree(orig_path);
1346 }
1347 if (holecheck_path) {
1348 ext4_ext_drop_refs(holecheck_path);
1349 kfree(holecheck_path);
1350 }
1351 double_up_write_data_sem(orig_inode, donor_inode);
1352 mext_inode_double_unlock(orig_inode, donor_inode);
1353
1354 return ret;
1355}
1356