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_written_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_written_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
990STATIC int
991xfs_reflink_remap_extent(
992 struct xfs_inode *ip,
993 struct xfs_bmbt_irec *dmap,
994 xfs_off_t new_isize)
995{
996 struct xfs_bmbt_irec smap;
997 struct xfs_mount *mp = ip->i_mount;
998 struct xfs_trans *tp;
999 xfs_off_t newlen;
1000 int64_t qres, qdelta;
1001 unsigned int resblks;
1002 bool smap_real;
1003 bool dmap_written = xfs_bmap_is_written_extent(dmap);
1004 int nimaps;
1005 int error;
1006
1007
1008 resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
1009 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
1010 if (error)
1011 goto out;
1012
1013 xfs_ilock(ip, XFS_ILOCK_EXCL);
1014 xfs_trans_ijoin(tp, ip, 0);
1015
1016
1017
1018
1019
1020
1021 nimaps = 1;
1022 error = xfs_bmapi_read(ip, dmap->br_startoff, dmap->br_blockcount,
1023 &smap, &nimaps, 0);
1024 if (error)
1025 goto out_cancel;
1026 ASSERT(nimaps == 1 && smap.br_startoff == dmap->br_startoff);
1027 smap_real = xfs_bmap_is_real_extent(&smap);
1028
1029
1030
1031
1032
1033 dmap->br_blockcount = min(dmap->br_blockcount, smap.br_blockcount);
1034 ASSERT(dmap->br_blockcount == smap.br_blockcount);
1035
1036 trace_xfs_reflink_remap_extent_dest(ip, &smap);
1037
1038
1039
1040
1041
1042
1043 if (dmap->br_startblock == smap.br_startblock) {
1044 if (dmap->br_state != smap.br_state)
1045 error = -EFSCORRUPTED;
1046 goto out_cancel;
1047 }
1048
1049
1050 if (dmap->br_state == XFS_EXT_UNWRITTEN &&
1051 smap.br_state == XFS_EXT_UNWRITTEN)
1052 goto out_cancel;
1053
1054
1055 if (dmap_written) {
1056 error = xfs_reflink_ag_has_free_space(mp,
1057 XFS_FSB_TO_AGNO(mp, dmap->br_startblock));
1058 if (error)
1059 goto out_cancel;
1060 }
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 qres = qdelta = 0;
1086 if (smap_real || dmap_written)
1087 qres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
1088 if (!smap_real && dmap_written)
1089 qres += dmap->br_blockcount;
1090 if (qres > 0) {
1091 error = xfs_trans_reserve_quota_nblks(tp, ip, qres, 0,
1092 XFS_QMOPT_RES_REGBLKS);
1093 if (error)
1094 goto out_cancel;
1095 }
1096
1097 if (smap_real) {
1098
1099
1100
1101
1102 xfs_bmap_unmap_extent(tp, ip, &smap);
1103 xfs_refcount_decrease_extent(tp, &smap);
1104 qdelta -= smap.br_blockcount;
1105 } else if (smap.br_startblock == DELAYSTARTBLOCK) {
1106 xfs_filblks_t len = smap.br_blockcount;
1107
1108
1109
1110
1111
1112
1113
1114 error = __xfs_bunmapi(NULL, ip, smap.br_startoff, &len, 0, 1);
1115 if (error)
1116 goto out_cancel;
1117 ASSERT(len == 0);
1118 }
1119
1120
1121
1122
1123
1124 if (dmap_written) {
1125 xfs_refcount_increase_extent(tp, dmap);
1126 xfs_bmap_map_extent(tp, ip, dmap);
1127 qdelta += dmap->br_blockcount;
1128 }
1129
1130 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, qdelta);
1131
1132
1133 newlen = XFS_FSB_TO_B(mp, dmap->br_startoff + dmap->br_blockcount);
1134 newlen = min_t(xfs_off_t, newlen, new_isize);
1135 if (newlen > i_size_read(VFS_I(ip))) {
1136 trace_xfs_reflink_update_inode_size(ip, newlen);
1137 i_size_write(VFS_I(ip), newlen);
1138 ip->i_d.di_size = newlen;
1139 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1140 }
1141
1142
1143 error = xfs_trans_commit(tp);
1144 goto out_unlock;
1145
1146out_cancel:
1147 xfs_trans_cancel(tp);
1148out_unlock:
1149 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1150out:
1151 if (error)
1152 trace_xfs_reflink_remap_extent_error(ip, error, _RET_IP_);
1153 return error;
1154}
1155
1156
1157int
1158xfs_reflink_remap_blocks(
1159 struct xfs_inode *src,
1160 loff_t pos_in,
1161 struct xfs_inode *dest,
1162 loff_t pos_out,
1163 loff_t remap_len,
1164 loff_t *remapped)
1165{
1166 struct xfs_bmbt_irec imap;
1167 struct xfs_mount *mp = src->i_mount;
1168 xfs_fileoff_t srcoff = XFS_B_TO_FSBT(mp, pos_in);
1169 xfs_fileoff_t destoff = XFS_B_TO_FSBT(mp, pos_out);
1170 xfs_filblks_t len;
1171 xfs_filblks_t remapped_len = 0;
1172 xfs_off_t new_isize = pos_out + remap_len;
1173 int nimaps;
1174 int error = 0;
1175
1176 len = min_t(xfs_filblks_t, XFS_B_TO_FSB(mp, remap_len),
1177 XFS_MAX_FILEOFF);
1178
1179 trace_xfs_reflink_remap_blocks(src, srcoff, len, dest, destoff);
1180
1181 while (len > 0) {
1182 unsigned int lock_mode;
1183
1184
1185 nimaps = 1;
1186 lock_mode = xfs_ilock_data_map_shared(src);
1187 error = xfs_bmapi_read(src, srcoff, len, &imap, &nimaps, 0);
1188 xfs_iunlock(src, lock_mode);
1189 if (error)
1190 break;
1191
1192
1193
1194
1195
1196
1197
1198 ASSERT(nimaps == 1 && imap.br_startoff == srcoff);
1199 if (imap.br_startblock == DELAYSTARTBLOCK) {
1200 ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
1201 error = -EFSCORRUPTED;
1202 break;
1203 }
1204
1205 trace_xfs_reflink_remap_extent_src(src, &imap);
1206
1207
1208 imap.br_startoff = destoff;
1209 error = xfs_reflink_remap_extent(dest, &imap, new_isize);
1210 if (error)
1211 break;
1212
1213 if (fatal_signal_pending(current)) {
1214 error = -EINTR;
1215 break;
1216 }
1217
1218
1219 srcoff += imap.br_blockcount;
1220 destoff += imap.br_blockcount;
1221 len -= imap.br_blockcount;
1222 remapped_len += imap.br_blockcount;
1223 }
1224
1225 if (error)
1226 trace_xfs_reflink_remap_blocks_error(dest, error, _RET_IP_);
1227 *remapped = min_t(loff_t, remap_len,
1228 XFS_FSB_TO_B(src->i_mount, remapped_len));
1229 return error;
1230}
1231
1232
1233
1234
1235
1236
1237static int
1238xfs_reflink_zero_posteof(
1239 struct xfs_inode *ip,
1240 loff_t pos)
1241{
1242 loff_t isize = i_size_read(VFS_I(ip));
1243
1244 if (pos <= isize)
1245 return 0;
1246
1247 trace_xfs_zero_eof(ip, isize, pos - isize);
1248 return iomap_zero_range(VFS_I(ip), isize, pos - isize, NULL,
1249 &xfs_buffered_write_iomap_ops);
1250}
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281int
1282xfs_reflink_remap_prep(
1283 struct file *file_in,
1284 loff_t pos_in,
1285 struct file *file_out,
1286 loff_t pos_out,
1287 loff_t *len,
1288 unsigned int remap_flags)
1289{
1290 struct inode *inode_in = file_inode(file_in);
1291 struct xfs_inode *src = XFS_I(inode_in);
1292 struct inode *inode_out = file_inode(file_out);
1293 struct xfs_inode *dest = XFS_I(inode_out);
1294 int ret;
1295
1296
1297 ret = xfs_ilock2_io_mmap(src, dest);
1298 if (ret)
1299 return ret;
1300
1301
1302 ret = -EINVAL;
1303
1304 if (XFS_IS_REALTIME_INODE(src) || XFS_IS_REALTIME_INODE(dest))
1305 goto out_unlock;
1306
1307
1308 if (IS_DAX(inode_in) || IS_DAX(inode_out))
1309 goto out_unlock;
1310
1311 ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
1312 len, remap_flags);
1313 if (ret || *len == 0)
1314 goto out_unlock;
1315
1316
1317 ret = xfs_qm_dqattach(dest);
1318 if (ret)
1319 goto out_unlock;
1320
1321
1322
1323
1324
1325 ret = xfs_reflink_zero_posteof(dest, pos_out);
1326 if (ret)
1327 goto out_unlock;
1328
1329
1330 ret = xfs_reflink_set_inode_flag(src, dest);
1331 if (ret)
1332 goto out_unlock;
1333
1334
1335
1336
1337
1338
1339 if (pos_out > XFS_ISIZE(dest)) {
1340 loff_t flen = *len + (pos_out - XFS_ISIZE(dest));
1341 ret = xfs_flush_unmap_range(dest, XFS_ISIZE(dest), flen);
1342 } else {
1343 ret = xfs_flush_unmap_range(dest, pos_out, *len);
1344 }
1345 if (ret)
1346 goto out_unlock;
1347
1348 return 0;
1349out_unlock:
1350 xfs_iunlock2_io_mmap(src, dest);
1351 return ret;
1352}
1353
1354
1355int
1356xfs_reflink_inode_has_shared_extents(
1357 struct xfs_trans *tp,
1358 struct xfs_inode *ip,
1359 bool *has_shared)
1360{
1361 struct xfs_bmbt_irec got;
1362 struct xfs_mount *mp = ip->i_mount;
1363 struct xfs_ifork *ifp;
1364 xfs_agnumber_t agno;
1365 xfs_agblock_t agbno;
1366 xfs_extlen_t aglen;
1367 xfs_agblock_t rbno;
1368 xfs_extlen_t rlen;
1369 struct xfs_iext_cursor icur;
1370 bool found;
1371 int error;
1372
1373 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1374 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
1375 error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
1376 if (error)
1377 return error;
1378 }
1379
1380 *has_shared = false;
1381 found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got);
1382 while (found) {
1383 if (isnullstartblock(got.br_startblock) ||
1384 got.br_state != XFS_EXT_NORM)
1385 goto next;
1386 agno = XFS_FSB_TO_AGNO(mp, got.br_startblock);
1387 agbno = XFS_FSB_TO_AGBNO(mp, got.br_startblock);
1388 aglen = got.br_blockcount;
1389
1390 error = xfs_reflink_find_shared(mp, tp, agno, agbno, aglen,
1391 &rbno, &rlen, false);
1392 if (error)
1393 return error;
1394
1395 if (rbno != NULLAGBLOCK) {
1396 *has_shared = true;
1397 return 0;
1398 }
1399next:
1400 found = xfs_iext_next_extent(ifp, &icur, &got);
1401 }
1402
1403 return 0;
1404}
1405
1406
1407
1408
1409
1410
1411
1412int
1413xfs_reflink_clear_inode_flag(
1414 struct xfs_inode *ip,
1415 struct xfs_trans **tpp)
1416{
1417 bool needs_flag;
1418 int error = 0;
1419
1420 ASSERT(xfs_is_reflink_inode(ip));
1421
1422 error = xfs_reflink_inode_has_shared_extents(*tpp, ip, &needs_flag);
1423 if (error || needs_flag)
1424 return error;
1425
1426
1427
1428
1429
1430 error = xfs_reflink_cancel_cow_blocks(ip, tpp, 0, XFS_MAX_FILEOFF,
1431 true);
1432 if (error)
1433 return error;
1434
1435
1436 trace_xfs_reflink_unset_inode_flag(ip);
1437 ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1438 xfs_inode_clear_cowblocks_tag(ip);
1439 xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
1440
1441 return error;
1442}
1443
1444
1445
1446
1447
1448STATIC int
1449xfs_reflink_try_clear_inode_flag(
1450 struct xfs_inode *ip)
1451{
1452 struct xfs_mount *mp = ip->i_mount;
1453 struct xfs_trans *tp;
1454 int error = 0;
1455
1456
1457 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
1458 if (error)
1459 return error;
1460
1461 xfs_ilock(ip, XFS_ILOCK_EXCL);
1462 xfs_trans_ijoin(tp, ip, 0);
1463
1464 error = xfs_reflink_clear_inode_flag(ip, &tp);
1465 if (error)
1466 goto cancel;
1467
1468 error = xfs_trans_commit(tp);
1469 if (error)
1470 goto out;
1471
1472 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1473 return 0;
1474cancel:
1475 xfs_trans_cancel(tp);
1476out:
1477 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1478 return error;
1479}
1480
1481
1482
1483
1484
1485int
1486xfs_reflink_unshare(
1487 struct xfs_inode *ip,
1488 xfs_off_t offset,
1489 xfs_off_t len)
1490{
1491 struct inode *inode = VFS_I(ip);
1492 int error;
1493
1494 if (!xfs_is_reflink_inode(ip))
1495 return 0;
1496
1497 trace_xfs_reflink_unshare(ip, offset, len);
1498
1499 inode_dio_wait(inode);
1500
1501 error = iomap_file_unshare(inode, offset, len,
1502 &xfs_buffered_write_iomap_ops);
1503 if (error)
1504 goto out;
1505
1506 error = filemap_write_and_wait_range(inode->i_mapping, offset,
1507 offset + len - 1);
1508 if (error)
1509 goto out;
1510
1511
1512 error = xfs_reflink_try_clear_inode_flag(ip);
1513 if (error)
1514 goto out;
1515 return 0;
1516
1517out:
1518 trace_xfs_reflink_unshare_error(ip, error, _RET_IP_);
1519 return error;
1520}
1521