40
40
#include "xfs_bmap_item.h"
41
41
#include "xfs_symlink_remote.h"
42
42
#include "xfs_inode_util.h"
43
+ #include "xfs_rtgroup.h"
43
44
44
45
struct kmem_cache * xfs_bmap_intent_cache ;
45
46
@@ -1426,6 +1427,24 @@ xfs_bmap_last_offset(
1426
1427
* Extent tree manipulation functions used during allocation.
1427
1428
*/
1428
1429
1430
+ static inline bool
1431
+ xfs_bmap_same_rtgroup (
1432
+ struct xfs_inode * ip ,
1433
+ int whichfork ,
1434
+ struct xfs_bmbt_irec * left ,
1435
+ struct xfs_bmbt_irec * right )
1436
+ {
1437
+ struct xfs_mount * mp = ip -> i_mount ;
1438
+
1439
+ if (xfs_ifork_is_realtime (ip , whichfork ) && xfs_has_rtgroups (mp )) {
1440
+ if (xfs_rtb_to_rgno (mp , left -> br_startblock ) !=
1441
+ xfs_rtb_to_rgno (mp , right -> br_startblock ))
1442
+ return false;
1443
+ }
1444
+
1445
+ return true;
1446
+ }
1447
+
1429
1448
/*
1430
1449
* Convert a delayed allocation to a real allocation.
1431
1450
*/
@@ -1495,7 +1514,8 @@ xfs_bmap_add_extent_delay_real(
1495
1514
LEFT .br_startoff + LEFT .br_blockcount == new -> br_startoff &&
1496
1515
LEFT .br_startblock + LEFT .br_blockcount == new -> br_startblock &&
1497
1516
LEFT .br_state == new -> br_state &&
1498
- LEFT .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN )
1517
+ LEFT .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
1518
+ xfs_bmap_same_rtgroup (bma -> ip , whichfork , & LEFT , new ))
1499
1519
state |= BMAP_LEFT_CONTIG ;
1500
1520
1501
1521
/*
@@ -1519,7 +1539,8 @@ xfs_bmap_add_extent_delay_real(
1519
1539
(BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
1520
1540
BMAP_RIGHT_FILLING ) ||
1521
1541
LEFT .br_blockcount + new -> br_blockcount + RIGHT .br_blockcount
1522
- <= XFS_MAX_BMBT_EXTLEN ))
1542
+ <= XFS_MAX_BMBT_EXTLEN ) &&
1543
+ xfs_bmap_same_rtgroup (bma -> ip , whichfork , new , & RIGHT ))
1523
1544
state |= BMAP_RIGHT_CONTIG ;
1524
1545
1525
1546
error = 0 ;
@@ -2064,7 +2085,8 @@ xfs_bmap_add_extent_unwritten_real(
2064
2085
LEFT .br_startoff + LEFT .br_blockcount == new -> br_startoff &&
2065
2086
LEFT .br_startblock + LEFT .br_blockcount == new -> br_startblock &&
2066
2087
LEFT .br_state == new -> br_state &&
2067
- LEFT .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN )
2088
+ LEFT .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
2089
+ xfs_bmap_same_rtgroup (ip , whichfork , & LEFT , new ))
2068
2090
state |= BMAP_LEFT_CONTIG ;
2069
2091
2070
2092
/*
@@ -2088,7 +2110,8 @@ xfs_bmap_add_extent_unwritten_real(
2088
2110
(BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
2089
2111
BMAP_RIGHT_FILLING ) ||
2090
2112
LEFT .br_blockcount + new -> br_blockcount + RIGHT .br_blockcount
2091
- <= XFS_MAX_BMBT_EXTLEN ))
2113
+ <= XFS_MAX_BMBT_EXTLEN ) &&
2114
+ xfs_bmap_same_rtgroup (ip , whichfork , new , & RIGHT ))
2092
2115
state |= BMAP_RIGHT_CONTIG ;
2093
2116
2094
2117
/*
@@ -2597,15 +2620,17 @@ xfs_bmap_add_extent_hole_delay(
2597
2620
*/
2598
2621
if ((state & BMAP_LEFT_VALID ) && (state & BMAP_LEFT_DELAY ) &&
2599
2622
left .br_startoff + left .br_blockcount == new -> br_startoff &&
2600
- left .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN )
2623
+ left .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
2624
+ xfs_bmap_same_rtgroup (ip , whichfork , & left , new ))
2601
2625
state |= BMAP_LEFT_CONTIG ;
2602
2626
2603
2627
if ((state & BMAP_RIGHT_VALID ) && (state & BMAP_RIGHT_DELAY ) &&
2604
2628
new -> br_startoff + new -> br_blockcount == right .br_startoff &&
2605
2629
new -> br_blockcount + right .br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
2606
2630
(!(state & BMAP_LEFT_CONTIG ) ||
2607
2631
(left .br_blockcount + new -> br_blockcount +
2608
- right .br_blockcount <= XFS_MAX_BMBT_EXTLEN )))
2632
+ right .br_blockcount <= XFS_MAX_BMBT_EXTLEN )) &&
2633
+ xfs_bmap_same_rtgroup (ip , whichfork , new , & right ))
2609
2634
state |= BMAP_RIGHT_CONTIG ;
2610
2635
2611
2636
/*
@@ -2748,7 +2773,8 @@ xfs_bmap_add_extent_hole_real(
2748
2773
left .br_startoff + left .br_blockcount == new -> br_startoff &&
2749
2774
left .br_startblock + left .br_blockcount == new -> br_startblock &&
2750
2775
left .br_state == new -> br_state &&
2751
- left .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN )
2776
+ left .br_blockcount + new -> br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
2777
+ xfs_bmap_same_rtgroup (ip , whichfork , & left , new ))
2752
2778
state |= BMAP_LEFT_CONTIG ;
2753
2779
2754
2780
if ((state & BMAP_RIGHT_VALID ) && !(state & BMAP_RIGHT_DELAY ) &&
@@ -2758,7 +2784,8 @@ xfs_bmap_add_extent_hole_real(
2758
2784
new -> br_blockcount + right .br_blockcount <= XFS_MAX_BMBT_EXTLEN &&
2759
2785
(!(state & BMAP_LEFT_CONTIG ) ||
2760
2786
left .br_blockcount + new -> br_blockcount +
2761
- right .br_blockcount <= XFS_MAX_BMBT_EXTLEN ))
2787
+ right .br_blockcount <= XFS_MAX_BMBT_EXTLEN ) &&
2788
+ xfs_bmap_same_rtgroup (ip , whichfork , new , & right ))
2762
2789
state |= BMAP_RIGHT_CONTIG ;
2763
2790
2764
2791
error = 0 ;
@@ -3124,8 +3151,15 @@ xfs_bmap_adjacent_valid(
3124
3151
struct xfs_mount * mp = ap -> ip -> i_mount ;
3125
3152
3126
3153
if (XFS_IS_REALTIME_INODE (ap -> ip ) &&
3127
- (ap -> datatype & XFS_ALLOC_USERDATA ))
3128
- return x < mp -> m_sb .sb_rblocks ;
3154
+ (ap -> datatype & XFS_ALLOC_USERDATA )) {
3155
+ if (!xfs_has_rtgroups (mp ))
3156
+ return x < mp -> m_sb .sb_rblocks ;
3157
+
3158
+ return xfs_rtb_to_rgno (mp , x ) == xfs_rtb_to_rgno (mp , y ) &&
3159
+ xfs_rtb_to_rgno (mp , x ) < mp -> m_sb .sb_rgcount &&
3160
+ xfs_rtb_to_rtx (mp , x ) < mp -> m_sb .sb_rgextents ;
3161
+
3162
+ }
3129
3163
3130
3164
return XFS_FSB_TO_AGNO (mp , x ) == XFS_FSB_TO_AGNO (mp , y ) &&
3131
3165
XFS_FSB_TO_AGNO (mp , x ) < mp -> m_sb .sb_agcount &&
@@ -5356,9 +5390,11 @@ xfs_bmap_del_extent_real(
5356
5390
* If we need to, add to list of extents to delete.
5357
5391
*/
5358
5392
if (!(bflags & XFS_BMAPI_REMAP )) {
5393
+ bool isrt = xfs_ifork_is_realtime (ip , whichfork );
5394
+
5359
5395
if (xfs_is_reflink_inode (ip ) && whichfork == XFS_DATA_FORK ) {
5360
5396
xfs_refcount_decrease_extent (tp , del );
5361
- } else if (xfs_ifork_is_realtime ( ip , whichfork )) {
5397
+ } else if (isrt && ! xfs_has_rtgroups ( mp )) {
5362
5398
error = xfs_bmap_free_rtblocks (tp , del );
5363
5399
} else {
5364
5400
unsigned int efi_flags = 0 ;
@@ -5367,6 +5403,19 @@ xfs_bmap_del_extent_real(
5367
5403
del -> br_state == XFS_EXT_UNWRITTEN )
5368
5404
efi_flags |= XFS_FREE_EXTENT_SKIP_DISCARD ;
5369
5405
5406
+ /*
5407
+ * Historically, we did not use EFIs to free realtime
5408
+ * extents. However, when reverse mapping is enabled,
5409
+ * we must maintain the same order of operations as the
5410
+ * data device, which is: Remove the file mapping,
5411
+ * remove the reverse mapping, and then free the
5412
+ * blocks. Reflink for realtime volumes requires the
5413
+ * same sort of ordering. Both features rely on
5414
+ * rtgroups, so let's gate rt EFI usage on rtgroups.
5415
+ */
5416
+ if (isrt )
5417
+ efi_flags |= XFS_FREE_EXTENT_REALTIME ;
5418
+
5370
5419
error = xfs_free_extent_later (tp , del -> br_startblock ,
5371
5420
del -> br_blockcount , NULL ,
5372
5421
XFS_AG_RESV_NONE , efi_flags );
@@ -5715,6 +5764,8 @@ xfs_bunmapi(
5715
5764
*/
5716
5765
STATIC bool
5717
5766
xfs_bmse_can_merge (
5767
+ struct xfs_inode * ip ,
5768
+ int whichfork ,
5718
5769
struct xfs_bmbt_irec * left , /* preceding extent */
5719
5770
struct xfs_bmbt_irec * got , /* current extent to shift */
5720
5771
xfs_fileoff_t shift ) /* shift fsb */
@@ -5730,7 +5781,8 @@ xfs_bmse_can_merge(
5730
5781
if ((left -> br_startoff + left -> br_blockcount != startoff ) ||
5731
5782
(left -> br_startblock + left -> br_blockcount != got -> br_startblock ) ||
5732
5783
(left -> br_state != got -> br_state ) ||
5733
- (left -> br_blockcount + got -> br_blockcount > XFS_MAX_BMBT_EXTLEN ))
5784
+ (left -> br_blockcount + got -> br_blockcount > XFS_MAX_BMBT_EXTLEN ) ||
5785
+ !xfs_bmap_same_rtgroup (ip , whichfork , left , got ))
5734
5786
return false;
5735
5787
5736
5788
return true;
@@ -5766,7 +5818,7 @@ xfs_bmse_merge(
5766
5818
blockcount = left -> br_blockcount + got -> br_blockcount ;
5767
5819
5768
5820
xfs_assert_ilocked (ip , XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL );
5769
- ASSERT (xfs_bmse_can_merge (left , got , shift ));
5821
+ ASSERT (xfs_bmse_can_merge (ip , whichfork , left , got , shift ));
5770
5822
5771
5823
new = * left ;
5772
5824
new .br_blockcount = blockcount ;
@@ -5928,7 +5980,8 @@ xfs_bmap_collapse_extents(
5928
5980
goto del_cursor ;
5929
5981
}
5930
5982
5931
- if (xfs_bmse_can_merge (& prev , & got , offset_shift_fsb )) {
5983
+ if (xfs_bmse_can_merge (ip , whichfork , & prev , & got ,
5984
+ offset_shift_fsb )) {
5932
5985
error = xfs_bmse_merge (tp , ip , whichfork ,
5933
5986
offset_shift_fsb , & icur , & got , & prev ,
5934
5987
cur , & logflags );
@@ -6064,7 +6117,8 @@ xfs_bmap_insert_extents(
6064
6117
* never find mergeable extents in this scenario. Check anyways
6065
6118
* and warn if we encounter two extents that could be one.
6066
6119
*/
6067
- if (xfs_bmse_can_merge (& got , & next , offset_shift_fsb ))
6120
+ if (xfs_bmse_can_merge (ip , whichfork , & got , & next ,
6121
+ offset_shift_fsb ))
6068
6122
WARN_ON_ONCE (1 );
6069
6123
}
6070
6124
0 commit comments