^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) 2000-2006 Silicon Graphics, Inc.
^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_bit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_defer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_dir2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "xfs_alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "xfs_bmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "xfs_bmap_util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "xfs_bmap_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "xfs_rtalloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "xfs_errortag.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "xfs_error.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) #include "xfs_trans_space.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "xfs_buf_item.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "xfs_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "xfs_attr_leaf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "xfs_filestream.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "xfs_rmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "xfs_ag_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "xfs_refcount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "xfs_icache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "xfs_iomap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) kmem_zone_t *xfs_bmap_free_item_zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Miscellaneous helper functions
^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) * Compute and fill in the value of the maximum depth of a bmap btree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * in this filesystem. Done once, during mount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) xfs_bmap_compute_maxlevels(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) xfs_mount_t *mp, /* file system mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int whichfork) /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int level; /* btree level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) uint maxblocks; /* max blocks at this level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) uint maxleafents; /* max leaf entries possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int maxrootrecs; /* max records in root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int minleafrecs; /* min records in leaf block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int minnoderecs; /* min records in node block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int sz; /* root block size */
^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) * The maximum number of extents in a file, hence the maximum number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * leaf entries, is controlled by the size of the on-disk extent count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * either a signed 32-bit number for the data fork, or a signed 16-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * number for the attr fork.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Note that we can no longer assume that if we are in ATTR1 that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * the fork offset of all the inodes will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * (xfs_default_attroffset(ip) >> 3) because we could have mounted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * with ATTR2 and then mounted back with ATTR1, keeping the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * di_forkoff's fixed but probably at various positions. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * for both ATTR1 and ATTR2 we have to assume the worst case scenario
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * of a minimum size available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (whichfork == XFS_DATA_FORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) maxleafents = MAXEXTNUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) maxleafents = MAXAEXTNUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) minleafrecs = mp->m_bmap_dmnr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) minnoderecs = mp->m_bmap_dmnr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) for (level = 1; maxblocks > 1; level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (maxblocks <= maxrootrecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) maxblocks = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) mp->m_bm_maxlevels[whichfork] = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) xfs_bmbt_lookup_eq(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct xfs_bmbt_irec *irec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int *stat) /* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) cur->bc_rec.b = *irec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) xfs_bmbt_lookup_first(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int *stat) /* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) cur->bc_rec.b.br_startoff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) cur->bc_rec.b.br_startblock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) cur->bc_rec.b.br_blockcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^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) * Check if the inode needs to be converted to btree format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return whichfork != XFS_COW_FORK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ifp->if_format == XFS_DINODE_FMT_EXTENTS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Check if the inode should be converted to extent format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return whichfork != XFS_COW_FORK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ifp->if_format == XFS_DINODE_FMT_BTREE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Update the record referred to by cur to the value given by irec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * This either works (return 0) or gets an EFSCORRUPTED error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) xfs_bmbt_update(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct xfs_bmbt_irec *irec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) union xfs_btree_rec rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) xfs_bmbt_disk_set_all(&rec.bmbt, irec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return xfs_btree_update(cur, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^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) * Compute the worst-case number of indirect blocks that will be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * for ip's delayed extent of length "len".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) STATIC xfs_filblks_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) xfs_bmap_worst_indlen(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) xfs_filblks_t len) /* delayed extent length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int level; /* btree level number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int maxrecs; /* maximum record count at this level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) xfs_mount_t *mp; /* mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) xfs_filblks_t rval; /* return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) maxrecs = mp->m_bmap_dmxr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) for (level = 0, rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) len += maxrecs - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) do_div(len, maxrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) rval += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (len == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) level - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) maxrecs = mp->m_bmap_dmxr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Calculate the default attribute fork offset for newly created inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) uint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) xfs_default_attroffset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct xfs_inode *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) uint offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (mp->m_sb.sb_inodesize == 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) offset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ASSERT(offset < XFS_LITINO(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^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) * Helper routine to reset inode di_forkoff field when switching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * attribute fork from local to extent format - we reset it where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * possible to make space available for inline data fork extents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) xfs_bmap_forkoff_reset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) xfs_inode_t *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (whichfork == XFS_ATTR_FORK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ip->i_df.if_format != XFS_DINODE_FMT_DEV &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ip->i_df.if_format != XFS_DINODE_FMT_BTREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (dfl_forkoff > ip->i_d.di_forkoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ip->i_d.di_forkoff = dfl_forkoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) STATIC struct xfs_buf *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) xfs_bmap_get_bp(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) xfs_fsblock_t bno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct xfs_log_item *lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (!cur->bc_bufs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (XFS_BUF_ADDR(cur->bc_bufs[i]) == bno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return cur->bc_bufs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Chase down all the log items to see if the bp is there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) list_for_each_entry(lip, &cur->bc_tp->t_items, li_trans) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct xfs_buf_log_item *bip = (struct xfs_buf_log_item *)lip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (bip->bli_item.li_type == XFS_LI_BUF &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) XFS_BUF_ADDR(bip->bli_buf) == bno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return bip->bli_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) xfs_check_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct xfs_btree_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) xfs_mount_t *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) short sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int i, j, dmxr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) __be64 *pp, *thispa; /* pointer to block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) xfs_bmbt_key_t *prevp, *keyp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ASSERT(be16_to_cpu(block->bb_level) > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) prevp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) for( i = 1; i <= xfs_btree_get_numrecs(block); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dmxr = mp->m_bmap_dmxr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) keyp = XFS_BMBT_KEY_ADDR(mp, block, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (prevp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ASSERT(be64_to_cpu(prevp->br_startoff) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) be64_to_cpu(keyp->br_startoff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) prevp = keyp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * Compare the block numbers to see if there are dups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (*thispa == *pp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) xfs_warn(mp, "%s: thispa(%d) == pp(%d) %Ld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) __func__, j, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) (unsigned long long)be64_to_cpu(*thispa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) xfs_err(mp, "%s: ptrs are equal in node\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * Check that the extents for the inode ip are in the right order in all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * btree leaves. THis becomes prohibitively expensive for large extent count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * files, so don't bother with inodes that have more than 10,000 extents in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * them. The btree record ordering checks will still be done, so for such large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * bmapbt constructs that is going to catch most corruptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) xfs_bmap_check_leaf_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) xfs_btree_cur_t *cur, /* btree cursor or null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int whichfork) /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct xfs_btree_block *block; /* current btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) xfs_fsblock_t bno; /* block # of "block" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) xfs_buf_t *bp; /* buffer for "block" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) xfs_extnum_t i=0, j; /* index into the extents list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int level; /* btree level, for checking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) __be64 *pp; /* pointer to block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) xfs_bmbt_rec_t *ep; /* pointer to current extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) xfs_bmbt_rec_t *nextp; /* pointer to next extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int bp_release = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ifp->if_format != XFS_DINODE_FMT_BTREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* skip large extent count inodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (ip->i_df.if_nextents > 10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) bno = NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) block = ifp->if_broot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) level = be16_to_cpu(block->bb_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ASSERT(level > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) bno = be64_to_cpu(*pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ASSERT(bno != NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * Go down the tree until leaf level is reached, following the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * pointer (leftmost) at each level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) while (level-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* See if buf is in cur first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) bp_release = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) bp_release = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) XFS_BMAP_BTREE_REF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) &xfs_bmbt_buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) goto error_norelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Check this block for basic sanity (increasing keys and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * no duplicate blocks).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) xfs_check_block(block, mp, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) bno = be64_to_cpu(*pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, bno))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (bp_release) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) bp_release = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) xfs_trans_brelse(NULL, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * Here with bp and block set to the leftmost leaf node in the tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) i = 0;
^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) * Loop over all leaf nodes checking that all extents are in the right order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) xfs_fsblock_t nextbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) xfs_extnum_t num_recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) num_recs = xfs_btree_get_numrecs(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * Read-ahead the next leaf block, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * Check all the extents to make sure they are OK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * If we had a previous block, the last entry should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * conform with the first entry in this one.
^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) ep = XFS_BMBT_REC_ADDR(mp, block, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ASSERT(xfs_bmbt_disk_get_startoff(&last) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) xfs_bmbt_disk_get_blockcount(&last) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) xfs_bmbt_disk_get_startoff(ep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) for (j = 1; j < num_recs; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ASSERT(xfs_bmbt_disk_get_startoff(ep) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) xfs_bmbt_disk_get_blockcount(ep) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) xfs_bmbt_disk_get_startoff(nextp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ep = nextp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) last = *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) i += num_recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (bp_release) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) bp_release = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) xfs_trans_brelse(NULL, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) bno = nextbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * If we've reached the end, stop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (bno == NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) bp_release = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) bp_release = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) XFS_BMAP_BTREE_REF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) &xfs_bmbt_buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) goto error_norelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) xfs_warn(mp, "%s: at error0", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (bp_release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) xfs_trans_brelse(NULL, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) error_norelse:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) xfs_warn(mp, "%s: BAD after btree leaves for %d extents",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) __func__, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) xfs_err(mp, "%s: CORRUPTED BTREE OR SOMETHING", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * Validate that the bmbt_irecs being returned from bmapi are valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * given the caller's original parameters. Specifically check the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * ranges of the returned irecs to ensure that they only extend beyond
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * the given parameters if the XFS_BMAPI_ENTIRE flag was set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) xfs_bmap_validate_ret(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) xfs_fileoff_t bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) xfs_bmbt_irec_t *mval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int nmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int ret_nmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int i; /* index to map values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ASSERT(ret_nmap <= nmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) for (i = 0; i < ret_nmap; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ASSERT(mval[i].br_blockcount > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (!(flags & XFS_BMAPI_ENTIRE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ASSERT(mval[i].br_startoff >= bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ASSERT(mval[i].br_blockcount <= len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ASSERT(mval[i].br_startoff + mval[i].br_blockcount <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) bno + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ASSERT(mval[i].br_startoff < bno + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ASSERT(mval[i].br_startoff + mval[i].br_blockcount >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ASSERT(i == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) mval[i - 1].br_startoff + mval[i - 1].br_blockcount ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) mval[i].br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) mval[i].br_startblock != HOLESTARTBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ASSERT(mval[i].br_state == XFS_EXT_NORM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mval[i].br_state == XFS_EXT_UNWRITTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^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) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) #define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * bmap free list manipulation functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * Add the extent to the list of extents to be free at transaction end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * The list is maintained sorted (by block number).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) __xfs_bmap_add_free(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) xfs_fsblock_t bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) const struct xfs_owner_info *oinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) bool skip_discard)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct xfs_extent_free_item *new; /* new element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct xfs_mount *mp = tp->t_mountp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) xfs_agnumber_t agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) xfs_agblock_t agbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ASSERT(bno != NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ASSERT(len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ASSERT(len <= MAXEXTLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ASSERT(!isnullstartblock(bno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) agno = XFS_FSB_TO_AGNO(mp, bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) agbno = XFS_FSB_TO_AGBNO(mp, bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ASSERT(agno < mp->m_sb.sb_agcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ASSERT(agbno < mp->m_sb.sb_agblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ASSERT(len < mp->m_sb.sb_agblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ASSERT(xfs_bmap_free_item_zone != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) new = kmem_cache_alloc(xfs_bmap_free_item_zone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) new->xefi_startblock = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) new->xefi_blockcount = (xfs_extlen_t)len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (oinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) new->xefi_oinfo = *oinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) new->xefi_skip_discard = skip_discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) trace_xfs_bmap_free_defer(tp->t_mountp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * Inode fork format manipulation functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * Convert the inode format to extent format if it currently is in btree format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * but the extent list is small enough that it fits into the extent format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * Since the extents are already in-core, all we have to do is give up the space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * for the btree root and pitch the leaf block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) xfs_bmap_btree_to_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct xfs_inode *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct xfs_btree_cur *cur, /* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int *logflagsp, /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int whichfork) /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct xfs_btree_block *rblock = ifp->if_broot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct xfs_btree_block *cblock;/* child btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) xfs_fsblock_t cbno; /* child block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) xfs_buf_t *cbp; /* child block's buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) __be64 *pp; /* ptr to block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct xfs_owner_info oinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* check if we actually need the extent format first: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!xfs_bmap_wants_extents(ip, whichfork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ASSERT(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ASSERT(whichfork != XFS_COW_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ASSERT(ifp->if_flags & XFS_IFEXTENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ASSERT(be16_to_cpu(rblock->bb_level) == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) cbno = be64_to_cpu(*pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) &xfs_bmbt_buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) cblock = XFS_BUF_TO_BLOCK(cbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) xfs_bmap_add_free(cur->bc_tp, cbno, 1, &oinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ip->i_d.di_nblocks--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) xfs_trans_binval(tp, cbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (cur->bc_bufs[0] == cbp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) cur->bc_bufs[0] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) xfs_iroot_realloc(ip, -1, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ASSERT(ifp->if_broot == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ASSERT((ifp->if_flags & XFS_IFBROOT) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ifp->if_format = XFS_DINODE_FMT_EXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * Convert an extents-format file into a btree-format file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * The new file will have a root block (in the inode) and a single child block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) xfs_bmap_extents_to_btree(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct xfs_inode *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct xfs_btree_cur **curp, /* cursor returned to caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int wasdel, /* converting a delayed alloc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int *logflagsp, /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) int whichfork) /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct xfs_btree_block *ablock; /* allocated (child) bt block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct xfs_buf *abp; /* buffer for ablock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct xfs_alloc_arg args; /* allocation arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct xfs_bmbt_rec *arp; /* child record pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct xfs_btree_block *block; /* btree root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct xfs_btree_cur *cur; /* bmap btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct xfs_ifork *ifp; /* inode fork pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct xfs_bmbt_key *kp; /* root block key pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct xfs_mount *mp; /* mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) xfs_bmbt_ptr_t *pp; /* root block address pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct xfs_bmbt_irec rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) xfs_extnum_t cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ASSERT(whichfork != XFS_COW_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * Make space in the inode incore. This needs to be undone if we fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * to expand the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) xfs_iroot_realloc(ip, 1, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ifp->if_flags |= XFS_IFBROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * Fill in the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) block = ifp->if_broot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) xfs_btree_init_block_int(mp, block, XFS_BUF_DADDR_NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) XFS_BTNUM_BMAP, 1, 1, ip->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) XFS_BTREE_LONG_PTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * Need a cursor. Can't allocate until bb_level is filled in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) cur->bc_ino.flags = wasdel ? XFS_BTCUR_BMBT_WASDEL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * Convert to a btree with two levels, one record in root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ifp->if_format = XFS_DINODE_FMT_BTREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) memset(&args, 0, sizeof(args));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) args.tp = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) args.mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) xfs_rmap_ino_bmbt_owner(&args.oinfo, ip->i_ino, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (tp->t_firstblock == NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) args.type = XFS_ALLOCTYPE_START_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) } else if (tp->t_flags & XFS_TRANS_LOWMODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) args.type = XFS_ALLOCTYPE_START_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) args.fsbno = tp->t_firstblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) args.type = XFS_ALLOCTYPE_NEAR_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) args.fsbno = tp->t_firstblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) args.minlen = args.maxlen = args.prod = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) args.wasdel = wasdel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) *logflagsp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) error = xfs_alloc_vextent(&args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) goto out_root_realloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) error = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) goto out_root_realloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * Allocation can't fail, the space was reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ASSERT(tp->t_firstblock == NULLFSBLOCK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) args.agno >= XFS_FSB_TO_AGNO(mp, tp->t_firstblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) tp->t_firstblock = args.fsbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) cur->bc_ino.allocated++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ip->i_d.di_nblocks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) XFS_FSB_TO_DADDR(mp, args.fsbno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) mp->m_bsize, 0, &abp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) goto out_unreserve_dquot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * Fill in the child block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) abp->b_ops = &xfs_bmbt_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) ablock = XFS_BUF_TO_BLOCK(abp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) xfs_btree_init_block_int(mp, ablock, abp->b_bn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) XFS_BTNUM_BMAP, 0, 0, ip->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) XFS_BTREE_LONG_PTRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) for_each_xfs_iext(ifp, &icur, &rec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (isnullstartblock(rec.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) arp = XFS_BMBT_REC_ADDR(mp, ablock, 1 + cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) xfs_bmbt_disk_set_all(arp, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ASSERT(cnt == ifp->if_nextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) xfs_btree_set_numrecs(ablock, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * Fill in the root key and pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) kp = XFS_BMBT_KEY_ADDR(mp, block, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) arp = XFS_BMBT_REC_ADDR(mp, ablock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) be16_to_cpu(block->bb_level)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) *pp = cpu_to_be64(args.fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * Do all this logging at the end so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * the root is at the right level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) xfs_btree_log_block(cur, abp, XFS_BB_ALL_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ASSERT(*curp == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) *curp = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) out_unreserve_dquot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) out_root_realloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) xfs_iroot_realloc(ip, -1, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) ifp->if_format = XFS_DINODE_FMT_EXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ASSERT(ifp->if_broot == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * Convert a local file to an extents file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * This code is out of bounds for data forks of regular files,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * since the file data needs to get logged so things will stay consistent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * (The bmap-level manipulations are ok, though).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) xfs_bmap_local_to_extents_empty(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ASSERT(whichfork != XFS_COW_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ASSERT(ifp->if_bytes == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ASSERT(ifp->if_nextents == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) xfs_bmap_forkoff_reset(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ifp->if_flags &= ~XFS_IFINLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ifp->if_flags |= XFS_IFEXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ifp->if_u1.if_root = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ifp->if_height = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ifp->if_format = XFS_DINODE_FMT_EXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) xfs_bmap_local_to_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) xfs_extlen_t total, /* total blocks needed by transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) int *logflagsp, /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) void (*init_fn)(struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct xfs_buf *bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct xfs_ifork *ifp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) int flags; /* logging flags returned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct xfs_ifork *ifp; /* inode fork pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) xfs_alloc_arg_t args; /* allocation arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) xfs_buf_t *bp; /* buffer for extent block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct xfs_bmbt_irec rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * We don't want to deal with the case of keeping inode data inline yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * So sending the data fork of a regular inode is invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!ifp->if_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) flags = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ASSERT((ifp->if_flags & (XFS_IFINLINE|XFS_IFEXTENTS)) == XFS_IFINLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) memset(&args, 0, sizeof(args));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) args.tp = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) args.mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) xfs_rmap_ino_owner(&args.oinfo, ip->i_ino, whichfork, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * Allocate a block. We know we need only one, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * file currently fits in an inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (tp->t_firstblock == NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) args.type = XFS_ALLOCTYPE_START_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) args.fsbno = tp->t_firstblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) args.type = XFS_ALLOCTYPE_NEAR_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) args.total = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) args.minlen = args.maxlen = args.prod = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) error = xfs_alloc_vextent(&args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /* Can't fail, the space was reserved. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ASSERT(args.fsbno != NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ASSERT(args.len == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) tp->t_firstblock = args.fsbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) error = xfs_trans_get_buf(tp, args.mp->m_ddev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) XFS_FSB_TO_DADDR(args.mp, args.fsbno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) args.mp->m_bsize, 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * Initialize the block, copy the data and log the remote buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * The callout is responsible for logging because the remote format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * might differ from the local format and thus we don't know how much to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * log here. Note that init_fn must also set the buffer log item type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) init_fn(tp, bp, ip, ifp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /* account for the change in fork size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) xfs_bmap_local_to_extents_empty(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) flags |= XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) ifp->if_u1.if_root = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) ifp->if_height = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) rec.br_startoff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) rec.br_startblock = args.fsbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) rec.br_blockcount = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) rec.br_state = XFS_EXT_NORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) xfs_iext_first(ifp, &icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) xfs_iext_insert(ip, &icur, &rec, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) ifp->if_nextents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ip->i_d.di_nblocks = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) xfs_trans_mod_dquot_byino(tp, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) XFS_TRANS_DQ_BCOUNT, 1L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) flags |= xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) *logflagsp = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * Called from xfs_bmap_add_attrfork to handle btree format files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) xfs_bmap_add_attrfork_btree(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int *flags) /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) xfs_btree_cur_t *cur; /* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) xfs_mount_t *mp; /* file system mount struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int stat; /* newroot status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) *flags |= XFS_ILOG_DBROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) error = xfs_bmbt_lookup_first(cur, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* must be at least one entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (XFS_IS_CORRUPT(mp, stat != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if ((error = xfs_btree_new_iroot(cur, flags, &stat)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (stat == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) cur->bc_ino.allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * Called from xfs_bmap_add_attrfork to handle extents format files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) xfs_bmap_add_attrfork_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct xfs_inode *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int *flags) /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) xfs_btree_cur_t *cur; /* bmap btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (ip->i_df.if_nextents * sizeof(struct xfs_bmbt_rec) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) XFS_IFORK_DSIZE(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) XFS_DATA_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) cur->bc_ino.allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * Called from xfs_bmap_add_attrfork to handle local format files. Each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * different data fork content type needs a different callout to do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * conversion. Some are basic and only require special block initialisation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * callouts for the data formating, others (directories) are so specialised they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * handle everything themselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * XXX (dgc): investigate whether directory conversion can use the generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * formatting callout. It should be possible - it's just a very complex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * formatter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) xfs_bmap_add_attrfork_local(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct xfs_inode *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) int *flags) /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct xfs_da_args dargs; /* args for dir/attr code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (S_ISDIR(VFS_I(ip)->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) memset(&dargs, 0, sizeof(dargs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dargs.geo = ip->i_mount->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) dargs.dp = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) dargs.total = dargs.geo->fsbcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dargs.whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) dargs.trans = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return xfs_dir2_sf_to_block(&dargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (S_ISLNK(VFS_I(ip)->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return xfs_bmap_local_to_extents(tp, ip, 1, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) XFS_DATA_FORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) xfs_symlink_local_to_remote);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /* should only be called for types that support local format data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* Set an inode attr fork off based on the format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) xfs_bmap_set_attrforkoff(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int *version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) switch (ip->i_df.if_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) case XFS_DINODE_FMT_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) case XFS_DINODE_FMT_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) case XFS_DINODE_FMT_EXTENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) case XFS_DINODE_FMT_BTREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (!ip->i_d.di_forkoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) else if ((ip->i_mount->m_flags & XFS_MOUNT_ATTR2) && version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) *version = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * Convert inode from non-attributed to attributed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * Must not be in a transaction, ip must not be locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) int /* error code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) xfs_bmap_add_attrfork(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) int size, /* space new attribute needs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) int rsvd) /* xact may use reserved blks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) xfs_mount_t *mp; /* mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) xfs_trans_t *tp; /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) int blks; /* space reservation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) int version = 1; /* superblock attr version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) int logflags; /* logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ASSERT(XFS_IFORK_Q(ip) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) blks = XFS_ADDAFORK_SPACE_RES(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_addafork, blks, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) rsvd ? XFS_TRANS_RESERVE : 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) XFS_QMOPT_RES_REGBLKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) goto trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (XFS_IFORK_Q(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) goto trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) xfs_trans_ijoin(tp, ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) error = xfs_bmap_set_attrforkoff(ip, size, &version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) goto trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ASSERT(ip->i_afp == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ip->i_afp = kmem_cache_zalloc(xfs_ifork_zone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) ip->i_afp->if_flags = XFS_IFEXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) switch (ip->i_df.if_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) case XFS_DINODE_FMT_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) error = xfs_bmap_add_attrfork_local(tp, ip, &logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) case XFS_DINODE_FMT_EXTENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) error = xfs_bmap_add_attrfork_extents(tp, ip, &logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case XFS_DINODE_FMT_BTREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) error = xfs_bmap_add_attrfork_btree(tp, ip, &logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (logflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) xfs_trans_log_inode(tp, ip, logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) goto trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (!xfs_sb_version_hasattr(&mp->m_sb) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) bool log_sb = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) spin_lock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (!xfs_sb_version_hasattr(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) xfs_sb_version_addattr(&mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) log_sb = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) xfs_sb_version_addattr2(&mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) log_sb = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) spin_unlock(&mp->m_sb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (log_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) xfs_log_sb(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) trans_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) xfs_trans_cancel(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * Internal and external extent tree search functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct xfs_iread_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) xfs_extnum_t loaded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* Stuff every bmbt record from this block into the incore extent map. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) xfs_iread_bmbt_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) int level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct xfs_iread_state *ir = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct xfs_mount *mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct xfs_inode *ip = cur->bc_ino.ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct xfs_btree_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct xfs_buf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct xfs_bmbt_rec *frp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) xfs_extnum_t num_recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) xfs_extnum_t j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) int whichfork = cur->bc_ino.whichfork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* Abort if we find more records than nextents. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) num_recs = xfs_btree_get_numrecs(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (unlikely(ir->loaded + num_recs > ifp->if_nextents)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) xfs_warn(ip->i_mount, "corrupt dinode %llu, (btree extents).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) (unsigned long long)ip->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) sizeof(*block), __this_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* Copy records into the incore cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) frp = XFS_BMBT_REC_ADDR(mp, block, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) for (j = 0; j < num_recs; j++, frp++, ir->loaded++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct xfs_bmbt_irec new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) xfs_failaddr_t fa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) xfs_bmbt_disk_get_all(frp, &new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) fa = xfs_bmap_validate_extent(ip, whichfork, &new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (fa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) xfs_inode_verifier_error(ip, -EFSCORRUPTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) "xfs_iread_extents(2)", frp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) sizeof(*frp), fa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) xfs_iext_insert(ip, &ir->icur, &new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) xfs_bmap_fork_to_state(whichfork));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) trace_xfs_read_extent(ip, &ir->icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) xfs_bmap_fork_to_state(whichfork), _THIS_IP_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) xfs_iext_next(ifp, &ir->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * Read in extents from a btree-format inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) xfs_iread_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) struct xfs_iread_state ir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct xfs_btree_cur *cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (XFS_IS_CORRUPT(mp, ifp->if_format != XFS_DINODE_FMT_BTREE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ir.loaded = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) xfs_iext_first(ifp, &ir.icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) error = xfs_btree_visit_blocks(cur, xfs_iread_bmbt_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) XFS_BTREE_VISIT_RECORDS, &ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (XFS_IS_CORRUPT(mp, ir.loaded != ifp->if_nextents)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ASSERT(ir.loaded == xfs_iext_count(ifp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ifp->if_flags |= XFS_IFEXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) xfs_iext_destroy(ifp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) * Returns the relative block number of the first unused block(s) in the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) * fork with at least "len" logically contiguous blocks free. This is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * lowest-address hole if the fork has holes, else the first block past the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * of fork. Return 0 if the fork is currently local (in-inode).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) xfs_bmap_first_unused(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) struct xfs_inode *ip, /* incore inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) xfs_extlen_t len, /* size of hole to find */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) xfs_fileoff_t *first_unused, /* unused block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) int whichfork) /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct xfs_bmbt_irec got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) xfs_fileoff_t lastaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) xfs_fileoff_t lowest, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (ifp->if_format == XFS_DINODE_FMT_LOCAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) *first_unused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ASSERT(xfs_ifork_has_extents(ifp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) lowest = max = *first_unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) for_each_xfs_iext(ifp, &icur, &got) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * See if the hole before this extent will work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (got.br_startoff >= lowest + len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) got.br_startoff - max >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) lastaddr = got.br_startoff + got.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) max = XFS_FILEOFF_MAX(lastaddr, lowest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) *first_unused = max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * Returns the file-relative block number of the last block - 1 before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) * last_block (input value) in the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * This is not based on i_size, it is based on the extent records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) * Returns 0 for local files, as they do not have extent records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) xfs_bmap_last_before(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct xfs_inode *ip, /* incore inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) xfs_fileoff_t *last_block, /* last block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) int whichfork) /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct xfs_bmbt_irec got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) switch (ifp->if_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case XFS_DINODE_FMT_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) *last_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) case XFS_DINODE_FMT_BTREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) case XFS_DINODE_FMT_EXTENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (!xfs_iext_lookup_extent_before(ip, ifp, last_block, &icur, &got))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) *last_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) xfs_bmap_last_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct xfs_bmbt_irec *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) int *is_empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) xfs_iext_last(ifp, &icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (!xfs_iext_get_extent(ifp, &icur, rec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) *is_empty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) *is_empty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * Check the last inode extent to determine whether this allocation will result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) * in blocks being allocated at the end of the file. When we allocate new data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) * blocks at the end of the file which do not start at the previous data block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * we will try to align the new blocks at stripe unit boundaries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * Returns 1 in bma->aeof if the file (fork) is empty as any new write will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * at, or past the EOF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) xfs_bmap_isaeof(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct xfs_bmalloca *bma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct xfs_bmbt_irec rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) int is_empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) bma->aeof = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) &is_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (is_empty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) bma->aeof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) * Check if we are allocation or past the last extent, or at least into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) * the last delayed allocated extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) bma->aeof = bma->offset >= rec.br_startoff + rec.br_blockcount ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) (bma->offset >= rec.br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) isnullstartblock(rec.br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) * Returns the file-relative block number of the first block past eof in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * the file. This is not based on i_size, it is based on the extent records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * Returns 0 for local files, as they do not have extent records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) xfs_bmap_last_offset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) xfs_fileoff_t *last_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) struct xfs_bmbt_irec rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) int is_empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) *last_block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (ifp->if_format == XFS_DINODE_FMT_LOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (error || is_empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) *last_block = rec.br_startoff + rec.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) * Returns whether the selected fork of the inode has exactly one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * block or not. For the data fork we check this matches di_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * implying the file's range is 0..bsize-1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) int /* 1=>1 block, 0=>otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) xfs_bmap_one_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) struct xfs_inode *ip, /* incore inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) int whichfork) /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) int rval; /* return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) struct xfs_bmbt_irec s; /* internal version of extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) #ifndef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (whichfork == XFS_DATA_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) #endif /* !DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) if (ifp->if_nextents != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (ifp->if_format != XFS_DINODE_FMT_EXTENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) ASSERT(ifp->if_flags & XFS_IFEXTENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) xfs_iext_first(ifp, &icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) xfs_iext_get_extent(ifp, &icur, &s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) rval = s.br_startoff == 0 && s.br_blockcount == 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (rval && whichfork == XFS_DATA_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) ASSERT(XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) * Extent tree manipulation functions used during allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * Convert a delayed allocation to a real allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) xfs_bmap_add_extent_delay_real(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) struct xfs_bmalloca *bma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) int whichfork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) struct xfs_mount *mp = bma->ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct xfs_bmbt_irec *new = &bma->got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) int i; /* temp state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) xfs_fileoff_t new_endoff; /* end offset of new entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /* left is 0, right is 1, prev is 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) int rval=0; /* return value (logging flags) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) int state = xfs_bmap_fork_to_state(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) xfs_filblks_t da_new; /* new count del alloc blocks used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) xfs_filblks_t da_old; /* old count del alloc blocks used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) xfs_filblks_t temp=0; /* value for da_new calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) int tmp_rval; /* partial logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct xfs_bmbt_irec old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) ASSERT(whichfork != XFS_ATTR_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) ASSERT(!isnullstartblock(new->br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) ASSERT(!bma->cur ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) (bma->cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) XFS_STATS_INC(mp, xs_add_exlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) #define LEFT r[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) #define RIGHT r[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) #define PREV r[2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) * Set up a bunch of variables to make the tests simpler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) xfs_iext_get_extent(ifp, &bma->icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) new_endoff = new->br_startoff + new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) ASSERT(isnullstartblock(PREV.br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) ASSERT(PREV.br_startoff <= new->br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) da_old = startblockval(PREV.br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) da_new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * Set flags determining what part of the previous delayed allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * extent is being replaced by a real allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (PREV.br_startoff == new->br_startoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) state |= BMAP_LEFT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) if (PREV.br_startoff + PREV.br_blockcount == new_endoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) state |= BMAP_RIGHT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) * Check and set flags if this segment has a left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * Don't set contiguous if the combined extent would be too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (xfs_iext_peek_prev_extent(ifp, &bma->icur, &LEFT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) state |= BMAP_LEFT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (isnullstartblock(LEFT.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) state |= BMAP_LEFT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) LEFT.br_state == new->br_state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) state |= BMAP_LEFT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) * Check and set flags if this segment has a right neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) * Don't set contiguous if the combined extent would be too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) * Also check for all-three-contiguous being too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (xfs_iext_peek_next_extent(ifp, &bma->icur, &RIGHT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) state |= BMAP_RIGHT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (isnullstartblock(RIGHT.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) state |= BMAP_RIGHT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) new_endoff == RIGHT.br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) new->br_state == RIGHT.br_state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) BMAP_RIGHT_FILLING)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) BMAP_RIGHT_FILLING) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) <= MAXEXTLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) state |= BMAP_RIGHT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * Switch out based on the FILLING and CONTIG state bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * Filling in all of a previously delayed allocation extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * The left and right neighbors are both contiguous with new.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) LEFT.br_blockcount += PREV.br_blockcount + RIGHT.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) xfs_iext_remove(bma->ip, &bma->icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) xfs_iext_remove(bma->ip, &bma->icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) xfs_iext_prev(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) ifp->if_nextents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) error = xfs_btree_delete(bma->cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) error = xfs_btree_decrement(bma->cur, 0, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) error = xfs_bmbt_update(bma->cur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) * Filling in all of a previously delayed allocation extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) * The left neighbor is contiguous, the right is not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) old = LEFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) LEFT.br_blockcount += PREV.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) xfs_iext_remove(bma->ip, &bma->icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) xfs_iext_prev(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) rval = XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) error = xfs_bmbt_update(bma->cur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * Filling in all of a previously delayed allocation extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * The right neighbor is contiguous, the left is not. Take care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) * with delay -> unwritten extent allocation here because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) * delalloc record we are overwriting is always written.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) PREV.br_startblock = new->br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) PREV.br_blockcount += RIGHT.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) PREV.br_state = new->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) xfs_iext_next(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) xfs_iext_remove(bma->ip, &bma->icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) xfs_iext_prev(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) rval = XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) error = xfs_bmbt_update(bma->cur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * Filling in all of a previously delayed allocation extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * Neither the left nor right neighbors are contiguous with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) * the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) PREV.br_startblock = new->br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) PREV.br_state = new->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) error = xfs_btree_insert(bma->cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) * Filling in the first part of a previous delayed allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) * The left neighbor is contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) old = LEFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) temp = PREV.br_blockcount - new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) startblockval(PREV.br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) LEFT.br_blockcount += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) PREV.br_blockcount = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) PREV.br_startoff += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) PREV.br_startblock = nullstartblock(da_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) xfs_iext_prev(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) rval = XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) error = xfs_bmbt_update(bma->cur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) case BMAP_LEFT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) * Filling in the first part of a previous delayed allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) * The left neighbor is not contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) xfs_iext_update_extent(bma->ip, state, &bma->icur, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) error = xfs_btree_insert(bma->cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) &bma->cur, 1, &tmp_rval, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) rval |= tmp_rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) temp = PREV.br_blockcount - new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) startblockval(PREV.br_startblock) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) (bma->cur ? bma->cur->bc_ino.allocated : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) PREV.br_startoff = new_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) PREV.br_blockcount = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) PREV.br_startblock = nullstartblock(da_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) xfs_iext_next(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) xfs_iext_insert(bma->ip, &bma->icur, &PREV, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) xfs_iext_prev(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) * Filling in the last part of a previous delayed allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) * The right neighbor is contiguous with the new allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) old = RIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) RIGHT.br_startoff = new->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) RIGHT.br_startblock = new->br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) RIGHT.br_blockcount += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) rval = XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) error = xfs_bmbt_update(bma->cur, &RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) temp = PREV.br_blockcount - new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) startblockval(PREV.br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) PREV.br_blockcount = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) PREV.br_startblock = nullstartblock(da_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) xfs_iext_next(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) xfs_iext_update_extent(bma->ip, state, &bma->icur, &RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) case BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) * Filling in the last part of a previous delayed allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) * The right neighbor is not contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) xfs_iext_update_extent(bma->ip, state, &bma->icur, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) error = xfs_btree_insert(bma->cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) &bma->cur, 1, &tmp_rval, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) rval |= tmp_rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) temp = PREV.br_blockcount - new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) startblockval(PREV.br_startblock) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) (bma->cur ? bma->cur->bc_ino.allocated : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) PREV.br_startblock = nullstartblock(da_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) PREV.br_blockcount = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) xfs_iext_insert(bma->ip, &bma->icur, &PREV, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) xfs_iext_next(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) * Filling in the middle part of a previous delayed allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) * Contiguity is impossible here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) * This case is avoided almost all the time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) * We start with a delayed allocation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) * PREV @ idx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) * and we are allocating:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * +rrrrrrrrrrrrrrrrr+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) * new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) * and we set it up for insertion as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) * new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * PREV @ idx LEFT RIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * inserted at idx + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) old = PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) /* LEFT is the new middle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) LEFT = *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) /* RIGHT is the new right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) RIGHT.br_state = PREV.br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) RIGHT.br_startoff = new_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) RIGHT.br_blockcount =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) PREV.br_startoff + PREV.br_blockcount - new_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) RIGHT.br_startblock =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) nullstartblock(xfs_bmap_worst_indlen(bma->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) RIGHT.br_blockcount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) /* truncate PREV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) PREV.br_blockcount = new->br_startoff - PREV.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) PREV.br_startblock =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) nullstartblock(xfs_bmap_worst_indlen(bma->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) PREV.br_blockcount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) xfs_iext_next(ifp, &bma->icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) xfs_iext_insert(bma->ip, &bma->icur, &RIGHT, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) xfs_iext_insert(bma->ip, &bma->icur, &LEFT, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if (bma->cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) error = xfs_btree_insert(bma->cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) &bma->cur, 1, &tmp_rval, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) rval |= tmp_rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) da_new = startblockval(PREV.br_startblock) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) startblockval(RIGHT.br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) case BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) case BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) * These cases are all impossible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) /* add reverse mapping unless caller opted out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if (!(bma->flags & XFS_BMAPI_NORMAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) xfs_rmap_map_extent(bma->tp, bma->ip, whichfork, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) /* convert to a btree if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) int tmp_logflags; /* partial log flag return val */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) ASSERT(bma->cur == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) &bma->cur, da_old > 0, &tmp_logflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) bma->logflags |= tmp_logflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) if (da_new != da_old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) xfs_mod_delalloc(mp, (int64_t)da_new - da_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (bma->cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) da_new += bma->cur->bc_ino.allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) bma->cur->bc_ino.allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /* adjust for changes in reserved delayed indirect blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (da_new != da_old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) ASSERT(state == 0 || da_new < da_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) error = xfs_mod_fdblocks(mp, (int64_t)(da_old - da_new),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) if (whichfork != XFS_COW_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) bma->logflags |= rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) #undef LEFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) #undef RIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) #undef PREV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) * Convert an unwritten allocation to a real allocation or vice versa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) xfs_bmap_add_extent_unwritten_real(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) xfs_bmbt_irec_t *new, /* new data to add to file extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) int *logflagsp) /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) xfs_btree_cur_t *cur; /* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) int i; /* temp state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) struct xfs_ifork *ifp; /* inode fork pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) xfs_fileoff_t new_endoff; /* end offset of new entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) xfs_bmbt_irec_t r[3]; /* neighbor extent entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /* left is 0, right is 1, prev is 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) int rval=0; /* return value (logging flags) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) int state = xfs_bmap_fork_to_state(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) struct xfs_bmbt_irec old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) *logflagsp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) cur = *curp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) ASSERT(!isnullstartblock(new->br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) XFS_STATS_INC(mp, xs_add_exlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) #define LEFT r[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) #define RIGHT r[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) #define PREV r[2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) * Set up a bunch of variables to make the tests simpler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) xfs_iext_get_extent(ifp, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) ASSERT(new->br_state != PREV.br_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) new_endoff = new->br_startoff + new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) ASSERT(PREV.br_startoff <= new->br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) * Set flags determining what part of the previous oldext allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) * extent is being replaced by a newext allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) if (PREV.br_startoff == new->br_startoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) state |= BMAP_LEFT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) if (PREV.br_startoff + PREV.br_blockcount == new_endoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) state |= BMAP_RIGHT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) * Check and set flags if this segment has a left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) * Don't set contiguous if the combined extent would be too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) if (xfs_iext_peek_prev_extent(ifp, icur, &LEFT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) state |= BMAP_LEFT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (isnullstartblock(LEFT.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) state |= BMAP_LEFT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) LEFT.br_state == new->br_state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) state |= BMAP_LEFT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) * Check and set flags if this segment has a right neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) * Don't set contiguous if the combined extent would be too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) * Also check for all-three-contiguous being too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (xfs_iext_peek_next_extent(ifp, icur, &RIGHT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) state |= BMAP_RIGHT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if (isnullstartblock(RIGHT.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) state |= BMAP_RIGHT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) new_endoff == RIGHT.br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) new->br_startblock + new->br_blockcount == RIGHT.br_startblock &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) new->br_state == RIGHT.br_state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) ((state & (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) BMAP_RIGHT_FILLING)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) (BMAP_LEFT_CONTIG | BMAP_LEFT_FILLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) BMAP_RIGHT_FILLING) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) <= MAXEXTLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) state |= BMAP_RIGHT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) * Switch out based on the FILLING and CONTIG state bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) switch (state & (BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) * Setting all of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) * The left and right neighbors are both contiguous with new.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) LEFT.br_blockcount += PREV.br_blockcount + RIGHT.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) xfs_iext_update_extent(ip, state, icur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) ifp->if_nextents -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if ((error = xfs_btree_delete(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if ((error = xfs_btree_decrement(cur, 0, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) if ((error = xfs_btree_delete(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) if ((error = xfs_btree_decrement(cur, 0, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) error = xfs_bmbt_update(cur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) * Setting all of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) * The left neighbor is contiguous, the right is not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) LEFT.br_blockcount += PREV.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) xfs_iext_update_extent(ip, state, icur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) ifp->if_nextents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) error = xfs_bmbt_lookup_eq(cur, &PREV, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if ((error = xfs_btree_delete(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) if ((error = xfs_btree_decrement(cur, 0, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) error = xfs_bmbt_update(cur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) * Setting all of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) * The right neighbor is contiguous, the left is not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) PREV.br_blockcount += RIGHT.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) PREV.br_state = new->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) xfs_iext_next(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) xfs_iext_update_extent(ip, state, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) ifp->if_nextents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) if ((error = xfs_btree_delete(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if ((error = xfs_btree_decrement(cur, 0, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) error = xfs_bmbt_update(cur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) * Setting all of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) * Neither the left nor right neighbors are contiguous with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) * the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) PREV.br_state = new->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) xfs_iext_update_extent(ip, state, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) rval = XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) error = xfs_bmbt_lookup_eq(cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) error = xfs_bmbt_update(cur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) * Setting the first part of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) * The left neighbor is contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) LEFT.br_blockcount += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) old = PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) PREV.br_startoff += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) PREV.br_startblock += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) PREV.br_blockcount -= new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) xfs_iext_update_extent(ip, state, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) xfs_iext_update_extent(ip, state, icur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) rval = XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) error = xfs_bmbt_lookup_eq(cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) error = xfs_bmbt_update(cur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) error = xfs_btree_decrement(cur, 0, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) error = xfs_bmbt_update(cur, &LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) case BMAP_LEFT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) * Setting the first part of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) * The left neighbor is not contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) old = PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) PREV.br_startoff += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) PREV.br_startblock += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) PREV.br_blockcount -= new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) xfs_iext_update_extent(ip, state, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) xfs_iext_insert(ip, icur, new, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) error = xfs_bmbt_lookup_eq(cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) error = xfs_bmbt_update(cur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) cur->bc_rec.b = *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) if ((error = xfs_btree_insert(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) * Setting the last part of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) * The right neighbor is contiguous with the new allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) old = PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) PREV.br_blockcount -= new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) RIGHT.br_startoff = new->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) RIGHT.br_startblock = new->br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) RIGHT.br_blockcount += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) xfs_iext_update_extent(ip, state, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) xfs_iext_next(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) xfs_iext_update_extent(ip, state, icur, &RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) rval = XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) error = xfs_bmbt_lookup_eq(cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) error = xfs_bmbt_update(cur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) error = xfs_btree_increment(cur, 0, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) error = xfs_bmbt_update(cur, &RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) case BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) * Setting the last part of a previous oldext extent to newext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) * The right neighbor is not contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) old = PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) PREV.br_blockcount -= new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) xfs_iext_update_extent(ip, state, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) xfs_iext_next(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) xfs_iext_insert(ip, icur, new, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) error = xfs_bmbt_lookup_eq(cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) error = xfs_bmbt_update(cur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) error = xfs_bmbt_lookup_eq(cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) if ((error = xfs_btree_insert(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * Setting the middle part of a previous oldext extent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) * newext. Contiguity is impossible here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) * One extent becomes three extents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) old = PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) PREV.br_blockcount = new->br_startoff - PREV.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) r[0] = *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) r[1].br_startoff = new_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) r[1].br_blockcount =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) old.br_startoff + old.br_blockcount - new_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) r[1].br_startblock = new->br_startblock + new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) r[1].br_state = PREV.br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) xfs_iext_update_extent(ip, state, icur, &PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) xfs_iext_next(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) xfs_iext_insert(ip, icur, &r[1], state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) xfs_iext_insert(ip, icur, &r[0], state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) ifp->if_nextents += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) if (cur == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) error = xfs_bmbt_lookup_eq(cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) /* new right extent - oldext */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) error = xfs_bmbt_update(cur, &r[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) /* new left extent - oldext */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) cur->bc_rec.b = PREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) if ((error = xfs_btree_insert(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) * Reset the cursor to the position of the new extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) * we are about to insert as we can't trust it after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) * the previous insert.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) error = xfs_bmbt_lookup_eq(cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) /* new middle extent - newext */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if ((error = xfs_btree_insert(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) case BMAP_LEFT_FILLING | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) case BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) case BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) case BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) * These cases are all impossible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) /* update reverse mappings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) xfs_rmap_convert_extent(mp, tp, ip, whichfork, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) /* convert to a btree if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) if (xfs_bmap_needs_btree(ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) int tmp_logflags; /* partial log flag return val */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) ASSERT(cur == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) &tmp_logflags, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) *logflagsp |= tmp_logflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) /* clear out the allocated field, done with it now in any case. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) cur->bc_ino.allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) *curp = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) xfs_bmap_check_leaf_extents(*curp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) *logflagsp |= rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) #undef LEFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) #undef RIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) #undef PREV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) * Convert a hole to a delayed allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) xfs_bmap_add_extent_hole_delay(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) xfs_bmbt_irec_t *new) /* new data to add to file extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) struct xfs_ifork *ifp; /* inode fork pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) xfs_bmbt_irec_t left; /* left neighbor extent entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) xfs_filblks_t newlen=0; /* new indirect size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) xfs_filblks_t oldlen=0; /* old indirect size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) xfs_bmbt_irec_t right; /* right neighbor extent entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) int state = xfs_bmap_fork_to_state(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) xfs_filblks_t temp; /* temp for indirect calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) ASSERT(isnullstartblock(new->br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) * Check and set flags if this segment has a left neighbor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) if (xfs_iext_peek_prev_extent(ifp, icur, &left)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) state |= BMAP_LEFT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) if (isnullstartblock(left.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) state |= BMAP_LEFT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) * Check and set flags if the current (right) segment exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) * If it doesn't exist, we're converting the hole at end-of-file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) if (xfs_iext_get_extent(ifp, icur, &right)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) state |= BMAP_RIGHT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) if (isnullstartblock(right.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) state |= BMAP_RIGHT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) * Set contiguity flags on the left and right neighbors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) * Don't let extents get too large, even if the pieces are contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) if ((state & BMAP_LEFT_VALID) && (state & BMAP_LEFT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) left.br_startoff + left.br_blockcount == new->br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) state |= BMAP_LEFT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) if ((state & BMAP_RIGHT_VALID) && (state & BMAP_RIGHT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) new->br_startoff + new->br_blockcount == right.br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) (!(state & BMAP_LEFT_CONTIG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) (left.br_blockcount + new->br_blockcount +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) right.br_blockcount <= MAXEXTLEN)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) state |= BMAP_RIGHT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) * Switch out based on the contiguity flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) * New allocation is contiguous with delayed allocations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) * on the left and on the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) * Merge all three into a single extent record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) temp = left.br_blockcount + new->br_blockcount +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) right.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) oldlen = startblockval(left.br_startblock) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) startblockval(new->br_startblock) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) startblockval(right.br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) oldlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) left.br_startblock = nullstartblock(newlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) left.br_blockcount = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) xfs_iext_update_extent(ip, state, icur, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) case BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) * New allocation is contiguous with a delayed allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) * on the left.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) * Merge the new allocation with the left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) temp = left.br_blockcount + new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) oldlen = startblockval(left.br_startblock) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) startblockval(new->br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) oldlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) left.br_blockcount = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) left.br_startblock = nullstartblock(newlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) xfs_iext_update_extent(ip, state, icur, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) case BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) * New allocation is contiguous with a delayed allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) * on the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) * Merge the new allocation with the right neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) temp = new->br_blockcount + right.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) oldlen = startblockval(new->br_startblock) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) startblockval(right.br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) oldlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) right.br_startoff = new->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) right.br_startblock = nullstartblock(newlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) right.br_blockcount = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) xfs_iext_update_extent(ip, state, icur, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) * New allocation is not contiguous with another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) * delayed allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) * Insert a new entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) oldlen = newlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) xfs_iext_insert(ip, icur, new, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) if (oldlen != newlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) ASSERT(oldlen > newlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) xfs_mod_fdblocks(ip->i_mount, (int64_t)(oldlen - newlen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) * Nothing to do for disk quota accounting here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) xfs_mod_delalloc(ip->i_mount, (int64_t)newlen - oldlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) * Convert a hole to a real allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) xfs_bmap_add_extent_hole_real(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) struct xfs_btree_cur **curp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) struct xfs_bmbt_irec *new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) int *logflagsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) struct xfs_btree_cur *cur = *curp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) int i; /* temp state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) xfs_bmbt_irec_t left; /* left neighbor extent entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) xfs_bmbt_irec_t right; /* right neighbor extent entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) int rval=0; /* return value (logging flags) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) int state = xfs_bmap_fork_to_state(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) struct xfs_bmbt_irec old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) ASSERT(!isnullstartblock(new->br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) ASSERT(!cur || !(cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) XFS_STATS_INC(mp, xs_add_exlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) * Check and set flags if this segment has a left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) if (xfs_iext_peek_prev_extent(ifp, icur, &left)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) state |= BMAP_LEFT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) if (isnullstartblock(left.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) state |= BMAP_LEFT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) * Check and set flags if this segment has a current value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) * Not true if we're inserting into the "hole" at eof.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) if (xfs_iext_get_extent(ifp, icur, &right)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) state |= BMAP_RIGHT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) if (isnullstartblock(right.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) state |= BMAP_RIGHT_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) * We're inserting a real allocation between "left" and "right".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) * Set the contiguity flags. Don't let extents get too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) if ((state & BMAP_LEFT_VALID) && !(state & BMAP_LEFT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) left.br_startoff + left.br_blockcount == new->br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) left.br_startblock + left.br_blockcount == new->br_startblock &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) left.br_state == new->br_state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) left.br_blockcount + new->br_blockcount <= MAXEXTLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) state |= BMAP_LEFT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) if ((state & BMAP_RIGHT_VALID) && !(state & BMAP_RIGHT_DELAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) new->br_startoff + new->br_blockcount == right.br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) new->br_startblock + new->br_blockcount == right.br_startblock &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) new->br_state == right.br_state &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) new->br_blockcount + right.br_blockcount <= MAXEXTLEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) (!(state & BMAP_LEFT_CONTIG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) left.br_blockcount + new->br_blockcount +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) right.br_blockcount <= MAXEXTLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) state |= BMAP_RIGHT_CONTIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) * Select which case we're in here, and implement it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) switch (state & (BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) case BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) * New allocation is contiguous with real allocations on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) * left and on the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) * Merge all three into a single extent record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) left.br_blockcount += new->br_blockcount + right.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) xfs_iext_update_extent(ip, state, icur, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) ifp->if_nextents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) if (cur == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) error = xfs_bmbt_lookup_eq(cur, &right, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) error = xfs_btree_delete(cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) error = xfs_btree_decrement(cur, 0, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) error = xfs_bmbt_update(cur, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) case BMAP_LEFT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) * New allocation is contiguous with a real allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) * on the left.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) * Merge the new allocation with the left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) old = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) left.br_blockcount += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) xfs_iext_update_extent(ip, state, icur, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) if (cur == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) rval = xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) error = xfs_bmbt_lookup_eq(cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) error = xfs_bmbt_update(cur, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) case BMAP_RIGHT_CONTIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) * New allocation is contiguous with a real allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) * on the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) * Merge the new allocation with the right neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) old = right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) right.br_startoff = new->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) right.br_startblock = new->br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) right.br_blockcount += new->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) xfs_iext_update_extent(ip, state, icur, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) if (cur == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) rval = xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) error = xfs_bmbt_lookup_eq(cur, &old, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) error = xfs_bmbt_update(cur, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) * New allocation is not contiguous with another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) * real allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) * Insert a new entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) xfs_iext_insert(ip, icur, new, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) if (cur == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) rval = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) error = xfs_bmbt_lookup_eq(cur, new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) error = xfs_btree_insert(cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) /* add reverse mapping unless caller opted out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (!(flags & XFS_BMAPI_NORMAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) xfs_rmap_map_extent(tp, ip, whichfork, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) /* convert to a btree if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) if (xfs_bmap_needs_btree(ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) int tmp_logflags; /* partial log flag return val */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) ASSERT(cur == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) error = xfs_bmap_extents_to_btree(tp, ip, curp, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) &tmp_logflags, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) *logflagsp |= tmp_logflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) cur = *curp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) /* clear out the allocated field, done with it now in any case. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) if (cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) cur->bc_ino.allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) xfs_bmap_check_leaf_extents(cur, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) *logflagsp |= rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) * Functions used in the extent read, allocate and remove paths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) * Adjust the size of the new extent based on di_extsize and rt extsize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) xfs_bmap_extsize_align(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) xfs_mount_t *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) xfs_bmbt_irec_t *gotp, /* next extent pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) xfs_bmbt_irec_t *prevp, /* previous extent pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) xfs_extlen_t extsz, /* align to this extent size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) int rt, /* is this a realtime inode? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) int eof, /* is extent at end-of-file? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) int delay, /* creating delalloc extent? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) int convert, /* overwriting unwritten extent? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) xfs_fileoff_t *offp, /* in/out: aligned offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) xfs_extlen_t *lenp) /* in/out: aligned length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) xfs_fileoff_t orig_off; /* original offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) xfs_extlen_t orig_alen; /* original length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) xfs_fileoff_t orig_end; /* original off+len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) xfs_fileoff_t nexto; /* next file offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) xfs_fileoff_t prevo; /* previous file offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) xfs_fileoff_t align_off; /* temp for offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) xfs_extlen_t align_alen; /* temp for length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) xfs_extlen_t temp; /* temp for calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) if (convert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) orig_off = align_off = *offp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) orig_alen = align_alen = *lenp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) orig_end = orig_off + orig_alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) * If this request overlaps an existing extent, then don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) * attempt to perform any additional alignment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) if (!delay && !eof &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) (orig_off >= gotp->br_startoff) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) (orig_end <= gotp->br_startoff + gotp->br_blockcount)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) * If the file offset is unaligned vs. the extent size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) * we need to align it. This will be possible unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) * the file was previously written with a kernel that didn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) * perform this alignment, or if a truncate shot us in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) * foot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) div_u64_rem(orig_off, extsz, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) if (temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) align_alen += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) align_off -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) /* Same adjustment for the end of the requested area. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) temp = (align_alen % extsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) if (temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) align_alen += extsz - temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) * For large extent hint sizes, the aligned extent might be larger than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) * MAXEXTLEN. In that case, reduce the size by an extsz so that it pulls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) * the length back under MAXEXTLEN. The outer allocation loops handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) * short allocation just fine, so it is safe to do this. We only want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) * do it when we are forced to, though, because it means more allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) * operations are required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) while (align_alen > MAXEXTLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) align_alen -= extsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) ASSERT(align_alen <= MAXEXTLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) * If the previous block overlaps with this proposed allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) * then move the start forward without adjusting the length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) if (prevp->br_startoff != NULLFILEOFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) if (prevp->br_startblock == HOLESTARTBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) prevo = prevp->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) prevo = prevp->br_startoff + prevp->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) prevo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) if (align_off != orig_off && align_off < prevo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) align_off = prevo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) * If the next block overlaps with this proposed allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) * then move the start back without adjusting the length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) * but not before offset 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) * This may of course make the start overlap previous block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) * and if we hit the offset 0 limit then the next block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) * can still overlap too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) if (!eof && gotp->br_startoff != NULLFILEOFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) if ((delay && gotp->br_startblock == HOLESTARTBLOCK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) (!delay && gotp->br_startblock == DELAYSTARTBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) nexto = gotp->br_startoff + gotp->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) nexto = gotp->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) nexto = NULLFILEOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) if (!eof &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) align_off + align_alen != orig_end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) align_off + align_alen > nexto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) align_off = nexto > align_alen ? nexto - align_alen : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) * If we're now overlapping the next or previous extent that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) * means we can't fit an extsz piece in this hole. Just move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) * the start forward to the first valid spot and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) * the length so we hit the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) if (align_off != orig_off && align_off < prevo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) align_off = prevo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) if (align_off + align_alen != orig_end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) align_off + align_alen > nexto &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) nexto != NULLFILEOFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) ASSERT(nexto > prevo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) align_alen = nexto - align_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) * If realtime, and the result isn't a multiple of the realtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) * extent size we need to remove blocks until it is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) * We're not covering the original request, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) * we won't be able to once we fix the length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) if (orig_off < align_off ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) orig_end > align_off + align_alen ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) align_alen - temp < orig_alen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) * Try to fix it by moving the start up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) if (align_off + temp <= orig_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) align_alen -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) align_off += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) * Try to fix it by moving the end in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) else if (align_off + align_alen - temp >= orig_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) align_alen -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) * Set the start to the minimum then trim the length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) align_alen -= orig_off - align_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) align_off = orig_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) align_alen -= align_alen % mp->m_sb.sb_rextsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) * Result doesn't cover the request, fail it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) if (orig_off < align_off || orig_end > align_off + align_alen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) ASSERT(orig_off >= align_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) /* see MAXEXTLEN handling above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) ASSERT(orig_end <= align_off + align_alen ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) align_alen + extsz > MAXEXTLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) if (!eof && gotp->br_startoff != NULLFILEOFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) ASSERT(align_off + align_alen <= gotp->br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) if (prevp->br_startoff != NULLFILEOFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) ASSERT(align_off >= prevp->br_startoff + prevp->br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) *lenp = align_alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) *offp = align_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) #define XFS_ALLOC_GAP_UNITS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) xfs_bmap_adjacent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) struct xfs_bmalloca *ap) /* bmap alloc argument struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) xfs_fsblock_t adjust; /* adjustment to block numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) xfs_mount_t *mp; /* mount point structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) int nullfb; /* true if ap->firstblock isn't set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) int rt; /* true if inode is realtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) #define ISVALID(x,y) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) (rt ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) (x) < mp->m_sb.sb_rblocks : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) mp = ap->ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) nullfb = ap->tp->t_firstblock == NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) rt = XFS_IS_REALTIME_INODE(ap->ip) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) (ap->datatype & XFS_ALLOC_USERDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) ap->tp->t_firstblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) * If allocating at eof, and there's a previous real block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) * try to use its last block as our starting point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) if (ap->eof && ap->prev.br_startoff != NULLFILEOFF &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) !isnullstartblock(ap->prev.br_startblock) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) ap->prev.br_startblock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) * Adjust for the gap between prevp and us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) adjust = ap->offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) (ap->prev.br_startoff + ap->prev.br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) if (adjust &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) ISVALID(ap->blkno + adjust, ap->prev.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) ap->blkno += adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) * If not at eof, then compare the two neighbor blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) * Figure out whether either one gives us a good starting point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) * and pick the better one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) else if (!ap->eof) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) xfs_fsblock_t gotbno; /* right side block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) xfs_fsblock_t gotdiff=0; /* right side difference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) xfs_fsblock_t prevbno; /* left side block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) xfs_fsblock_t prevdiff=0; /* left side difference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) * If there's a previous (left) block, select a requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) * start block based on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) if (ap->prev.br_startoff != NULLFILEOFF &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) !isnullstartblock(ap->prev.br_startblock) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) (prevbno = ap->prev.br_startblock +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) ap->prev.br_blockcount) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) ISVALID(prevbno, ap->prev.br_startblock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) * Calculate gap to end of previous block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) adjust = prevdiff = ap->offset -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) (ap->prev.br_startoff +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) ap->prev.br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) * Figure the startblock based on the previous block's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) * end and the gap size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) * Heuristic!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) * If the gap is large relative to the piece we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) * allocating, or using it gives us an invalid block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) * number, then just use the end of the previous block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) ISVALID(prevbno + prevdiff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) ap->prev.br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) prevbno += adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) prevdiff += adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) * If the firstblock forbids it, can't use it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) * must use default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) if (!rt && !nullfb &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) prevbno = NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) * No previous block or can't follow it, just default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) prevbno = NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) * If there's a following (right) block, select a requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) * start block based on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) if (!isnullstartblock(ap->got.br_startblock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) * Calculate gap to start of next block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) adjust = gotdiff = ap->got.br_startoff - ap->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) * Figure the startblock based on the next block's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) * start and the gap size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) gotbno = ap->got.br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) * Heuristic!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) * If the gap is large relative to the piece we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) * allocating, or using it gives us an invalid block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) * number, then just use the start of the next block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) * offset by our length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) ISVALID(gotbno - gotdiff, gotbno))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) gotbno -= adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) else if (ISVALID(gotbno - ap->length, gotbno)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) gotbno -= ap->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) gotdiff += adjust - ap->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) gotdiff += adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) * If the firstblock forbids it, can't use it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) * must use default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) if (!rt && !nullfb &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) gotbno = NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) * No next block, just default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) gotbno = NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) * If both valid, pick the better one, else the only good
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) * one, else ap->blkno is already set (to 0 or the inode block).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) ap->blkno = prevdiff <= gotdiff ? prevbno : gotbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) else if (prevbno != NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) ap->blkno = prevbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) else if (gotbno != NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) ap->blkno = gotbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) #undef ISVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) xfs_bmap_longest_free_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) xfs_agnumber_t ag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) xfs_extlen_t *blen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) int *notinit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) struct xfs_mount *mp = tp->t_mountp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) struct xfs_perag *pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) xfs_extlen_t longest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) pag = xfs_perag_get(mp, ag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) if (!pag->pagf_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) /* Couldn't lock the AGF, so skip this AG. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) if (error == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) *notinit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) longest = xfs_alloc_longest_free_extent(pag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) xfs_alloc_min_freelist(mp, pag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) if (*blen < longest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) *blen = longest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) xfs_perag_put(pag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) xfs_bmap_select_minlen(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) struct xfs_bmalloca *ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) struct xfs_alloc_arg *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) xfs_extlen_t *blen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) int notinit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) if (notinit || *blen < ap->minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) * Since we did a BUF_TRYLOCK above, it is possible that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) * there is space for this request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) args->minlen = ap->minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) } else if (*blen < args->maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) * If the best seen length is less than the request length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) * use the best as the minimum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) args->minlen = *blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) * Otherwise we've seen an extent as big as maxlen, use that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) * as the minimum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) args->minlen = args->maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) xfs_bmap_btalloc_nullfb(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) struct xfs_bmalloca *ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) struct xfs_alloc_arg *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) xfs_extlen_t *blen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) struct xfs_mount *mp = ap->ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) xfs_agnumber_t ag, startag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) int notinit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) args->type = XFS_ALLOCTYPE_START_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) args->total = ap->total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) if (startag == NULLAGNUMBER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) startag = ag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) while (*blen < args->maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) ¬init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) if (++ag == mp->m_sb.sb_agcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) ag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) if (ag == startag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) xfs_bmap_select_minlen(ap, args, blen, notinit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) xfs_bmap_btalloc_filestreams(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) struct xfs_bmalloca *ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) struct xfs_alloc_arg *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) xfs_extlen_t *blen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) struct xfs_mount *mp = ap->ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) xfs_agnumber_t ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) int notinit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) args->type = XFS_ALLOCTYPE_NEAR_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) args->total = ap->total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) if (ag == NULLAGNUMBER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) ag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) error = xfs_bmap_longest_free_extent(args->tp, ag, blen, ¬init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) if (*blen < args->maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) error = xfs_filestream_new_ag(ap, &ag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) ¬init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) xfs_bmap_select_minlen(ap, args, blen, notinit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) * Set the failure fallback case to look in the selected AG as stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) * may have moved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) /* Update all inode and quota accounting for the allocation we just did. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) xfs_bmap_btalloc_accounting(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) struct xfs_bmalloca *ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) struct xfs_alloc_arg *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) if (ap->flags & XFS_BMAPI_COWFORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) * COW fork blocks are in-core only and thus are treated as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) * in-core quota reservation (like delalloc blocks) even when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) * converted to real blocks. The quota reservation is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) * accounted to disk until blocks are remapped to the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) * fork. So if these blocks were previously delalloc, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) * already have quota reservation and there's nothing to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) * yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) if (ap->wasdel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) xfs_mod_delalloc(ap->ip->i_mount, -(int64_t)args->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) * Otherwise, we've allocated blocks in a hole. The transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) * has acquired in-core quota reservation for this extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) * Rather than account these as real blocks, however, we reduce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) * the transaction quota reservation based on the allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) * This essentially transfers the transaction quota reservation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) * to that of a delalloc extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) ap->ip->i_delayed_blks += args->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) xfs_trans_mod_dquot_byino(ap->tp, ap->ip, XFS_TRANS_DQ_RES_BLKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) -(long)args->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) /* data/attr fork only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) ap->ip->i_d.di_nblocks += args->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) if (ap->wasdel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) ap->ip->i_delayed_blks -= args->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) xfs_mod_delalloc(ap->ip->i_mount, -(int64_t)args->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : XFS_TRANS_DQ_BCOUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) args->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) xfs_bmap_btalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) struct xfs_bmalloca *ap) /* bmap alloc argument struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) xfs_mount_t *mp; /* mount point structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) xfs_alloctype_t atype = 0; /* type for allocation routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) xfs_extlen_t align = 0; /* minimum allocation alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) xfs_agnumber_t ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) xfs_alloc_arg_t args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) xfs_fileoff_t orig_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) xfs_extlen_t orig_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) xfs_extlen_t blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) xfs_extlen_t nextminlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) int nullfb; /* true if ap->firstblock isn't set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) int isaligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) int tryagain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) int stripe_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) ASSERT(ap->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) orig_offset = ap->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) orig_length = ap->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) mp = ap->ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) /* stripe alignment for allocation is determined by mount parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) stripe_align = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) stripe_align = mp->m_swidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) else if (mp->m_dalign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) stripe_align = mp->m_dalign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) if (ap->flags & XFS_BMAPI_COWFORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) align = xfs_get_cowextsz_hint(ap->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) else if (ap->datatype & XFS_ALLOC_USERDATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) align = xfs_get_extsz_hint(ap->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) if (align) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) align, 0, ap->eof, 0, ap->conv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) &ap->offset, &ap->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) ASSERT(!error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) ASSERT(ap->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) nullfb = ap->tp->t_firstblock == NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) ap->tp->t_firstblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) if (nullfb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) if ((ap->datatype & XFS_ALLOC_USERDATA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) xfs_inode_is_filestream(ap->ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) ag = xfs_filestream_lookup_ag(ap->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) ag = (ag != NULLAGNUMBER) ? ag : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) ap->blkno = XFS_INO_TO_FSB(mp, ap->ip->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) ap->blkno = ap->tp->t_firstblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) xfs_bmap_adjacent(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) * If allowed, use ap->blkno; otherwise must use firstblock since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) * it's in the right allocation group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) if (nullfb || XFS_FSB_TO_AGNO(mp, ap->blkno) == fb_agno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) ap->blkno = ap->tp->t_firstblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) * Normal allocation, done through xfs_alloc_vextent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) tryagain = isaligned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) memset(&args, 0, sizeof(args));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) args.tp = ap->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) args.mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) args.fsbno = ap->blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) /* Trim the allocation back to the maximum an AG can fit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) args.maxlen = min(ap->length, mp->m_ag_max_usable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) blen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) if (nullfb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) * Search for an allocation group with a single extent large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) * enough for the request. If one isn't found, then adjust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) * the minimum allocation size to the largest space found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) if ((ap->datatype & XFS_ALLOC_USERDATA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) xfs_inode_is_filestream(ap->ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) error = xfs_bmap_btalloc_filestreams(ap, &args, &blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) } else if (ap->tp->t_flags & XFS_TRANS_LOWMODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) if (xfs_inode_is_filestream(ap->ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) args.type = XFS_ALLOCTYPE_FIRST_AG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) args.type = XFS_ALLOCTYPE_START_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) args.total = args.minlen = ap->minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) args.type = XFS_ALLOCTYPE_NEAR_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) args.total = ap->total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) args.minlen = ap->minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) /* apply extent size hints if obtained earlier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) if (align) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) args.prod = align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) div_u64_rem(ap->offset, args.prod, &args.mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) if (args.mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) args.mod = args.prod - args.mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) } else if (mp->m_sb.sb_blocksize >= PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) args.prod = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) args.mod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) args.prod = PAGE_SIZE >> mp->m_sb.sb_blocklog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) div_u64_rem(ap->offset, args.prod, &args.mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) if (args.mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) args.mod = args.prod - args.mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) * If we are not low on available data blocks, and the underlying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) * logical volume manager is a stripe, and the file offset is zero then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) * try to allocate data blocks on stripe unit boundary. NOTE: ap->aeof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) * is only set if the allocation length is >= the stripe unit and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) * allocation offset is at the end of file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) if (!(ap->tp->t_flags & XFS_TRANS_LOWMODE) && ap->aeof) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) if (!ap->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) args.alignment = stripe_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) atype = args.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) isaligned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) * Adjust minlen to try and preserve alignment if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) * can't guarantee an aligned maxlen extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) if (blen > args.alignment &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) blen <= args.maxlen + args.alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) args.minlen = blen - args.alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) args.minalignslop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) * First try an exact bno allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) * If it fails then do a near or start bno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) * allocation with alignment turned on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) atype = args.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) tryagain = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) args.type = XFS_ALLOCTYPE_THIS_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) args.alignment = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) * Compute the minlen+alignment for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) * next case. Set slop so that the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) * of minlen+alignment+slop doesn't go up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) * between the calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) if (blen > stripe_align && blen <= args.maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) nextminlen = blen - stripe_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) nextminlen = args.minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) if (nextminlen + stripe_align > args.minlen + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) args.minalignslop =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) nextminlen + stripe_align -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) args.minlen - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) args.minalignslop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) args.alignment = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) args.minalignslop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) args.minleft = ap->minleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) args.wasdel = ap->wasdel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) args.resv = XFS_AG_RESV_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) args.datatype = ap->datatype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) error = xfs_alloc_vextent(&args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) if (tryagain && args.fsbno == NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) * Exact allocation failed. Now try with alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) * turned on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) args.type = atype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) args.fsbno = ap->blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) args.alignment = stripe_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) args.minlen = nextminlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) args.minalignslop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) isaligned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) if ((error = xfs_alloc_vextent(&args)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) if (isaligned && args.fsbno == NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) * allocation failed, so turn off alignment and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) * try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) args.type = atype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) args.fsbno = ap->blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) args.alignment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) if ((error = xfs_alloc_vextent(&args)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) if (args.fsbno == NULLFSBLOCK && nullfb &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) args.minlen > ap->minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) args.minlen = ap->minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) args.type = XFS_ALLOCTYPE_START_BNO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) args.fsbno = ap->blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) if ((error = xfs_alloc_vextent(&args)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) if (args.fsbno == NULLFSBLOCK && nullfb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) args.fsbno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) args.type = XFS_ALLOCTYPE_FIRST_AG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) args.total = ap->minlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) if ((error = xfs_alloc_vextent(&args)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) ap->tp->t_flags |= XFS_TRANS_LOWMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) if (args.fsbno != NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) * check the allocation happened at the same or higher AG than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) * the first block that was allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) ASSERT(ap->tp->t_firstblock == NULLFSBLOCK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) XFS_FSB_TO_AGNO(mp, ap->tp->t_firstblock) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) XFS_FSB_TO_AGNO(mp, args.fsbno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) ap->blkno = args.fsbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) if (ap->tp->t_firstblock == NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) ap->tp->t_firstblock = args.fsbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) ASSERT(nullfb || fb_agno <= args.agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) ap->length = args.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) * If the extent size hint is active, we tried to round the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) * caller's allocation request offset down to extsz and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) * length up to another extsz boundary. If we found a free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) * extent we mapped it in starting at this new offset. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) * newly mapped space isn't long enough to cover any of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) * range of offsets that was originally requested, move the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) * mapping up so that we can fill as much of the caller's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) * original request as possible. Free space is apparently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) * very fragmented so we're unlikely to be able to satisfy the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) * hints anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) if (ap->length <= orig_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) ap->offset = orig_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) else if (ap->offset + ap->length < orig_offset + orig_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) ap->offset = orig_offset + orig_length - ap->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) xfs_bmap_btalloc_accounting(ap, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) ap->blkno = NULLFSBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) ap->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) /* Trim extent to fit a logical block range. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) xfs_trim_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) struct xfs_bmbt_irec *irec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) xfs_fileoff_t bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) xfs_filblks_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) xfs_fileoff_t distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) xfs_fileoff_t end = bno + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) if (irec->br_startoff + irec->br_blockcount <= bno ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) irec->br_startoff >= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) irec->br_blockcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) if (irec->br_startoff < bno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) distance = bno - irec->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) if (isnullstartblock(irec->br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) irec->br_startblock = DELAYSTARTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) if (irec->br_startblock != DELAYSTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) irec->br_startblock != HOLESTARTBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) irec->br_startblock += distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) irec->br_startoff += distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) irec->br_blockcount -= distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) if (end < irec->br_startoff + irec->br_blockcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) distance = irec->br_startoff + irec->br_blockcount - end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) irec->br_blockcount -= distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) * Trim the returned map to the required bounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) xfs_bmapi_trim_map(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) struct xfs_bmbt_irec *mval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) struct xfs_bmbt_irec *got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) xfs_fileoff_t *bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) xfs_fileoff_t obno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) xfs_fileoff_t end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) int n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) if ((flags & XFS_BMAPI_ENTIRE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) got->br_startoff + got->br_blockcount <= obno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) *mval = *got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) if (isnullstartblock(got->br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) mval->br_startblock = DELAYSTARTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) if (obno > *bno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) *bno = obno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) ASSERT((*bno >= obno) || (n == 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) ASSERT(*bno < end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) mval->br_startoff = *bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) if (isnullstartblock(got->br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) mval->br_startblock = DELAYSTARTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) mval->br_startblock = got->br_startblock +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) (*bno - got->br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) * Return the minimum of what we got and what we asked for for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) * the length. We can use the len variable here because it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) * modified below and we could have been there before coming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) * here if the first part of the allocation didn't overlap what
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) * was asked for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) mval->br_blockcount = XFS_FILBLKS_MIN(end - *bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) got->br_blockcount - (*bno - got->br_startoff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) mval->br_state = got->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) ASSERT(mval->br_blockcount <= len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) * Update and validate the extent map to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) xfs_bmapi_update_map(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) struct xfs_bmbt_irec **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) xfs_fileoff_t *bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) xfs_filblks_t *len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) xfs_fileoff_t obno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) xfs_fileoff_t end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) int *n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) xfs_bmbt_irec_t *mval = *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) ASSERT((flags & XFS_BMAPI_ENTIRE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) ((mval->br_startoff + mval->br_blockcount) <= end));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) ASSERT((flags & XFS_BMAPI_ENTIRE) || (mval->br_blockcount <= *len) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) (mval->br_startoff < obno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) *bno = mval->br_startoff + mval->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) *len = end - *bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) if (*n > 0 && mval->br_startoff == mval[-1].br_startoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) /* update previous map with new information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) ASSERT(mval->br_startblock == mval[-1].br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) ASSERT(mval->br_blockcount > mval[-1].br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) ASSERT(mval->br_state == mval[-1].br_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) mval[-1].br_blockcount = mval->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) mval[-1].br_state = mval->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) } else if (*n > 0 && mval->br_startblock != DELAYSTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) mval[-1].br_startblock != DELAYSTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) mval[-1].br_startblock != HOLESTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) mval->br_startblock == mval[-1].br_startblock +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) mval[-1].br_blockcount &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) mval[-1].br_state == mval->br_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) ASSERT(mval->br_startoff ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) mval[-1].br_startoff + mval[-1].br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) mval[-1].br_blockcount += mval->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) } else if (*n > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) mval->br_startblock == DELAYSTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) mval[-1].br_startblock == DELAYSTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) mval->br_startoff ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) mval[-1].br_startoff + mval[-1].br_blockcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) mval[-1].br_blockcount += mval->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) mval[-1].br_state = mval->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) } else if (!((*n == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) ((mval->br_startoff + mval->br_blockcount) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) obno))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) mval++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) (*n)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) *map = mval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) * Map file blocks to filesystem blocks without allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) xfs_bmapi_read(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) xfs_fileoff_t bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) struct xfs_bmbt_irec *mval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) int *nmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) int whichfork = xfs_bmapi_whichfork(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) struct xfs_bmbt_irec got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) xfs_fileoff_t obno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) xfs_fileoff_t end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) bool eof = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) ASSERT(*nmap >= 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_ENTIRE)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) if (WARN_ON_ONCE(!ifp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) if (XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) XFS_STATS_INC(mp, xs_blk_mapr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) error = xfs_iread_extents(NULL, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) if (!xfs_iext_lookup_extent(ip, ifp, bno, &icur, &got))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) end = bno + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) obno = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) while (bno < end && n < *nmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) /* Reading past eof, act as though there's a hole up to end. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) if (eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) got.br_startoff = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) if (got.br_startoff > bno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) /* Reading in a hole. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) mval->br_startoff = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) mval->br_startblock = HOLESTARTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) mval->br_blockcount =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) XFS_FILBLKS_MIN(len, got.br_startoff - bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) mval->br_state = XFS_EXT_NORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) bno += mval->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) len -= mval->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) mval++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) /* set up the extent map to return. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) /* If we're done, stop now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) if (bno >= end || n >= *nmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) /* Else go on to the next record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) if (!xfs_iext_next_extent(ifp, &icur, &got))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) *nmap = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) * Add a delayed allocation extent to an inode. Blocks are reserved from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) * global pool and the extent inserted into the inode in-core extent tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) * On entry, got refers to the first extent beyond the offset of the extent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) * allocate or eof is specified if no such extent exists. On return, got refers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) * to the extent record that was inserted to the inode fork.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) * Note that the allocated extent may have been merged with contiguous extents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) * during insertion into the inode fork. Thus, got does not reflect the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) * state of the inode fork on return. If necessary, the caller can use lastx to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) * look up the updated record in the inode fork.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) xfs_bmapi_reserve_delalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) xfs_fileoff_t off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) xfs_filblks_t prealloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) struct xfs_bmbt_irec *got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) int eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) xfs_extlen_t alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) xfs_extlen_t indlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) xfs_fileoff_t aoff = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) * Cap the alloc length. Keep track of prealloc so we know whether to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) * tag the inode before we return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) alen = XFS_FILBLKS_MIN(len + prealloc, MAXEXTLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) if (!eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) if (prealloc && alen >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) prealloc = alen - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) /* Figure out the extent size, adjust alen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) if (whichfork == XFS_COW_FORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) struct xfs_bmbt_irec prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) xfs_extlen_t extsz = xfs_get_cowextsz_hint(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) if (!xfs_iext_peek_prev_extent(ifp, icur, &prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) prev.br_startoff = NULLFILEOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) error = xfs_bmap_extsize_align(mp, got, &prev, extsz, 0, eof,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 1, 0, &aoff, &alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) ASSERT(!error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) * Make a transaction-less quota reservation for delayed allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) * blocks. This number gets adjusted later. We return if we haven't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) * allocated blocks already inside this loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) error = xfs_trans_reserve_quota_nblks(NULL, ip, (long)alen, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) XFS_QMOPT_RES_REGBLKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) * Split changing sb for alen and indlen since they could be coming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) * from different places.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) ASSERT(indlen > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) error = xfs_mod_fdblocks(mp, -((int64_t)alen), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) goto out_unreserve_quota;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) error = xfs_mod_fdblocks(mp, -((int64_t)indlen), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) goto out_unreserve_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) ip->i_delayed_blks += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) xfs_mod_delalloc(ip->i_mount, alen + indlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) got->br_startoff = aoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) got->br_startblock = nullstartblock(indlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) got->br_blockcount = alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) got->br_state = XFS_EXT_NORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) xfs_bmap_add_extent_hole_delay(ip, whichfork, icur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) * Tag the inode if blocks were preallocated. Note that COW fork
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) * preallocation can occur at the start or end of the extent, even when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) * prealloc == 0, so we must also check the aligned offset and length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) if (whichfork == XFS_DATA_FORK && prealloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) xfs_inode_set_eofblocks_tag(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) if (whichfork == XFS_COW_FORK && (prealloc || aoff < off || alen > len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) xfs_inode_set_cowblocks_tag(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) out_unreserve_blocks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) xfs_mod_fdblocks(mp, alen, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) out_unreserve_quota:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) if (XFS_IS_QUOTA_ON(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) XFS_QMOPT_RES_REGBLKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) xfs_bmap_alloc_userdata(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) struct xfs_bmalloca *bma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) struct xfs_mount *mp = bma->ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) int whichfork = xfs_bmapi_whichfork(bma->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) * Set the data type being allocated. For the data fork, the first data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) * in the file is treated differently to all other allocations. For the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) * attribute fork, we only need to ensure the allocated range is not on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) * the busy list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) bma->datatype = XFS_ALLOC_NOBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) if (whichfork == XFS_DATA_FORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) bma->datatype |= XFS_ALLOC_USERDATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) if (bma->offset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) if (mp->m_dalign && bma->length >= mp->m_dalign) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) error = xfs_bmap_isaeof(bma, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) if (XFS_IS_REALTIME_INODE(bma->ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) return xfs_bmap_rtalloc(bma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) return xfs_bmap_btalloc(bma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) xfs_bmapi_allocate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) struct xfs_bmalloca *bma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) struct xfs_mount *mp = bma->ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) int whichfork = xfs_bmapi_whichfork(bma->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) int tmp_logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) ASSERT(bma->length > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) * For the wasdelay case, we could also just allocate the stuff asked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) * for in this bmap call but that wouldn't be as good.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) if (bma->wasdel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) bma->length = (xfs_extlen_t)bma->got.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) bma->offset = bma->got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) if (!xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) bma->prev.br_startoff = NULLFILEOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) if (!bma->eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) bma->length = XFS_FILBLKS_MIN(bma->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) bma->got.br_startoff - bma->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) if (bma->flags & XFS_BMAPI_CONTIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) bma->minlen = bma->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) bma->minlen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) if (bma->flags & XFS_BMAPI_METADATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) error = xfs_bmap_btalloc(bma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) error = xfs_bmap_alloc_userdata(bma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) if (error || bma->blkno == NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) if (bma->flags & XFS_BMAPI_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) error = xfs_zero_extent(bma->ip, bma->blkno, bma->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) * Bump the number of extents we've allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) * in this call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) bma->nallocs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) if (bma->cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) bma->cur->bc_ino.flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) bma->wasdel ? XFS_BTCUR_BMBT_WASDEL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) bma->got.br_startoff = bma->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) bma->got.br_startblock = bma->blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) bma->got.br_blockcount = bma->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) bma->got.br_state = XFS_EXT_NORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) if (bma->flags & XFS_BMAPI_PREALLOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) bma->got.br_state = XFS_EXT_UNWRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) if (bma->wasdel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) error = xfs_bmap_add_extent_delay_real(bma, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) whichfork, &bma->icur, &bma->cur, &bma->got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) &bma->logflags, bma->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) bma->logflags |= tmp_logflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) * Update our extent pointer, given that xfs_bmap_add_extent_delay_real
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) * or xfs_bmap_add_extent_hole_real might have merged it into one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) * the neighbouring ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) xfs_iext_get_extent(ifp, &bma->icur, &bma->got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) ASSERT(bma->got.br_startoff <= bma->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) ASSERT(bma->got.br_startoff + bma->got.br_blockcount >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) bma->offset + bma->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) ASSERT(bma->got.br_state == XFS_EXT_NORM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) bma->got.br_state == XFS_EXT_UNWRITTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) xfs_bmapi_convert_unwritten(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) struct xfs_bmalloca *bma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) struct xfs_bmbt_irec *mval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) int whichfork = xfs_bmapi_whichfork(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) int tmp_logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) /* check if we need to do unwritten->real conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) if (mval->br_state == XFS_EXT_UNWRITTEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) (flags & XFS_BMAPI_PREALLOC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) /* check if we need to do real->unwritten conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) if (mval->br_state == XFS_EXT_NORM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) (flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) * Modify (by adding) the state flag, if writing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) ASSERT(mval->br_blockcount <= len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) bma->cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) bma->ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) * Before insertion into the bmbt, zero the range being converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) * if required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) if (flags & XFS_BMAPI_ZERO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) error = xfs_zero_extent(bma->ip, mval->br_startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) mval->br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) &bma->icur, &bma->cur, mval, &tmp_logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) * Log the inode core unconditionally in the unwritten extent conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) * path because the conversion might not have done so (e.g., if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) * extent count hasn't changed). We need to make sure the inode is dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) * in the transaction for the sake of fsync(), even if nothing has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) * changed, because fsync() will not force the log for this transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) * unless it sees the inode pinned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) * Note: If we're only converting cow fork extents, there aren't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) * any on-disk updates to make, so we don't need to log anything.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) if (whichfork != XFS_COW_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) bma->logflags |= tmp_logflags | XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) * Update our extent pointer, given that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) * xfs_bmap_add_extent_unwritten_real might have merged it into one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) * of the neighbouring ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) xfs_iext_get_extent(ifp, &bma->icur, &bma->got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) * We may have combined previously unwritten space with written space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) * so generate another request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) if (mval->br_blockcount < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) static inline xfs_extlen_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) xfs_bmapi_minleft(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) int fork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, fork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) if (tp && tp->t_firstblock != NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) if (ifp->if_format != XFS_DINODE_FMT_BTREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) return be16_to_cpu(ifp->if_broot->bb_level) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) * Log whatever the flags say, even if error. Otherwise we might miss detecting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) * a case where the data is changed, there's an error, and it's not logged so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) * don't shutdown when we should. Don't bother logging extents/btree changes if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) * we converted to the other format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) xfs_bmapi_finish(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) struct xfs_bmalloca *bma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) if ((bma->logflags & xfs_ilog_fext(whichfork)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) ifp->if_format != XFS_DINODE_FMT_EXTENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) bma->logflags &= ~xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) else if ((bma->logflags & xfs_ilog_fbroot(whichfork)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) ifp->if_format != XFS_DINODE_FMT_BTREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) bma->logflags &= ~xfs_ilog_fbroot(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) if (bma->logflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) xfs_trans_log_inode(bma->tp, bma->ip, bma->logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) if (bma->cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) xfs_btree_del_cursor(bma->cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) * Map file blocks to filesystem blocks, and allocate blocks or convert the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) * extent state if necessary. Details behaviour is controlled by the flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) * parameter. Only allocates blocks from a single allocation group, to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) * locking problems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) xfs_bmapi_write(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) struct xfs_inode *ip, /* incore inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) xfs_fileoff_t bno, /* starting file offs. mapped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) xfs_filblks_t len, /* length to map in file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) int flags, /* XFS_BMAPI_... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) xfs_extlen_t total, /* total blocks needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) struct xfs_bmbt_irec *mval, /* output: map values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) int *nmap) /* i/o: mval size/count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) struct xfs_bmalloca bma = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) .tp = tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) .ip = ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) .total = total,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) int whichfork = xfs_bmapi_whichfork(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) xfs_fileoff_t end; /* end of mapped file region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) bool eof = false; /* after the end of extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) int error; /* error return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) int n; /* current extent index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) xfs_fileoff_t obno; /* old block number (offset) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) xfs_fileoff_t orig_bno; /* original block number value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) int orig_flags; /* original flags arg value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) xfs_filblks_t orig_len; /* original value of len arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) struct xfs_bmbt_irec *orig_mval; /* original value of mval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) int orig_nmap; /* original value of *nmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) orig_bno = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) orig_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) orig_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) orig_mval = mval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) orig_nmap = *nmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) ASSERT(*nmap >= 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) ASSERT(tp != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) ASSERT(len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) ASSERT(!(flags & XFS_BMAPI_REMAP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) /* zeroing is for currently only for data extents, not metadata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) * we can allocate unwritten extents or pre-zero allocated blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) * but it makes no sense to do both at once. This would result in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) * zeroing the unwritten extent twice, but it still being an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) * unwritten extent....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) if (XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) XFS_STATS_INC(mp, xs_blk_mapw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) if (!xfs_iext_lookup_extent(ip, ifp, bno, &bma.icur, &bma.got))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) if (!xfs_iext_peek_prev_extent(ifp, &bma.icur, &bma.prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) bma.prev.br_startoff = NULLFILEOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) end = bno + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) obno = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) while (bno < end && n < *nmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) bool need_alloc = false, wasdelay = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) /* in hole or beyond EOF? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) if (eof || bma.got.br_startoff > bno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) * CoW fork conversions should /never/ hit EOF or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) * holes. There should always be something for us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) * to work on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) ASSERT(!((flags & XFS_BMAPI_CONVERT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) (flags & XFS_BMAPI_COWFORK)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) need_alloc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) } else if (isnullstartblock(bma.got.br_startblock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) wasdelay = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) * First, deal with the hole before the allocated space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) * that we found, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) if (need_alloc || wasdelay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) bma.eof = eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) bma.conv = !!(flags & XFS_BMAPI_CONVERT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) bma.wasdel = wasdelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) bma.offset = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) bma.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) * There's a 32/64 bit type mismatch between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) * allocation length request (which can be 64 bits in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) * length) and the bma length request, which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) * xfs_extlen_t and therefore 32 bits. Hence we have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) * check for 32-bit overflows and handle them here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) if (len > (xfs_filblks_t)MAXEXTLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) bma.length = MAXEXTLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) bma.length = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) ASSERT(len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) ASSERT(bma.length > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) error = xfs_bmapi_allocate(&bma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) if (bma.blkno == NULLFSBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) * If this is a CoW allocation, record the data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) * the refcount btree for orphan recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) if (whichfork == XFS_COW_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) xfs_refcount_alloc_cow_extent(tp, bma.blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) bma.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) /* Deal with the allocated space we found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) xfs_bmapi_trim_map(mval, &bma.got, &bno, len, obno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) end, n, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) /* Execute unwritten extent conversion if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) error = xfs_bmapi_convert_unwritten(&bma, mval, len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) if (error == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) /* update the extent map to return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) * If we're done, stop now. Stop when we've allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) * the transaction may get too big.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) if (bno >= end || n >= *nmap || bma.nallocs >= *nmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) /* Else go on to the next record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) bma.prev = bma.got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) if (!xfs_iext_next_extent(ifp, &bma.icur, &bma.got))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) *nmap = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) ASSERT(ifp->if_format != XFS_DINODE_FMT_BTREE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) xfs_bmapi_finish(&bma, whichfork, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) orig_nmap, *nmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) xfs_bmapi_finish(&bma, whichfork, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) * Convert an existing delalloc extent to real blocks based on file offset. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) * attempts to allocate the entire delalloc extent and may require multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) * invocations to allocate the target offset if a large enough physical extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) * is not available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) xfs_bmapi_convert_delalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) xfs_off_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) struct iomap *iomap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) unsigned int *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) struct xfs_bmalloca bma = { NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) uint16_t flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) struct xfs_trans *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) if (whichfork == XFS_COW_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) flags |= IOMAP_F_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) * Space for the extent and indirect blocks was reserved when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) * delalloc extent was created so there's no need to do so here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) XFS_TRANS_RESERVE, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) xfs_trans_ijoin(tp, ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &bma.icur, &bma.got) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) bma.got.br_startoff > offset_fsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) * No extent found in the range we are trying to convert. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) * should only happen for the COW fork, where another thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) * might have moved the extent to the data fork in the meantime.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) WARN_ON_ONCE(whichfork != XFS_COW_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) error = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) goto out_trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) * If we find a real extent here we raced with another thread converting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) * the extent. Just return the real extent at this offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) if (!isnullstartblock(bma.got.br_startblock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) xfs_bmbt_to_iomap(ip, iomap, &bma.got, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) *seq = READ_ONCE(ifp->if_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) goto out_trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) bma.tp = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) bma.ip = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) bma.wasdel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) bma.offset = bma.got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount, MAXEXTLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) * When we're converting the delalloc reservations backing dirty pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) * in the page cache, we must be careful about how we create the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) * extents:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) * New CoW fork extents are created unwritten, turned into real extents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) * when we're about to write the data to disk, and mapped into the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) * fork after the write finishes. End of story.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) * New data fork extents must be mapped in as unwritten and converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) * to real extents after the write succeeds to avoid exposing stale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) * disk contents if we crash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) bma.flags = XFS_BMAPI_PREALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) if (whichfork == XFS_COW_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) bma.flags |= XFS_BMAPI_COWFORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) if (!xfs_iext_peek_prev_extent(ifp, &bma.icur, &bma.prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) bma.prev.br_startoff = NULLFILEOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) error = xfs_bmapi_allocate(&bma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) goto out_finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) error = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) if (WARN_ON_ONCE(bma.blkno == NULLFSBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) goto out_finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) goto out_finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, bma.length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) XFS_STATS_INC(mp, xs_xstrat_quick);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) ASSERT(!isnullstartblock(bma.got.br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) xfs_bmbt_to_iomap(ip, iomap, &bma.got, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) *seq = READ_ONCE(ifp->if_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) if (whichfork == XFS_COW_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) xfs_refcount_alloc_cow_extent(tp, bma.blkno, bma.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) goto out_finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) xfs_bmapi_finish(&bma, whichfork, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) out_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) xfs_bmapi_finish(&bma, whichfork, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) out_trans_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) xfs_trans_cancel(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) xfs_bmapi_remap(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) xfs_fileoff_t bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) xfs_fsblock_t startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) struct xfs_ifork *ifp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) struct xfs_btree_cur *cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) struct xfs_bmbt_irec got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) int whichfork = xfs_bmapi_whichfork(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) int logflags = 0, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) ASSERT(len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) ASSERT(len <= (xfs_filblks_t)MAXEXTLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) XFS_BMAPI_NORMAP)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) if (XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) if (xfs_iext_lookup_extent(ip, ifp, bno, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) /* make sure we only reflink into a hole. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) ASSERT(got.br_startoff > bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) ASSERT(got.br_startoff - bno >= len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) ip->i_d.di_nblocks += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) if (ifp->if_flags & XFS_IFBROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) cur->bc_ino.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) got.br_startoff = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) got.br_startblock = startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) got.br_blockcount = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) if (flags & XFS_BMAPI_PREALLOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) got.br_state = XFS_EXT_UNWRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) got.br_state = XFS_EXT_NORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) error = xfs_bmap_add_extent_hole_real(tp, ip, whichfork, &icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) &cur, &got, &logflags, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) if (ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) logflags &= ~XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) else if (ip->i_df.if_format != XFS_DINODE_FMT_BTREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) logflags &= ~XFS_ILOG_DBROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) if (logflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) xfs_trans_log_inode(tp, ip, logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) if (cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) * When a delalloc extent is split (e.g., due to a hole punch), the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) * indlen reservation must be shared across the two new extents that are left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) * behind.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) * Given the original reservation and the worst case indlen for the two new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) * extents (as calculated by xfs_bmap_worst_indlen()), split the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) * reservation fairly across the two new extents. If necessary, steal available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) * blocks from a deleted extent to make up a reservation deficiency (e.g., if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) * ores == 1). The number of stolen blocks is returned. The availability and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) * subsequent accounting of stolen blocks is the responsibility of the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) static xfs_filblks_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) xfs_bmap_split_indlen(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) xfs_filblks_t ores, /* original res. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) xfs_filblks_t *indlen1, /* ext1 worst indlen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) xfs_filblks_t *indlen2, /* ext2 worst indlen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) xfs_filblks_t avail) /* stealable blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) xfs_filblks_t len1 = *indlen1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) xfs_filblks_t len2 = *indlen2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) xfs_filblks_t nres = len1 + len2; /* new total res. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) xfs_filblks_t stolen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) xfs_filblks_t resfactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) * Steal as many blocks as we can to try and satisfy the worst case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) * indlen for both new extents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) if (ores < nres && avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) stolen = XFS_FILBLKS_MIN(nres - ores, avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) ores += stolen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) /* nothing else to do if we've satisfied the new reservation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) if (ores >= nres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) return stolen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) * We can't meet the total required reservation for the two extents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) * Calculate the percent of the overall shortage between both extents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) * and apply this percentage to each of the requested indlen values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) * This distributes the shortage fairly and reduces the chances that one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) * of the two extents is left with nothing when extents are repeatedly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) * split.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) resfactor = (ores * 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) do_div(resfactor, nres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) len1 *= resfactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) do_div(len1, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) len2 *= resfactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) do_div(len2, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) ASSERT(len1 + len2 <= ores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) ASSERT(len1 < *indlen1 && len2 < *indlen2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) * Hand out the remainder to each extent. If one of the two reservations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) * is zero, we want to make sure that one gets a block first. The loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) * below starts with len1, so hand len2 a block right off the bat if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) * is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) ores -= (len1 + len2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) ASSERT((*indlen1 - len1) + (*indlen2 - len2) >= ores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) if (ores && !len2 && *indlen2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) len2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) ores--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) while (ores) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) if (len1 < *indlen1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) len1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) ores--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) if (!ores)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) if (len2 < *indlen2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) len2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) ores--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) *indlen1 = len1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) *indlen2 = len2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) return stolen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) xfs_bmap_del_extent_delay(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) struct xfs_bmbt_irec *got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) struct xfs_bmbt_irec *del)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) struct xfs_bmbt_irec new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) int64_t da_old, da_new, da_diff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) xfs_fileoff_t del_endoff, got_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) xfs_filblks_t got_indlen, new_indlen, stolen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) int state = xfs_bmap_fork_to_state(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) bool isrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) XFS_STATS_INC(mp, xs_del_exlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) del_endoff = del->br_startoff + del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) got_endoff = got->br_startoff + got->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) da_old = startblockval(got->br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) da_new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) ASSERT(del->br_blockcount > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) ASSERT(got->br_startoff <= del->br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) ASSERT(got_endoff >= del_endoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) if (isrt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) uint64_t rtexts = XFS_FSB_TO_B(mp, del->br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) do_div(rtexts, mp->m_sb.sb_rextsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) xfs_mod_frextents(mp, rtexts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) * Update the inode delalloc counter now and wait to update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) * sb counters as we might have to borrow some blocks for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) * indirect block accounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) error = xfs_trans_reserve_quota_nblks(NULL, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) -((long)del->br_blockcount), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) isrt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) ip->i_delayed_blks -= del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) if (got->br_startoff == del->br_startoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) state |= BMAP_LEFT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) if (got_endoff == del_endoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) state |= BMAP_RIGHT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) switch (state & (BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) * Matches the whole extent. Delete the entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) case BMAP_LEFT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) * Deleting the first part of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) got->br_startoff = del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) got->br_blockcount -= del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) got->br_blockcount), da_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) got->br_startblock = nullstartblock((int)da_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) xfs_iext_update_extent(ip, state, icur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) case BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) * Deleting the last part of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) got->br_blockcount = got->br_blockcount - del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) got->br_blockcount), da_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) got->br_startblock = nullstartblock((int)da_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) xfs_iext_update_extent(ip, state, icur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) * Deleting the middle of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) * Distribute the original indlen reservation across the two new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) * extents. Steal blocks from the deleted extent if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) * Stealing blocks simply fudges the fdblocks accounting below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) * Warn if either of the new indlen reservations is zero as this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) * can lead to delalloc problems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) got->br_blockcount = del->br_startoff - got->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) got_indlen = xfs_bmap_worst_indlen(ip, got->br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) new.br_blockcount = got_endoff - del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) new_indlen = xfs_bmap_worst_indlen(ip, new.br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) WARN_ON_ONCE(!got_indlen || !new_indlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) stolen = xfs_bmap_split_indlen(da_old, &got_indlen, &new_indlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) del->br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) got->br_startblock = nullstartblock((int)got_indlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) new.br_startoff = del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) new.br_state = got->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) new.br_startblock = nullstartblock((int)new_indlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) xfs_iext_update_extent(ip, state, icur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) xfs_iext_next(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) xfs_iext_insert(ip, icur, &new, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) da_new = got_indlen + new_indlen - stolen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) del->br_blockcount -= stolen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) ASSERT(da_old >= da_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) da_diff = da_old - da_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) if (!isrt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) da_diff += del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) if (da_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) xfs_mod_fdblocks(mp, da_diff, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) xfs_mod_delalloc(mp, -da_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) xfs_bmap_del_extent_cow(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) struct xfs_bmbt_irec *got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) struct xfs_bmbt_irec *del)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) struct xfs_bmbt_irec new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) xfs_fileoff_t del_endoff, got_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) int state = BMAP_COWFORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) XFS_STATS_INC(mp, xs_del_exlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) del_endoff = del->br_startoff + del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) got_endoff = got->br_startoff + got->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) ASSERT(del->br_blockcount > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) ASSERT(got->br_startoff <= del->br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) ASSERT(got_endoff >= del_endoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) ASSERT(!isnullstartblock(got->br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) if (got->br_startoff == del->br_startoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) state |= BMAP_LEFT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) if (got_endoff == del_endoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) state |= BMAP_RIGHT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) switch (state & (BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) * Matches the whole extent. Delete the entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) case BMAP_LEFT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) * Deleting the first part of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) got->br_startoff = del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) got->br_blockcount -= del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) got->br_startblock = del->br_startblock + del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) xfs_iext_update_extent(ip, state, icur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) case BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) * Deleting the last part of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) got->br_blockcount -= del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) xfs_iext_update_extent(ip, state, icur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) * Deleting the middle of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) got->br_blockcount = del->br_startoff - got->br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) new.br_startoff = del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) new.br_blockcount = got_endoff - del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) new.br_state = got->br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) new.br_startblock = del->br_startblock + del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) xfs_iext_update_extent(ip, state, icur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) xfs_iext_next(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) xfs_iext_insert(ip, icur, &new, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) ip->i_delayed_blks -= del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) * Called by xfs_bmapi to update file extent records and the btree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) * after removing space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) xfs_bmap_del_extent_real(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) xfs_inode_t *ip, /* incore inode pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) xfs_trans_t *tp, /* current transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) xfs_btree_cur_t *cur, /* if null, not a btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) xfs_bmbt_irec_t *del, /* data to remove from extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) int *logflagsp, /* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) int whichfork, /* data or attr fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) int bflags) /* bmapi flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) xfs_fsblock_t del_endblock=0; /* first block past del */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) xfs_fileoff_t del_endoff; /* first offset past del */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) int do_fx; /* free extent at end of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) int flags = 0;/* inode logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) struct xfs_bmbt_irec got; /* current extent entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) xfs_fileoff_t got_endoff; /* first offset past got */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) int i; /* temp state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) struct xfs_ifork *ifp; /* inode fork pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) xfs_mount_t *mp; /* mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) xfs_filblks_t nblks; /* quota/sb block count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) xfs_bmbt_irec_t new; /* new record to be inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) /* REFERENCED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) uint qfield; /* quota field to update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) int state = xfs_bmap_fork_to_state(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) struct xfs_bmbt_irec old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) XFS_STATS_INC(mp, xs_del_exlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) ASSERT(del->br_blockcount > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) xfs_iext_get_extent(ifp, icur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) ASSERT(got.br_startoff <= del->br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) del_endoff = del->br_startoff + del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) got_endoff = got.br_startoff + got.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) ASSERT(got_endoff >= del_endoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) ASSERT(!isnullstartblock(got.br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) qfield = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) * If it's the case where the directory code is running with no block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) * reservation, and the deleted block is in the middle of its extent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) * and the resulting insert of an extent would cause transformation to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) * btree format, then reject it. The calling code will then swap blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) * around instead. We have to do this now, rather than waiting for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) * conversion to btree format, since the transaction will be dirty then.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) if (tp->t_blk_res == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) ifp->if_format == XFS_DINODE_FMT_EXTENTS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) del->br_startoff > got.br_startoff && del_endoff < got_endoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) flags = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) xfs_filblks_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) xfs_extlen_t mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) len = div_u64_rem(del->br_blockcount, mp->m_sb.sb_rextsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) &mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) ASSERT(mod == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) if (!(bflags & XFS_BMAPI_REMAP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) xfs_fsblock_t bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) bno = div_u64_rem(del->br_startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) mp->m_sb.sb_rextsize, &mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) ASSERT(mod == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) do_fx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) nblks = len * mp->m_sb.sb_rextsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) qfield = XFS_TRANS_DQ_RTBCOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) do_fx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) nblks = del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) qfield = XFS_TRANS_DQ_BCOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) del_endblock = del->br_startblock + del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) error = xfs_bmbt_lookup_eq(cur, &got, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) if (got.br_startoff == del->br_startoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) state |= BMAP_LEFT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) if (got_endoff == del_endoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) state |= BMAP_RIGHT_FILLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) switch (state & (BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) * Matches the whole extent. Delete the entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) xfs_iext_remove(ip, icur, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) ifp->if_nextents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) flags |= XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) if (!cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) flags |= xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) if ((error = xfs_btree_delete(cur, &i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) case BMAP_LEFT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) * Deleting the first part of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) got.br_startoff = del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) got.br_startblock = del_endblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) got.br_blockcount -= del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) xfs_iext_update_extent(ip, state, icur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) if (!cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) flags |= xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) error = xfs_bmbt_update(cur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) case BMAP_RIGHT_FILLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) * Deleting the last part of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) got.br_blockcount -= del->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) xfs_iext_update_extent(ip, state, icur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) if (!cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) flags |= xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) error = xfs_bmbt_update(cur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) * Deleting the middle of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) old = got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) got.br_blockcount = del->br_startoff - got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) xfs_iext_update_extent(ip, state, icur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) new.br_startoff = del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) new.br_blockcount = got_endoff - del_endoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) new.br_state = got.br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) new.br_startblock = del_endblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) flags |= XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) error = xfs_bmbt_update(cur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) error = xfs_btree_increment(cur, 0, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) cur->bc_rec.b = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) error = xfs_btree_insert(cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) if (error && error != -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) * If get no-space back from btree insert, it tried a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) * split, and we have a zero block reservation. Fix up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) * our state and return the error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) if (error == -ENOSPC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) * Reset the cursor, don't trust it after any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) * insert operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) error = xfs_bmbt_lookup_eq(cur, &got, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) * Update the btree record back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) * to the original value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) error = xfs_bmbt_update(cur, &old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) * Reset the extent record back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) * to the original value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) xfs_iext_update_extent(ip, state, icur, &old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) error = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) flags |= xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) xfs_iext_next(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) xfs_iext_insert(ip, icur, &new, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) /* remove reverse mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) xfs_rmap_unmap_extent(tp, ip, whichfork, del);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) * If we need to, add to list of extents to delete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) if (do_fx && !(bflags & XFS_BMAPI_REMAP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) xfs_refcount_decrease_extent(tp, del);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) __xfs_bmap_add_free(tp, del->br_startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) del->br_blockcount, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) (bflags & XFS_BMAPI_NODISCARD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) del->br_state == XFS_EXT_UNWRITTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) * Adjust inode # blocks in the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) if (nblks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) ip->i_d.di_nblocks -= nblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) * Adjust quota data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) if (qfield && !(bflags & XFS_BMAPI_REMAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) *logflagsp = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) * Unmap (remove) blocks from a file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) * If nexts is nonzero then the number of extents to remove is limited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) * that value. If not all extents in the block range can be removed then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) * *done is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) __xfs_bunmapi(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) struct xfs_trans *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) struct xfs_inode *ip, /* incore inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) xfs_fileoff_t start, /* first file offset deleted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) xfs_filblks_t *rlen, /* i/o: amount remaining */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) int flags, /* misc flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) xfs_extnum_t nexts) /* number of extents max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) struct xfs_btree_cur *cur; /* bmap btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) struct xfs_bmbt_irec del; /* extent being deleted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) xfs_extnum_t extno; /* extent number in list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) struct xfs_bmbt_irec got; /* current extent record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) struct xfs_ifork *ifp; /* inode fork pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) int isrt; /* freeing in rt area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) int logflags; /* transaction logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) xfs_extlen_t mod; /* rt extent offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) int tmp_logflags; /* partial logging flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) int wasdel; /* was a delayed alloc extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) int whichfork; /* data or attribute fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) xfs_fsblock_t sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) xfs_filblks_t len = *rlen; /* length to unmap in file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) xfs_fileoff_t max_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) xfs_agnumber_t prev_agno = NULLAGNUMBER, agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) xfs_fileoff_t end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) bool done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) trace_xfs_bunmap(ip, start, len, flags, _RET_IP_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) whichfork = xfs_bmapi_whichfork(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) ASSERT(whichfork != XFS_COW_FORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) if (XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) ASSERT(len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) ASSERT(nexts >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) * Guesstimate how many blocks we can unmap without running the risk of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) * blowing out the transaction with a mix of EFIs and reflink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) * adjustments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) if (tp && xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) max_len = min(len, xfs_refcount_max_unmap(tp->t_log_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) max_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) if (!(ifp->if_flags & XFS_IFEXTENTS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) (error = xfs_iread_extents(tp, ip, whichfork)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) if (xfs_iext_count(ifp) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) *rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) XFS_STATS_INC(mp, xs_blk_unmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) end = start + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) if (!xfs_iext_lookup_extent_before(ip, ifp, &end, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) *rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) end--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) if (ifp->if_flags & XFS_IFBROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) cur->bc_ino.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) if (isrt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) * Synchronize by locking the bitmap inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) extno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) while (end != (xfs_fileoff_t)-1 && end >= start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) (nexts == 0 || extno < nexts) && max_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) * Is the found extent after a hole in which end lives?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) * Just back up to the previous extent, if so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) if (got.br_startoff > end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) !xfs_iext_prev_extent(ifp, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) * Is the last block of this extent before the range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) * we're supposed to delete? If so, we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) end = XFS_FILEOFF_MIN(end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) got.br_startoff + got.br_blockcount - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) if (end < start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) * Then deal with the (possibly delayed) allocated space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) * we found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) del = got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) wasdel = isnullstartblock(del.br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) * Make sure we don't touch multiple AGF headers out of order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) * in a single transaction, as that could cause AB-BA deadlocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) if (!wasdel && !isrt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) agno = XFS_FSB_TO_AGNO(mp, del.br_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) if (prev_agno != NULLAGNUMBER && prev_agno > agno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) prev_agno = agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) if (got.br_startoff < start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) del.br_startoff = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) del.br_blockcount -= start - got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) if (!wasdel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) del.br_startblock += start - got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) if (del.br_startoff + del.br_blockcount > end + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) del.br_blockcount = end + 1 - del.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) /* How much can we safely unmap? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) if (max_len < del.br_blockcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) del.br_startoff += del.br_blockcount - max_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) if (!wasdel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) del.br_startblock += del.br_blockcount - max_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) del.br_blockcount = max_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) if (!isrt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) goto delete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) sum = del.br_startblock + del.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) if (mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) * Realtime extent not lined up at the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) * The extent could have been split into written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) * and unwritten pieces, or we could just be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) * unmapping part of it. But we can't really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) * get rid of part of a realtime extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) if (del.br_state == XFS_EXT_UNWRITTEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) * This piece is unwritten, or we're not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) * using unwritten extents. Skip over it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) ASSERT(end >= mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) end -= mod > del.br_blockcount ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) del.br_blockcount : mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) if (end < got.br_startoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) !xfs_iext_prev_extent(ifp, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) * It's written, turn it unwritten.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) * This is better than zeroing it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) ASSERT(del.br_state == XFS_EXT_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) ASSERT(tp->t_blk_res > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) * If this spans a realtime extent boundary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) * chop it back to the start of the one we end at.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) if (del.br_blockcount > mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) del.br_startoff += del.br_blockcount - mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) del.br_startblock += del.br_blockcount - mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) del.br_blockcount = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) del.br_state = XFS_EXT_UNWRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) error = xfs_bmap_add_extent_unwritten_real(tp, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) whichfork, &icur, &cur, &del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) &logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) goto nodelete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) if (mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) xfs_extlen_t off = mp->m_sb.sb_rextsize - mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) * Realtime extent is lined up at the end but not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) * at the front. We'll get rid of full extents if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) * we can.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) if (del.br_blockcount > off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) del.br_blockcount -= off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) del.br_startoff += off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) del.br_startblock += off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) } else if (del.br_startoff == start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) (del.br_state == XFS_EXT_UNWRITTEN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) tp->t_blk_res == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) * Can't make it unwritten. There isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) * a full extent here so just skip it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) ASSERT(end >= del.br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) end -= del.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) if (got.br_startoff > end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) !xfs_iext_prev_extent(ifp, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) } else if (del.br_state == XFS_EXT_UNWRITTEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) struct xfs_bmbt_irec prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) xfs_fileoff_t unwrite_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) * This one is already unwritten.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) * It must have a written left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) * Unwrite the killed part of that one and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) * try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) if (!xfs_iext_prev_extent(ifp, &icur, &prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) ASSERT(prev.br_state == XFS_EXT_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) ASSERT(!isnullstartblock(prev.br_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) ASSERT(del.br_startblock ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) prev.br_startblock + prev.br_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) unwrite_start = max3(start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) del.br_startoff - mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) prev.br_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) mod = unwrite_start - prev.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) prev.br_startoff = unwrite_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) prev.br_startblock += mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) prev.br_blockcount -= mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) prev.br_state = XFS_EXT_UNWRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) error = xfs_bmap_add_extent_unwritten_real(tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) ip, whichfork, &icur, &cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) &prev, &logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) goto nodelete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) ASSERT(del.br_state == XFS_EXT_NORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) del.br_state = XFS_EXT_UNWRITTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) error = xfs_bmap_add_extent_unwritten_real(tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) ip, whichfork, &icur, &cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) &del, &logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) goto nodelete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) delete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) if (wasdel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) error = xfs_bmap_del_extent_delay(ip, whichfork, &icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) &got, &del);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) error = xfs_bmap_del_extent_real(ip, tp, &icur, cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) &del, &tmp_logflags, whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) logflags |= tmp_logflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) max_len -= del.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) end = del.br_startoff - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) nodelete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) * If not done go on to the next (previous) record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) if (end != (xfs_fileoff_t)-1 && end >= start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) if (!xfs_iext_get_extent(ifp, &icur, &got) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) (got.br_startoff > end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) !xfs_iext_prev_extent(ifp, &icur, &got))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) extno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) if (done || end == (xfs_fileoff_t)-1 || end < start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) *rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) *rlen = end - start + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) * Convert to a btree if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) if (xfs_bmap_needs_btree(ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) ASSERT(cur == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) &tmp_logflags, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) logflags |= tmp_logflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) * Log everything. Do this after conversion, there's no point in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) * logging the extent records if we've converted to btree format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) if ((logflags & xfs_ilog_fext(whichfork)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) ifp->if_format != XFS_DINODE_FMT_EXTENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) logflags &= ~xfs_ilog_fext(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) else if ((logflags & xfs_ilog_fbroot(whichfork)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) ifp->if_format != XFS_DINODE_FMT_BTREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) logflags &= ~xfs_ilog_fbroot(whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) * Log inode even in the error case, if the transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) * is dirty we'll need to shut down the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) if (logflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) xfs_trans_log_inode(tp, ip, logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) cur->bc_ino.allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) /* Unmap a range of a file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) xfs_bunmapi(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) xfs_trans_t *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) xfs_fileoff_t bno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) xfs_filblks_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) xfs_extnum_t nexts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) int *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) *done = (len == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) * Determine whether an extent shift can be accomplished by a merge with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) * extent that precedes the target hole of the shift.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) STATIC bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) xfs_bmse_can_merge(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) struct xfs_bmbt_irec *left, /* preceding extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) struct xfs_bmbt_irec *got, /* current extent to shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) xfs_fileoff_t shift) /* shift fsb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) xfs_fileoff_t startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) startoff = got->br_startoff - shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) * The extent, once shifted, must be adjacent in-file and on-disk with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) * the preceding extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) if ((left->br_startoff + left->br_blockcount != startoff) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) (left->br_startblock + left->br_blockcount != got->br_startblock) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) (left->br_state != got->br_state) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) (left->br_blockcount + got->br_blockcount > MAXEXTLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) * A bmap extent shift adjusts the file offset of an extent to fill a preceding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) * hole in the file. If an extent shift would result in the extent being fully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) * adjacent to the extent that currently precedes the hole, we can merge with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) * the preceding extent rather than do the shift.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) * This function assumes the caller has verified a shift-by-merge is possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) * with the provided extents via xfs_bmse_can_merge().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) xfs_bmse_merge(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) xfs_fileoff_t shift, /* shift fsb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) struct xfs_bmbt_irec *got, /* extent to shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) struct xfs_bmbt_irec *left, /* preceding extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) int *logflags) /* output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) struct xfs_bmbt_irec new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) xfs_filblks_t blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) int error, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) blockcount = left->br_blockcount + got->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) ASSERT(xfs_bmse_can_merge(left, got, shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) new = *left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) new.br_blockcount = blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) * Update the on-disk extent count, the btree if necessary and log the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) * inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) ifp->if_nextents--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) *logflags |= XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) if (!cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) *logflags |= XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) /* lookup and remove the extent to merge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) error = xfs_bmbt_lookup_eq(cur, got, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) if (XFS_IS_CORRUPT(mp, i != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) error = xfs_btree_delete(cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) if (XFS_IS_CORRUPT(mp, i != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) /* lookup and update size of the previous extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) error = xfs_bmbt_lookup_eq(cur, left, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) if (XFS_IS_CORRUPT(mp, i != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) error = xfs_bmbt_update(cur, &new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) /* change to extent format if required after extent removal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) error = xfs_bmap_btree_to_extents(tp, ip, cur, logflags, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) xfs_iext_remove(ip, icur, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) xfs_iext_prev(ifp, icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) &new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) /* update reverse mapping. rmap functions merge the rmaps for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) xfs_rmap_unmap_extent(tp, ip, whichfork, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) memcpy(&new, got, sizeof(new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) new.br_startoff = left->br_startoff + left->br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) xfs_rmap_map_extent(tp, ip, whichfork, &new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) xfs_bmap_shift_update_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) struct xfs_iext_cursor *icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) struct xfs_bmbt_irec *got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) int *logflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) xfs_fileoff_t startoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) struct xfs_bmbt_irec prev = *got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) int error, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) *logflags |= XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) got->br_startoff = startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) error = xfs_bmbt_lookup_eq(cur, &prev, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) if (XFS_IS_CORRUPT(mp, i != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) error = xfs_bmbt_update(cur, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) *logflags |= XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) /* update reverse mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) xfs_rmap_unmap_extent(tp, ip, whichfork, &prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) xfs_rmap_map_extent(tp, ip, whichfork, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) xfs_bmap_collapse_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) xfs_fileoff_t *next_fsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) xfs_fileoff_t offset_shift_fsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) bool *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) int whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) struct xfs_btree_cur *cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) struct xfs_bmbt_irec got, prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) xfs_fileoff_t new_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) int logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) if (XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) if (ifp->if_flags & XFS_IFBROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) cur->bc_ino.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) *done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) new_startoff = got.br_startoff - offset_shift_fsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) if (xfs_iext_peek_prev_extent(ifp, &icur, &prev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) if (new_startoff < prev.br_startoff + prev.br_blockcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) if (xfs_bmse_can_merge(&prev, &got, offset_shift_fsb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) error = xfs_bmse_merge(tp, ip, whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) offset_shift_fsb, &icur, &got, &prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) cur, &logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) if (got.br_startoff < offset_shift_fsb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) error = xfs_bmap_shift_update_extent(tp, ip, whichfork, &icur, &got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) cur, &logflags, new_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) if (!xfs_iext_next_extent(ifp, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) *done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) *next_fsb = got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) del_cursor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) if (cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) if (logflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) xfs_trans_log_inode(tp, ip, logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) /* Make sure we won't be right-shifting an extent past the maximum bound. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) xfs_bmap_can_insert_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) xfs_fileoff_t off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) xfs_fileoff_t shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) struct xfs_bmbt_irec got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) int is_empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) if (XFS_FORCED_SHUTDOWN(ip->i_mount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) error = xfs_bmap_last_extent(NULL, ip, XFS_DATA_FORK, &got, &is_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) if (!error && !is_empty && got.br_startoff >= off &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) ((got.br_startoff + shift) & BMBT_STARTOFF_MASK) < got.br_startoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) xfs_iunlock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) xfs_bmap_insert_extents(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) xfs_fileoff_t *next_fsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) xfs_fileoff_t offset_shift_fsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) bool *done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) xfs_fileoff_t stop_fsb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) int whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) struct xfs_btree_cur *cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) struct xfs_bmbt_irec got, next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) xfs_fileoff_t new_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) int logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) if (XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) if (ifp->if_flags & XFS_IFBROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) cur->bc_ino.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) if (*next_fsb == NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) xfs_iext_last(ifp, &icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) if (!xfs_iext_get_extent(ifp, &icur, &got) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) stop_fsb > got.br_startoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) *done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &icur, &got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) *done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) if (XFS_IS_CORRUPT(mp, stop_fsb > got.br_startoff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) new_startoff = got.br_startoff + offset_shift_fsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) if (xfs_iext_peek_next_extent(ifp, &icur, &next)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) if (new_startoff + got.br_blockcount > next.br_startoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) * Unlike a left shift (which involves a hole punch), a right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) * shift does not modify extent neighbors in any way. We should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) * never find mergeable extents in this scenario. Check anyways
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) * and warn if we encounter two extents that could be one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) if (xfs_bmse_can_merge(&got, &next, offset_shift_fsb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) error = xfs_bmap_shift_update_extent(tp, ip, whichfork, &icur, &got,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) cur, &logflags, new_startoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) if (!xfs_iext_prev_extent(ifp, &icur, &got) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) stop_fsb >= got.br_startoff + got.br_blockcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) *done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) *next_fsb = got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) del_cursor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) if (cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) if (logflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) xfs_trans_log_inode(tp, ip, logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) * Splits an extent into two extents at split_fsb block such that it is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) * first block of the current_ext. @ext is a target extent to be split.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) * @split_fsb is a block where the extents is split. If split_fsb lies in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) * hole or the first block of extents, just return 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) xfs_bmap_split_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) xfs_fileoff_t split_fsb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) int whichfork = XFS_DATA_FORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) struct xfs_btree_cur *cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) struct xfs_bmbt_irec got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) struct xfs_bmbt_irec new; /* split extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) xfs_fsblock_t gotblkcnt; /* new block count for got */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) struct xfs_iext_cursor icur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) int logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) if (XFS_FORCED_SHUTDOWN(mp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) if (!(ifp->if_flags & XFS_IFEXTENTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) /* Read in all the extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) error = xfs_iread_extents(tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) * If there are not extents, or split_fsb lies in a hole we are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) if (!xfs_iext_lookup_extent(ip, ifp, split_fsb, &icur, &got) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) got.br_startoff >= split_fsb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) gotblkcnt = split_fsb - got.br_startoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) new.br_startoff = split_fsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) new.br_startblock = got.br_startblock + gotblkcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) new.br_blockcount = got.br_blockcount - gotblkcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) new.br_state = got.br_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) if (ifp->if_flags & XFS_IFBROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) cur->bc_ino.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) error = xfs_bmbt_lookup_eq(cur, &got, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) got.br_blockcount = gotblkcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), &icur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) logflags = XFS_ILOG_CORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) error = xfs_bmbt_update(cur, &got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) logflags |= XFS_ILOG_DEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) /* Add new extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) xfs_iext_next(ifp, &icur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) xfs_iext_insert(ip, &icur, &new, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) ifp->if_nextents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) error = xfs_bmbt_lookup_eq(cur, &new, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) if (XFS_IS_CORRUPT(mp, i != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) error = xfs_btree_insert(cur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) if (XFS_IS_CORRUPT(mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) goto del_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) * Convert to a btree if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) if (xfs_bmap_needs_btree(ip, whichfork)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) int tmp_logflags; /* partial log flag return val */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) ASSERT(cur == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) &tmp_logflags, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) logflags |= tmp_logflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) del_cursor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) if (cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) cur->bc_ino.allocated = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) if (logflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) xfs_trans_log_inode(tp, ip, logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) /* Deferred mapping is only for real extents in the data fork. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) xfs_bmap_is_update_needed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) struct xfs_bmbt_irec *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) return bmap->br_startblock != HOLESTARTBLOCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) bmap->br_startblock != DELAYSTARTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) /* Record a bmap intent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) __xfs_bmap_add(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) enum xfs_bmap_intent_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) struct xfs_bmbt_irec *bmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) struct xfs_bmap_intent *bi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) trace_xfs_bmap_defer(tp->t_mountp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) ip->i_ino, whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) bmap->br_startoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) bmap->br_blockcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) bmap->br_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) INIT_LIST_HEAD(&bi->bi_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) bi->bi_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) bi->bi_owner = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) bi->bi_whichfork = whichfork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) bi->bi_bmap = *bmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_BMAP, &bi->bi_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) /* Map an extent into a file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) xfs_bmap_map_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) struct xfs_bmbt_irec *PREV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) if (!xfs_bmap_is_update_needed(PREV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) __xfs_bmap_add(tp, XFS_BMAP_MAP, ip, XFS_DATA_FORK, PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) /* Unmap an extent out of a file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) xfs_bmap_unmap_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) struct xfs_bmbt_irec *PREV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) if (!xfs_bmap_is_update_needed(PREV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) __xfs_bmap_add(tp, XFS_BMAP_UNMAP, ip, XFS_DATA_FORK, PREV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) * Process one of the deferred bmap operations. We pass back the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) * btree cursor to maintain our lock on the bmapbt between calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) xfs_bmap_finish_one(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) struct xfs_trans *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) enum xfs_bmap_intent_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) xfs_fileoff_t startoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) xfs_fsblock_t startblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) xfs_filblks_t *blockcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) xfs_exntst_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) ASSERT(tp->t_firstblock == NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) trace_xfs_bmap_deferred(tp->t_mountp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) XFS_FSB_TO_AGNO(tp->t_mountp, startblock), type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) ip->i_ino, whichfork, startoff, *blockcount, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) if (WARN_ON_ONCE(whichfork != XFS_DATA_FORK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) if (XFS_TEST_ERROR(false, tp->t_mountp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) XFS_ERRTAG_BMAP_FINISH_ONE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) case XFS_BMAP_MAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) error = xfs_bmapi_remap(tp, ip, startoff, *blockcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) startblock, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) *blockcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) case XFS_BMAP_UNMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) error = __xfs_bunmapi(tp, ip, startoff, blockcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) XFS_BMAPI_REMAP, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) /* Check that an inode's extent does not have invalid flags or bad ranges. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) xfs_failaddr_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) xfs_bmap_validate_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) struct xfs_inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) int whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) struct xfs_bmbt_irec *irec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) struct xfs_mount *mp = ip->i_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) xfs_fsblock_t endfsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) bool isrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) isrt = XFS_IS_REALTIME_INODE(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) endfsb = irec->br_startblock + irec->br_blockcount - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) if (isrt && whichfork == XFS_DATA_FORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) if (!xfs_verify_rtbno(mp, irec->br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) if (!xfs_verify_rtbno(mp, endfsb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) if (!xfs_verify_fsbno(mp, irec->br_startblock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) if (!xfs_verify_fsbno(mp, endfsb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) if (XFS_FSB_TO_AGNO(mp, irec->br_startblock) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) XFS_FSB_TO_AGNO(mp, endfsb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) if (irec->br_state != XFS_EXT_NORM && whichfork != XFS_DATA_FORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) }