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