^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2016 Oracle. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Darrick J. Wong <darrick.wong@oracle.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_bit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_defer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_trans_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_bmap_item.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "xfs_bmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "xfs_icache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "xfs_bmap_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "xfs_trans_space.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "xfs_error.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "xfs_log_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "xfs_log_recover.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "xfs_quota.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) kmem_zone_t *xfs_bui_zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) kmem_zone_t *xfs_bud_zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static const struct xfs_item_ops xfs_bui_item_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static inline struct xfs_bui_log_item *BUI_ITEM(struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return container_of(lip, struct xfs_bui_log_item, bui_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) xfs_bui_item_free(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct xfs_bui_log_item *buip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) kmem_cache_free(xfs_bui_zone, buip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Freeing the BUI requires that we remove it from the AIL if it has already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * been placed there. However, the BUI may not yet have been placed in the AIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * when called by xfs_bui_release() from BUD processing due to the ordering of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * committed vs unpin operations in bulk insert operations. Hence the reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * count to ensure only the last caller frees the BUI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) xfs_bui_release(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct xfs_bui_log_item *buip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ASSERT(atomic_read(&buip->bui_refcount) > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (atomic_dec_and_test(&buip->bui_refcount)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) xfs_trans_ail_delete(&buip->bui_item, SHUTDOWN_LOG_IO_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) xfs_bui_item_free(buip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) xfs_bui_item_size(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int *nvecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int *nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct xfs_bui_log_item *buip = BUI_ITEM(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *nvecs += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *nbytes += xfs_bui_log_format_sizeof(buip->bui_format.bui_nextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * This is called to fill in the vector of log iovecs for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * given bui log item. We use only 1 iovec, and we point that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * at the bui_log_format structure embedded in the bui item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * It is at this point that we assert that all of the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * slots in the bui item have been filled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) xfs_bui_item_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct xfs_log_vec *lv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct xfs_bui_log_item *buip = BUI_ITEM(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct xfs_log_iovec *vecp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ASSERT(atomic_read(&buip->bui_next_extent) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) buip->bui_format.bui_nextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) buip->bui_format.bui_type = XFS_LI_BUI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) buip->bui_format.bui_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_BUI_FORMAT, &buip->bui_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) xfs_bui_log_format_sizeof(buip->bui_format.bui_nextents));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * The unpin operation is the last place an BUI is manipulated in the log. It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * either inserted in the AIL or aborted in the event of a log I/O error. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * either case, the BUI transaction has been successfully committed to make it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * this far. Therefore, we expect whoever committed the BUI to either construct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * and commit the BUD or drop the BUD's reference in the event of error. Simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * drop the log's BUI reference now that the log is done with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) xfs_bui_item_unpin(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct xfs_bui_log_item *buip = BUI_ITEM(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) xfs_bui_release(buip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * The BUI has been either committed or aborted if the transaction has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * cancelled. If the transaction was cancelled, an BUD isn't going to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * constructed and thus we free the BUI here directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) xfs_bui_item_release(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) xfs_bui_release(BUI_ITEM(lip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Allocate and initialize an bui item with the given number of extents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) STATIC struct xfs_bui_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) xfs_bui_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct xfs_mount *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct xfs_bui_log_item *buip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) buip = kmem_cache_zalloc(xfs_bui_zone, GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) xfs_log_item_init(mp, &buip->bui_item, XFS_LI_BUI, &xfs_bui_item_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) buip->bui_format.bui_nextents = XFS_BUI_MAX_FAST_EXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) buip->bui_format.bui_id = (uintptr_t)(void *)buip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) atomic_set(&buip->bui_next_extent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) atomic_set(&buip->bui_refcount, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return buip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static inline struct xfs_bud_log_item *BUD_ITEM(struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return container_of(lip, struct xfs_bud_log_item, bud_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) xfs_bud_item_size(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int *nvecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int *nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *nvecs += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *nbytes += sizeof(struct xfs_bud_log_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * This is called to fill in the vector of log iovecs for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * given bud log item. We use only 1 iovec, and we point that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * at the bud_log_format structure embedded in the bud item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * It is at this point that we assert that all of the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * slots in the bud item have been filled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) xfs_bud_item_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct xfs_log_vec *lv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct xfs_bud_log_item *budp = BUD_ITEM(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct xfs_log_iovec *vecp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) budp->bud_format.bud_type = XFS_LI_BUD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) budp->bud_format.bud_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_BUD_FORMAT, &budp->bud_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) sizeof(struct xfs_bud_log_format));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * The BUD is either committed or aborted if the transaction is cancelled. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * the transaction is cancelled, drop our reference to the BUI and free the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * BUD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) xfs_bud_item_release(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct xfs_bud_log_item *budp = BUD_ITEM(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) xfs_bui_release(budp->bud_buip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) kmem_cache_free(xfs_bud_zone, budp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static const struct xfs_item_ops xfs_bud_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .iop_size = xfs_bud_item_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .iop_format = xfs_bud_item_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .iop_release = xfs_bud_item_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static struct xfs_bud_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) xfs_trans_get_bud(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct xfs_bui_log_item *buip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct xfs_bud_log_item *budp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) budp = kmem_cache_zalloc(xfs_bud_zone, GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) xfs_log_item_init(tp->t_mountp, &budp->bud_item, XFS_LI_BUD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) &xfs_bud_item_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) budp->bud_buip = buip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) budp->bud_format.bud_bui_id = buip->bui_format.bui_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) xfs_trans_add_item(tp, &budp->bud_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return budp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * Finish an bmap update and log it to the BUD. Note that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * transaction is marked dirty regardless of whether the bmap update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * succeeds or fails to support the BUI/BUD lifecycle rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) xfs_trans_log_finish_bmap_update(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct xfs_bud_log_item *budp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) enum xfs_bmap_intent_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) xfs_fileoff_t startoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) xfs_fsblock_t startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) xfs_filblks_t *blockcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) xfs_exntst_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) error = xfs_bmap_finish_one(tp, ip, type, whichfork, startoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) startblock, blockcount, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * Mark the transaction dirty, even on error. This ensures the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * transaction is aborted, which:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * 1.) releases the BUI and frees the BUD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * 2.) shuts down the filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) tp->t_flags |= XFS_TRANS_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Sort bmap intents by inode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) xfs_bmap_update_diff_items(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct list_head *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct list_head *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct xfs_bmap_intent *ba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct xfs_bmap_intent *bb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ba = container_of(a, struct xfs_bmap_intent, bi_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) bb = container_of(b, struct xfs_bmap_intent, bi_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ba->bi_owner->i_ino - bb->bi_owner->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Set the map extent flags for this mapping. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) xfs_trans_set_bmap_flags(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct xfs_map_extent *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) enum xfs_bmap_intent_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) xfs_exntst_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) bmap->me_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case XFS_BMAP_MAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case XFS_BMAP_UNMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) bmap->me_flags = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (state == XFS_EXT_UNWRITTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) bmap->me_flags |= XFS_BMAP_EXTENT_UNWRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (whichfork == XFS_ATTR_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) bmap->me_flags |= XFS_BMAP_EXTENT_ATTR_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Log bmap updates in the intent item. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) xfs_bmap_update_log_item(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct xfs_bui_log_item *buip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct xfs_bmap_intent *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) uint next_extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct xfs_map_extent *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) tp->t_flags |= XFS_TRANS_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) set_bit(XFS_LI_DIRTY, &buip->bui_item.li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * atomic_inc_return gives us the value after the increment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * we want to use it as an array index so we need to subtract 1 from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) next_extent = atomic_inc_return(&buip->bui_next_extent) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ASSERT(next_extent < buip->bui_format.bui_nextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) map = &buip->bui_format.bui_extents[next_extent];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) map->me_owner = bmap->bi_owner->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) map->me_startblock = bmap->bi_bmap.br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) map->me_startoff = bmap->bi_bmap.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) map->me_len = bmap->bi_bmap.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) xfs_trans_set_bmap_flags(map, bmap->bi_type, bmap->bi_whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) bmap->bi_bmap.br_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) xfs_bmap_update_create_intent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct list_head *items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) bool sort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct xfs_mount *mp = tp->t_mountp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct xfs_bui_log_item *buip = xfs_bui_init(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct xfs_bmap_intent *bmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ASSERT(count == XFS_BUI_MAX_FAST_EXTENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) xfs_trans_add_item(tp, &buip->bui_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (sort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) list_sort(mp, items, xfs_bmap_update_diff_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) list_for_each_entry(bmap, items, bi_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) xfs_bmap_update_log_item(tp, buip, bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return &buip->bui_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* Get an BUD so we can process all the deferred rmap updates. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) xfs_bmap_update_create_done(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct xfs_log_item *intent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return &xfs_trans_get_bud(tp, BUI_ITEM(intent))->bud_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Process a deferred rmap update. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) xfs_bmap_update_finish_item(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct xfs_log_item *done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct list_head *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct xfs_btree_cur **state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct xfs_bmap_intent *bmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) xfs_filblks_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) bmap = container_of(item, struct xfs_bmap_intent, bi_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) count = bmap->bi_bmap.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) error = xfs_trans_log_finish_bmap_update(tp, BUD_ITEM(done),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) bmap->bi_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) bmap->bi_owner, bmap->bi_whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) bmap->bi_bmap.br_startoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) bmap->bi_bmap.br_startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) &count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) bmap->bi_bmap.br_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!error && count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ASSERT(bmap->bi_type == XFS_BMAP_UNMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) bmap->bi_bmap.br_blockcount = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) kmem_free(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Abort all pending BUIs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) xfs_bmap_update_abort_intent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct xfs_log_item *intent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) xfs_bui_release(BUI_ITEM(intent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Cancel a deferred rmap update. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) xfs_bmap_update_cancel_item(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct list_head *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct xfs_bmap_intent *bmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) bmap = container_of(item, struct xfs_bmap_intent, bi_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) kmem_free(bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .max_items = XFS_BUI_MAX_FAST_EXTENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .create_intent = xfs_bmap_update_create_intent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .abort_intent = xfs_bmap_update_abort_intent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .create_done = xfs_bmap_update_create_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .finish_item = xfs_bmap_update_finish_item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .cancel_item = xfs_bmap_update_cancel_item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * Process a bmap update intent item that was recovered from the log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * We need to update some inode's bmbt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) xfs_bui_item_recover(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct list_head *capture_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct xfs_bmbt_irec irec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct xfs_bui_log_item *buip = BUI_ITEM(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct xfs_trans *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct xfs_inode *ip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct xfs_mount *mp = lip->li_mountp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct xfs_map_extent *bmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct xfs_bud_log_item *budp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) xfs_fsblock_t startblock_fsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) xfs_fsblock_t inode_fsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) xfs_filblks_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) xfs_exntst_t state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned int bui_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int whichfork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* Only one mapping operation per BUI... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * First check the validity of the extent described by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * BUI. If anything is bad, then toss the BUI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) bmap = &buip->bui_format.bui_extents[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) startblock_fsb = XFS_BB_TO_FSB(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) XFS_FSB_TO_DADDR(mp, bmap->me_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) inode_fsb = XFS_BB_TO_FSB(mp, XFS_FSB_TO_DADDR(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) XFS_INO_TO_FSB(mp, bmap->me_owner)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) state = (bmap->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) whichfork = (bmap->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) XFS_ATTR_FORK : XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) bui_type = bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) switch (bui_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case XFS_BMAP_MAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case XFS_BMAP_UNMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (startblock_fsb == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) bmap->me_len == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) inode_fsb == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) startblock_fsb >= mp->m_sb.sb_dblocks ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) bmap->me_len >= mp->m_sb.sb_agblocks ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) inode_fsb >= mp->m_sb.sb_dblocks ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) (bmap->me_flags & ~XFS_BMAP_EXTENT_FLAGS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* Grab the inode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) error = xfs_iget(mp, NULL, bmap->me_owner, 0, 0, &ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) error = xfs_qm_dqattach(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) goto err_rele;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (VFS_I(ip)->i_nlink == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) xfs_iflags_set(ip, XFS_IRECOVERY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Allocate transaction and do the work. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) goto err_rele;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) budp = xfs_trans_get_bud(tp, buip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) xfs_trans_ijoin(tp, ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) count = bmap->me_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) error = xfs_trans_log_finish_bmap_update(tp, budp, bui_type, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) whichfork, bmap->me_startoff, bmap->me_startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) &count, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) goto err_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ASSERT(bui_type == XFS_BMAP_UNMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) irec.br_startblock = bmap->me_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) irec.br_blockcount = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) irec.br_startoff = bmap->me_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) irec.br_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) xfs_bmap_unmap_extent(tp, ip, &irec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * Commit transaction, which frees the transaction and saves the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * for later replay activities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) error = xfs_defer_ops_capture_and_commit(tp, ip, capture_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) xfs_irele(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) err_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) xfs_trans_cancel(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) err_rele:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) xfs_irele(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) STATIC bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) xfs_bui_item_match(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) uint64_t intent_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return BUI_ITEM(lip)->bui_format.bui_id == intent_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* Relog an intent item to push the log tail forward. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static struct xfs_log_item *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) xfs_bui_item_relog(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct xfs_log_item *intent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct xfs_trans *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct xfs_bud_log_item *budp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct xfs_bui_log_item *buip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct xfs_map_extent *extp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) count = BUI_ITEM(intent)->bui_format.bui_nextents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) extp = BUI_ITEM(intent)->bui_format.bui_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) tp->t_flags |= XFS_TRANS_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) budp = xfs_trans_get_bud(tp, BUI_ITEM(intent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) buip = xfs_bui_init(tp->t_mountp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) memcpy(buip->bui_format.bui_extents, extp, count * sizeof(*extp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) atomic_set(&buip->bui_next_extent, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) xfs_trans_add_item(tp, &buip->bui_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) set_bit(XFS_LI_DIRTY, &buip->bui_item.li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return &buip->bui_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static const struct xfs_item_ops xfs_bui_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .iop_size = xfs_bui_item_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .iop_format = xfs_bui_item_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .iop_unpin = xfs_bui_item_unpin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .iop_release = xfs_bui_item_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .iop_recover = xfs_bui_item_recover,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .iop_match = xfs_bui_item_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .iop_relog = xfs_bui_item_relog,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * Copy an BUI format buffer from the given buf, and into the destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * BUI format structure. The BUI/BUD items were designed not to need any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * special alignment handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) xfs_bui_copy_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct xfs_log_iovec *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct xfs_bui_log_format *dst_bui_fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct xfs_bui_log_format *src_bui_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) uint len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) src_bui_fmt = buf->i_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) len = xfs_bui_log_format_sizeof(src_bui_fmt->bui_nextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (buf->i_len == len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) memcpy(dst_bui_fmt, src_bui_fmt, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * This routine is called to create an in-core extent bmap update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * item from the bui format structure which was logged on disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * It allocates an in-core bui, copies the extents from the format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * structure into it, and adds the bui to the AIL with the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * LSN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) xlog_recover_bui_commit_pass2(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct xlog *log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct list_head *buffer_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct xlog_recover_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct xfs_mount *mp = log->l_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct xfs_bui_log_item *buip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct xfs_bui_log_format *bui_formatp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) bui_formatp = item->ri_buf[0].i_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) buip = xfs_bui_init(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) error = xfs_bui_copy_format(&item->ri_buf[0], &buip->bui_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) xfs_bui_item_free(buip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) atomic_set(&buip->bui_next_extent, bui_formatp->bui_nextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * Insert the intent into the AIL directly and drop one reference so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * that finishing or canceling the work will drop the other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) xfs_trans_ail_insert(log->l_ailp, &buip->bui_item, lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) xfs_bui_release(buip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) const struct xlog_recover_item_ops xlog_bui_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .item_type = XFS_LI_BUI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .commit_pass2 = xlog_recover_bui_commit_pass2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * This routine is called when an BUD format structure is found in a committed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * transaction in the log. Its purpose is to cancel the corresponding BUI if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * was still in the log. To do this it searches the AIL for the BUI with an id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * equal to that in the BUD format structure. If we find it we drop the BUD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * reference, which removes the BUI from the AIL and frees it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) xlog_recover_bud_commit_pass2(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct xlog *log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct list_head *buffer_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct xlog_recover_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct xfs_bud_log_format *bud_formatp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) bud_formatp = item->ri_buf[0].i_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) xlog_recover_release_intent(log, XFS_LI_BUI, bud_formatp->bud_bui_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) const struct xlog_recover_item_ops xlog_bud_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) .item_type = XFS_LI_BUD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) .commit_pass2 = xlog_recover_bud_commit_pass2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) };