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