1
2
3
4
5
6#include "xfs.h"
7#include "xfs_fs.h"
8#include "xfs_shared.h"
9#include "xfs_format.h"
10#include "xfs_log_format.h"
11#include "xfs_trans_resv.h"
12#include "xfs_mount.h"
13#include "xfs_defer.h"
14#include "xfs_inode.h"
15#include "xfs_trans.h"
16#include "xfs_bmap.h"
17#include "xfs_bmap_util.h"
18#include "xfs_trace.h"
19#include "xfs_icache.h"
20#include "xfs_btree.h"
21#include "xfs_refcount_btree.h"
22#include "xfs_refcount.h"
23#include "xfs_bmap_btree.h"
24#include "xfs_trans_space.h"
25#include "xfs_bit.h"
26#include "xfs_alloc.h"
27#include "xfs_quota.h"
28#include "xfs_reflink.h"
29#include "xfs_iomap.h"
30#include "xfs_sb.h"
31#include "xfs_ag_resv.h"
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128int
129xfs_reflink_find_shared(
130 struct xfs_mount *mp,
131 struct xfs_trans *tp,
132 xfs_agnumber_t agno,
133 xfs_agblock_t agbno,
134 xfs_extlen_t aglen,
135 xfs_agblock_t *fbno,
136 xfs_extlen_t *flen,
137 bool find_end_of_shared)
138{
139 struct xfs_buf *agbp;
140 struct xfs_btree_cur *cur;
141 int error;
142
143 error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
144 if (error)
145 return error;
146 if (!agbp)
147 return -ENOMEM;
148
149 cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno);
150
151 error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen,
152 find_end_of_shared);
153
154 xfs_btree_del_cursor(cur, error);
155
156 xfs_trans_brelse(tp, agbp);
157 return error;
158}
159
160
161
162
163
164
165
166
167
168
169
170int
171xfs_reflink_trim_around_shared(
172 struct xfs_inode *ip,
173 struct xfs_bmbt_irec *irec,
174 bool *shared)
175{
176 xfs_agnumber_t agno;
177 xfs_agblock_t agbno;
178 xfs_extlen_t aglen;
179 xfs_agblock_t fbno;
180 xfs_extlen_t flen;
181 int error = 0;
182
183
184 if (!xfs_is_cow_inode(ip) || !xfs_bmap_is_real_extent(irec)) {
185 *shared = false;
186 return 0;
187 }
188
189 trace_xfs_reflink_trim_around_shared(ip, irec);
190
191 agno = XFS_FSB_TO_AGNO(ip->i_mount, irec->br_startblock);
192 agbno = XFS_FSB_TO_AGBNO(ip->i_mount, irec->br_startblock);
193 aglen = irec->br_blockcount;
194
195 error = xfs_reflink_find_shared(ip->i_mount, NULL, agno, agbno,
196 aglen, &fbno, &flen, true);
197 if (error)
198 return error;
199
200 *shared = false;
201 if (fbno == NULLAGBLOCK) {
202
203 return 0;
204 } else if (fbno == agbno) {
205
206
207
208
209
210
211 irec->br_blockcount = flen;
212 *shared = true;
213 return 0;
214 } else {
215
216
217
218
219
220
221 irec->br_blockcount = fbno - agbno;
222 return 0;
223 }
224}
225
226bool
227xfs_inode_need_cow(
228 struct xfs_inode *ip,
229 struct xfs_bmbt_irec *imap,
230 bool *shared)
231{
232
233 if (xfs_is_always_cow_inode(ip) &&
234 !isnullstartblock(imap->br_startblock)) {
235 *shared = true;
236 return 0;
237 }
238
239
240 return xfs_reflink_trim_around_shared(ip, imap, shared);
241}
242
243static int
244xfs_reflink_convert_cow_locked(
245 struct xfs_inode *ip,
246 xfs_fileoff_t offset_fsb,
247 xfs_filblks_t count_fsb)
248{
249 struct xfs_iext_cursor icur;
250 struct xfs_bmbt_irec got;
251 struct xfs_btree_cur *dummy_cur = NULL;
252 int dummy_logflags;
253 int error = 0;
254
255 if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &got))
256 return 0;
257
258 do {
259 if (got.br_startoff >= offset_fsb + count_fsb)
260 break;
261 if (got.br_state == XFS_EXT_NORM)
262 continue;
263 if (WARN_ON_ONCE(isnullstartblock(got.br_startblock)))
264 return -EIO;
265
266 xfs_trim_extent(&got, offset_fsb, count_fsb);
267 if (!got.br_blockcount)
268 continue;
269
270 got.br_state = XFS_EXT_NORM;
271 error = xfs_bmap_add_extent_unwritten_real(NULL, ip,
272 XFS_COW_FORK, &icur, &dummy_cur, &got,
273 &dummy_logflags);
274 if (error)
275 return error;
276 } while (xfs_iext_next_extent(ip->i_cowfp, &icur, &got));
277
278 return error;
279}
280
281
282int
283xfs_reflink_convert_cow(
284 struct xfs_inode *ip,
285 xfs_off_t offset,
286 xfs_off_t count)
287{
288 struct xfs_mount *mp = ip->i_mount;
289 xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
290 xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + count);
291 xfs_filblks_t count_fsb = end_fsb - offset_fsb;
292 int error;
293
294 ASSERT(count != 0);
295
296 xfs_ilock(ip, XFS_ILOCK_EXCL);
297 error = xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb);
298 xfs_iunlock(ip, XFS_ILOCK_EXCL);
299 return error;
300}
301
302
303
304
305
306
307static int
308xfs_find_trim_cow_extent(
309 struct xfs_inode *ip,
310 struct xfs_bmbt_irec *imap,
311 bool *shared,
312 bool *found)
313{
314 xfs_fileoff_t offset_fsb = imap->br_startoff;
315 xfs_filblks_t count_fsb = imap->br_blockcount;
316 struct xfs_iext_cursor icur;
317 struct xfs_bmbt_irec got;
318
319 *found = false;
320
321
322
323
324
325 if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &got))
326 got.br_startoff = offset_fsb + count_fsb;
327 if (got.br_startoff > offset_fsb) {
328 xfs_trim_extent(imap, imap->br_startoff,
329 got.br_startoff - imap->br_startoff);
330 return xfs_inode_need_cow(ip, imap, shared);
331 }
332
333 *shared = true;
334 if (isnullstartblock(got.br_startblock)) {
335 xfs_trim_extent(imap, got.br_startoff, got.br_blockcount);
336 return 0;
337 }
338
339
340 xfs_trim_extent(&got, offset_fsb, count_fsb);
341 *imap = got;
342 *found = true;
343 return 0;
344}
345
346
347int
348xfs_reflink_allocate_cow(
349 struct xfs_inode *ip,
350 struct xfs_bmbt_irec *imap,
351 bool *shared,
352 uint *lockmode,
353 bool convert_now)
354{
355 struct xfs_mount *mp = ip->i_mount;
356 xfs_fileoff_t offset_fsb = imap->br_startoff;
357 xfs_filblks_t count_fsb = imap->br_blockcount;
358 struct xfs_trans *tp;
359 int nimaps, error = 0;
360 bool found;
361 xfs_filblks_t resaligned;
362 xfs_extlen_t resblks = 0;
363
364 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
365 if (!ip->i_cowfp) {
366 ASSERT(!xfs_is_reflink_inode(ip));
367 xfs_ifork_init_cow(ip);
368 }
369
370 error = xfs_find_trim_cow_extent(ip, imap, shared, &found);
371 if (error || !*shared)
372 return error;
373 if (found)
374 goto convert;
375
376 resaligned = xfs_aligned_fsb_count(imap->br_startoff,
377 imap->br_blockcount, xfs_get_cowextsz_hint(ip));
378 resblks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
379
380 xfs_iunlock(ip, *lockmode);
381 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
382 *lockmode = XFS_ILOCK_EXCL;
383 xfs_ilock(ip, *lockmode);
384
385 if (error)
386 return error;
387
388 error = xfs_qm_dqattach_locked(ip, false);
389 if (error)
390 goto out_trans_cancel;
391
392
393
394
395 error = xfs_find_trim_cow_extent(ip, imap, shared, &found);
396 if (error || !*shared)
397 goto out_trans_cancel;
398 if (found) {
399 xfs_trans_cancel(tp);
400 goto convert;
401 }
402
403 error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0,
404 XFS_QMOPT_RES_REGBLKS);
405 if (error)
406 goto out_trans_cancel;
407
408 xfs_trans_ijoin(tp, ip, 0);
409
410
411 nimaps = 1;
412 error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount,
413 XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC,
414 resblks, imap, &nimaps);
415 if (error)
416 goto out_unreserve;
417
418 xfs_inode_set_cowblocks_tag(ip);
419 error = xfs_trans_commit(tp);
420 if (error)
421 return error;
422
423
424
425
426
427 if (nimaps == 0)
428 return -ENOSPC;
429convert:
430 xfs_trim_extent(imap, offset_fsb, count_fsb);
431
432
433
434
435
436 if (!convert_now || imap->br_state == XFS_EXT_NORM)
437 return 0;
438 trace_xfs_reflink_convert_cow(ip, imap);
439 return xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb);
440
441out_unreserve:
442 xfs_trans_unreserve_quota_nblks(tp, ip, (long)resblks, 0,
443 XFS_QMOPT_RES_REGBLKS);
444out_trans_cancel:
445 xfs_trans_cancel(tp);
446 return error;
447}
448
449
450
451
452
453
454
455
456
457
458int
459xfs_reflink_cancel_cow_blocks(
460 struct xfs_inode *ip,
461 struct xfs_trans **tpp,
462 xfs_fileoff_t offset_fsb,
463 xfs_fileoff_t end_fsb,
464 bool cancel_real)
465{
466 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
467 struct xfs_bmbt_irec got, del;
468 struct xfs_iext_cursor icur;
469 int error = 0;
470
471 if (!xfs_inode_has_cow_data(ip))
472 return 0;
473 if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &icur, &got))
474 return 0;
475
476
477 while (got.br_startoff + got.br_blockcount > offset_fsb) {
478 del = got;
479 xfs_trim_extent(&del, offset_fsb, end_fsb - offset_fsb);
480
481
482 if (!del.br_blockcount) {
483 xfs_iext_prev(ifp, &icur);
484 goto next_extent;
485 }
486
487 trace_xfs_reflink_cancel_cow(ip, &del);
488
489 if (isnullstartblock(del.br_startblock)) {
490 error = xfs_bmap_del_extent_delay(ip, XFS_COW_FORK,
491 &icur, &got, &del);
492 if (error)
493 break;
494 } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) {
495 ASSERT((*tpp)->t_firstblock == NULLFSBLOCK);
496
497
498 error = xfs_refcount_free_cow_extent(*tpp,
499 del.br_startblock, del.br_blockcount);
500 if (error)
501 break;
502
503 xfs_bmap_add_free(*tpp, del.br_startblock,
504 del.br_blockcount, NULL);
505
506
507 error = xfs_defer_finish(tpp);
508 if (error)
509 break;
510
511
512 xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
513
514
515 error = xfs_trans_reserve_quota_nblks(NULL, ip,
516 -(long)del.br_blockcount, 0,
517 XFS_QMOPT_RES_REGBLKS);
518 if (error)
519 break;
520 } else {
521
522 xfs_iext_prev(ifp, &icur);
523 }
524next_extent:
525 if (!xfs_iext_get_extent(ifp, &icur, &got))
526 break;
527 }
528
529
530 if (!ifp->if_bytes)
531 xfs_inode_clear_cowblocks_tag(ip);
532 return error;
533}
534
535
536
537
538
539
540
541int
542xfs_reflink_cancel_cow_range(
543 struct xfs_inode *ip,
544 xfs_off_t offset,
545 xfs_off_t count,
546 bool cancel_real)
547{
548 struct xfs_trans *tp;
549 xfs_fileoff_t offset_fsb;
550 xfs_fileoff_t end_fsb;
551 int error;
552
553 trace_xfs_reflink_cancel_cow_range(ip, offset, count);
554 ASSERT(ip->i_cowfp);
555
556 offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
557 if (count == NULLFILEOFF)
558 end_fsb = NULLFILEOFF;
559 else
560 end_fsb = XFS_B_TO_FSB(ip->i_mount, offset + count);
561
562
563 error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write,
564 0, 0, 0, &tp);
565 if (error)
566 goto out;
567
568 xfs_ilock(ip, XFS_ILOCK_EXCL);
569 xfs_trans_ijoin(tp, ip, 0);
570
571
572 error = xfs_reflink_cancel_cow_blocks(ip, &tp, offset_fsb, end_fsb,
573 cancel_real);
574 if (error)
575 goto out_cancel;
576
577 error = xfs_trans_commit(tp);
578
579 xfs_iunlock(ip, XFS_ILOCK_EXCL);
580 return error;
581
582out_cancel:
583 xfs_trans_cancel(tp);
584 xfs_iunlock(ip, XFS_ILOCK_EXCL);
585out:
586 trace_xfs_reflink_cancel_cow_range_error(ip, error, _RET_IP_);
587 return error;
588}
589
590
591
592
593
594
595
596
597
598
599
600STATIC int
601xfs_reflink_end_cow_extent(
602 struct xfs_inode *ip,
603 xfs_fileoff_t offset_fsb,
604 xfs_fileoff_t *end_fsb)
605{
606 struct xfs_bmbt_irec got, del;
607 struct xfs_iext_cursor icur;
608 struct xfs_mount *mp = ip->i_mount;
609 struct xfs_trans *tp;
610 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
611 xfs_filblks_t rlen;
612 unsigned int resblks;
613 int error;
614
615
616 if (ifp->if_bytes == 0) {
617 *end_fsb = offset_fsb;
618 return 0;
619 }
620
621 resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
622 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
623 XFS_TRANS_RESERVE, &tp);
624 if (error)
625 return error;
626
627
628
629
630
631
632 xfs_ilock(ip, XFS_ILOCK_EXCL);
633 xfs_trans_ijoin(tp, ip, 0);
634
635
636
637
638
639
640 if (!xfs_iext_lookup_extent_before(ip, ifp, end_fsb, &icur, &got) ||
641 got.br_startoff + got.br_blockcount <= offset_fsb) {
642 *end_fsb = offset_fsb;
643 goto out_cancel;
644 }
645
646
647
648
649
650
651
652 del = got;
653 xfs_trim_extent(&del, offset_fsb, *end_fsb - offset_fsb);
654
655 ASSERT(del.br_blockcount > 0);
656
657
658
659
660
661
662 if (!xfs_bmap_is_real_extent(&got)) {
663 *end_fsb = del.br_startoff;
664 goto out_cancel;
665 }
666
667
668 rlen = del.br_blockcount;
669 error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1);
670 if (error)
671 goto out_cancel;
672
673
674 xfs_trim_extent(&del, del.br_startoff + rlen, del.br_blockcount - rlen);
675 trace_xfs_reflink_cow_remap(ip, &del);
676
677
678 error = xfs_refcount_free_cow_extent(tp, del.br_startblock,
679 del.br_blockcount);
680 if (error)
681 goto out_cancel;
682
683
684 error = xfs_bmap_map_extent(tp, ip, &del);
685 if (error)
686 goto out_cancel;
687
688
689 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_DELBCOUNT,
690 (long)del.br_blockcount);
691
692
693 xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
694
695 error = xfs_trans_commit(tp);
696 xfs_iunlock(ip, XFS_ILOCK_EXCL);
697 if (error)
698 return error;
699
700
701 *end_fsb = del.br_startoff;
702 return 0;
703
704out_cancel:
705 xfs_trans_cancel(tp);
706 xfs_iunlock(ip, XFS_ILOCK_EXCL);
707 return error;
708}
709
710
711
712
713int
714xfs_reflink_end_cow(
715 struct xfs_inode *ip,
716 xfs_off_t offset,
717 xfs_off_t count)
718{
719 xfs_fileoff_t offset_fsb;
720 xfs_fileoff_t end_fsb;
721 int error = 0;
722
723 trace_xfs_reflink_end_cow(ip, offset, count);
724
725 offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
726 end_fsb = XFS_B_TO_FSB(ip->i_mount, offset + count);
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760 while (end_fsb > offset_fsb && !error)
761 error = xfs_reflink_end_cow_extent(ip, offset_fsb, &end_fsb);
762
763 if (error)
764 trace_xfs_reflink_end_cow_error(ip, error, _RET_IP_);
765 return error;
766}
767
768
769
770
771int
772xfs_reflink_recover_cow(
773 struct xfs_mount *mp)
774{
775 xfs_agnumber_t agno;
776 int error = 0;
777
778 if (!xfs_sb_version_hasreflink(&mp->m_sb))
779 return 0;
780
781 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
782 error = xfs_refcount_recover_cow_leftovers(mp, agno);
783 if (error)
784 break;
785 }
786
787 return error;
788}
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869STATIC int
870xfs_reflink_set_inode_flag(
871 struct xfs_inode *src,
872 struct xfs_inode *dest)
873{
874 struct xfs_mount *mp = src->i_mount;
875 int error;
876 struct xfs_trans *tp;
877
878 if (xfs_is_reflink_inode(src) && xfs_is_reflink_inode(dest))
879 return 0;
880
881 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
882 if (error)
883 goto out_error;
884
885
886 if (src->i_ino == dest->i_ino)
887 xfs_ilock(src, XFS_ILOCK_EXCL);
888 else
889 xfs_lock_two_inodes(src, XFS_ILOCK_EXCL, dest, XFS_ILOCK_EXCL);
890
891 if (!xfs_is_reflink_inode(src)) {
892 trace_xfs_reflink_set_inode_flag(src);
893 xfs_trans_ijoin(tp, src, XFS_ILOCK_EXCL);
894 src->i_d.di_flags2 |= XFS_DIFLAG2_REFLINK;
895 xfs_trans_log_inode(tp, src, XFS_ILOG_CORE);
896 xfs_ifork_init_cow(src);
897 } else
898 xfs_iunlock(src, XFS_ILOCK_EXCL);
899
900 if (src->i_ino == dest->i_ino)
901 goto commit_flags;
902
903 if (!xfs_is_reflink_inode(dest)) {
904 trace_xfs_reflink_set_inode_flag(dest);
905 xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL);
906 dest->i_d.di_flags2 |= XFS_DIFLAG2_REFLINK;
907 xfs_trans_log_inode(tp, dest, XFS_ILOG_CORE);
908 xfs_ifork_init_cow(dest);
909 } else
910 xfs_iunlock(dest, XFS_ILOCK_EXCL);
911
912commit_flags:
913 error = xfs_trans_commit(tp);
914 if (error)
915 goto out_error;
916 return error;
917
918out_error:
919 trace_xfs_reflink_set_inode_flag_error(dest, error, _RET_IP_);
920 return error;
921}
922
923
924
925
926int
927xfs_reflink_update_dest(
928 struct xfs_inode *dest,
929 xfs_off_t newlen,
930 xfs_extlen_t cowextsize,
931 unsigned int remap_flags)
932{
933 struct xfs_mount *mp = dest->i_mount;
934 struct xfs_trans *tp;
935 int error;
936
937 if (newlen <= i_size_read(VFS_I(dest)) && cowextsize == 0)
938 return 0;
939
940 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
941 if (error)
942 goto out_error;
943
944 xfs_ilock(dest, XFS_ILOCK_EXCL);
945 xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL);
946
947 if (newlen > i_size_read(VFS_I(dest))) {
948 trace_xfs_reflink_update_inode_size(dest, newlen);
949 i_size_write(VFS_I(dest), newlen);
950 dest->i_d.di_size = newlen;
951 }
952
953 if (cowextsize) {
954 dest->i_d.di_cowextsize = cowextsize;
955 dest->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
956 }
957
958 xfs_trans_log_inode(tp, dest, XFS_ILOG_CORE);
959
960 error = xfs_trans_commit(tp);
961 if (error)
962 goto out_error;
963 return error;
964
965out_error:
966 trace_xfs_reflink_update_inode_size_error(dest, error, _RET_IP_);
967 return error;
968}
969
970
971
972
973
974
975
976static int
977xfs_reflink_ag_has_free_space(
978 struct xfs_mount *mp,
979 xfs_agnumber_t agno)
980{
981 struct xfs_perag *pag;
982 int error = 0;
983
984 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
985 return 0;
986
987 pag = xfs_perag_get(mp, agno);
988 if (xfs_ag_resv_critical(pag, XFS_AG_RESV_RMAPBT) ||
989 xfs_ag_resv_critical(pag, XFS_AG_RESV_METADATA))
990 error = -ENOSPC;
991 xfs_perag_put(pag);
992 return error;
993}
994
995
996
997
998
999
1000STATIC int
1001xfs_reflink_remap_extent(
1002 struct xfs_inode *ip,
1003 struct xfs_bmbt_irec *irec,
1004 xfs_fileoff_t destoff,
1005 xfs_off_t new_isize)
1006{
1007 struct xfs_mount *mp = ip->i_mount;
1008 bool real_extent = xfs_bmap_is_real_extent(irec);
1009 struct xfs_trans *tp;
1010 unsigned int resblks;
1011 struct xfs_bmbt_irec uirec;
1012 xfs_filblks_t rlen;
1013 xfs_filblks_t unmap_len;
1014 xfs_off_t newlen;
1015 int error;
1016
1017 unmap_len = irec->br_startoff + irec->br_blockcount - destoff;
1018 trace_xfs_reflink_punch_range(ip, destoff, unmap_len);
1019
1020
1021 if (real_extent) {
1022 error = xfs_reflink_ag_has_free_space(mp,
1023 XFS_FSB_TO_AGNO(mp, irec->br_startblock));
1024 if (error)
1025 goto out;
1026 }
1027
1028
1029 resblks = XFS_EXTENTADD_SPACE_RES(ip->i_mount, XFS_DATA_FORK);
1030 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
1031 if (error)
1032 goto out;
1033
1034 xfs_ilock(ip, XFS_ILOCK_EXCL);
1035 xfs_trans_ijoin(tp, ip, 0);
1036
1037
1038 if (real_extent) {
1039 error = xfs_trans_reserve_quota_nblks(tp, ip,
1040 irec->br_blockcount, 0, XFS_QMOPT_RES_REGBLKS);
1041 if (error)
1042 goto out_cancel;
1043 }
1044
1045 trace_xfs_reflink_remap(ip, irec->br_startoff,
1046 irec->br_blockcount, irec->br_startblock);
1047
1048
1049 rlen = unmap_len;
1050 while (rlen) {
1051 ASSERT(tp->t_firstblock == NULLFSBLOCK);
1052 error = __xfs_bunmapi(tp, ip, destoff, &rlen, 0, 1);
1053 if (error)
1054 goto out_cancel;
1055
1056
1057
1058
1059
1060 uirec.br_startblock = irec->br_startblock + rlen;
1061 uirec.br_startoff = irec->br_startoff + rlen;
1062 uirec.br_blockcount = unmap_len - rlen;
1063 unmap_len = rlen;
1064
1065
1066 if (!real_extent || uirec.br_blockcount == 0)
1067 goto next_extent;
1068
1069 trace_xfs_reflink_remap(ip, uirec.br_startoff,
1070 uirec.br_blockcount, uirec.br_startblock);
1071
1072
1073 error = xfs_refcount_increase_extent(tp, &uirec);
1074 if (error)
1075 goto out_cancel;
1076
1077
1078 error = xfs_bmap_map_extent(tp, ip, &uirec);
1079 if (error)
1080 goto out_cancel;
1081
1082
1083 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT,
1084 uirec.br_blockcount);
1085
1086
1087 newlen = XFS_FSB_TO_B(mp,
1088 uirec.br_startoff + uirec.br_blockcount);
1089 newlen = min_t(xfs_off_t, newlen, new_isize);
1090 if (newlen > i_size_read(VFS_I(ip))) {
1091 trace_xfs_reflink_update_inode_size(ip, newlen);
1092 i_size_write(VFS_I(ip), newlen);
1093 ip->i_d.di_size = newlen;
1094 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1095 }
1096
1097next_extent:
1098
1099 error = xfs_defer_finish(&tp);
1100 if (error)
1101 goto out_cancel;
1102 }
1103
1104 error = xfs_trans_commit(tp);
1105 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1106 if (error)
1107 goto out;
1108 return 0;
1109
1110out_cancel:
1111 xfs_trans_cancel(tp);
1112 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1113out:
1114 trace_xfs_reflink_remap_extent_error(ip, error, _RET_IP_);
1115 return error;
1116}
1117
1118
1119
1120
1121int
1122xfs_reflink_remap_blocks(
1123 struct xfs_inode *src,
1124 loff_t pos_in,
1125 struct xfs_inode *dest,
1126 loff_t pos_out,
1127 loff_t remap_len,
1128 loff_t *remapped)
1129{
1130 struct xfs_bmbt_irec imap;
1131 xfs_fileoff_t srcoff;
1132 xfs_fileoff_t destoff;
1133 xfs_filblks_t len;
1134 xfs_filblks_t range_len;
1135 xfs_filblks_t remapped_len = 0;
1136 xfs_off_t new_isize = pos_out + remap_len;
1137 int nimaps;
1138 int error = 0;
1139
1140 destoff = XFS_B_TO_FSBT(src->i_mount, pos_out);
1141 srcoff = XFS_B_TO_FSBT(src->i_mount, pos_in);
1142 len = XFS_B_TO_FSB(src->i_mount, remap_len);
1143
1144
1145 while (len) {
1146 uint lock_mode;
1147
1148 trace_xfs_reflink_remap_blocks_loop(src, srcoff, len,
1149 dest, destoff);
1150
1151
1152 nimaps = 1;
1153 lock_mode = xfs_ilock_data_map_shared(src);
1154 error = xfs_bmapi_read(src, srcoff, len, &imap, &nimaps, 0);
1155 xfs_iunlock(src, lock_mode);
1156 if (error)
1157 break;
1158 ASSERT(nimaps == 1);
1159
1160 trace_xfs_reflink_remap_imap(src, srcoff, len, XFS_DATA_FORK,
1161 &imap);
1162
1163
1164 range_len = imap.br_startoff + imap.br_blockcount - srcoff;
1165 imap.br_startoff += destoff - srcoff;
1166
1167
1168 error = xfs_reflink_remap_extent(dest, &imap, destoff,
1169 new_isize);
1170 if (error)
1171 break;
1172
1173 if (fatal_signal_pending(current)) {
1174 error = -EINTR;
1175 break;
1176 }
1177
1178
1179 srcoff += range_len;
1180 destoff += range_len;
1181 len -= range_len;
1182 remapped_len += range_len;
1183 }
1184
1185 if (error)
1186 trace_xfs_reflink_remap_blocks_error(dest, error, _RET_IP_);
1187 *remapped = min_t(loff_t, remap_len,
1188 XFS_FSB_TO_B(src->i_mount, remapped_len));
1189 return error;
1190}
1191
1192
1193
1194
1195
1196
1197
1198
1199static int
1200xfs_iolock_two_inodes_and_break_layout(
1201 struct inode *src,
1202 struct inode *dest)
1203{
1204 int error;
1205
1206 if (src > dest)
1207 swap(src, dest);
1208
1209retry:
1210
1211 error = break_layout(src, true);
1212 if (error)
1213 return error;
1214 if (src != dest) {
1215 error = break_layout(dest, true);
1216 if (error)
1217 return error;
1218 }
1219
1220
1221 inode_lock(src);
1222 error = break_layout(src, false);
1223 if (error) {
1224 inode_unlock(src);
1225 if (error == -EWOULDBLOCK)
1226 goto retry;
1227 return error;
1228 }
1229
1230 if (src == dest)
1231 return 0;
1232
1233
1234 inode_lock_nested(dest, I_MUTEX_NONDIR2);
1235 error = break_layout(dest, false);
1236 if (error) {
1237 inode_unlock(src);
1238 inode_unlock(dest);
1239 if (error == -EWOULDBLOCK)
1240 goto retry;
1241 return error;
1242 }
1243
1244 return 0;
1245}
1246
1247
1248void
1249xfs_reflink_remap_unlock(
1250 struct file *file_in,
1251 struct file *file_out)
1252{
1253 struct inode *inode_in = file_inode(file_in);
1254 struct xfs_inode *src = XFS_I(inode_in);
1255 struct inode *inode_out = file_inode(file_out);
1256 struct xfs_inode *dest = XFS_I(inode_out);
1257 bool same_inode = (inode_in == inode_out);
1258
1259 xfs_iunlock(dest, XFS_MMAPLOCK_EXCL);
1260 if (!same_inode)
1261 xfs_iunlock(src, XFS_MMAPLOCK_EXCL);
1262 inode_unlock(inode_out);
1263 if (!same_inode)
1264 inode_unlock(inode_in);
1265}
1266
1267
1268
1269
1270
1271
1272static int
1273xfs_reflink_zero_posteof(
1274 struct xfs_inode *ip,
1275 loff_t pos)
1276{
1277 loff_t isize = i_size_read(VFS_I(ip));
1278
1279 if (pos <= isize)
1280 return 0;
1281
1282 trace_xfs_zero_eof(ip, isize, pos - isize);
1283 return iomap_zero_range(VFS_I(ip), isize, pos - isize, NULL,
1284 &xfs_iomap_ops);
1285}
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316int
1317xfs_reflink_remap_prep(
1318 struct file *file_in,
1319 loff_t pos_in,
1320 struct file *file_out,
1321 loff_t pos_out,
1322 loff_t *len,
1323 unsigned int remap_flags)
1324{
1325 struct inode *inode_in = file_inode(file_in);
1326 struct xfs_inode *src = XFS_I(inode_in);
1327 struct inode *inode_out = file_inode(file_out);
1328 struct xfs_inode *dest = XFS_I(inode_out);
1329 bool same_inode = (inode_in == inode_out);
1330 ssize_t ret;
1331
1332
1333 ret = xfs_iolock_two_inodes_and_break_layout(inode_in, inode_out);
1334 if (ret)
1335 return ret;
1336 if (same_inode)
1337 xfs_ilock(src, XFS_MMAPLOCK_EXCL);
1338 else
1339 xfs_lock_two_inodes(src, XFS_MMAPLOCK_EXCL, dest,
1340 XFS_MMAPLOCK_EXCL);
1341
1342
1343 ret = -EINVAL;
1344
1345 if (XFS_IS_REALTIME_INODE(src) || XFS_IS_REALTIME_INODE(dest))
1346 goto out_unlock;
1347
1348
1349 if (IS_DAX(inode_in) || IS_DAX(inode_out))
1350 goto out_unlock;
1351
1352 ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
1353 len, remap_flags);
1354 if (ret < 0 || *len == 0)
1355 goto out_unlock;
1356
1357
1358 ret = xfs_qm_dqattach(dest);
1359 if (ret)
1360 goto out_unlock;
1361
1362
1363
1364
1365
1366 ret = xfs_reflink_zero_posteof(dest, pos_out);
1367 if (ret)
1368 goto out_unlock;
1369
1370
1371 ret = xfs_reflink_set_inode_flag(src, dest);
1372 if (ret)
1373 goto out_unlock;
1374
1375
1376
1377
1378
1379
1380 if (pos_out > XFS_ISIZE(dest)) {
1381 loff_t flen = *len + (pos_out - XFS_ISIZE(dest));
1382 ret = xfs_flush_unmap_range(dest, XFS_ISIZE(dest), flen);
1383 } else {
1384 ret = xfs_flush_unmap_range(dest, pos_out, *len);
1385 }
1386 if (ret)
1387 goto out_unlock;
1388
1389 return 1;
1390out_unlock:
1391 xfs_reflink_remap_unlock(file_in, file_out);
1392 return ret;
1393}
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403STATIC int
1404xfs_reflink_dirty_extents(
1405 struct xfs_inode *ip,
1406 xfs_fileoff_t fbno,
1407 xfs_filblks_t end,
1408 xfs_off_t isize)
1409{
1410 struct xfs_mount *mp = ip->i_mount;
1411 xfs_agnumber_t agno;
1412 xfs_agblock_t agbno;
1413 xfs_extlen_t aglen;
1414 xfs_agblock_t rbno;
1415 xfs_extlen_t rlen;
1416 xfs_off_t fpos;
1417 xfs_off_t flen;
1418 struct xfs_bmbt_irec map[2];
1419 int nmaps;
1420 int error = 0;
1421
1422 while (end - fbno > 0) {
1423 nmaps = 1;
1424
1425
1426
1427
1428 error = xfs_bmapi_read(ip, fbno, end - fbno, map, &nmaps, 0);
1429 if (error)
1430 goto out;
1431 if (nmaps == 0)
1432 break;
1433 if (!xfs_bmap_is_real_extent(&map[0]))
1434 goto next;
1435
1436 map[1] = map[0];
1437 while (map[1].br_blockcount) {
1438 agno = XFS_FSB_TO_AGNO(mp, map[1].br_startblock);
1439 agbno = XFS_FSB_TO_AGBNO(mp, map[1].br_startblock);
1440 aglen = map[1].br_blockcount;
1441
1442 error = xfs_reflink_find_shared(mp, NULL, agno, agbno,
1443 aglen, &rbno, &rlen, true);
1444 if (error)
1445 goto out;
1446 if (rbno == NULLAGBLOCK)
1447 break;
1448
1449
1450 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1451 fpos = XFS_FSB_TO_B(mp, map[1].br_startoff +
1452 (rbno - agbno));
1453 flen = XFS_FSB_TO_B(mp, rlen);
1454 if (fpos + flen > isize)
1455 flen = isize - fpos;
1456 error = iomap_file_dirty(VFS_I(ip), fpos, flen,
1457 &xfs_iomap_ops);
1458 xfs_ilock(ip, XFS_ILOCK_EXCL);
1459 if (error)
1460 goto out;
1461
1462 map[1].br_blockcount -= (rbno - agbno + rlen);
1463 map[1].br_startoff += (rbno - agbno + rlen);
1464 map[1].br_startblock += (rbno - agbno + rlen);
1465 }
1466
1467next:
1468 fbno = map[0].br_startoff + map[0].br_blockcount;
1469 }
1470out:
1471 return error;
1472}
1473
1474
1475int
1476xfs_reflink_inode_has_shared_extents(
1477 struct xfs_trans *tp,
1478 struct xfs_inode *ip,
1479 bool *has_shared)
1480{
1481 struct xfs_bmbt_irec got;
1482 struct xfs_mount *mp = ip->i_mount;
1483 struct xfs_ifork *ifp;
1484 xfs_agnumber_t agno;
1485 xfs_agblock_t agbno;
1486 xfs_extlen_t aglen;
1487 xfs_agblock_t rbno;
1488 xfs_extlen_t rlen;
1489 struct xfs_iext_cursor icur;
1490 bool found;
1491 int error;
1492
1493 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1494 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
1495 error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
1496 if (error)
1497 return error;
1498 }
1499
1500 *has_shared = false;
1501 found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got);
1502 while (found) {
1503 if (isnullstartblock(got.br_startblock) ||
1504 got.br_state != XFS_EXT_NORM)
1505 goto next;
1506 agno = XFS_FSB_TO_AGNO(mp, got.br_startblock);
1507 agbno = XFS_FSB_TO_AGBNO(mp, got.br_startblock);
1508 aglen = got.br_blockcount;
1509
1510 error = xfs_reflink_find_shared(mp, tp, agno, agbno, aglen,
1511 &rbno, &rlen, false);
1512 if (error)
1513 return error;
1514
1515 if (rbno != NULLAGBLOCK) {
1516 *has_shared = true;
1517 return 0;
1518 }
1519next:
1520 found = xfs_iext_next_extent(ifp, &icur, &got);
1521 }
1522
1523 return 0;
1524}
1525
1526
1527
1528
1529
1530
1531
1532int
1533xfs_reflink_clear_inode_flag(
1534 struct xfs_inode *ip,
1535 struct xfs_trans **tpp)
1536{
1537 bool needs_flag;
1538 int error = 0;
1539
1540 ASSERT(xfs_is_reflink_inode(ip));
1541
1542 error = xfs_reflink_inode_has_shared_extents(*tpp, ip, &needs_flag);
1543 if (error || needs_flag)
1544 return error;
1545
1546
1547
1548
1549
1550 error = xfs_reflink_cancel_cow_blocks(ip, tpp, 0, NULLFILEOFF, true);
1551 if (error)
1552 return error;
1553
1554
1555 trace_xfs_reflink_unset_inode_flag(ip);
1556 ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1557 xfs_inode_clear_cowblocks_tag(ip);
1558 xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
1559
1560 return error;
1561}
1562
1563
1564
1565
1566
1567STATIC int
1568xfs_reflink_try_clear_inode_flag(
1569 struct xfs_inode *ip)
1570{
1571 struct xfs_mount *mp = ip->i_mount;
1572 struct xfs_trans *tp;
1573 int error = 0;
1574
1575
1576 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
1577 if (error)
1578 return error;
1579
1580 xfs_ilock(ip, XFS_ILOCK_EXCL);
1581 xfs_trans_ijoin(tp, ip, 0);
1582
1583 error = xfs_reflink_clear_inode_flag(ip, &tp);
1584 if (error)
1585 goto cancel;
1586
1587 error = xfs_trans_commit(tp);
1588 if (error)
1589 goto out;
1590
1591 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1592 return 0;
1593cancel:
1594 xfs_trans_cancel(tp);
1595out:
1596 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1597 return error;
1598}
1599
1600
1601
1602
1603
1604int
1605xfs_reflink_unshare(
1606 struct xfs_inode *ip,
1607 xfs_off_t offset,
1608 xfs_off_t len)
1609{
1610 struct xfs_mount *mp = ip->i_mount;
1611 xfs_fileoff_t fbno;
1612 xfs_filblks_t end;
1613 xfs_off_t isize;
1614 int error;
1615
1616 if (!xfs_is_reflink_inode(ip))
1617 return 0;
1618
1619 trace_xfs_reflink_unshare(ip, offset, len);
1620
1621 inode_dio_wait(VFS_I(ip));
1622
1623
1624 xfs_ilock(ip, XFS_ILOCK_EXCL);
1625 fbno = XFS_B_TO_FSBT(mp, offset);
1626 isize = i_size_read(VFS_I(ip));
1627 end = XFS_B_TO_FSB(mp, offset + len);
1628 error = xfs_reflink_dirty_extents(ip, fbno, end, isize);
1629 if (error)
1630 goto out_unlock;
1631 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1632
1633
1634 error = filemap_write_and_wait(VFS_I(ip)->i_mapping);
1635 if (error)
1636 goto out;
1637
1638
1639 error = xfs_reflink_try_clear_inode_flag(ip);
1640 if (error)
1641 goto out;
1642
1643 return 0;
1644
1645out_unlock:
1646 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1647out:
1648 trace_xfs_reflink_unshare_error(ip, error, _RET_IP_);
1649 return error;
1650}
1651