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 *lockmode = 0;
380
381 error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write, resblks, 0,
382 false, &tp);
383 if (error)
384 return error;
385
386 *lockmode = XFS_ILOCK_EXCL;
387
388
389
390
391 error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found);
392 if (error || !*shared)
393 goto out_trans_cancel;
394 if (found) {
395 xfs_trans_cancel(tp);
396 goto convert;
397 }
398
399
400 nimaps = 1;
401 error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount,
402 XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, 0, cmap,
403 &nimaps);
404 if (error)
405 goto out_trans_cancel;
406
407 xfs_inode_set_cowblocks_tag(ip);
408 error = xfs_trans_commit(tp);
409 if (error)
410 return error;
411
412
413
414
415
416 if (nimaps == 0)
417 return -ENOSPC;
418convert:
419 xfs_trim_extent(cmap, offset_fsb, count_fsb);
420
421
422
423
424
425 if (!convert_now || cmap->br_state == XFS_EXT_NORM)
426 return 0;
427 trace_xfs_reflink_convert_cow(ip, cmap);
428 return xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb);
429
430out_trans_cancel:
431 xfs_trans_cancel(tp);
432 return error;
433}
434
435
436
437
438
439
440
441
442
443
444int
445xfs_reflink_cancel_cow_blocks(
446 struct xfs_inode *ip,
447 struct xfs_trans **tpp,
448 xfs_fileoff_t offset_fsb,
449 xfs_fileoff_t end_fsb,
450 bool cancel_real)
451{
452 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
453 struct xfs_bmbt_irec got, del;
454 struct xfs_iext_cursor icur;
455 int error = 0;
456
457 if (!xfs_inode_has_cow_data(ip))
458 return 0;
459 if (!xfs_iext_lookup_extent_before(ip, ifp, &end_fsb, &icur, &got))
460 return 0;
461
462
463 while (got.br_startoff + got.br_blockcount > offset_fsb) {
464 del = got;
465 xfs_trim_extent(&del, offset_fsb, end_fsb - offset_fsb);
466
467
468 if (!del.br_blockcount) {
469 xfs_iext_prev(ifp, &icur);
470 goto next_extent;
471 }
472
473 trace_xfs_reflink_cancel_cow(ip, &del);
474
475 if (isnullstartblock(del.br_startblock)) {
476 error = xfs_bmap_del_extent_delay(ip, XFS_COW_FORK,
477 &icur, &got, &del);
478 if (error)
479 break;
480 } else if (del.br_state == XFS_EXT_UNWRITTEN || cancel_real) {
481 ASSERT((*tpp)->t_firstblock == NULLFSBLOCK);
482
483
484 xfs_refcount_free_cow_extent(*tpp, del.br_startblock,
485 del.br_blockcount);
486
487 xfs_bmap_add_free(*tpp, del.br_startblock,
488 del.br_blockcount, NULL);
489
490
491 error = xfs_defer_finish(tpp);
492 if (error)
493 break;
494
495
496 xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
497
498
499 error = xfs_quota_unreserve_blkres(ip,
500 del.br_blockcount);
501 if (error)
502 break;
503 } else {
504
505 xfs_iext_prev(ifp, &icur);
506 }
507next_extent:
508 if (!xfs_iext_get_extent(ifp, &icur, &got))
509 break;
510 }
511
512
513 if (!ifp->if_bytes)
514 xfs_inode_clear_cowblocks_tag(ip);
515 return error;
516}
517
518
519
520
521
522
523
524int
525xfs_reflink_cancel_cow_range(
526 struct xfs_inode *ip,
527 xfs_off_t offset,
528 xfs_off_t count,
529 bool cancel_real)
530{
531 struct xfs_trans *tp;
532 xfs_fileoff_t offset_fsb;
533 xfs_fileoff_t end_fsb;
534 int error;
535
536 trace_xfs_reflink_cancel_cow_range(ip, offset, count);
537 ASSERT(ip->i_cowfp);
538
539 offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
540 if (count == NULLFILEOFF)
541 end_fsb = NULLFILEOFF;
542 else
543 end_fsb = XFS_B_TO_FSB(ip->i_mount, offset + count);
544
545
546 error = xfs_trans_alloc(ip->i_mount, &M_RES(ip->i_mount)->tr_write,
547 0, 0, 0, &tp);
548 if (error)
549 goto out;
550
551 xfs_ilock(ip, XFS_ILOCK_EXCL);
552 xfs_trans_ijoin(tp, ip, 0);
553
554
555 error = xfs_reflink_cancel_cow_blocks(ip, &tp, offset_fsb, end_fsb,
556 cancel_real);
557 if (error)
558 goto out_cancel;
559
560 error = xfs_trans_commit(tp);
561
562 xfs_iunlock(ip, XFS_ILOCK_EXCL);
563 return error;
564
565out_cancel:
566 xfs_trans_cancel(tp);
567 xfs_iunlock(ip, XFS_ILOCK_EXCL);
568out:
569 trace_xfs_reflink_cancel_cow_range_error(ip, error, _RET_IP_);
570 return error;
571}
572
573
574
575
576
577
578
579
580
581
582
583STATIC int
584xfs_reflink_end_cow_extent(
585 struct xfs_inode *ip,
586 xfs_fileoff_t offset_fsb,
587 xfs_fileoff_t *end_fsb)
588{
589 struct xfs_bmbt_irec got, del;
590 struct xfs_iext_cursor icur;
591 struct xfs_mount *mp = ip->i_mount;
592 struct xfs_trans *tp;
593 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
594 xfs_filblks_t rlen;
595 unsigned int resblks;
596 int error;
597
598
599 if (ifp->if_bytes == 0) {
600 *end_fsb = offset_fsb;
601 return 0;
602 }
603
604 resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
605 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0,
606 XFS_TRANS_RESERVE, &tp);
607 if (error)
608 return error;
609
610
611
612
613
614
615 xfs_ilock(ip, XFS_ILOCK_EXCL);
616 xfs_trans_ijoin(tp, ip, 0);
617
618 error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
619 XFS_IEXT_REFLINK_END_COW_CNT);
620 if (error)
621 goto out_cancel;
622
623
624
625
626
627
628 if (!xfs_iext_lookup_extent_before(ip, ifp, end_fsb, &icur, &got) ||
629 got.br_startoff + got.br_blockcount <= offset_fsb) {
630 *end_fsb = offset_fsb;
631 goto out_cancel;
632 }
633
634
635
636
637
638
639
640 del = got;
641 xfs_trim_extent(&del, offset_fsb, *end_fsb - offset_fsb);
642
643 ASSERT(del.br_blockcount > 0);
644
645
646
647
648
649
650 if (!xfs_bmap_is_written_extent(&got)) {
651 *end_fsb = del.br_startoff;
652 goto out_cancel;
653 }
654
655
656 rlen = del.br_blockcount;
657 error = __xfs_bunmapi(tp, ip, del.br_startoff, &rlen, 0, 1);
658 if (error)
659 goto out_cancel;
660
661
662 xfs_trim_extent(&del, del.br_startoff + rlen, del.br_blockcount - rlen);
663 trace_xfs_reflink_cow_remap(ip, &del);
664
665
666 xfs_refcount_free_cow_extent(tp, del.br_startblock, del.br_blockcount);
667
668
669 xfs_bmap_map_extent(tp, ip, &del);
670
671
672 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_DELBCOUNT,
673 (long)del.br_blockcount);
674
675
676 xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
677
678 error = xfs_trans_commit(tp);
679 xfs_iunlock(ip, XFS_ILOCK_EXCL);
680 if (error)
681 return error;
682
683
684 *end_fsb = del.br_startoff;
685 return 0;
686
687out_cancel:
688 xfs_trans_cancel(tp);
689 xfs_iunlock(ip, XFS_ILOCK_EXCL);
690 return error;
691}
692
693
694
695
696int
697xfs_reflink_end_cow(
698 struct xfs_inode *ip,
699 xfs_off_t offset,
700 xfs_off_t count)
701{
702 xfs_fileoff_t offset_fsb;
703 xfs_fileoff_t end_fsb;
704 int error = 0;
705
706 trace_xfs_reflink_end_cow(ip, offset, count);
707
708 offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
709 end_fsb = XFS_B_TO_FSB(ip->i_mount, offset + count);
710
711
712
713
714
715
716
717
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 while (end_fsb > offset_fsb && !error)
744 error = xfs_reflink_end_cow_extent(ip, offset_fsb, &end_fsb);
745
746 if (error)
747 trace_xfs_reflink_end_cow_error(ip, error, _RET_IP_);
748 return error;
749}
750
751
752
753
754int
755xfs_reflink_recover_cow(
756 struct xfs_mount *mp)
757{
758 xfs_agnumber_t agno;
759 int error = 0;
760
761 if (!xfs_sb_version_hasreflink(&mp->m_sb))
762 return 0;
763
764 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
765 error = xfs_refcount_recover_cow_leftovers(mp, agno);
766 if (error)
767 break;
768 }
769
770 return error;
771}
772
773
774
775
776
777
778
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
852STATIC int
853xfs_reflink_set_inode_flag(
854 struct xfs_inode *src,
855 struct xfs_inode *dest)
856{
857 struct xfs_mount *mp = src->i_mount;
858 int error;
859 struct xfs_trans *tp;
860
861 if (xfs_is_reflink_inode(src) && xfs_is_reflink_inode(dest))
862 return 0;
863
864 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
865 if (error)
866 goto out_error;
867
868
869 if (src->i_ino == dest->i_ino)
870 xfs_ilock(src, XFS_ILOCK_EXCL);
871 else
872 xfs_lock_two_inodes(src, XFS_ILOCK_EXCL, dest, XFS_ILOCK_EXCL);
873
874 if (!xfs_is_reflink_inode(src)) {
875 trace_xfs_reflink_set_inode_flag(src);
876 xfs_trans_ijoin(tp, src, XFS_ILOCK_EXCL);
877 src->i_diflags2 |= XFS_DIFLAG2_REFLINK;
878 xfs_trans_log_inode(tp, src, XFS_ILOG_CORE);
879 xfs_ifork_init_cow(src);
880 } else
881 xfs_iunlock(src, XFS_ILOCK_EXCL);
882
883 if (src->i_ino == dest->i_ino)
884 goto commit_flags;
885
886 if (!xfs_is_reflink_inode(dest)) {
887 trace_xfs_reflink_set_inode_flag(dest);
888 xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL);
889 dest->i_diflags2 |= XFS_DIFLAG2_REFLINK;
890 xfs_trans_log_inode(tp, dest, XFS_ILOG_CORE);
891 xfs_ifork_init_cow(dest);
892 } else
893 xfs_iunlock(dest, XFS_ILOCK_EXCL);
894
895commit_flags:
896 error = xfs_trans_commit(tp);
897 if (error)
898 goto out_error;
899 return error;
900
901out_error:
902 trace_xfs_reflink_set_inode_flag_error(dest, error, _RET_IP_);
903 return error;
904}
905
906
907
908
909int
910xfs_reflink_update_dest(
911 struct xfs_inode *dest,
912 xfs_off_t newlen,
913 xfs_extlen_t cowextsize,
914 unsigned int remap_flags)
915{
916 struct xfs_mount *mp = dest->i_mount;
917 struct xfs_trans *tp;
918 int error;
919
920 if (newlen <= i_size_read(VFS_I(dest)) && cowextsize == 0)
921 return 0;
922
923 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
924 if (error)
925 goto out_error;
926
927 xfs_ilock(dest, XFS_ILOCK_EXCL);
928 xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL);
929
930 if (newlen > i_size_read(VFS_I(dest))) {
931 trace_xfs_reflink_update_inode_size(dest, newlen);
932 i_size_write(VFS_I(dest), newlen);
933 dest->i_disk_size = newlen;
934 }
935
936 if (cowextsize) {
937 dest->i_cowextsize = cowextsize;
938 dest->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE;
939 }
940
941 xfs_trans_log_inode(tp, dest, XFS_ILOG_CORE);
942
943 error = xfs_trans_commit(tp);
944 if (error)
945 goto out_error;
946 return error;
947
948out_error:
949 trace_xfs_reflink_update_inode_size_error(dest, error, _RET_IP_);
950 return error;
951}
952
953
954
955
956
957
958
959static int
960xfs_reflink_ag_has_free_space(
961 struct xfs_mount *mp,
962 xfs_agnumber_t agno)
963{
964 struct xfs_perag *pag;
965 int error = 0;
966
967 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
968 return 0;
969
970 pag = xfs_perag_get(mp, agno);
971 if (xfs_ag_resv_critical(pag, XFS_AG_RESV_RMAPBT) ||
972 xfs_ag_resv_critical(pag, XFS_AG_RESV_METADATA))
973 error = -ENOSPC;
974 xfs_perag_put(pag);
975 return error;
976}
977
978
979
980
981
982STATIC int
983xfs_reflink_remap_extent(
984 struct xfs_inode *ip,
985 struct xfs_bmbt_irec *dmap,
986 xfs_off_t new_isize)
987{
988 struct xfs_bmbt_irec smap;
989 struct xfs_mount *mp = ip->i_mount;
990 struct xfs_trans *tp;
991 xfs_off_t newlen;
992 int64_t qdelta = 0;
993 unsigned int resblks;
994 bool quota_reserved = true;
995 bool smap_real;
996 bool dmap_written = xfs_bmap_is_written_extent(dmap);
997 int iext_delta = 0;
998 int nimaps;
999 int error;
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022 resblks = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
1023 error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write,
1024 resblks + dmap->br_blockcount, 0, false, &tp);
1025 if (error == -EDQUOT || error == -ENOSPC) {
1026 quota_reserved = false;
1027 error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write,
1028 resblks, 0, false, &tp);
1029 }
1030 if (error)
1031 goto out;
1032
1033
1034
1035
1036
1037
1038 nimaps = 1;
1039 error = xfs_bmapi_read(ip, dmap->br_startoff, dmap->br_blockcount,
1040 &smap, &nimaps, 0);
1041 if (error)
1042 goto out_cancel;
1043 ASSERT(nimaps == 1 && smap.br_startoff == dmap->br_startoff);
1044 smap_real = xfs_bmap_is_real_extent(&smap);
1045
1046
1047
1048
1049
1050 dmap->br_blockcount = min(dmap->br_blockcount, smap.br_blockcount);
1051 ASSERT(dmap->br_blockcount == smap.br_blockcount);
1052
1053 trace_xfs_reflink_remap_extent_dest(ip, &smap);
1054
1055
1056
1057
1058
1059
1060 if (dmap->br_startblock == smap.br_startblock) {
1061 if (dmap->br_state != smap.br_state)
1062 error = -EFSCORRUPTED;
1063 goto out_cancel;
1064 }
1065
1066
1067 if (dmap->br_state == XFS_EXT_UNWRITTEN &&
1068 smap.br_state == XFS_EXT_UNWRITTEN)
1069 goto out_cancel;
1070
1071
1072 if (dmap_written) {
1073 error = xfs_reflink_ag_has_free_space(mp,
1074 XFS_FSB_TO_AGNO(mp, dmap->br_startblock));
1075 if (error)
1076 goto out_cancel;
1077 }
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101 if (!quota_reserved && !smap_real && dmap_written) {
1102 error = xfs_trans_reserve_quota_nblks(tp, ip,
1103 dmap->br_blockcount, 0, false);
1104 if (error)
1105 goto out_cancel;
1106 }
1107
1108 if (smap_real)
1109 ++iext_delta;
1110
1111 if (dmap_written)
1112 ++iext_delta;
1113
1114 error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK, iext_delta);
1115 if (error)
1116 goto out_cancel;
1117
1118 if (smap_real) {
1119
1120
1121
1122
1123 xfs_bmap_unmap_extent(tp, ip, &smap);
1124 xfs_refcount_decrease_extent(tp, &smap);
1125 qdelta -= smap.br_blockcount;
1126 } else if (smap.br_startblock == DELAYSTARTBLOCK) {
1127 xfs_filblks_t len = smap.br_blockcount;
1128
1129
1130
1131
1132
1133
1134
1135 error = __xfs_bunmapi(NULL, ip, smap.br_startoff, &len, 0, 1);
1136 if (error)
1137 goto out_cancel;
1138 ASSERT(len == 0);
1139 }
1140
1141
1142
1143
1144
1145 if (dmap_written) {
1146 xfs_refcount_increase_extent(tp, dmap);
1147 xfs_bmap_map_extent(tp, ip, dmap);
1148 qdelta += dmap->br_blockcount;
1149 }
1150
1151 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, qdelta);
1152
1153
1154 newlen = XFS_FSB_TO_B(mp, dmap->br_startoff + dmap->br_blockcount);
1155 newlen = min_t(xfs_off_t, newlen, new_isize);
1156 if (newlen > i_size_read(VFS_I(ip))) {
1157 trace_xfs_reflink_update_inode_size(ip, newlen);
1158 i_size_write(VFS_I(ip), newlen);
1159 ip->i_disk_size = newlen;
1160 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1161 }
1162
1163
1164 error = xfs_trans_commit(tp);
1165 goto out_unlock;
1166
1167out_cancel:
1168 xfs_trans_cancel(tp);
1169out_unlock:
1170 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1171out:
1172 if (error)
1173 trace_xfs_reflink_remap_extent_error(ip, error, _RET_IP_);
1174 return error;
1175}
1176
1177
1178int
1179xfs_reflink_remap_blocks(
1180 struct xfs_inode *src,
1181 loff_t pos_in,
1182 struct xfs_inode *dest,
1183 loff_t pos_out,
1184 loff_t remap_len,
1185 loff_t *remapped)
1186{
1187 struct xfs_bmbt_irec imap;
1188 struct xfs_mount *mp = src->i_mount;
1189 xfs_fileoff_t srcoff = XFS_B_TO_FSBT(mp, pos_in);
1190 xfs_fileoff_t destoff = XFS_B_TO_FSBT(mp, pos_out);
1191 xfs_filblks_t len;
1192 xfs_filblks_t remapped_len = 0;
1193 xfs_off_t new_isize = pos_out + remap_len;
1194 int nimaps;
1195 int error = 0;
1196
1197 len = min_t(xfs_filblks_t, XFS_B_TO_FSB(mp, remap_len),
1198 XFS_MAX_FILEOFF);
1199
1200 trace_xfs_reflink_remap_blocks(src, srcoff, len, dest, destoff);
1201
1202 while (len > 0) {
1203 unsigned int lock_mode;
1204
1205
1206 nimaps = 1;
1207 lock_mode = xfs_ilock_data_map_shared(src);
1208 error = xfs_bmapi_read(src, srcoff, len, &imap, &nimaps, 0);
1209 xfs_iunlock(src, lock_mode);
1210 if (error)
1211 break;
1212
1213
1214
1215
1216
1217
1218
1219 ASSERT(nimaps == 1 && imap.br_startoff == srcoff);
1220 if (imap.br_startblock == DELAYSTARTBLOCK) {
1221 ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
1222 error = -EFSCORRUPTED;
1223 break;
1224 }
1225
1226 trace_xfs_reflink_remap_extent_src(src, &imap);
1227
1228
1229 imap.br_startoff = destoff;
1230 error = xfs_reflink_remap_extent(dest, &imap, new_isize);
1231 if (error)
1232 break;
1233
1234 if (fatal_signal_pending(current)) {
1235 error = -EINTR;
1236 break;
1237 }
1238
1239
1240 srcoff += imap.br_blockcount;
1241 destoff += imap.br_blockcount;
1242 len -= imap.br_blockcount;
1243 remapped_len += imap.br_blockcount;
1244 }
1245
1246 if (error)
1247 trace_xfs_reflink_remap_blocks_error(dest, error, _RET_IP_);
1248 *remapped = min_t(loff_t, remap_len,
1249 XFS_FSB_TO_B(src->i_mount, remapped_len));
1250 return error;
1251}
1252
1253
1254
1255
1256
1257
1258static int
1259xfs_reflink_zero_posteof(
1260 struct xfs_inode *ip,
1261 loff_t pos)
1262{
1263 loff_t isize = i_size_read(VFS_I(ip));
1264
1265 if (pos <= isize)
1266 return 0;
1267
1268 trace_xfs_zero_eof(ip, isize, pos - isize);
1269 return iomap_zero_range(VFS_I(ip), isize, pos - isize, NULL,
1270 &xfs_buffered_write_iomap_ops);
1271}
1272
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
1302int
1303xfs_reflink_remap_prep(
1304 struct file *file_in,
1305 loff_t pos_in,
1306 struct file *file_out,
1307 loff_t pos_out,
1308 loff_t *len,
1309 unsigned int remap_flags)
1310{
1311 struct inode *inode_in = file_inode(file_in);
1312 struct xfs_inode *src = XFS_I(inode_in);
1313 struct inode *inode_out = file_inode(file_out);
1314 struct xfs_inode *dest = XFS_I(inode_out);
1315 int ret;
1316
1317
1318 ret = xfs_ilock2_io_mmap(src, dest);
1319 if (ret)
1320 return ret;
1321
1322
1323 ret = -EINVAL;
1324
1325 if (XFS_IS_REALTIME_INODE(src) || XFS_IS_REALTIME_INODE(dest))
1326 goto out_unlock;
1327
1328
1329 if (IS_DAX(inode_in) || IS_DAX(inode_out))
1330 goto out_unlock;
1331
1332 ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out,
1333 len, remap_flags);
1334 if (ret || *len == 0)
1335 goto out_unlock;
1336
1337
1338 ret = xfs_qm_dqattach(dest);
1339 if (ret)
1340 goto out_unlock;
1341
1342
1343
1344
1345
1346 ret = xfs_reflink_zero_posteof(dest, pos_out);
1347 if (ret)
1348 goto out_unlock;
1349
1350
1351 ret = xfs_reflink_set_inode_flag(src, dest);
1352 if (ret)
1353 goto out_unlock;
1354
1355
1356
1357
1358
1359
1360 if (pos_out > XFS_ISIZE(dest)) {
1361 loff_t flen = *len + (pos_out - XFS_ISIZE(dest));
1362 ret = xfs_flush_unmap_range(dest, XFS_ISIZE(dest), flen);
1363 } else {
1364 ret = xfs_flush_unmap_range(dest, pos_out, *len);
1365 }
1366 if (ret)
1367 goto out_unlock;
1368
1369 return 0;
1370out_unlock:
1371 xfs_iunlock2_io_mmap(src, dest);
1372 return ret;
1373}
1374
1375
1376int
1377xfs_reflink_inode_has_shared_extents(
1378 struct xfs_trans *tp,
1379 struct xfs_inode *ip,
1380 bool *has_shared)
1381{
1382 struct xfs_bmbt_irec got;
1383 struct xfs_mount *mp = ip->i_mount;
1384 struct xfs_ifork *ifp;
1385 xfs_agnumber_t agno;
1386 xfs_agblock_t agbno;
1387 xfs_extlen_t aglen;
1388 xfs_agblock_t rbno;
1389 xfs_extlen_t rlen;
1390 struct xfs_iext_cursor icur;
1391 bool found;
1392 int error;
1393
1394 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1395 error = xfs_iread_extents(tp, ip, XFS_DATA_FORK);
1396 if (error)
1397 return error;
1398
1399 *has_shared = false;
1400 found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got);
1401 while (found) {
1402 if (isnullstartblock(got.br_startblock) ||
1403 got.br_state != XFS_EXT_NORM)
1404 goto next;
1405 agno = XFS_FSB_TO_AGNO(mp, got.br_startblock);
1406 agbno = XFS_FSB_TO_AGBNO(mp, got.br_startblock);
1407 aglen = got.br_blockcount;
1408
1409 error = xfs_reflink_find_shared(mp, tp, agno, agbno, aglen,
1410 &rbno, &rlen, false);
1411 if (error)
1412 return error;
1413
1414 if (rbno != NULLAGBLOCK) {
1415 *has_shared = true;
1416 return 0;
1417 }
1418next:
1419 found = xfs_iext_next_extent(ifp, &icur, &got);
1420 }
1421
1422 return 0;
1423}
1424
1425
1426
1427
1428
1429
1430
1431int
1432xfs_reflink_clear_inode_flag(
1433 struct xfs_inode *ip,
1434 struct xfs_trans **tpp)
1435{
1436 bool needs_flag;
1437 int error = 0;
1438
1439 ASSERT(xfs_is_reflink_inode(ip));
1440
1441 error = xfs_reflink_inode_has_shared_extents(*tpp, ip, &needs_flag);
1442 if (error || needs_flag)
1443 return error;
1444
1445
1446
1447
1448
1449 error = xfs_reflink_cancel_cow_blocks(ip, tpp, 0, XFS_MAX_FILEOFF,
1450 true);
1451 if (error)
1452 return error;
1453
1454
1455 trace_xfs_reflink_unset_inode_flag(ip);
1456 ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
1457 xfs_inode_clear_cowblocks_tag(ip);
1458 xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
1459
1460 return error;
1461}
1462
1463
1464
1465
1466
1467STATIC int
1468xfs_reflink_try_clear_inode_flag(
1469 struct xfs_inode *ip)
1470{
1471 struct xfs_mount *mp = ip->i_mount;
1472 struct xfs_trans *tp;
1473 int error = 0;
1474
1475
1476 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
1477 if (error)
1478 return error;
1479
1480 xfs_ilock(ip, XFS_ILOCK_EXCL);
1481 xfs_trans_ijoin(tp, ip, 0);
1482
1483 error = xfs_reflink_clear_inode_flag(ip, &tp);
1484 if (error)
1485 goto cancel;
1486
1487 error = xfs_trans_commit(tp);
1488 if (error)
1489 goto out;
1490
1491 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1492 return 0;
1493cancel:
1494 xfs_trans_cancel(tp);
1495out:
1496 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1497 return error;
1498}
1499
1500
1501
1502
1503
1504int
1505xfs_reflink_unshare(
1506 struct xfs_inode *ip,
1507 xfs_off_t offset,
1508 xfs_off_t len)
1509{
1510 struct inode *inode = VFS_I(ip);
1511 int error;
1512
1513 if (!xfs_is_reflink_inode(ip))
1514 return 0;
1515
1516 trace_xfs_reflink_unshare(ip, offset, len);
1517
1518 inode_dio_wait(inode);
1519
1520 error = iomap_file_unshare(inode, offset, len,
1521 &xfs_buffered_write_iomap_ops);
1522 if (error)
1523 goto out;
1524
1525 error = filemap_write_and_wait_range(inode->i_mapping, offset,
1526 offset + len - 1);
1527 if (error)
1528 goto out;
1529
1530
1531 error = xfs_reflink_try_clear_inode_flag(ip);
1532 if (error)
1533 goto out;
1534 return 0;
1535
1536out:
1537 trace_xfs_reflink_unshare_error(ip, error, _RET_IP_);
1538 return error;
1539}
1540