^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-2005 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_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_bmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_bmap_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_trans_space.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_icache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "xfs_rtalloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "xfs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Read and return the summary information for a given extent size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * bitmap block combination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Keeps track of a current summary block, so we don't keep reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * it from the buffer cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) xfs_rtget_summary(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) xfs_mount_t *mp, /* file system mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int log, /* log2 of extent size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) xfs_rtblock_t bbno, /* bitmap block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) xfs_buf_t **rbpp, /* in/out: summary block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) xfs_fsblock_t *rsb, /* in/out: summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) xfs_suminfo_t *sum) /* out: summary info for this block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^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) * Return whether there are any free extents in the size range given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * by low and high, for the bitmap block bbno.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) xfs_rtany_summary(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) xfs_mount_t *mp, /* file system mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int low, /* low log2 extent size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int high, /* high log2 extent size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) xfs_rtblock_t bbno, /* bitmap block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) xfs_buf_t **rbpp, /* in/out: summary block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) xfs_fsblock_t *rsb, /* in/out: summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int *stat) /* out: any good extents here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int error; /* error value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int log; /* loop counter, log2 of ext. size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) xfs_suminfo_t sum; /* summary data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* There are no extents at levels < m_rsum_cache[bbno]. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) low = mp->m_rsum_cache[bbno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Loop over logs of extent sizes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) for (log = low; log <= high; log++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Get one summary datum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * If there are any, return success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (sum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Found nothing, return failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* There were no extents at levels < log. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mp->m_rsum_cache[bbno] = log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^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) * Copy and transform the summary file, given the old and new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * parameters in the mount structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) xfs_rtcopy_summary(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) xfs_mount_t *omp, /* old file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) xfs_mount_t *nmp, /* new file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) xfs_trans_t *tp) /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) xfs_rtblock_t bbno; /* bitmap block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) xfs_buf_t *bp; /* summary buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int log; /* summary level number (log length) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) xfs_suminfo_t sum; /* summary data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) xfs_fsblock_t sumbno; /* summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) for (log = omp->m_rsumlevels - 1; log >= 0; log--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) for (bbno = omp->m_sb.sb_rbmblocks - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) (xfs_srtblock_t)bbno >= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) bbno--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) error = xfs_rtget_summary(omp, tp, log, bbno, &bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) &sumbno, &sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (sum == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) &bp, &sumbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) &bp, &sumbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ASSERT(sum > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Mark an extent specified by start and len allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Updates all the summary information as well as the bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) xfs_rtallocate_range(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) xfs_mount_t *mp, /* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) xfs_rtblock_t start, /* start block to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) xfs_extlen_t len, /* length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) xfs_buf_t **rbpp, /* in/out: summary block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) xfs_fsblock_t *rsb) /* in/out: summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) xfs_rtblock_t end; /* end of the allocated extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int error; /* error value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) xfs_rtblock_t postblock = 0; /* first block allocated > end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) xfs_rtblock_t preblock = 0; /* first block allocated < start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) end = start + len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Assume we're allocating out of the middle of a free extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * We need to find the beginning and end of the extent so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * properly update the summary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * Find the next allocated block (end of free extent).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) &postblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Decrement the summary information corresponding to the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * (old) free extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) error = xfs_rtmodify_summary(mp, tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) XFS_RTBLOCKLOG(postblock + 1 - preblock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * If there are blocks not being allocated at the front of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * old extent, add summary data for them to be free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (preblock < start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) error = xfs_rtmodify_summary(mp, tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) XFS_RTBLOCKLOG(start - preblock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * If there are blocks not being allocated at the end of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * old extent, add summary data for them to be free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (postblock > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) error = xfs_rtmodify_summary(mp, tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) XFS_RTBLOCKLOG(postblock - end),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return error;
^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) * Modify the bitmap to mark this extent allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) error = xfs_rtmodify_range(mp, tp, start, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Attempt to allocate an extent minlen<=len<=maxlen starting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * bitmap block bbno. If we don't get maxlen then use prod to trim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * the length, if given. Returns error; returns starting block in *rtblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * The lengths are all in rtextents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) xfs_rtallocate_extent_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) xfs_mount_t *mp, /* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) xfs_rtblock_t bbno, /* bitmap block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) xfs_extlen_t minlen, /* minimum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) xfs_extlen_t maxlen, /* maximum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) xfs_extlen_t *len, /* out: actual length allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) xfs_rtblock_t *nextp, /* out: next block to try */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) xfs_buf_t **rbpp, /* in/out: summary block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) xfs_fsblock_t *rsb, /* in/out: summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) xfs_extlen_t prod, /* extent product factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) xfs_rtblock_t *rtblock) /* out: start block allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) xfs_rtblock_t besti; /* best rtblock found so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) xfs_rtblock_t bestlen; /* best length found so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) xfs_rtblock_t end; /* last rtblock in chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int error; /* error value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) xfs_rtblock_t i; /* current rtblock trying */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) xfs_rtblock_t next; /* next rtblock to try */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int stat; /* status from internal calls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Loop over all the extents starting in this bitmap block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * looking for one that's long enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) for (i = XFS_BLOCKTOBIT(mp, bbno), besti = -1, bestlen = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) end = XFS_BLOCKTOBIT(mp, bbno + 1) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) i <= end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* Make sure we don't scan off the end of the rt volume. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) maxlen = min(mp->m_sb.sb_rextents, i + maxlen) - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * See if there's a free extent of maxlen starting at i.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * If it's not so then next will contain the first non-free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, &next, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (stat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * i for maxlen is all free, allocate and return that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) error = xfs_rtallocate_range(mp, tp, i, maxlen, rbpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) rsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *len = maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *rtblock = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * In the case where we have a variable-sized allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * request, figure out how big this free piece is,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * and if it's big enough for the minimum, and the best
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * so far, remember it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (minlen < maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) xfs_rtblock_t thislen; /* this extent size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) thislen = next - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (thislen >= minlen && thislen > bestlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) besti = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) bestlen = thislen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * If not done yet, find the start of the next free space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (next < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) error = xfs_rtfind_forw(mp, tp, next, end, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * Searched the whole thing & didn't find a maxlen free extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (minlen < maxlen && besti != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) xfs_extlen_t p; /* amount to trim length by */
^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) * If size should be a multiple of prod, make that so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (prod > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) div_u64_rem(bestlen, prod, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) bestlen -= p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * Allocate besti for bestlen & return that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) error = xfs_rtallocate_range(mp, tp, besti, bestlen, rbpp, rsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) *len = bestlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *rtblock = besti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * Allocation failed. Set *nextp to the next block to try.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) *nextp = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Allocate an extent of length minlen<=len<=maxlen, starting at block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * bno. If we don't get maxlen then use prod to trim the length, if given.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Returns error; returns starting block in *rtblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * The lengths are all in rtextents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) xfs_rtallocate_extent_exact(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) xfs_mount_t *mp, /* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) xfs_rtblock_t bno, /* starting block number to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) xfs_extlen_t minlen, /* minimum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) xfs_extlen_t maxlen, /* maximum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) xfs_extlen_t *len, /* out: actual length allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) xfs_buf_t **rbpp, /* in/out: summary block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) xfs_fsblock_t *rsb, /* in/out: summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) xfs_extlen_t prod, /* extent product factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) xfs_rtblock_t *rtblock) /* out: start block allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int error; /* error value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) xfs_extlen_t i; /* extent length trimmed due to prod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int isfree; /* extent is free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) xfs_rtblock_t next; /* next block to try (dummy) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ASSERT(minlen % prod == 0 && maxlen % prod == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * Check if the range in question (for maxlen) is free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, &next, &isfree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (isfree) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * If it is, allocate it and return success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) *len = maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) *rtblock = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * If not, allocate what there is, if it's at least minlen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) maxlen = next - bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (maxlen < minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * Failed, return failure status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * Trim off tail of extent, if prod is specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (prod > 1 && (i = maxlen % prod)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) maxlen -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (maxlen < minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Now we can't do it, return failure status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Allocate what we can and return it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *len = maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *rtblock = bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * Allocate an extent of length minlen<=len<=maxlen, starting as near
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * to bno as possible. If we don't get maxlen then use prod to trim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * the length, if given. The lengths are all in rtextents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) xfs_rtallocate_extent_near(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) xfs_mount_t *mp, /* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) xfs_rtblock_t bno, /* starting block number to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) xfs_extlen_t minlen, /* minimum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) xfs_extlen_t maxlen, /* maximum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) xfs_extlen_t *len, /* out: actual length allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) xfs_buf_t **rbpp, /* in/out: summary block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) xfs_fsblock_t *rsb, /* in/out: summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) xfs_extlen_t prod, /* extent product factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) xfs_rtblock_t *rtblock) /* out: start block allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int any; /* any useful extents from summary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) xfs_rtblock_t bbno; /* bitmap block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int error; /* error value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int i; /* bitmap block offset (loop control) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int j; /* secondary loop control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int log2len; /* log2 of minlen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) xfs_rtblock_t n; /* next block to try */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) xfs_rtblock_t r; /* result block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ASSERT(minlen % prod == 0 && maxlen % prod == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * If the block number given is off the end, silently set it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * the last block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (bno >= mp->m_sb.sb_rextents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) bno = mp->m_sb.sb_rextents - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Make sure we don't run off the end of the rt volume. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) maxlen = min(mp->m_sb.sb_rextents, bno + maxlen) - bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (maxlen < minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * Try the exact allocation first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) rbpp, rsb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * If the exact allocation worked, return that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (r != NULLRTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *rtblock = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) bbno = XFS_BITTOBLOCK(mp, bno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ASSERT(minlen != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) log2len = xfs_highbit32(minlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * Loop over all bitmap blocks (bbno + i is current block).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * Get summary information of extents of all useful levels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * starting in this bitmap block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) bbno + i, rbpp, rsb, &any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * If there are any useful extents starting here, try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * allocating one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (any) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * On the positive side of the starting location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * Try to allocate an extent starting in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * this block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) error = xfs_rtallocate_extent_block(mp, tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) bbno + i, minlen, maxlen, len, &n, rbpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) rsb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * If it worked, return it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (r != NULLRTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) *rtblock = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return 0;
^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) * On the negative side of the starting location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) else { /* i < 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * Loop backwards through the bitmap blocks from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * the starting point-1 up to where we are now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * There should be an extent which ends in this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * bitmap block and is long enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) for (j = -1; j > i; j--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * Grab the summary information for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * this bitmap block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) error = xfs_rtany_summary(mp, tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) log2len, mp->m_rsumlevels - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) bbno + j, rbpp, rsb, &any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * If there's no extent given in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * summary that means the extent we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * found must carry over from an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * earlier block. If there is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * extent given, we've already tried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * that allocation, don't do it again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) error = xfs_rtallocate_extent_block(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) tp, bbno + j, minlen, maxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) len, &n, rbpp, rsb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * If it works, return the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (r != NULLRTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) *rtblock = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * There weren't intervening bitmap blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * with a long enough extent, or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * allocation didn't work for some reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * (i.e. it's a little * too short).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * Try to allocate from the summary block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * that we found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) error = xfs_rtallocate_extent_block(mp, tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) bbno + i, minlen, maxlen, len, &n, rbpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) rsb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return error;
^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) * If it works, return the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (r != NULLRTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) *rtblock = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * Loop control. If we were on the positive side, and there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * still more blocks on the negative side, go there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (i > 0 && (int)bbno - i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) i = -i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * If positive, and no more negative, but there are more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * positive, go there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) else if (i > 0 && (int)bbno + i < mp->m_sb.sb_rbmblocks - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * If negative or 0 (just started), and there are positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * blocks to go, go there. The 0 case moves to block 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) else if (i <= 0 && (int)bbno - i < mp->m_sb.sb_rbmblocks - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) i = 1 - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * If negative or 0 and there are more negative blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * go there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) else if (i <= 0 && (int)bbno + i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * Must be done. Return failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * Allocate an extent of length minlen<=len<=maxlen, with no position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * specified. If we don't get maxlen then use prod to trim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * the length, if given. The lengths are all in rtextents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) STATIC int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) xfs_rtallocate_extent_size(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) xfs_mount_t *mp, /* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) xfs_extlen_t minlen, /* minimum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) xfs_extlen_t maxlen, /* maximum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) xfs_extlen_t *len, /* out: actual length allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) xfs_buf_t **rbpp, /* in/out: summary block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) xfs_fsblock_t *rsb, /* in/out: summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) xfs_extlen_t prod, /* extent product factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) xfs_rtblock_t *rtblock) /* out: start block allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) int error; /* error value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int i; /* bitmap block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) int l; /* level number (loop control) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) xfs_rtblock_t n; /* next block to be tried */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) xfs_rtblock_t r; /* result block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) xfs_suminfo_t sum; /* summary information for extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ASSERT(minlen % prod == 0 && maxlen % prod == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ASSERT(maxlen != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * Loop over all the levels starting with maxlen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * At each level, look at all the bitmap blocks, to see if there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * are extents starting there that are long enough (>= maxlen).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * Note, only on the initial level can the allocation fail if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * the summary says there's an extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) for (l = xfs_highbit32(maxlen); l < mp->m_rsumlevels; l++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * Loop over all the bitmap blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * Get the summary for this level/block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) &sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * Nothing there, on to the next block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * Try allocating the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) error = xfs_rtallocate_extent_block(mp, tp, i, maxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) maxlen, len, &n, rbpp, rsb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * If it worked, return that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (r != NULLRTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) *rtblock = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * If the "next block to try" returned from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * allocator is beyond the next bitmap block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * skip to that bitmap block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (XFS_BITTOBLOCK(mp, n) > i + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) i = XFS_BITTOBLOCK(mp, n) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Didn't find any maxlen blocks. Try smaller ones, unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * we're asking for a fixed size extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (minlen > --maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ASSERT(minlen != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ASSERT(maxlen != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * Loop over sizes, from maxlen down to minlen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * This time, when we do the allocations, allow smaller ones
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * to succeed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * Loop over all the bitmap blocks, try an allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * starting in that block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * Get the summary information for this level/block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) &sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * If nothing there, go on to next.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (!sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * Try the allocation. Make sure the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * minlen/maxlen are in the possible range for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * this summary level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) error = xfs_rtallocate_extent_block(mp, tp, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) XFS_RTMAX(minlen, 1 << l),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) XFS_RTMIN(maxlen, (1 << (l + 1)) - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) len, &n, rbpp, rsb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * If it worked, return that extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (r != NULLRTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) *rtblock = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * If the "next block to try" returned from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * allocator is beyond the next bitmap block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * skip to that bitmap block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (XFS_BITTOBLOCK(mp, n) > i + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) i = XFS_BITTOBLOCK(mp, n) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^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) * Got nothing, return failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * Allocate space to the bitmap or summary file, and zero it, for growfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) xfs_growfs_rt_alloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) struct xfs_mount *mp, /* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) xfs_extlen_t oblocks, /* old count of blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) xfs_extlen_t nblocks, /* new count of blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct xfs_inode *ip) /* inode (bitmap/summary) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) xfs_fileoff_t bno; /* block number in file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct xfs_buf *bp; /* temporary buffer for zeroing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) xfs_daddr_t d; /* disk block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) xfs_fsblock_t fsbno; /* filesystem block for bno */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct xfs_bmbt_irec map; /* block map output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int nmap; /* number of block maps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) int resblks; /* space reservation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) enum xfs_blft buf_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct xfs_trans *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (ip == mp->m_rsumip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) buf_type = XFS_BLFT_RTSUMMARY_BUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) buf_type = XFS_BLFT_RTBITMAP_BUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * Allocate space to the file, as necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) while (oblocks < nblocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * Reserve space & log for one extent added to the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc, resblks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 0, 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * Lock the inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * Allocate blocks to the bitmap file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) nmap = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) XFS_BMAPI_METADATA, 0, &map, &nmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (!error && nmap < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) error = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) goto out_trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * Free any blocks freed up in the transaction, then commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * Now we need to clear the allocated blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * Do this one block per transaction, to keep it simple.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) for (bno = map.br_startoff, fsbno = map.br_startblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) bno < map.br_startoff + map.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) bno++, fsbno++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * Reserve log for one block zeroing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 0, 0, 0, &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * Lock the bitmap inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) xfs_ilock(ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * Get a buffer for the block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) d = XFS_FSB_TO_DADDR(mp, fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) mp->m_bsize, 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto out_trans_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) xfs_trans_buf_set_type(tp, bp, buf_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) bp->b_ops = &xfs_rtbuf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) memset(bp->b_addr, 0, mp->m_sb.sb_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * Commit the transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * Go on to the next extent, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) oblocks = map.br_startoff + map.br_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) out_trans_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) xfs_trans_cancel(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) xfs_alloc_rsum_cache(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) xfs_mount_t *mp, /* file system mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * The rsum cache is initialized to all zeroes, which is trivially a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * lower bound on the minimum level with any free extents. We can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * continue without the cache if it couldn't be allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) mp->m_rsum_cache = kvzalloc(rbmblocks, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (!mp->m_rsum_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) xfs_warn(mp, "could not allocate realtime summary cache");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * Visible (exported) functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * Grow the realtime area of the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) xfs_growfs_rt(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) xfs_mount_t *mp, /* mount point for filesystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) xfs_growfs_rt_t *in) /* growfs rt input struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) xfs_rtblock_t bmbno; /* bitmap block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) xfs_buf_t *bp; /* temporary buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) xfs_mount_t *nmp; /* new (fake) mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) xfs_rfsblock_t nrblocks; /* new number of realtime blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) xfs_rtblock_t nrextents; /* new number of realtime extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) uint8_t nrextslog; /* new log2 of sb_rextents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) xfs_extlen_t nrsumblocks; /* new number of summary blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) uint nrsumlevels; /* new rt summary levels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) uint nrsumsize; /* new size of rt summary, bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) xfs_sb_t *nsbp; /* new superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) xfs_extlen_t rsumblocks; /* current number of rt summary blks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) xfs_sb_t *sbp; /* old superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) xfs_fsblock_t sumbno; /* summary block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) uint8_t *rsum_cache; /* old summary cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) sbp = &mp->m_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * Initial error checking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (mp->m_rtdev_targp == NULL || mp->m_rbmip == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) (nrblocks = in->newblocks) <= sbp->sb_rblocks ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if ((error = xfs_sb_validate_fsb_count(sbp, nrblocks)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * Read in the last block of the device, make sure it exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) error = xfs_buf_read_uncached(mp->m_rtdev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) XFS_FSB_TO_BB(mp, nrblocks - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) xfs_buf_relse(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * Calculate new parameters. These are the final values to be reached.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) nrextents = nrblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) do_div(nrextents, in->extsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) nrextslog = xfs_highbit32(nrextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) nrsumlevels = nrextslog + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * New summary size can't be more than half the size of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * the log. This prevents us from getting a log overflow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * since we'll log basically the whole summary file at once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (nrsumblocks > (mp->m_sb.sb_logblocks >> 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * Get the old block counts for bitmap and summary inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * These can't change since other growfs callers are locked out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) rbmblocks = XFS_B_TO_FSB(mp, mp->m_rbmip->i_d.di_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) rsumblocks = XFS_B_TO_FSB(mp, mp->m_rsumip->i_d.di_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * Allocate space to the bitmap and summary files, as necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) error = xfs_growfs_rt_alloc(mp, rbmblocks, nrbmblocks, mp->m_rbmip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) rsum_cache = mp->m_rsum_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (nrbmblocks != sbp->sb_rbmblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) xfs_alloc_rsum_cache(mp, nrbmblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * Allocate a new (fake) mount/sb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) nmp = kmem_alloc(sizeof(*nmp), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * Loop over the bitmap blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * We will do everything one bitmap block at a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * Skip the current block if it is exactly full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * This also deals with the case where there were no rtextents before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) for (bmbno = sbp->sb_rbmblocks -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) bmbno < nrbmblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) bmbno++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) xfs_trans_t *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) *nmp = *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) nsbp = &nmp->m_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * Calculate new sb and mount fields for this round.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) nsbp->sb_rextsize = in->extsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) nsbp->sb_rbmblocks = bmbno + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) nsbp->sb_rblocks =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) XFS_RTMIN(nrblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) nsbp->sb_rbmblocks * NBBY *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) nsbp->sb_blocksize * nsbp->sb_rextsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) nsbp->sb_rextents = nsbp->sb_rblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) ASSERT(nsbp->sb_rextents != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) nrsumsize =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) (uint)sizeof(xfs_suminfo_t) * nrsumlevels *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) nsbp->sb_rbmblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * Start a transaction, get the log reservation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtfree, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) &tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * Lock out other callers by grabbing the bitmap inode lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * Update the bitmap inode's size ondisk and incore. We need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * to update the incore size so that inode inactivation won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * punch what it thinks are "posteof" blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) mp->m_rbmip->i_d.di_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) nsbp->sb_rbmblocks * nsbp->sb_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_d.di_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * Get the summary inode into the transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * Update the summary inode's size. We need to update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * incore size so that inode inactivation won't punch what it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * thinks are "posteof" blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) mp->m_rsumip->i_d.di_size = nmp->m_rsumsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) i_size_write(VFS_I(mp->m_rsumip), mp->m_rsumip->i_d.di_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) xfs_trans_log_inode(tp, mp->m_rsumip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * Copy summary data from old to new sizes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * Do this when the real size (not block-aligned) changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (sbp->sb_rbmblocks != nsbp->sb_rbmblocks ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) mp->m_rsumlevels != nmp->m_rsumlevels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) error = xfs_rtcopy_summary(mp, nmp, tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) goto error_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * Update superblock fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (nsbp->sb_rextsize != sbp->sb_rextsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) nsbp->sb_rextsize - sbp->sb_rextsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (nsbp->sb_rbmblocks != sbp->sb_rbmblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBMBLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) nsbp->sb_rbmblocks - sbp->sb_rbmblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (nsbp->sb_rblocks != sbp->sb_rblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) nsbp->sb_rblocks - sbp->sb_rblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (nsbp->sb_rextents != sbp->sb_rextents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) nsbp->sb_rextents - sbp->sb_rextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (nsbp->sb_rextslog != sbp->sb_rextslog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) nsbp->sb_rextslog - sbp->sb_rextslog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * Free new extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) error_cancel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) xfs_trans_cancel(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * Mark more blocks free in the superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) nsbp->sb_rextents - sbp->sb_rextents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * Update mp values into the real mp structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) mp->m_rsumlevels = nrsumlevels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) mp->m_rsumsize = nrsumsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) error = xfs_trans_commit(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* Update secondary superblocks now the physical grow has completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) error = xfs_update_secondary_sbs(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * Free the fake mp structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) kmem_free(nmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) * If we had to allocate a new rsum_cache, we either need to free the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * old one (if we succeeded) or free the new one and restore the old one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) * (if there was an error).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (rsum_cache != mp->m_rsum_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) kmem_free(mp->m_rsum_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) mp->m_rsum_cache = rsum_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) kmem_free(rsum_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * Allocate an extent in the realtime subvolume, with the usual allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * parameters. The length units are all in realtime extents, as is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) * result block number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) xfs_rtallocate_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) xfs_rtblock_t bno, /* starting block number to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) xfs_extlen_t minlen, /* minimum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) xfs_extlen_t maxlen, /* maximum length to allocate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) xfs_extlen_t *len, /* out: actual length allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) int wasdel, /* was a delayed allocation extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) xfs_extlen_t prod, /* extent product factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) xfs_rtblock_t *rtblock) /* out: start block allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) xfs_mount_t *mp = tp->t_mountp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) int error; /* error value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) xfs_rtblock_t r; /* result allocated block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) xfs_fsblock_t sb; /* summary file block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) xfs_buf_t *sumbp; /* summary file block buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ASSERT(minlen > 0 && minlen <= maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) * If prod is set then figure out what to do to minlen and maxlen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (prod > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) xfs_extlen_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if ((i = maxlen % prod))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) maxlen -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if ((i = minlen % prod))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) minlen += prod - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (maxlen < minlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) *rtblock = NULLRTBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) sumbp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (bno == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) error = xfs_rtallocate_extent_size(mp, tp, minlen, maxlen, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) &sumbp, &sb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) error = xfs_rtallocate_extent_near(mp, tp, bno, minlen, maxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) len, &sumbp, &sb, prod, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * If it worked, update the superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (r != NULLRTBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) long slen = (long)*len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ASSERT(*len >= minlen && *len <= maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (wasdel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FREXTENTS, -slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, -slen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) } else if (prod > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) prod = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) *rtblock = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * Initialize realtime fields in the mount structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) xfs_rtmount_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct xfs_mount *mp) /* file system mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct xfs_buf *bp; /* buffer for last block of subvolume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) struct xfs_sb *sbp; /* filesystem superblock copy in mount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) xfs_daddr_t d; /* address of last block of subvolume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) sbp = &mp->m_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (sbp->sb_rblocks == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (mp->m_rtdev_targp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) xfs_warn(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) "Filesystem has a realtime volume, use rtdev=device option");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) mp->m_rsumlevels = sbp->sb_rextslog + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) mp->m_rsumsize =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) sbp->sb_rbmblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) mp->m_rbmip = mp->m_rsumip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * Check that the realtime section is an ok size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_rblocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) xfs_warn(mp, "realtime mount -- %llu != %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) (unsigned long long) XFS_BB_TO_FSB(mp, d),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) (unsigned long long) mp->m_sb.sb_rblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) return -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) error = xfs_buf_read_uncached(mp->m_rtdev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) d - XFS_FSB_TO_BB(mp, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) xfs_warn(mp, "realtime device size check failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) xfs_buf_relse(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) * Get the bitmap and summary inodes and the summary cache into the mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) * structure at mount time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) xfs_rtmount_inodes(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) xfs_mount_t *mp) /* file system mount structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) int error; /* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) xfs_sb_t *sbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) sbp = &mp->m_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) ASSERT(mp->m_rbmip != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) xfs_irele(mp->m_rbmip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ASSERT(mp->m_rsumip != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) xfs_rtunmount_inodes(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct xfs_mount *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) kmem_free(mp->m_rsum_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (mp->m_rbmip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) xfs_irele(mp->m_rbmip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (mp->m_rsumip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) xfs_irele(mp->m_rsumip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * Pick an extent for allocation at the start of a new realtime file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * Use the sequence number stored in the atime field of the bitmap inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * Translate this to a fraction of the rtextents, and return the product
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * of rtextents and the fraction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) int /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) xfs_rtpick_extent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) xfs_mount_t *mp, /* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) xfs_trans_t *tp, /* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) xfs_extlen_t len, /* allocation length (rtextents) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) xfs_rtblock_t *pick) /* result rt extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) xfs_rtblock_t b; /* result block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) int log2; /* log of sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) uint64_t resid; /* residual after log removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) uint64_t seq; /* sequence number of file creation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) uint64_t *seqp; /* pointer to seqno in inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) seqp = (uint64_t *)&VFS_I(mp->m_rbmip)->i_atime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) *seqp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) seq = *seqp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if ((log2 = xfs_highbit64(seq)) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) b = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) resid = seq - (1ULL << log2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) (log2 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (b >= mp->m_sb.sb_rextents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) div64_u64_rem(b, mp->m_sb.sb_rextents, &b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (b + len > mp->m_sb.sb_rextents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) b = mp->m_sb.sb_rextents - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) *seqp = seq + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) *pick = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }