^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) 2008-2010, 2013 Dave Chinner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * All Rights Reserved.
^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_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_trans_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_icreate_item.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_log_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_log_recover.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "xfs_ialloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "xfs_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) kmem_zone_t *xfs_icreate_zone; /* inode create item zone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static inline struct xfs_icreate_item *ICR_ITEM(struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return container_of(lip, struct xfs_icreate_item, ic_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * This returns the number of iovecs needed to log the given inode item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * We only need one iovec for the icreate log structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) xfs_icreate_item_size(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int *nvecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int *nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *nvecs += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *nbytes += sizeof(struct xfs_icreate_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^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) * This is called to fill in the vector of log iovecs for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * given inode create log item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) xfs_icreate_item_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct xfs_log_item *lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct xfs_log_vec *lv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct xfs_icreate_item *icp = ICR_ITEM(lip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct xfs_log_iovec *vecp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICREATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) &icp->ic_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) sizeof(struct xfs_icreate_log));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) xfs_icreate_item_release(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct xfs_log_item *lip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) kmem_cache_free(xfs_icreate_zone, ICR_ITEM(lip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static const struct xfs_item_ops xfs_icreate_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .iop_size = xfs_icreate_item_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .iop_format = xfs_icreate_item_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .iop_release = xfs_icreate_item_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^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) * Initialize the inode log item for a newly allocated (in-core) inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Inode extents can only reside within an AG. Hence specify the starting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * block for the inode chunk by offset within an AG as well as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * length of the allocated extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * This joins the item to the transaction and marks it dirty so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * that we don't need a separate call to do this, nor does the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * caller need to know anything about the icreate item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) xfs_icreate_log(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) xfs_agnumber_t agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) xfs_agblock_t agbno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned int inode_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) xfs_agblock_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned int generation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct xfs_icreate_item *icp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) icp = kmem_cache_zalloc(xfs_icreate_zone, GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) xfs_log_item_init(tp->t_mountp, &icp->ic_item, XFS_LI_ICREATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) &xfs_icreate_item_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) icp->ic_format.icl_type = XFS_LI_ICREATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) icp->ic_format.icl_size = 1; /* single vector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) icp->ic_format.icl_ag = cpu_to_be32(agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) icp->ic_format.icl_agbno = cpu_to_be32(agbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) icp->ic_format.icl_count = cpu_to_be32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) icp->ic_format.icl_isize = cpu_to_be32(inode_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) icp->ic_format.icl_length = cpu_to_be32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) icp->ic_format.icl_gen = cpu_to_be32(generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) xfs_trans_add_item(tp, &icp->ic_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) tp->t_flags |= XFS_TRANS_DIRTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) set_bit(XFS_LI_DIRTY, &icp->ic_item.li_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static enum xlog_recover_reorder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) xlog_recover_icreate_reorder(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct xlog_recover_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * Inode allocation buffers must be replayed before subsequent inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * items try to modify those buffers. ICREATE items are the logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * equivalent of logging a newly initialized inode buffer, so recover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * these at the same time that we recover logged buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return XLOG_REORDER_BUFFER_LIST;
^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) * This routine is called when an inode create format structure is found in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * committed transaction in the log. It's purpose is to initialise the inodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * being allocated on disk. This requires us to get inode cluster buffers that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * match the range to be initialised, stamped with inode templates and written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * by delayed write so that subsequent modifications will hit the cached buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * and only need writing out at the end of recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) xlog_recover_icreate_commit_pass2(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct xlog *log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct list_head *buffer_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct xlog_recover_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) xfs_lsn_t lsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct xfs_mount *mp = log->l_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct xfs_icreate_log *icl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct xfs_ino_geometry *igeo = M_IGEO(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) xfs_agnumber_t agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) xfs_agblock_t agbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned int isize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) xfs_agblock_t length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int bb_per_cluster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int cancel_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int nbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) icl = (struct xfs_icreate_log *)item->ri_buf[0].i_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (icl->icl_type != XFS_LI_ICREATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (icl->icl_size != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad icl size");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) agno = be32_to_cpu(icl->icl_ag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (agno >= mp->m_sb.sb_agcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agno");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) agbno = be32_to_cpu(icl->icl_agbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!agbno || agbno == NULLAGBLOCK || agbno >= mp->m_sb.sb_agblocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad agbno");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) isize = be32_to_cpu(icl->icl_isize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (isize != mp->m_sb.sb_inodesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad isize");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) count = be32_to_cpu(icl->icl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) length = be32_to_cpu(icl->icl_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!length || length >= mp->m_sb.sb_agblocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * The inode chunk is either full or sparse and we only support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * m_ino_geo.ialloc_min_blks sized sparse allocations at this time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (length != igeo->ialloc_blks &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) length != igeo->ialloc_min_blks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) xfs_warn(log->l_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) "%s: unsupported chunk length", __FUNCTION__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* verify inode count is consistent with extent length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if ((count >> mp->m_sb.sb_inopblog) != length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) xfs_warn(log->l_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) "%s: inconsistent inode count and chunk length",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __FUNCTION__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * The icreate transaction can cover multiple cluster buffers and these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * buffers could have been freed and reused. Check the individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * buffers for cancellation so we don't overwrite anything written after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * a cancellation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) bb_per_cluster = XFS_FSB_TO_BB(mp, igeo->blocks_per_cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) nbufs = length / igeo->blocks_per_cluster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) for (i = 0, cancel_count = 0; i < nbufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) xfs_daddr_t daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) daddr = XFS_AGB_TO_DADDR(mp, agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) agbno + i * igeo->blocks_per_cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (xlog_is_buffer_cancelled(log, daddr, bb_per_cluster))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) cancel_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * We currently only use icreate for a single allocation at a time. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * means we should expect either all or none of the buffers to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * cancelled. Be conservative and skip replay if at least one buffer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * cancelled, but warn the user that something is awry if the buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * are not consistent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * XXX: This must be refined to only skip cancelled clusters once we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * icreate for multiple chunk allocations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ASSERT(!cancel_count || cancel_count == nbufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (cancel_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (cancel_count != nbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) xfs_warn(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) "WARNING: partial inode chunk cancellation, skipped icreate.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) trace_xfs_log_recover_icreate_cancel(log, icl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return 0;
^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) trace_xfs_log_recover_icreate_recover(log, icl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return xfs_ialloc_inode_init(mp, NULL, buffer_list, count, agno, agbno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) length, be32_to_cpu(icl->icl_gen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) const struct xlog_recover_item_ops xlog_icreate_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .item_type = XFS_LI_ICREATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .reorder = xlog_recover_icreate_reorder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .commit_pass2 = xlog_recover_icreate_commit_pass2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) };