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