10b61f8a4SDave Chinner // SPDX-License-Identifier: GPL-2.0+ 25880f2d7SDarrick J. Wong /* 35880f2d7SDarrick J. Wong * Copyright (C) 2016 Oracle. All Rights Reserved. 45880f2d7SDarrick J. Wong * Author: Darrick J. Wong <darrick.wong@oracle.com> 55880f2d7SDarrick J. Wong */ 65880f2d7SDarrick J. Wong #include "xfs.h" 75880f2d7SDarrick J. Wong #include "xfs_fs.h" 85880f2d7SDarrick J. Wong #include "xfs_format.h" 95880f2d7SDarrick J. Wong #include "xfs_log_format.h" 105880f2d7SDarrick J. Wong #include "xfs_trans_resv.h" 119e88b5d8SDarrick J. Wong #include "xfs_bit.h" 12b31c2bdcSDarrick J. Wong #include "xfs_shared.h" 135880f2d7SDarrick J. Wong #include "xfs_mount.h" 149c194644SDarrick J. Wong #include "xfs_defer.h" 155880f2d7SDarrick J. Wong #include "xfs_trans.h" 165880f2d7SDarrick J. Wong #include "xfs_trans_priv.h" 175880f2d7SDarrick J. Wong #include "xfs_buf_item.h" 185880f2d7SDarrick J. Wong #include "xfs_rmap_item.h" 195880f2d7SDarrick J. Wong #include "xfs_log.h" 209c194644SDarrick J. Wong #include "xfs_rmap.h" 215880f2d7SDarrick J. Wong 225880f2d7SDarrick J. Wong 235880f2d7SDarrick J. Wong kmem_zone_t *xfs_rui_zone; 245880f2d7SDarrick J. Wong kmem_zone_t *xfs_rud_zone; 255880f2d7SDarrick J. Wong 265880f2d7SDarrick J. Wong static inline struct xfs_rui_log_item *RUI_ITEM(struct xfs_log_item *lip) 275880f2d7SDarrick J. Wong { 285880f2d7SDarrick J. Wong return container_of(lip, struct xfs_rui_log_item, rui_item); 295880f2d7SDarrick J. Wong } 305880f2d7SDarrick J. Wong 315880f2d7SDarrick J. Wong void 325880f2d7SDarrick J. Wong xfs_rui_item_free( 335880f2d7SDarrick J. Wong struct xfs_rui_log_item *ruip) 345880f2d7SDarrick J. Wong { 355880f2d7SDarrick J. Wong if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS) 365880f2d7SDarrick J. Wong kmem_free(ruip); 375880f2d7SDarrick J. Wong else 385880f2d7SDarrick J. Wong kmem_zone_free(xfs_rui_zone, ruip); 395880f2d7SDarrick J. Wong } 405880f2d7SDarrick J. Wong 410612d116SDave Chinner /* 420612d116SDave Chinner * Freeing the RUI requires that we remove it from the AIL if it has already 430612d116SDave Chinner * been placed there. However, the RUI may not yet have been placed in the AIL 440612d116SDave Chinner * when called by xfs_rui_release() from RUD processing due to the ordering of 450612d116SDave Chinner * committed vs unpin operations in bulk insert operations. Hence the reference 460612d116SDave Chinner * count to ensure only the last caller frees the RUI. 470612d116SDave Chinner */ 480612d116SDave Chinner void 490612d116SDave Chinner xfs_rui_release( 500612d116SDave Chinner struct xfs_rui_log_item *ruip) 510612d116SDave Chinner { 520612d116SDave Chinner ASSERT(atomic_read(&ruip->rui_refcount) > 0); 530612d116SDave Chinner if (atomic_dec_and_test(&ruip->rui_refcount)) { 540612d116SDave Chinner xfs_trans_ail_remove(&ruip->rui_item, SHUTDOWN_LOG_IO_ERROR); 550612d116SDave Chinner xfs_rui_item_free(ruip); 560612d116SDave Chinner } 570612d116SDave Chinner } 580612d116SDave Chinner 595880f2d7SDarrick J. Wong STATIC void 605880f2d7SDarrick J. Wong xfs_rui_item_size( 615880f2d7SDarrick J. Wong struct xfs_log_item *lip, 625880f2d7SDarrick J. Wong int *nvecs, 635880f2d7SDarrick J. Wong int *nbytes) 645880f2d7SDarrick J. Wong { 65cd00158cSDarrick J. Wong struct xfs_rui_log_item *ruip = RUI_ITEM(lip); 66cd00158cSDarrick J. Wong 675880f2d7SDarrick J. Wong *nvecs += 1; 68cd00158cSDarrick J. Wong *nbytes += xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents); 695880f2d7SDarrick J. Wong } 705880f2d7SDarrick J. Wong 715880f2d7SDarrick J. Wong /* 725880f2d7SDarrick J. Wong * This is called to fill in the vector of log iovecs for the 735880f2d7SDarrick J. Wong * given rui log item. We use only 1 iovec, and we point that 745880f2d7SDarrick J. Wong * at the rui_log_format structure embedded in the rui item. 755880f2d7SDarrick J. Wong * It is at this point that we assert that all of the extent 765880f2d7SDarrick J. Wong * slots in the rui item have been filled. 775880f2d7SDarrick J. Wong */ 785880f2d7SDarrick J. Wong STATIC void 795880f2d7SDarrick J. Wong xfs_rui_item_format( 805880f2d7SDarrick J. Wong struct xfs_log_item *lip, 815880f2d7SDarrick J. Wong struct xfs_log_vec *lv) 825880f2d7SDarrick J. Wong { 835880f2d7SDarrick J. Wong struct xfs_rui_log_item *ruip = RUI_ITEM(lip); 845880f2d7SDarrick J. Wong struct xfs_log_iovec *vecp = NULL; 855880f2d7SDarrick J. Wong 865880f2d7SDarrick J. Wong ASSERT(atomic_read(&ruip->rui_next_extent) == 875880f2d7SDarrick J. Wong ruip->rui_format.rui_nextents); 885880f2d7SDarrick J. Wong 895880f2d7SDarrick J. Wong ruip->rui_format.rui_type = XFS_LI_RUI; 905880f2d7SDarrick J. Wong ruip->rui_format.rui_size = 1; 915880f2d7SDarrick J. Wong 925880f2d7SDarrick J. Wong xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUI_FORMAT, &ruip->rui_format, 93cd00158cSDarrick J. Wong xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents)); 945880f2d7SDarrick J. Wong } 955880f2d7SDarrick J. Wong 965880f2d7SDarrick J. Wong /* 975880f2d7SDarrick J. Wong * The unpin operation is the last place an RUI is manipulated in the log. It is 985880f2d7SDarrick J. Wong * either inserted in the AIL or aborted in the event of a log I/O error. In 995880f2d7SDarrick J. Wong * either case, the RUI transaction has been successfully committed to make it 1005880f2d7SDarrick J. Wong * this far. Therefore, we expect whoever committed the RUI to either construct 1015880f2d7SDarrick J. Wong * and commit the RUD or drop the RUD's reference in the event of error. Simply 1025880f2d7SDarrick J. Wong * drop the log's RUI reference now that the log is done with it. 1035880f2d7SDarrick J. Wong */ 1045880f2d7SDarrick J. Wong STATIC void 1055880f2d7SDarrick J. Wong xfs_rui_item_unpin( 1065880f2d7SDarrick J. Wong struct xfs_log_item *lip, 1075880f2d7SDarrick J. Wong int remove) 1085880f2d7SDarrick J. Wong { 1095880f2d7SDarrick J. Wong struct xfs_rui_log_item *ruip = RUI_ITEM(lip); 1105880f2d7SDarrick J. Wong 1115880f2d7SDarrick J. Wong xfs_rui_release(ruip); 1125880f2d7SDarrick J. Wong } 1135880f2d7SDarrick J. Wong 1145880f2d7SDarrick J. Wong /* 1155880f2d7SDarrick J. Wong * The RUI has been either committed or aborted if the transaction has been 1165880f2d7SDarrick J. Wong * cancelled. If the transaction was cancelled, an RUD isn't going to be 1175880f2d7SDarrick J. Wong * constructed and thus we free the RUI here directly. 1185880f2d7SDarrick J. Wong */ 1195880f2d7SDarrick J. Wong STATIC void 120ddf92053SChristoph Hellwig xfs_rui_item_release( 1215880f2d7SDarrick J. Wong struct xfs_log_item *lip) 1225880f2d7SDarrick J. Wong { 1230612d116SDave Chinner xfs_rui_release(RUI_ITEM(lip)); 1245880f2d7SDarrick J. Wong } 1255880f2d7SDarrick J. Wong 1265880f2d7SDarrick J. Wong /* 1275880f2d7SDarrick J. Wong * This is the ops vector shared by all rui log items. 1285880f2d7SDarrick J. Wong */ 1295880f2d7SDarrick J. Wong static const struct xfs_item_ops xfs_rui_item_ops = { 1305880f2d7SDarrick J. Wong .iop_size = xfs_rui_item_size, 1315880f2d7SDarrick J. Wong .iop_format = xfs_rui_item_format, 1325880f2d7SDarrick J. Wong .iop_unpin = xfs_rui_item_unpin, 133ddf92053SChristoph Hellwig .iop_release = xfs_rui_item_release, 1345880f2d7SDarrick J. Wong }; 1355880f2d7SDarrick J. Wong 1365880f2d7SDarrick J. Wong /* 1375880f2d7SDarrick J. Wong * Allocate and initialize an rui item with the given number of extents. 1385880f2d7SDarrick J. Wong */ 1395880f2d7SDarrick J. Wong struct xfs_rui_log_item * 1405880f2d7SDarrick J. Wong xfs_rui_init( 1415880f2d7SDarrick J. Wong struct xfs_mount *mp, 1425880f2d7SDarrick J. Wong uint nextents) 1435880f2d7SDarrick J. Wong 1445880f2d7SDarrick J. Wong { 1455880f2d7SDarrick J. Wong struct xfs_rui_log_item *ruip; 1465880f2d7SDarrick J. Wong 1475880f2d7SDarrick J. Wong ASSERT(nextents > 0); 148cd00158cSDarrick J. Wong if (nextents > XFS_RUI_MAX_FAST_EXTENTS) 149cd00158cSDarrick J. Wong ruip = kmem_zalloc(xfs_rui_log_item_sizeof(nextents), KM_SLEEP); 150cd00158cSDarrick J. Wong else 1515880f2d7SDarrick J. Wong ruip = kmem_zone_zalloc(xfs_rui_zone, KM_SLEEP); 1525880f2d7SDarrick J. Wong 1535880f2d7SDarrick J. Wong xfs_log_item_init(mp, &ruip->rui_item, XFS_LI_RUI, &xfs_rui_item_ops); 1545880f2d7SDarrick J. Wong ruip->rui_format.rui_nextents = nextents; 1555880f2d7SDarrick J. Wong ruip->rui_format.rui_id = (uintptr_t)(void *)ruip; 1565880f2d7SDarrick J. Wong atomic_set(&ruip->rui_next_extent, 0); 1575880f2d7SDarrick J. Wong atomic_set(&ruip->rui_refcount, 2); 1585880f2d7SDarrick J. Wong 1595880f2d7SDarrick J. Wong return ruip; 1605880f2d7SDarrick J. Wong } 1615880f2d7SDarrick J. Wong 1625880f2d7SDarrick J. Wong /* 1635880f2d7SDarrick J. Wong * Copy an RUI format buffer from the given buf, and into the destination 1645880f2d7SDarrick J. Wong * RUI format structure. The RUI/RUD items were designed not to need any 1655880f2d7SDarrick J. Wong * special alignment handling. 1665880f2d7SDarrick J. Wong */ 1675880f2d7SDarrick J. Wong int 1685880f2d7SDarrick J. Wong xfs_rui_copy_format( 1695880f2d7SDarrick J. Wong struct xfs_log_iovec *buf, 1705880f2d7SDarrick J. Wong struct xfs_rui_log_format *dst_rui_fmt) 1715880f2d7SDarrick J. Wong { 1725880f2d7SDarrick J. Wong struct xfs_rui_log_format *src_rui_fmt; 1735880f2d7SDarrick J. Wong uint len; 1745880f2d7SDarrick J. Wong 1755880f2d7SDarrick J. Wong src_rui_fmt = buf->i_addr; 176cd00158cSDarrick J. Wong len = xfs_rui_log_format_sizeof(src_rui_fmt->rui_nextents); 1775880f2d7SDarrick J. Wong 1785880f2d7SDarrick J. Wong if (buf->i_len != len) 1795880f2d7SDarrick J. Wong return -EFSCORRUPTED; 1805880f2d7SDarrick J. Wong 181cd00158cSDarrick J. Wong memcpy(dst_rui_fmt, src_rui_fmt, len); 1825880f2d7SDarrick J. Wong return 0; 1835880f2d7SDarrick J. Wong } 1845880f2d7SDarrick J. Wong 1855880f2d7SDarrick J. Wong static inline struct xfs_rud_log_item *RUD_ITEM(struct xfs_log_item *lip) 1865880f2d7SDarrick J. Wong { 1875880f2d7SDarrick J. Wong return container_of(lip, struct xfs_rud_log_item, rud_item); 1885880f2d7SDarrick J. Wong } 1895880f2d7SDarrick J. Wong 1905880f2d7SDarrick J. Wong STATIC void 1915880f2d7SDarrick J. Wong xfs_rud_item_size( 1925880f2d7SDarrick J. Wong struct xfs_log_item *lip, 1935880f2d7SDarrick J. Wong int *nvecs, 1945880f2d7SDarrick J. Wong int *nbytes) 1955880f2d7SDarrick J. Wong { 1965880f2d7SDarrick J. Wong *nvecs += 1; 197722e2517SDarrick J. Wong *nbytes += sizeof(struct xfs_rud_log_format); 1985880f2d7SDarrick J. Wong } 1995880f2d7SDarrick J. Wong 2005880f2d7SDarrick J. Wong /* 2015880f2d7SDarrick J. Wong * This is called to fill in the vector of log iovecs for the 2025880f2d7SDarrick J. Wong * given rud log item. We use only 1 iovec, and we point that 2035880f2d7SDarrick J. Wong * at the rud_log_format structure embedded in the rud item. 2045880f2d7SDarrick J. Wong * It is at this point that we assert that all of the extent 2055880f2d7SDarrick J. Wong * slots in the rud item have been filled. 2065880f2d7SDarrick J. Wong */ 2075880f2d7SDarrick J. Wong STATIC void 2085880f2d7SDarrick J. Wong xfs_rud_item_format( 2095880f2d7SDarrick J. Wong struct xfs_log_item *lip, 2105880f2d7SDarrick J. Wong struct xfs_log_vec *lv) 2115880f2d7SDarrick J. Wong { 2125880f2d7SDarrick J. Wong struct xfs_rud_log_item *rudp = RUD_ITEM(lip); 2135880f2d7SDarrick J. Wong struct xfs_log_iovec *vecp = NULL; 2145880f2d7SDarrick J. Wong 2155880f2d7SDarrick J. Wong rudp->rud_format.rud_type = XFS_LI_RUD; 2165880f2d7SDarrick J. Wong rudp->rud_format.rud_size = 1; 2175880f2d7SDarrick J. Wong 2185880f2d7SDarrick J. Wong xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUD_FORMAT, &rudp->rud_format, 219722e2517SDarrick J. Wong sizeof(struct xfs_rud_log_format)); 2205880f2d7SDarrick J. Wong } 2215880f2d7SDarrick J. Wong 2225880f2d7SDarrick J. Wong /* 2235880f2d7SDarrick J. Wong * The RUD is either committed or aborted if the transaction is cancelled. If 2245880f2d7SDarrick J. Wong * the transaction is cancelled, drop our reference to the RUI and free the 2255880f2d7SDarrick J. Wong * RUD. 2265880f2d7SDarrick J. Wong */ 2275880f2d7SDarrick J. Wong STATIC void 228ddf92053SChristoph Hellwig xfs_rud_item_release( 2295880f2d7SDarrick J. Wong struct xfs_log_item *lip) 2305880f2d7SDarrick J. Wong { 2315880f2d7SDarrick J. Wong struct xfs_rud_log_item *rudp = RUD_ITEM(lip); 2325880f2d7SDarrick J. Wong 2335880f2d7SDarrick J. Wong xfs_rui_release(rudp->rud_ruip); 234722e2517SDarrick J. Wong kmem_zone_free(xfs_rud_zone, rudp); 2355880f2d7SDarrick J. Wong } 2365880f2d7SDarrick J. Wong 2375880f2d7SDarrick J. Wong /* 2385880f2d7SDarrick J. Wong * This is the ops vector shared by all rud log items. 2395880f2d7SDarrick J. Wong */ 2405880f2d7SDarrick J. Wong static const struct xfs_item_ops xfs_rud_item_ops = { 2419ce632a2SChristoph Hellwig .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, 2425880f2d7SDarrick J. Wong .iop_size = xfs_rud_item_size, 2435880f2d7SDarrick J. Wong .iop_format = xfs_rud_item_format, 244ddf92053SChristoph Hellwig .iop_release = xfs_rud_item_release, 2455880f2d7SDarrick J. Wong }; 2465880f2d7SDarrick J. Wong 2475880f2d7SDarrick J. Wong /* 2485880f2d7SDarrick J. Wong * Allocate and initialize an rud item with the given number of extents. 2495880f2d7SDarrick J. Wong */ 2505880f2d7SDarrick J. Wong struct xfs_rud_log_item * 2515880f2d7SDarrick J. Wong xfs_rud_init( 2525880f2d7SDarrick J. Wong struct xfs_mount *mp, 253722e2517SDarrick J. Wong struct xfs_rui_log_item *ruip) 2545880f2d7SDarrick J. Wong 2555880f2d7SDarrick J. Wong { 2565880f2d7SDarrick J. Wong struct xfs_rud_log_item *rudp; 2575880f2d7SDarrick J. Wong 2585880f2d7SDarrick J. Wong rudp = kmem_zone_zalloc(xfs_rud_zone, KM_SLEEP); 2595880f2d7SDarrick J. Wong xfs_log_item_init(mp, &rudp->rud_item, XFS_LI_RUD, &xfs_rud_item_ops); 2605880f2d7SDarrick J. Wong rudp->rud_ruip = ruip; 2615880f2d7SDarrick J. Wong rudp->rud_format.rud_rui_id = ruip->rui_format.rui_id; 2625880f2d7SDarrick J. Wong 2635880f2d7SDarrick J. Wong return rudp; 2645880f2d7SDarrick J. Wong } 2659e88b5d8SDarrick J. Wong 2669e88b5d8SDarrick J. Wong /* 2679e88b5d8SDarrick J. Wong * Process an rmap update intent item that was recovered from the log. 2689e88b5d8SDarrick J. Wong * We need to update the rmapbt. 2699e88b5d8SDarrick J. Wong */ 2709e88b5d8SDarrick J. Wong int 2719e88b5d8SDarrick J. Wong xfs_rui_recover( 2729e88b5d8SDarrick J. Wong struct xfs_mount *mp, 2739e88b5d8SDarrick J. Wong struct xfs_rui_log_item *ruip) 2749e88b5d8SDarrick J. Wong { 2759e88b5d8SDarrick J. Wong int i; 2769e88b5d8SDarrick J. Wong int error = 0; 2779e88b5d8SDarrick J. Wong struct xfs_map_extent *rmap; 2789e88b5d8SDarrick J. Wong xfs_fsblock_t startblock_fsb; 2799e88b5d8SDarrick J. Wong bool op_ok; 2809c194644SDarrick J. Wong struct xfs_rud_log_item *rudp; 2819c194644SDarrick J. Wong enum xfs_rmap_intent_type type; 2829c194644SDarrick J. Wong int whichfork; 2839c194644SDarrick J. Wong xfs_exntst_t state; 2849c194644SDarrick J. Wong struct xfs_trans *tp; 2859c194644SDarrick J. Wong struct xfs_btree_cur *rcur = NULL; 2869e88b5d8SDarrick J. Wong 2879e88b5d8SDarrick J. Wong ASSERT(!test_bit(XFS_RUI_RECOVERED, &ruip->rui_flags)); 2889e88b5d8SDarrick J. Wong 2899e88b5d8SDarrick J. Wong /* 2909e88b5d8SDarrick J. Wong * First check the validity of the extents described by the 2919e88b5d8SDarrick J. Wong * RUI. If any are bad, then assume that all are bad and 2929e88b5d8SDarrick J. Wong * just toss the RUI. 2939e88b5d8SDarrick J. Wong */ 2949e88b5d8SDarrick J. Wong for (i = 0; i < ruip->rui_format.rui_nextents; i++) { 295e127fafdSDarrick J. Wong rmap = &ruip->rui_format.rui_extents[i]; 2969e88b5d8SDarrick J. Wong startblock_fsb = XFS_BB_TO_FSB(mp, 2979e88b5d8SDarrick J. Wong XFS_FSB_TO_DADDR(mp, rmap->me_startblock)); 2989e88b5d8SDarrick J. Wong switch (rmap->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) { 2999e88b5d8SDarrick J. Wong case XFS_RMAP_EXTENT_MAP: 3000e07c039SDarrick J. Wong case XFS_RMAP_EXTENT_MAP_SHARED: 3019e88b5d8SDarrick J. Wong case XFS_RMAP_EXTENT_UNMAP: 3020e07c039SDarrick J. Wong case XFS_RMAP_EXTENT_UNMAP_SHARED: 3039e88b5d8SDarrick J. Wong case XFS_RMAP_EXTENT_CONVERT: 3040e07c039SDarrick J. Wong case XFS_RMAP_EXTENT_CONVERT_SHARED: 3059e88b5d8SDarrick J. Wong case XFS_RMAP_EXTENT_ALLOC: 3069e88b5d8SDarrick J. Wong case XFS_RMAP_EXTENT_FREE: 3079e88b5d8SDarrick J. Wong op_ok = true; 3089e88b5d8SDarrick J. Wong break; 3099e88b5d8SDarrick J. Wong default: 3109e88b5d8SDarrick J. Wong op_ok = false; 3119e88b5d8SDarrick J. Wong break; 3129e88b5d8SDarrick J. Wong } 313e127fafdSDarrick J. Wong if (!op_ok || startblock_fsb == 0 || 314e127fafdSDarrick J. Wong rmap->me_len == 0 || 315e127fafdSDarrick J. Wong startblock_fsb >= mp->m_sb.sb_dblocks || 316e127fafdSDarrick J. Wong rmap->me_len >= mp->m_sb.sb_agblocks || 3179e88b5d8SDarrick J. Wong (rmap->me_flags & ~XFS_RMAP_EXTENT_FLAGS)) { 3189e88b5d8SDarrick J. Wong /* 3199e88b5d8SDarrick J. Wong * This will pull the RUI from the AIL and 3209e88b5d8SDarrick J. Wong * free the memory associated with it. 3219e88b5d8SDarrick J. Wong */ 3229e88b5d8SDarrick J. Wong set_bit(XFS_RUI_RECOVERED, &ruip->rui_flags); 3239e88b5d8SDarrick J. Wong xfs_rui_release(ruip); 3249e88b5d8SDarrick J. Wong return -EIO; 3259e88b5d8SDarrick J. Wong } 3269e88b5d8SDarrick J. Wong } 3279e88b5d8SDarrick J. Wong 328b31c2bdcSDarrick J. Wong error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 329b31c2bdcSDarrick J. Wong mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp); 3309c194644SDarrick J. Wong if (error) 3319c194644SDarrick J. Wong return error; 332722e2517SDarrick J. Wong rudp = xfs_trans_get_rud(tp, ruip); 3339c194644SDarrick J. Wong 3349c194644SDarrick J. Wong for (i = 0; i < ruip->rui_format.rui_nextents; i++) { 335e127fafdSDarrick J. Wong rmap = &ruip->rui_format.rui_extents[i]; 3369c194644SDarrick J. Wong state = (rmap->me_flags & XFS_RMAP_EXTENT_UNWRITTEN) ? 3379c194644SDarrick J. Wong XFS_EXT_UNWRITTEN : XFS_EXT_NORM; 3389c194644SDarrick J. Wong whichfork = (rmap->me_flags & XFS_RMAP_EXTENT_ATTR_FORK) ? 3399c194644SDarrick J. Wong XFS_ATTR_FORK : XFS_DATA_FORK; 3409c194644SDarrick J. Wong switch (rmap->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) { 3419c194644SDarrick J. Wong case XFS_RMAP_EXTENT_MAP: 3429c194644SDarrick J. Wong type = XFS_RMAP_MAP; 3439c194644SDarrick J. Wong break; 344ceeb9c83SDarrick J. Wong case XFS_RMAP_EXTENT_MAP_SHARED: 345ceeb9c83SDarrick J. Wong type = XFS_RMAP_MAP_SHARED; 346ceeb9c83SDarrick J. Wong break; 3479c194644SDarrick J. Wong case XFS_RMAP_EXTENT_UNMAP: 3489c194644SDarrick J. Wong type = XFS_RMAP_UNMAP; 3499c194644SDarrick J. Wong break; 350ceeb9c83SDarrick J. Wong case XFS_RMAP_EXTENT_UNMAP_SHARED: 351ceeb9c83SDarrick J. Wong type = XFS_RMAP_UNMAP_SHARED; 352ceeb9c83SDarrick J. Wong break; 3539c194644SDarrick J. Wong case XFS_RMAP_EXTENT_CONVERT: 3549c194644SDarrick J. Wong type = XFS_RMAP_CONVERT; 3559c194644SDarrick J. Wong break; 3563f165b33SDarrick J. Wong case XFS_RMAP_EXTENT_CONVERT_SHARED: 3573f165b33SDarrick J. Wong type = XFS_RMAP_CONVERT_SHARED; 3583f165b33SDarrick J. Wong break; 3599c194644SDarrick J. Wong case XFS_RMAP_EXTENT_ALLOC: 3609c194644SDarrick J. Wong type = XFS_RMAP_ALLOC; 3619c194644SDarrick J. Wong break; 3629c194644SDarrick J. Wong case XFS_RMAP_EXTENT_FREE: 3639c194644SDarrick J. Wong type = XFS_RMAP_FREE; 3649c194644SDarrick J. Wong break; 3659c194644SDarrick J. Wong default: 3669c194644SDarrick J. Wong error = -EFSCORRUPTED; 3679c194644SDarrick J. Wong goto abort_error; 3689c194644SDarrick J. Wong } 3699c194644SDarrick J. Wong error = xfs_trans_log_finish_rmap_update(tp, rudp, type, 3709c194644SDarrick J. Wong rmap->me_owner, whichfork, 3719c194644SDarrick J. Wong rmap->me_startoff, rmap->me_startblock, 3729c194644SDarrick J. Wong rmap->me_len, state, &rcur); 3739c194644SDarrick J. Wong if (error) 3749c194644SDarrick J. Wong goto abort_error; 3759c194644SDarrick J. Wong 3769c194644SDarrick J. Wong } 3779c194644SDarrick J. Wong 3789c194644SDarrick J. Wong xfs_rmap_finish_one_cleanup(tp, rcur, error); 3799e88b5d8SDarrick J. Wong set_bit(XFS_RUI_RECOVERED, &ruip->rui_flags); 3809c194644SDarrick J. Wong error = xfs_trans_commit(tp); 3819c194644SDarrick J. Wong return error; 3829c194644SDarrick J. Wong 3839c194644SDarrick J. Wong abort_error: 3849c194644SDarrick J. Wong xfs_rmap_finish_one_cleanup(tp, rcur, error); 3859c194644SDarrick J. Wong xfs_trans_cancel(tp); 3869e88b5d8SDarrick J. Wong return error; 3879e88b5d8SDarrick J. Wong } 388