Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'xfs-6.7-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs updates from Chandan Babu:

- Realtime device subsystem:
- Cleanup usage of xfs_rtblock_t and xfs_fsblock_t data types
- Replace open coded conversions between rt blocks and rt extents
with calls to static inline helpers
- Replace open coded realtime geometry compuation and macros with
helper functions
- CPU usage optimizations for realtime allocator
- Misc bug fixes associated with Realtime device

- Allow read operations to execute while an FICLONE ioctl is being
serviced

- Misc bug fixes:
- Alert user when xfs_droplink() encounters an inode with a link
count of zero
- Handle the case where the allocator could return zero extents when
servicing an fallocate request

* tag 'xfs-6.7-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (40 commits)
xfs: allow read IO and FICLONE to run concurrently
xfs: handle nimaps=0 from xfs_bmapi_write in xfs_alloc_file_space
xfs: introduce protection for drop nlink
xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()
xfs: don't try redundant allocations in xfs_rtallocate_extent_near()
xfs: limit maxlen based on available space in xfs_rtallocate_extent_near()
xfs: return maximum free size from xfs_rtany_summary()
xfs: invert the realtime summary cache
xfs: simplify rt bitmap/summary block accessor functions
xfs: simplify xfs_rtbuf_get calling conventions
xfs: cache last bitmap block in realtime allocator
xfs: use accessor functions for summary info words
xfs: consolidate realtime allocation arguments
xfs: create helpers for rtsummary block/wordcount computations
xfs: use accessor functions for bitmap words
xfs: create helpers for rtbitmap block/wordcount computations
xfs: create a helper to handle logging parts of rt bitmap/summary blocks
xfs: convert rt summary macros to helpers
xfs: convert open-coded xfs_rtword_t pointer accesses to helper
xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros
...

+1429 -946
+14 -31
fs/xfs/libxfs/xfs_bmap.c
··· 21 21 #include "xfs_bmap.h" 22 22 #include "xfs_bmap_util.h" 23 23 #include "xfs_bmap_btree.h" 24 - #include "xfs_rtalloc.h" 24 + #include "xfs_rtbitmap.h" 25 25 #include "xfs_errortag.h" 26 26 #include "xfs_error.h" 27 27 #include "xfs_quota.h" ··· 2989 2989 * If realtime, and the result isn't a multiple of the realtime 2990 2990 * extent size we need to remove blocks until it is. 2991 2991 */ 2992 - if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) { 2992 + if (rt && (temp = xfs_extlen_to_rtxmod(mp, align_alen))) { 2993 2993 /* 2994 2994 * We're not covering the original request, or 2995 2995 * we won't be able to once we fix the length. ··· 3016 3016 else { 3017 3017 align_alen -= orig_off - align_off; 3018 3018 align_off = orig_off; 3019 - align_alen -= align_alen % mp->m_sb.sb_rextsize; 3019 + align_alen -= xfs_extlen_to_rtxmod(mp, align_alen); 3020 3020 } 3021 3021 /* 3022 3022 * Result doesn't cover the request, fail it. ··· 4826 4826 ASSERT(got->br_startoff <= del->br_startoff); 4827 4827 ASSERT(got_endoff >= del_endoff); 4828 4828 4829 - if (isrt) { 4830 - uint64_t rtexts = XFS_FSB_TO_B(mp, del->br_blockcount); 4831 - 4832 - do_div(rtexts, mp->m_sb.sb_rextsize); 4833 - xfs_mod_frextents(mp, rtexts); 4834 - } 4829 + if (isrt) 4830 + xfs_mod_frextents(mp, xfs_rtb_to_rtx(mp, del->br_blockcount)); 4835 4831 4836 4832 /* 4837 4833 * Update the inode delalloc counter now and wait to update the ··· 5053 5057 5054 5058 flags = XFS_ILOG_CORE; 5055 5059 if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) { 5056 - xfs_filblks_t len; 5057 - xfs_extlen_t mod; 5058 - 5059 - len = div_u64_rem(del->br_blockcount, mp->m_sb.sb_rextsize, 5060 - &mod); 5061 - ASSERT(mod == 0); 5062 - 5063 5060 if (!(bflags & XFS_BMAPI_REMAP)) { 5064 - xfs_fsblock_t bno; 5065 - 5066 - bno = div_u64_rem(del->br_startblock, 5067 - mp->m_sb.sb_rextsize, &mod); 5068 - ASSERT(mod == 0); 5069 - 5070 - error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len); 5061 + error = xfs_rtfree_blocks(tp, del->br_startblock, 5062 + del->br_blockcount); 5071 5063 if (error) 5072 5064 goto done; 5073 5065 } 5074 5066 5075 5067 do_fx = 0; 5076 - nblks = len * mp->m_sb.sb_rextsize; 5077 5068 qfield = XFS_TRANS_DQ_RTBCOUNT; 5078 5069 } else { 5079 5070 do_fx = 1; 5080 - nblks = del->br_blockcount; 5081 5071 qfield = XFS_TRANS_DQ_BCOUNT; 5082 5072 } 5073 + nblks = del->br_blockcount; 5083 5074 5084 5075 del_endblock = del->br_startblock + del->br_blockcount; 5085 5076 if (cur) { ··· 5272 5289 int tmp_logflags; /* partial logging flags */ 5273 5290 int wasdel; /* was a delayed alloc extent */ 5274 5291 int whichfork; /* data or attribute fork */ 5275 - xfs_fsblock_t sum; 5276 5292 xfs_filblks_t len = *rlen; /* length to unmap in file */ 5277 5293 xfs_fileoff_t end; 5278 5294 struct xfs_iext_cursor icur; ··· 5366 5384 if (!isrt) 5367 5385 goto delete; 5368 5386 5369 - sum = del.br_startblock + del.br_blockcount; 5370 - div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod); 5387 + mod = xfs_rtb_to_rtxoff(mp, 5388 + del.br_startblock + del.br_blockcount); 5371 5389 if (mod) { 5372 5390 /* 5373 5391 * Realtime extent not lined up at the end. ··· 5414 5432 goto error0; 5415 5433 goto nodelete; 5416 5434 } 5417 - div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod); 5435 + 5436 + mod = xfs_rtb_to_rtxoff(mp, del.br_startblock); 5418 5437 if (mod) { 5419 5438 xfs_extlen_t off = mp->m_sb.sb_rextsize - mod; 5420 5439 ··· 6192 6209 return __this_address; 6193 6210 6194 6211 if (XFS_IS_REALTIME_INODE(ip) && whichfork == XFS_DATA_FORK) { 6195 - if (!xfs_verify_rtext(mp, irec->br_startblock, 6196 - irec->br_blockcount)) 6212 + if (!xfs_verify_rtbext(mp, irec->br_startblock, 6213 + irec->br_blockcount)) 6197 6214 return __this_address; 6198 6215 } else { 6199 6216 if (!xfs_verify_fsbext(mp, irec->br_startblock,
+18 -16
fs/xfs/libxfs/xfs_format.h
··· 98 98 uint32_t sb_blocksize; /* logical block size, bytes */ 99 99 xfs_rfsblock_t sb_dblocks; /* number of data blocks */ 100 100 xfs_rfsblock_t sb_rblocks; /* number of realtime blocks */ 101 - xfs_rtblock_t sb_rextents; /* number of realtime extents */ 101 + xfs_rtbxlen_t sb_rextents; /* number of realtime extents */ 102 102 uuid_t sb_uuid; /* user-visible file system unique id */ 103 103 xfs_fsblock_t sb_logstart; /* starting block of log if internal */ 104 104 xfs_ino_t sb_rootino; /* root inode number */ ··· 691 691 xfs_daddr_to_agno(mp, (d) + (len) - 1))) 692 692 693 693 /* 694 + * Realtime bitmap information is accessed by the word, which is currently 695 + * stored in host-endian format. 696 + */ 697 + union xfs_rtword_raw { 698 + __u32 old; 699 + }; 700 + 701 + /* 702 + * Realtime summary counts are accessed by the word, which is currently 703 + * stored in host-endian format. 704 + */ 705 + union xfs_suminfo_raw { 706 + __u32 old; 707 + }; 708 + 709 + /* 694 710 * XFS Timestamps 695 711 * ============== 696 712 * ··· 1158 1142 1159 1143 #define XFS_BLOCKSIZE(mp) ((mp)->m_sb.sb_blocksize) 1160 1144 #define XFS_BLOCKMASK(mp) ((mp)->m_blockmask) 1161 - #define XFS_BLOCKWSIZE(mp) ((mp)->m_blockwsize) 1162 - #define XFS_BLOCKWMASK(mp) ((mp)->m_blockwmask) 1163 1145 1164 1146 /* 1165 - * RT Summary and bit manipulation macros. 1147 + * RT bit manipulation macros. 1166 1148 */ 1167 - #define XFS_SUMOFFS(mp,ls,bb) ((int)((ls) * (mp)->m_sb.sb_rbmblocks + (bb))) 1168 - #define XFS_SUMOFFSTOBLOCK(mp,s) \ 1169 - (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog) 1170 - #define XFS_SUMPTR(mp,bp,so) \ 1171 - ((xfs_suminfo_t *)((bp)->b_addr + \ 1172 - (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) 1173 - 1174 - #define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log) 1175 - #define XFS_BLOCKTOBIT(mp,bb) ((bb) << (mp)->m_blkbit_log) 1176 - #define XFS_BITTOWORD(mp,bi) \ 1177 - ((int)(((bi) >> XFS_NBWORDLOG) & XFS_BLOCKWMASK(mp))) 1178 - 1179 1149 #define XFS_RTMIN(a,b) ((a) < (b) ? (a) : (b)) 1180 1150 #define XFS_RTMAX(a,b) ((a) > (b) ? (a) : (b)) 1181 1151
+440 -367
fs/xfs/libxfs/xfs_rtbitmap.c
··· 16 16 #include "xfs_trans.h" 17 17 #include "xfs_rtalloc.h" 18 18 #include "xfs_error.h" 19 + #include "xfs_rtbitmap.h" 19 20 20 21 /* 21 22 * Realtime allocator bitmap functions shared with userspace. ··· 47 46 .verify_write = xfs_rtbuf_verify_write, 48 47 }; 49 48 49 + /* Release cached rt bitmap and summary buffers. */ 50 + void 51 + xfs_rtbuf_cache_relse( 52 + struct xfs_rtalloc_args *args) 53 + { 54 + if (args->rbmbp) { 55 + xfs_trans_brelse(args->tp, args->rbmbp); 56 + args->rbmbp = NULL; 57 + args->rbmoff = NULLFILEOFF; 58 + } 59 + if (args->sumbp) { 60 + xfs_trans_brelse(args->tp, args->sumbp); 61 + args->sumbp = NULL; 62 + args->sumoff = NULLFILEOFF; 63 + } 64 + } 65 + 50 66 /* 51 67 * Get a buffer for the bitmap or summary file block specified. 52 68 * The buffer is returned read and locked. 53 69 */ 54 70 int 55 71 xfs_rtbuf_get( 56 - xfs_mount_t *mp, /* file system mount structure */ 57 - xfs_trans_t *tp, /* transaction pointer */ 58 - xfs_rtblock_t block, /* block number in bitmap or summary */ 59 - int issum, /* is summary not bitmap */ 60 - struct xfs_buf **bpp) /* output: buffer for the block */ 72 + struct xfs_rtalloc_args *args, 73 + xfs_fileoff_t block, /* block number in bitmap or summary */ 74 + int issum) /* is summary not bitmap */ 61 75 { 62 - struct xfs_buf *bp; /* block buffer, result */ 63 - xfs_inode_t *ip; /* bitmap or summary inode */ 64 - xfs_bmbt_irec_t map; 65 - int nmap = 1; 66 - int error; /* error value */ 76 + struct xfs_mount *mp = args->mp; 77 + struct xfs_buf **cbpp; /* cached block buffer */ 78 + xfs_fileoff_t *coffp; /* cached block number */ 79 + struct xfs_buf *bp; /* block buffer, result */ 80 + struct xfs_inode *ip; /* bitmap or summary inode */ 81 + struct xfs_bmbt_irec map; 82 + enum xfs_blft type; 83 + int nmap = 1; 84 + int error; 67 85 68 - ip = issum ? mp->m_rsumip : mp->m_rbmip; 86 + if (issum) { 87 + cbpp = &args->sumbp; 88 + coffp = &args->sumoff; 89 + ip = mp->m_rsumip; 90 + type = XFS_BLFT_RTSUMMARY_BUF; 91 + } else { 92 + cbpp = &args->rbmbp; 93 + coffp = &args->rbmoff; 94 + ip = mp->m_rbmip; 95 + type = XFS_BLFT_RTBITMAP_BUF; 96 + } 97 + 98 + /* 99 + * If we have a cached buffer, and the block number matches, use that. 100 + */ 101 + if (*cbpp && *coffp == block) 102 + return 0; 103 + 104 + /* 105 + * Otherwise we have to have to get the buffer. If there was an old 106 + * one, get rid of it first. 107 + */ 108 + if (*cbpp) { 109 + xfs_trans_brelse(args->tp, *cbpp); 110 + *cbpp = NULL; 111 + } 69 112 70 113 error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0); 71 114 if (error) ··· 119 74 return -EFSCORRUPTED; 120 75 121 76 ASSERT(map.br_startblock != NULLFSBLOCK); 122 - error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 77 + error = xfs_trans_read_buf(mp, args->tp, mp->m_ddev_targp, 123 78 XFS_FSB_TO_DADDR(mp, map.br_startblock), 124 79 mp->m_bsize, 0, &bp, &xfs_rtbuf_ops); 125 80 if (error) 126 81 return error; 127 82 128 - xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF 129 - : XFS_BLFT_RTBITMAP_BUF); 130 - *bpp = bp; 83 + xfs_trans_buf_set_type(args->tp, bp, type); 84 + *cbpp = bp; 85 + *coffp = block; 131 86 return 0; 132 87 } 133 88 ··· 137 92 */ 138 93 int 139 94 xfs_rtfind_back( 140 - xfs_mount_t *mp, /* file system mount point */ 141 - xfs_trans_t *tp, /* transaction pointer */ 142 - xfs_rtblock_t start, /* starting block to look at */ 143 - xfs_rtblock_t limit, /* last block to look at */ 144 - xfs_rtblock_t *rtblock) /* out: start block found */ 95 + struct xfs_rtalloc_args *args, 96 + xfs_rtxnum_t start, /* starting rtext to look at */ 97 + xfs_rtxnum_t limit, /* last rtext to look at */ 98 + xfs_rtxnum_t *rtx) /* out: start rtext found */ 145 99 { 146 - xfs_rtword_t *b; /* current word in buffer */ 147 - int bit; /* bit number in the word */ 148 - xfs_rtblock_t block; /* bitmap block number */ 149 - struct xfs_buf *bp; /* buf for the block */ 150 - xfs_rtword_t *bufp; /* starting word in buffer */ 151 - int error; /* error value */ 152 - xfs_rtblock_t firstbit; /* first useful bit in the word */ 153 - xfs_rtblock_t i; /* current bit number rel. to start */ 154 - xfs_rtblock_t len; /* length of inspected area */ 155 - xfs_rtword_t mask; /* mask of relevant bits for value */ 156 - xfs_rtword_t want; /* mask for "good" values */ 157 - xfs_rtword_t wdiff; /* difference from wanted value */ 158 - int word; /* word number in the buffer */ 100 + struct xfs_mount *mp = args->mp; 101 + int bit; /* bit number in the word */ 102 + xfs_fileoff_t block; /* bitmap block number */ 103 + int error; /* error value */ 104 + xfs_rtxnum_t firstbit; /* first useful bit in the word */ 105 + xfs_rtxnum_t i; /* current bit number rel. to start */ 106 + xfs_rtxnum_t len; /* length of inspected area */ 107 + xfs_rtword_t mask; /* mask of relevant bits for value */ 108 + xfs_rtword_t want; /* mask for "good" values */ 109 + xfs_rtword_t wdiff; /* difference from wanted value */ 110 + xfs_rtword_t incore; 111 + unsigned int word; /* word number in the buffer */ 159 112 160 113 /* 161 114 * Compute and read in starting bitmap block for starting block. 162 115 */ 163 - block = XFS_BITTOBLOCK(mp, start); 164 - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 165 - if (error) { 116 + block = xfs_rtx_to_rbmblock(mp, start); 117 + error = xfs_rtbitmap_read_buf(args, block); 118 + if (error) 166 119 return error; 167 - } 168 - bufp = bp->b_addr; 120 + 169 121 /* 170 122 * Get the first word's index & point to it. 171 123 */ 172 - word = XFS_BITTOWORD(mp, start); 173 - b = &bufp[word]; 124 + word = xfs_rtx_to_rbmword(mp, start); 174 125 bit = (int)(start & (XFS_NBWORD - 1)); 175 126 len = start - limit + 1; 176 127 /* 177 128 * Compute match value, based on the bit at start: if 1 (free) 178 129 * then all-ones, else all-zeroes. 179 130 */ 180 - want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; 131 + incore = xfs_rtbitmap_getword(args, word); 132 + want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; 181 133 /* 182 134 * If the starting position is not word-aligned, deal with the 183 135 * partial word. ··· 191 149 * Calculate the difference between the value there 192 150 * and what we're looking for. 193 151 */ 194 - if ((wdiff = (*b ^ want) & mask)) { 152 + if ((wdiff = (incore ^ want) & mask)) { 195 153 /* 196 154 * Different. Mark where we are and return. 197 155 */ 198 - xfs_trans_brelse(tp, bp); 199 156 i = bit - XFS_RTHIBIT(wdiff); 200 - *rtblock = start - i + 1; 157 + *rtx = start - i + 1; 201 158 return 0; 202 159 } 203 160 i = bit - firstbit + 1; ··· 208 167 /* 209 168 * If done with this block, get the previous one. 210 169 */ 211 - xfs_trans_brelse(tp, bp); 212 - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); 213 - if (error) { 170 + error = xfs_rtbitmap_read_buf(args, --block); 171 + if (error) 214 172 return error; 215 - } 216 - bufp = bp->b_addr; 217 - word = XFS_BLOCKWMASK(mp); 218 - b = &bufp[word]; 219 - } else { 220 - /* 221 - * Go on to the previous word in the buffer. 222 - */ 223 - b--; 173 + 174 + word = mp->m_blockwsize - 1; 224 175 } 225 176 } else { 226 177 /* ··· 228 195 /* 229 196 * Compute difference between actual and desired value. 230 197 */ 231 - if ((wdiff = *b ^ want)) { 198 + incore = xfs_rtbitmap_getword(args, word); 199 + if ((wdiff = incore ^ want)) { 232 200 /* 233 201 * Different, mark where we are and return. 234 202 */ 235 - xfs_trans_brelse(tp, bp); 236 203 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); 237 - *rtblock = start - i + 1; 204 + *rtx = start - i + 1; 238 205 return 0; 239 206 } 240 207 i += XFS_NBWORD; ··· 246 213 /* 247 214 * If done with this block, get the previous one. 248 215 */ 249 - xfs_trans_brelse(tp, bp); 250 - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); 251 - if (error) { 216 + error = xfs_rtbitmap_read_buf(args, --block); 217 + if (error) 252 218 return error; 253 - } 254 - bufp = bp->b_addr; 255 - word = XFS_BLOCKWMASK(mp); 256 - b = &bufp[word]; 257 - } else { 258 - /* 259 - * Go on to the previous word in the buffer. 260 - */ 261 - b--; 219 + 220 + word = mp->m_blockwsize - 1; 262 221 } 263 222 } 264 223 /* ··· 267 242 /* 268 243 * Compute difference between actual and desired value. 269 244 */ 270 - if ((wdiff = (*b ^ want) & mask)) { 245 + incore = xfs_rtbitmap_getword(args, word); 246 + if ((wdiff = (incore ^ want) & mask)) { 271 247 /* 272 248 * Different, mark where we are and return. 273 249 */ 274 - xfs_trans_brelse(tp, bp); 275 250 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); 276 - *rtblock = start - i + 1; 251 + *rtx = start - i + 1; 277 252 return 0; 278 253 } else 279 254 i = len; ··· 281 256 /* 282 257 * No match, return that we scanned the whole area. 283 258 */ 284 - xfs_trans_brelse(tp, bp); 285 - *rtblock = start - i + 1; 259 + *rtx = start - i + 1; 286 260 return 0; 287 261 } 288 262 ··· 291 267 */ 292 268 int 293 269 xfs_rtfind_forw( 294 - xfs_mount_t *mp, /* file system mount point */ 295 - xfs_trans_t *tp, /* transaction pointer */ 296 - xfs_rtblock_t start, /* starting block to look at */ 297 - xfs_rtblock_t limit, /* last block to look at */ 298 - xfs_rtblock_t *rtblock) /* out: start block found */ 270 + struct xfs_rtalloc_args *args, 271 + xfs_rtxnum_t start, /* starting rtext to look at */ 272 + xfs_rtxnum_t limit, /* last rtext to look at */ 273 + xfs_rtxnum_t *rtx) /* out: start rtext found */ 299 274 { 300 - xfs_rtword_t *b; /* current word in buffer */ 301 - int bit; /* bit number in the word */ 302 - xfs_rtblock_t block; /* bitmap block number */ 303 - struct xfs_buf *bp; /* buf for the block */ 304 - xfs_rtword_t *bufp; /* starting word in buffer */ 305 - int error; /* error value */ 306 - xfs_rtblock_t i; /* current bit number rel. to start */ 307 - xfs_rtblock_t lastbit; /* last useful bit in the word */ 308 - xfs_rtblock_t len; /* length of inspected area */ 309 - xfs_rtword_t mask; /* mask of relevant bits for value */ 310 - xfs_rtword_t want; /* mask for "good" values */ 311 - xfs_rtword_t wdiff; /* difference from wanted value */ 312 - int word; /* word number in the buffer */ 275 + struct xfs_mount *mp = args->mp; 276 + int bit; /* bit number in the word */ 277 + xfs_fileoff_t block; /* bitmap block number */ 278 + int error; 279 + xfs_rtxnum_t i; /* current bit number rel. to start */ 280 + xfs_rtxnum_t lastbit;/* last useful bit in the word */ 281 + xfs_rtxnum_t len; /* length of inspected area */ 282 + xfs_rtword_t mask; /* mask of relevant bits for value */ 283 + xfs_rtword_t want; /* mask for "good" values */ 284 + xfs_rtword_t wdiff; /* difference from wanted value */ 285 + xfs_rtword_t incore; 286 + unsigned int word; /* word number in the buffer */ 313 287 314 288 /* 315 289 * Compute and read in starting bitmap block for starting block. 316 290 */ 317 - block = XFS_BITTOBLOCK(mp, start); 318 - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 319 - if (error) { 291 + block = xfs_rtx_to_rbmblock(mp, start); 292 + error = xfs_rtbitmap_read_buf(args, block); 293 + if (error) 320 294 return error; 321 - } 322 - bufp = bp->b_addr; 295 + 323 296 /* 324 297 * Get the first word's index & point to it. 325 298 */ 326 - word = XFS_BITTOWORD(mp, start); 327 - b = &bufp[word]; 299 + word = xfs_rtx_to_rbmword(mp, start); 328 300 bit = (int)(start & (XFS_NBWORD - 1)); 329 301 len = limit - start + 1; 330 302 /* 331 303 * Compute match value, based on the bit at start: if 1 (free) 332 304 * then all-ones, else all-zeroes. 333 305 */ 334 - want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; 306 + incore = xfs_rtbitmap_getword(args, word); 307 + want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0; 335 308 /* 336 309 * If the starting position is not word-aligned, deal with the 337 310 * partial word. ··· 344 323 * Calculate the difference between the value there 345 324 * and what we're looking for. 346 325 */ 347 - if ((wdiff = (*b ^ want) & mask)) { 326 + if ((wdiff = (incore ^ want) & mask)) { 348 327 /* 349 328 * Different. Mark where we are and return. 350 329 */ 351 - xfs_trans_brelse(tp, bp); 352 330 i = XFS_RTLOBIT(wdiff) - bit; 353 - *rtblock = start + i - 1; 331 + *rtx = start + i - 1; 354 332 return 0; 355 333 } 356 334 i = lastbit - bit; ··· 357 337 * Go on to next block if that's where the next word is 358 338 * and we need the next word. 359 339 */ 360 - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 340 + if (++word == mp->m_blockwsize && i < len) { 361 341 /* 362 342 * If done with this block, get the previous one. 363 343 */ 364 - xfs_trans_brelse(tp, bp); 365 - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 366 - if (error) { 344 + error = xfs_rtbitmap_read_buf(args, ++block); 345 + if (error) 367 346 return error; 368 - } 369 - b = bufp = bp->b_addr; 347 + 370 348 word = 0; 371 - } else { 372 - /* 373 - * Go on to the previous word in the buffer. 374 - */ 375 - b++; 376 349 } 377 350 } else { 378 351 /* ··· 381 368 /* 382 369 * Compute difference between actual and desired value. 383 370 */ 384 - if ((wdiff = *b ^ want)) { 371 + incore = xfs_rtbitmap_getword(args, word); 372 + if ((wdiff = incore ^ want)) { 385 373 /* 386 374 * Different, mark where we are and return. 387 375 */ 388 - xfs_trans_brelse(tp, bp); 389 376 i += XFS_RTLOBIT(wdiff); 390 - *rtblock = start + i - 1; 377 + *rtx = start + i - 1; 391 378 return 0; 392 379 } 393 380 i += XFS_NBWORD; ··· 395 382 * Go on to next block if that's where the next word is 396 383 * and we need the next word. 397 384 */ 398 - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 385 + if (++word == mp->m_blockwsize && i < len) { 399 386 /* 400 387 * If done with this block, get the next one. 401 388 */ 402 - xfs_trans_brelse(tp, bp); 403 - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 404 - if (error) { 389 + error = xfs_rtbitmap_read_buf(args, ++block); 390 + if (error) 405 391 return error; 406 - } 407 - b = bufp = bp->b_addr; 392 + 408 393 word = 0; 409 - } else { 410 - /* 411 - * Go on to the next word in the buffer. 412 - */ 413 - b++; 414 394 } 415 395 } 416 396 /* ··· 418 412 /* 419 413 * Compute difference between actual and desired value. 420 414 */ 421 - if ((wdiff = (*b ^ want) & mask)) { 415 + incore = xfs_rtbitmap_getword(args, word); 416 + if ((wdiff = (incore ^ want) & mask)) { 422 417 /* 423 418 * Different, mark where we are and return. 424 419 */ 425 - xfs_trans_brelse(tp, bp); 426 420 i += XFS_RTLOBIT(wdiff); 427 - *rtblock = start + i - 1; 421 + *rtx = start + i - 1; 428 422 return 0; 429 423 } else 430 424 i = len; ··· 432 426 /* 433 427 * No match, return that we scanned the whole area. 434 428 */ 435 - xfs_trans_brelse(tp, bp); 436 - *rtblock = start + i - 1; 429 + *rtx = start + i - 1; 437 430 return 0; 431 + } 432 + 433 + /* Log rtsummary counter at @infoword. */ 434 + static inline void 435 + xfs_trans_log_rtsummary( 436 + struct xfs_rtalloc_args *args, 437 + unsigned int infoword) 438 + { 439 + struct xfs_buf *bp = args->sumbp; 440 + size_t first, last; 441 + 442 + first = (void *)xfs_rsumblock_infoptr(args, infoword) - bp->b_addr; 443 + last = first + sizeof(xfs_suminfo_t) - 1; 444 + 445 + xfs_trans_log_buf(args->tp, bp, first, last); 438 446 } 439 447 440 448 /* ··· 462 442 */ 463 443 int 464 444 xfs_rtmodify_summary_int( 465 - xfs_mount_t *mp, /* file system mount structure */ 466 - xfs_trans_t *tp, /* transaction pointer */ 467 - int log, /* log2 of extent size */ 468 - xfs_rtblock_t bbno, /* bitmap block number */ 469 - int delta, /* change to make to summary info */ 470 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 471 - xfs_fsblock_t *rsb, /* in/out: summary block number */ 472 - xfs_suminfo_t *sum) /* out: summary info for this block */ 445 + struct xfs_rtalloc_args *args, 446 + int log, /* log2 of extent size */ 447 + xfs_fileoff_t bbno, /* bitmap block number */ 448 + int delta, /* change to make to summary info */ 449 + xfs_suminfo_t *sum) /* out: summary info for this block */ 473 450 { 474 - struct xfs_buf *bp; /* buffer for the summary block */ 475 - int error; /* error value */ 476 - xfs_fsblock_t sb; /* summary fsblock */ 477 - int so; /* index into the summary file */ 478 - xfs_suminfo_t *sp; /* pointer to returned data */ 451 + struct xfs_mount *mp = args->mp; 452 + int error; 453 + xfs_fileoff_t sb; /* summary fsblock */ 454 + xfs_rtsumoff_t so; /* index into the summary file */ 455 + unsigned int infoword; 479 456 480 457 /* 481 458 * Compute entry number in the summary file. 482 459 */ 483 - so = XFS_SUMOFFS(mp, log, bbno); 460 + so = xfs_rtsumoffs(mp, log, bbno); 484 461 /* 485 462 * Compute the block number in the summary file. 486 463 */ 487 - sb = XFS_SUMOFFSTOBLOCK(mp, so); 488 - /* 489 - * If we have an old buffer, and the block number matches, use that. 490 - */ 491 - if (*rbpp && *rsb == sb) 492 - bp = *rbpp; 493 - /* 494 - * Otherwise we have to get the buffer. 495 - */ 496 - else { 497 - /* 498 - * If there was an old one, get rid of it first. 499 - */ 500 - if (*rbpp) 501 - xfs_trans_brelse(tp, *rbpp); 502 - error = xfs_rtbuf_get(mp, tp, sb, 1, &bp); 503 - if (error) { 504 - return error; 505 - } 506 - /* 507 - * Remember this buffer and block for the next call. 508 - */ 509 - *rbpp = bp; 510 - *rsb = sb; 511 - } 464 + sb = xfs_rtsumoffs_to_block(mp, so); 465 + 466 + error = xfs_rtsummary_read_buf(args, sb); 467 + if (error) 468 + return error; 469 + 512 470 /* 513 471 * Point to the summary information, modify/log it, and/or copy it out. 514 472 */ 515 - sp = XFS_SUMPTR(mp, bp, so); 473 + infoword = xfs_rtsumoffs_to_infoword(mp, so); 516 474 if (delta) { 517 - uint first = (uint)((char *)sp - (char *)bp->b_addr); 475 + xfs_suminfo_t val = xfs_suminfo_add(args, infoword, delta); 518 476 519 - *sp += delta; 520 477 if (mp->m_rsum_cache) { 521 - if (*sp == 0 && log == mp->m_rsum_cache[bbno]) 522 - mp->m_rsum_cache[bbno]++; 523 - if (*sp != 0 && log < mp->m_rsum_cache[bbno]) 478 + if (val == 0 && log + 1 == mp->m_rsum_cache[bbno]) 524 479 mp->m_rsum_cache[bbno] = log; 480 + if (val != 0 && log >= mp->m_rsum_cache[bbno]) 481 + mp->m_rsum_cache[bbno] = log + 1; 525 482 } 526 - xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1); 483 + xfs_trans_log_rtsummary(args, infoword); 484 + if (sum) 485 + *sum = val; 486 + } else if (sum) { 487 + *sum = xfs_suminfo_get(args, infoword); 527 488 } 528 - if (sum) 529 - *sum = *sp; 530 489 return 0; 531 490 } 532 491 533 492 int 534 493 xfs_rtmodify_summary( 535 - xfs_mount_t *mp, /* file system mount structure */ 536 - xfs_trans_t *tp, /* transaction pointer */ 537 - int log, /* log2 of extent size */ 538 - xfs_rtblock_t bbno, /* bitmap block number */ 539 - int delta, /* change to make to summary info */ 540 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 541 - xfs_fsblock_t *rsb) /* in/out: summary block number */ 494 + struct xfs_rtalloc_args *args, 495 + int log, /* log2 of extent size */ 496 + xfs_fileoff_t bbno, /* bitmap block number */ 497 + int delta) /* in/out: summary block number */ 542 498 { 543 - return xfs_rtmodify_summary_int(mp, tp, log, bbno, 544 - delta, rbpp, rsb, NULL); 499 + return xfs_rtmodify_summary_int(args, log, bbno, delta, NULL); 500 + } 501 + 502 + /* Log rtbitmap block from the word @from to the byte before @next. */ 503 + static inline void 504 + xfs_trans_log_rtbitmap( 505 + struct xfs_rtalloc_args *args, 506 + unsigned int from, 507 + unsigned int next) 508 + { 509 + struct xfs_buf *bp = args->rbmbp; 510 + size_t first, last; 511 + 512 + first = (void *)xfs_rbmblock_wordptr(args, from) - bp->b_addr; 513 + last = ((void *)xfs_rbmblock_wordptr(args, next) - 1) - bp->b_addr; 514 + 515 + xfs_trans_log_buf(args->tp, bp, first, last); 545 516 } 546 517 547 518 /* ··· 541 530 */ 542 531 int 543 532 xfs_rtmodify_range( 544 - xfs_mount_t *mp, /* file system mount point */ 545 - xfs_trans_t *tp, /* transaction pointer */ 546 - xfs_rtblock_t start, /* starting block to modify */ 547 - xfs_extlen_t len, /* length of extent to modify */ 548 - int val) /* 1 for free, 0 for allocated */ 533 + struct xfs_rtalloc_args *args, 534 + xfs_rtxnum_t start, /* starting rtext to modify */ 535 + xfs_rtxlen_t len, /* length of extent to modify */ 536 + int val) /* 1 for free, 0 for allocated */ 549 537 { 550 - xfs_rtword_t *b; /* current word in buffer */ 551 - int bit; /* bit number in the word */ 552 - xfs_rtblock_t block; /* bitmap block number */ 553 - struct xfs_buf *bp; /* buf for the block */ 554 - xfs_rtword_t *bufp; /* starting word in buffer */ 555 - int error; /* error value */ 556 - xfs_rtword_t *first; /* first used word in the buffer */ 557 - int i; /* current bit number rel. to start */ 558 - int lastbit; /* last useful bit in word */ 559 - xfs_rtword_t mask; /* mask o frelevant bits for value */ 560 - int word; /* word number in the buffer */ 538 + struct xfs_mount *mp = args->mp; 539 + int bit; /* bit number in the word */ 540 + xfs_fileoff_t block; /* bitmap block number */ 541 + int error; 542 + int i; /* current bit number rel. to start */ 543 + int lastbit; /* last useful bit in word */ 544 + xfs_rtword_t mask; /* mask of relevant bits for value */ 545 + xfs_rtword_t incore; 546 + unsigned int firstword; /* first word used in the buffer */ 547 + unsigned int word; /* word number in the buffer */ 561 548 562 549 /* 563 550 * Compute starting bitmap block number. 564 551 */ 565 - block = XFS_BITTOBLOCK(mp, start); 552 + block = xfs_rtx_to_rbmblock(mp, start); 566 553 /* 567 554 * Read the bitmap block, and point to its data. 568 555 */ 569 - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 570 - if (error) { 556 + error = xfs_rtbitmap_read_buf(args, block); 557 + if (error) 571 558 return error; 572 - } 573 - bufp = bp->b_addr; 559 + 574 560 /* 575 561 * Compute the starting word's address, and starting bit. 576 562 */ 577 - word = XFS_BITTOWORD(mp, start); 578 - first = b = &bufp[word]; 563 + firstword = word = xfs_rtx_to_rbmword(mp, start); 579 564 bit = (int)(start & (XFS_NBWORD - 1)); 580 565 /* 581 566 * 0 (allocated) => all zeroes; 1 (free) => all ones. ··· 590 583 /* 591 584 * Set/clear the active bits. 592 585 */ 586 + incore = xfs_rtbitmap_getword(args, word); 593 587 if (val) 594 - *b |= mask; 588 + incore |= mask; 595 589 else 596 - *b &= ~mask; 590 + incore &= ~mask; 591 + xfs_rtbitmap_setword(args, word, incore); 597 592 i = lastbit - bit; 598 593 /* 599 594 * Go on to the next block if that's where the next word is 600 595 * and we need the next word. 601 596 */ 602 - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 597 + if (++word == mp->m_blockwsize && i < len) { 603 598 /* 604 599 * Log the changed part of this block. 605 600 * Get the next one. 606 601 */ 607 - xfs_trans_log_buf(tp, bp, 608 - (uint)((char *)first - (char *)bufp), 609 - (uint)((char *)b - (char *)bufp)); 610 - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 611 - if (error) { 602 + xfs_trans_log_rtbitmap(args, firstword, word); 603 + error = xfs_rtbitmap_read_buf(args, ++block); 604 + if (error) 612 605 return error; 613 - } 614 - first = b = bufp = bp->b_addr; 615 - word = 0; 616 - } else { 617 - /* 618 - * Go on to the next word in the buffer 619 - */ 620 - b++; 606 + 607 + firstword = word = 0; 621 608 } 622 609 } else { 623 610 /* ··· 627 626 /* 628 627 * Set the word value correctly. 629 628 */ 630 - *b = val; 629 + xfs_rtbitmap_setword(args, word, val); 631 630 i += XFS_NBWORD; 632 631 /* 633 632 * Go on to the next block if that's where the next word is 634 633 * and we need the next word. 635 634 */ 636 - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 635 + if (++word == mp->m_blockwsize && i < len) { 637 636 /* 638 637 * Log the changed part of this block. 639 638 * Get the next one. 640 639 */ 641 - xfs_trans_log_buf(tp, bp, 642 - (uint)((char *)first - (char *)bufp), 643 - (uint)((char *)b - (char *)bufp)); 644 - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 645 - if (error) { 640 + xfs_trans_log_rtbitmap(args, firstword, word); 641 + error = xfs_rtbitmap_read_buf(args, ++block); 642 + if (error) 646 643 return error; 647 - } 648 - first = b = bufp = bp->b_addr; 649 - word = 0; 650 - } else { 651 - /* 652 - * Go on to the next word in the buffer 653 - */ 654 - b++; 644 + 645 + firstword = word = 0; 655 646 } 656 647 } 657 648 /* ··· 658 665 /* 659 666 * Set/clear the active bits. 660 667 */ 668 + incore = xfs_rtbitmap_getword(args, word); 661 669 if (val) 662 - *b |= mask; 670 + incore |= mask; 663 671 else 664 - *b &= ~mask; 665 - b++; 672 + incore &= ~mask; 673 + xfs_rtbitmap_setword(args, word, incore); 674 + word++; 666 675 } 667 676 /* 668 677 * Log any remaining changed bytes. 669 678 */ 670 - if (b > first) 671 - xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), 672 - (uint)((char *)b - (char *)bufp - 1)); 679 + if (word > firstword) 680 + xfs_trans_log_rtbitmap(args, firstword, word); 673 681 return 0; 674 682 } 675 683 ··· 680 686 */ 681 687 int 682 688 xfs_rtfree_range( 683 - xfs_mount_t *mp, /* file system mount point */ 684 - xfs_trans_t *tp, /* transaction pointer */ 685 - xfs_rtblock_t start, /* starting block to free */ 686 - xfs_extlen_t len, /* length to free */ 687 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 688 - xfs_fsblock_t *rsb) /* in/out: summary block number */ 689 + struct xfs_rtalloc_args *args, 690 + xfs_rtxnum_t start, /* starting rtext to free */ 691 + xfs_rtxlen_t len) /* in/out: summary block number */ 689 692 { 690 - xfs_rtblock_t end; /* end of the freed extent */ 691 - int error; /* error value */ 692 - xfs_rtblock_t postblock; /* first block freed > end */ 693 - xfs_rtblock_t preblock; /* first block freed < start */ 693 + struct xfs_mount *mp = args->mp; 694 + xfs_rtxnum_t end; /* end of the freed extent */ 695 + int error; /* error value */ 696 + xfs_rtxnum_t postblock; /* first rtext freed > end */ 697 + xfs_rtxnum_t preblock; /* first rtext freed < start */ 694 698 695 699 end = start + len - 1; 696 700 /* 697 701 * Modify the bitmap to mark this extent freed. 698 702 */ 699 - error = xfs_rtmodify_range(mp, tp, start, len, 1); 703 + error = xfs_rtmodify_range(args, start, len, 1); 700 704 if (error) { 701 705 return error; 702 706 } ··· 703 711 * We need to find the beginning and end of the extent so we can 704 712 * properly update the summary. 705 713 */ 706 - error = xfs_rtfind_back(mp, tp, start, 0, &preblock); 714 + error = xfs_rtfind_back(args, start, 0, &preblock); 707 715 if (error) { 708 716 return error; 709 717 } 710 718 /* 711 719 * Find the next allocated block (end of allocated extent). 712 720 */ 713 - error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, 714 - &postblock); 721 + error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, 722 + &postblock); 715 723 if (error) 716 724 return error; 717 725 /* ··· 719 727 * old extent, add summary data for them to be allocated. 720 728 */ 721 729 if (preblock < start) { 722 - error = xfs_rtmodify_summary(mp, tp, 723 - XFS_RTBLOCKLOG(start - preblock), 724 - XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); 730 + error = xfs_rtmodify_summary(args, 731 + XFS_RTBLOCKLOG(start - preblock), 732 + xfs_rtx_to_rbmblock(mp, preblock), -1); 725 733 if (error) { 726 734 return error; 727 735 } ··· 731 739 * old extent, add summary data for them to be allocated. 732 740 */ 733 741 if (postblock > end) { 734 - error = xfs_rtmodify_summary(mp, tp, 735 - XFS_RTBLOCKLOG(postblock - end), 736 - XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb); 742 + error = xfs_rtmodify_summary(args, 743 + XFS_RTBLOCKLOG(postblock - end), 744 + xfs_rtx_to_rbmblock(mp, end + 1), -1); 737 745 if (error) { 738 746 return error; 739 747 } ··· 742 750 * Increment the summary information corresponding to the entire 743 751 * (new) free extent. 744 752 */ 745 - error = xfs_rtmodify_summary(mp, tp, 746 - XFS_RTBLOCKLOG(postblock + 1 - preblock), 747 - XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); 748 - return error; 753 + return xfs_rtmodify_summary(args, 754 + XFS_RTBLOCKLOG(postblock + 1 - preblock), 755 + xfs_rtx_to_rbmblock(mp, preblock), 1); 749 756 } 750 757 751 758 /* ··· 753 762 */ 754 763 int 755 764 xfs_rtcheck_range( 756 - xfs_mount_t *mp, /* file system mount point */ 757 - xfs_trans_t *tp, /* transaction pointer */ 758 - xfs_rtblock_t start, /* starting block number of extent */ 759 - xfs_extlen_t len, /* length of extent */ 760 - int val, /* 1 for free, 0 for allocated */ 761 - xfs_rtblock_t *new, /* out: first block not matching */ 762 - int *stat) /* out: 1 for matches, 0 for not */ 765 + struct xfs_rtalloc_args *args, 766 + xfs_rtxnum_t start, /* starting rtext number of extent */ 767 + xfs_rtxlen_t len, /* length of extent */ 768 + int val, /* 1 for free, 0 for allocated */ 769 + xfs_rtxnum_t *new, /* out: first rtext not matching */ 770 + int *stat) /* out: 1 for matches, 0 for not */ 763 771 { 764 - xfs_rtword_t *b; /* current word in buffer */ 765 - int bit; /* bit number in the word */ 766 - xfs_rtblock_t block; /* bitmap block number */ 767 - struct xfs_buf *bp; /* buf for the block */ 768 - xfs_rtword_t *bufp; /* starting word in buffer */ 769 - int error; /* error value */ 770 - xfs_rtblock_t i; /* current bit number rel. to start */ 771 - xfs_rtblock_t lastbit; /* last useful bit in word */ 772 - xfs_rtword_t mask; /* mask of relevant bits for value */ 773 - xfs_rtword_t wdiff; /* difference from wanted value */ 774 - int word; /* word number in the buffer */ 772 + struct xfs_mount *mp = args->mp; 773 + int bit; /* bit number in the word */ 774 + xfs_fileoff_t block; /* bitmap block number */ 775 + int error; 776 + xfs_rtxnum_t i; /* current bit number rel. to start */ 777 + xfs_rtxnum_t lastbit; /* last useful bit in word */ 778 + xfs_rtword_t mask; /* mask of relevant bits for value */ 779 + xfs_rtword_t wdiff; /* difference from wanted value */ 780 + xfs_rtword_t incore; 781 + unsigned int word; /* word number in the buffer */ 775 782 776 783 /* 777 784 * Compute starting bitmap block number 778 785 */ 779 - block = XFS_BITTOBLOCK(mp, start); 786 + block = xfs_rtx_to_rbmblock(mp, start); 780 787 /* 781 788 * Read the bitmap block. 782 789 */ 783 - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 784 - if (error) { 790 + error = xfs_rtbitmap_read_buf(args, block); 791 + if (error) 785 792 return error; 786 - } 787 - bufp = bp->b_addr; 793 + 788 794 /* 789 795 * Compute the starting word's address, and starting bit. 790 796 */ 791 - word = XFS_BITTOWORD(mp, start); 792 - b = &bufp[word]; 797 + word = xfs_rtx_to_rbmword(mp, start); 793 798 bit = (int)(start & (XFS_NBWORD - 1)); 794 799 /* 795 800 * 0 (allocated) => all zero's; 1 (free) => all one's. ··· 807 820 /* 808 821 * Compute difference between actual and desired value. 809 822 */ 810 - if ((wdiff = (*b ^ val) & mask)) { 823 + incore = xfs_rtbitmap_getword(args, word); 824 + if ((wdiff = (incore ^ val) & mask)) { 811 825 /* 812 826 * Different, compute first wrong bit and return. 813 827 */ 814 - xfs_trans_brelse(tp, bp); 815 828 i = XFS_RTLOBIT(wdiff) - bit; 816 829 *new = start + i; 817 830 *stat = 0; ··· 822 835 * Go on to next block if that's where the next word is 823 836 * and we need the next word. 824 837 */ 825 - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 838 + if (++word == mp->m_blockwsize && i < len) { 826 839 /* 827 840 * If done with this block, get the next one. 828 841 */ 829 - xfs_trans_brelse(tp, bp); 830 - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 831 - if (error) { 842 + error = xfs_rtbitmap_read_buf(args, ++block); 843 + if (error) 832 844 return error; 833 - } 834 - b = bufp = bp->b_addr; 845 + 835 846 word = 0; 836 - } else { 837 - /* 838 - * Go on to the next word in the buffer. 839 - */ 840 - b++; 841 847 } 842 848 } else { 843 849 /* ··· 846 866 /* 847 867 * Compute difference between actual and desired value. 848 868 */ 849 - if ((wdiff = *b ^ val)) { 869 + incore = xfs_rtbitmap_getword(args, word); 870 + if ((wdiff = incore ^ val)) { 850 871 /* 851 872 * Different, compute first wrong bit and return. 852 873 */ 853 - xfs_trans_brelse(tp, bp); 854 874 i += XFS_RTLOBIT(wdiff); 855 875 *new = start + i; 856 876 *stat = 0; ··· 861 881 * Go on to next block if that's where the next word is 862 882 * and we need the next word. 863 883 */ 864 - if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 884 + if (++word == mp->m_blockwsize && i < len) { 865 885 /* 866 886 * If done with this block, get the next one. 867 887 */ 868 - xfs_trans_brelse(tp, bp); 869 - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 870 - if (error) { 888 + error = xfs_rtbitmap_read_buf(args, ++block); 889 + if (error) 871 890 return error; 872 - } 873 - b = bufp = bp->b_addr; 891 + 874 892 word = 0; 875 - } else { 876 - /* 877 - * Go on to the next word in the buffer. 878 - */ 879 - b++; 880 893 } 881 894 } 882 895 /* ··· 884 911 /* 885 912 * Compute difference between actual and desired value. 886 913 */ 887 - if ((wdiff = (*b ^ val) & mask)) { 914 + incore = xfs_rtbitmap_getword(args, word); 915 + if ((wdiff = (incore ^ val) & mask)) { 888 916 /* 889 917 * Different, compute first wrong bit and return. 890 918 */ 891 - xfs_trans_brelse(tp, bp); 892 919 i += XFS_RTLOBIT(wdiff); 893 920 *new = start + i; 894 921 *stat = 0; ··· 899 926 /* 900 927 * Successful, return. 901 928 */ 902 - xfs_trans_brelse(tp, bp); 903 929 *new = start + i; 904 930 *stat = 1; 905 931 return 0; ··· 908 936 /* 909 937 * Check that the given extent (block range) is allocated already. 910 938 */ 911 - STATIC int /* error */ 939 + STATIC int 912 940 xfs_rtcheck_alloc_range( 913 - xfs_mount_t *mp, /* file system mount point */ 914 - xfs_trans_t *tp, /* transaction pointer */ 915 - xfs_rtblock_t bno, /* starting block number of extent */ 916 - xfs_extlen_t len) /* length of extent */ 941 + struct xfs_rtalloc_args *args, 942 + xfs_rtxnum_t start, /* starting rtext number of extent */ 943 + xfs_rtxlen_t len) /* length of extent */ 917 944 { 918 - xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */ 919 - int stat; 920 - int error; 945 + xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */ 946 + int stat; 947 + int error; 921 948 922 - error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat); 949 + error = xfs_rtcheck_range(args, start, len, 0, &new, &stat); 923 950 if (error) 924 951 return error; 925 952 ASSERT(stat); 926 953 return 0; 927 954 } 928 955 #else 929 - #define xfs_rtcheck_alloc_range(m,t,b,l) (0) 956 + #define xfs_rtcheck_alloc_range(a,b,l) (0) 930 957 #endif 931 958 /* 932 959 * Free an extent in the realtime subvolume. Length is expressed in 933 960 * realtime extents, as is the block number. 934 961 */ 935 - int /* error */ 962 + int 936 963 xfs_rtfree_extent( 937 - xfs_trans_t *tp, /* transaction pointer */ 938 - xfs_rtblock_t bno, /* starting block number to free */ 939 - xfs_extlen_t len) /* length of extent freed */ 964 + struct xfs_trans *tp, /* transaction pointer */ 965 + xfs_rtxnum_t start, /* starting rtext number to free */ 966 + xfs_rtxlen_t len) /* length of extent freed */ 940 967 { 941 - int error; /* error value */ 942 - xfs_mount_t *mp; /* file system mount structure */ 943 - xfs_fsblock_t sb; /* summary file block number */ 944 - struct xfs_buf *sumbp = NULL; /* summary file block buffer */ 945 - struct timespec64 atime; 946 - 947 - mp = tp->t_mountp; 968 + struct xfs_mount *mp = tp->t_mountp; 969 + struct xfs_rtalloc_args args = { 970 + .mp = mp, 971 + .tp = tp, 972 + }; 973 + int error; 974 + struct timespec64 atime; 948 975 949 976 ASSERT(mp->m_rbmip->i_itemp != NULL); 950 977 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); 951 978 952 - error = xfs_rtcheck_alloc_range(mp, tp, bno, len); 979 + error = xfs_rtcheck_alloc_range(&args, start, len); 953 980 if (error) 954 981 return error; 955 982 956 983 /* 957 984 * Free the range of realtime blocks. 958 985 */ 959 - error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb); 960 - if (error) { 961 - return error; 962 - } 986 + error = xfs_rtfree_range(&args, start, len); 987 + if (error) 988 + goto out; 989 + 963 990 /* 964 991 * Mark more blocks free in the superblock. 965 992 */ ··· 973 1002 mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; 974 1003 975 1004 atime = inode_get_atime(VFS_I(mp->m_rbmip)); 976 - *((uint64_t *)&atime) = 0; 1005 + atime.tv_sec = 0; 977 1006 inode_set_atime_to_ts(VFS_I(mp->m_rbmip), atime); 978 1007 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); 979 1008 } 980 - return 0; 1009 + error = 0; 1010 + out: 1011 + xfs_rtbuf_cache_relse(&args); 1012 + return error; 1013 + } 1014 + 1015 + /* 1016 + * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of 1017 + * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen 1018 + * cannot exceed XFS_MAX_BMBT_EXTLEN. 1019 + */ 1020 + int 1021 + xfs_rtfree_blocks( 1022 + struct xfs_trans *tp, 1023 + xfs_fsblock_t rtbno, 1024 + xfs_filblks_t rtlen) 1025 + { 1026 + struct xfs_mount *mp = tp->t_mountp; 1027 + xfs_rtxnum_t start; 1028 + xfs_filblks_t len; 1029 + xfs_extlen_t mod; 1030 + 1031 + ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN); 1032 + 1033 + len = xfs_rtb_to_rtxrem(mp, rtlen, &mod); 1034 + if (mod) { 1035 + ASSERT(mod == 0); 1036 + return -EIO; 1037 + } 1038 + 1039 + start = xfs_rtb_to_rtxrem(mp, rtbno, &mod); 1040 + if (mod) { 1041 + ASSERT(mod == 0); 1042 + return -EIO; 1043 + } 1044 + 1045 + return xfs_rtfree_extent(tp, start, len); 981 1046 } 982 1047 983 1048 /* Find all the free records within a given range. */ ··· 1026 1019 xfs_rtalloc_query_range_fn fn, 1027 1020 void *priv) 1028 1021 { 1022 + struct xfs_rtalloc_args args = { 1023 + .mp = mp, 1024 + .tp = tp, 1025 + }; 1029 1026 struct xfs_rtalloc_rec rec; 1030 - xfs_rtblock_t rtstart; 1031 - xfs_rtblock_t rtend; 1032 - xfs_rtblock_t high_key; 1027 + xfs_rtxnum_t rtstart; 1028 + xfs_rtxnum_t rtend; 1029 + xfs_rtxnum_t high_key; 1033 1030 int is_free; 1034 1031 int error = 0; 1035 1032 ··· 1049 1038 rtstart = low_rec->ar_startext; 1050 1039 while (rtstart <= high_key) { 1051 1040 /* Is the first block free? */ 1052 - error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend, 1041 + error = xfs_rtcheck_range(&args, rtstart, 1, 1, &rtend, 1053 1042 &is_free); 1054 1043 if (error) 1055 1044 break; 1056 1045 1057 1046 /* How long does the extent go for? */ 1058 - error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend); 1047 + error = xfs_rtfind_forw(&args, rtstart, high_key, &rtend); 1059 1048 if (error) 1060 1049 break; 1061 1050 ··· 1071 1060 rtstart = rtend + 1; 1072 1061 } 1073 1062 1063 + xfs_rtbuf_cache_relse(&args); 1074 1064 return error; 1075 1065 } 1076 1066 ··· 1097 1085 xfs_rtalloc_extent_is_free( 1098 1086 struct xfs_mount *mp, 1099 1087 struct xfs_trans *tp, 1100 - xfs_rtblock_t start, 1101 - xfs_extlen_t len, 1088 + xfs_rtxnum_t start, 1089 + xfs_rtxlen_t len, 1102 1090 bool *is_free) 1103 1091 { 1104 - xfs_rtblock_t end; 1092 + struct xfs_rtalloc_args args = { 1093 + .mp = mp, 1094 + .tp = tp, 1095 + }; 1096 + xfs_rtxnum_t end; 1105 1097 int matches; 1106 1098 int error; 1107 1099 1108 - error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches); 1100 + error = xfs_rtcheck_range(&args, start, len, 1, &end, &matches); 1101 + xfs_rtbuf_cache_relse(&args); 1109 1102 if (error) 1110 1103 return error; 1111 1104 1112 1105 *is_free = matches; 1113 1106 return 0; 1107 + } 1108 + 1109 + /* 1110 + * Compute the number of rtbitmap blocks needed to track the given number of rt 1111 + * extents. 1112 + */ 1113 + xfs_filblks_t 1114 + xfs_rtbitmap_blockcount( 1115 + struct xfs_mount *mp, 1116 + xfs_rtbxlen_t rtextents) 1117 + { 1118 + return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize); 1119 + } 1120 + 1121 + /* 1122 + * Compute the number of rtbitmap words needed to populate every block of a 1123 + * bitmap that is large enough to track the given number of rt extents. 1124 + */ 1125 + unsigned long long 1126 + xfs_rtbitmap_wordcount( 1127 + struct xfs_mount *mp, 1128 + xfs_rtbxlen_t rtextents) 1129 + { 1130 + xfs_filblks_t blocks; 1131 + 1132 + blocks = xfs_rtbitmap_blockcount(mp, rtextents); 1133 + return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; 1134 + } 1135 + 1136 + /* Compute the number of rtsummary blocks needed to track the given rt space. */ 1137 + xfs_filblks_t 1138 + xfs_rtsummary_blockcount( 1139 + struct xfs_mount *mp, 1140 + unsigned int rsumlevels, 1141 + xfs_extlen_t rbmblocks) 1142 + { 1143 + unsigned long long rsumwords; 1144 + 1145 + rsumwords = (unsigned long long)rsumlevels * rbmblocks; 1146 + return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG); 1147 + } 1148 + 1149 + /* 1150 + * Compute the number of rtsummary info words needed to populate every block of 1151 + * a summary file that is large enough to track the given rt space. 1152 + */ 1153 + unsigned long long 1154 + xfs_rtsummary_wordcount( 1155 + struct xfs_mount *mp, 1156 + unsigned int rsumlevels, 1157 + xfs_extlen_t rbmblocks) 1158 + { 1159 + xfs_filblks_t blocks; 1160 + 1161 + blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks); 1162 + return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; 1114 1163 }
+383
fs/xfs/libxfs/xfs_rtbitmap.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 4 + * All Rights Reserved. 5 + */ 6 + #ifndef __XFS_RTBITMAP_H__ 7 + #define __XFS_RTBITMAP_H__ 8 + 9 + struct xfs_rtalloc_args { 10 + struct xfs_mount *mp; 11 + struct xfs_trans *tp; 12 + 13 + struct xfs_buf *rbmbp; /* bitmap block buffer */ 14 + struct xfs_buf *sumbp; /* summary block buffer */ 15 + 16 + xfs_fileoff_t rbmoff; /* bitmap block number */ 17 + xfs_fileoff_t sumoff; /* summary block number */ 18 + }; 19 + 20 + static inline xfs_rtblock_t 21 + xfs_rtx_to_rtb( 22 + struct xfs_mount *mp, 23 + xfs_rtxnum_t rtx) 24 + { 25 + if (mp->m_rtxblklog >= 0) 26 + return rtx << mp->m_rtxblklog; 27 + 28 + return rtx * mp->m_sb.sb_rextsize; 29 + } 30 + 31 + static inline xfs_extlen_t 32 + xfs_rtxlen_to_extlen( 33 + struct xfs_mount *mp, 34 + xfs_rtxlen_t rtxlen) 35 + { 36 + if (mp->m_rtxblklog >= 0) 37 + return rtxlen << mp->m_rtxblklog; 38 + 39 + return rtxlen * mp->m_sb.sb_rextsize; 40 + } 41 + 42 + /* Compute the misalignment between an extent length and a realtime extent .*/ 43 + static inline unsigned int 44 + xfs_extlen_to_rtxmod( 45 + struct xfs_mount *mp, 46 + xfs_extlen_t len) 47 + { 48 + if (mp->m_rtxblklog >= 0) 49 + return len & mp->m_rtxblkmask; 50 + 51 + return len % mp->m_sb.sb_rextsize; 52 + } 53 + 54 + static inline xfs_rtxlen_t 55 + xfs_extlen_to_rtxlen( 56 + struct xfs_mount *mp, 57 + xfs_extlen_t len) 58 + { 59 + if (mp->m_rtxblklog >= 0) 60 + return len >> mp->m_rtxblklog; 61 + 62 + return len / mp->m_sb.sb_rextsize; 63 + } 64 + 65 + /* Convert an rt block number into an rt extent number. */ 66 + static inline xfs_rtxnum_t 67 + xfs_rtb_to_rtx( 68 + struct xfs_mount *mp, 69 + xfs_rtblock_t rtbno) 70 + { 71 + if (likely(mp->m_rtxblklog >= 0)) 72 + return rtbno >> mp->m_rtxblklog; 73 + 74 + return div_u64(rtbno, mp->m_sb.sb_rextsize); 75 + } 76 + 77 + /* Return the offset of an rt block number within an rt extent. */ 78 + static inline xfs_extlen_t 79 + xfs_rtb_to_rtxoff( 80 + struct xfs_mount *mp, 81 + xfs_rtblock_t rtbno) 82 + { 83 + if (likely(mp->m_rtxblklog >= 0)) 84 + return rtbno & mp->m_rtxblkmask; 85 + 86 + return do_div(rtbno, mp->m_sb.sb_rextsize); 87 + } 88 + 89 + /* 90 + * Crack an rt block number into an rt extent number and an offset within that 91 + * rt extent. Returns the rt extent number directly and the offset in @off. 92 + */ 93 + static inline xfs_rtxnum_t 94 + xfs_rtb_to_rtxrem( 95 + struct xfs_mount *mp, 96 + xfs_rtblock_t rtbno, 97 + xfs_extlen_t *off) 98 + { 99 + if (likely(mp->m_rtxblklog >= 0)) { 100 + *off = rtbno & mp->m_rtxblkmask; 101 + return rtbno >> mp->m_rtxblklog; 102 + } 103 + 104 + return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off); 105 + } 106 + 107 + /* 108 + * Convert an rt block number into an rt extent number, rounding up to the next 109 + * rt extent if the rt block is not aligned to an rt extent boundary. 110 + */ 111 + static inline xfs_rtxnum_t 112 + xfs_rtb_to_rtxup( 113 + struct xfs_mount *mp, 114 + xfs_rtblock_t rtbno) 115 + { 116 + if (likely(mp->m_rtxblklog >= 0)) { 117 + if (rtbno & mp->m_rtxblkmask) 118 + return (rtbno >> mp->m_rtxblklog) + 1; 119 + return rtbno >> mp->m_rtxblklog; 120 + } 121 + 122 + if (do_div(rtbno, mp->m_sb.sb_rextsize)) 123 + rtbno++; 124 + return rtbno; 125 + } 126 + 127 + /* Round this rtblock up to the nearest rt extent size. */ 128 + static inline xfs_rtblock_t 129 + xfs_rtb_roundup_rtx( 130 + struct xfs_mount *mp, 131 + xfs_rtblock_t rtbno) 132 + { 133 + return roundup_64(rtbno, mp->m_sb.sb_rextsize); 134 + } 135 + 136 + /* Round this rtblock down to the nearest rt extent size. */ 137 + static inline xfs_rtblock_t 138 + xfs_rtb_rounddown_rtx( 139 + struct xfs_mount *mp, 140 + xfs_rtblock_t rtbno) 141 + { 142 + return rounddown_64(rtbno, mp->m_sb.sb_rextsize); 143 + } 144 + 145 + /* Convert an rt extent number to a file block offset in the rt bitmap file. */ 146 + static inline xfs_fileoff_t 147 + xfs_rtx_to_rbmblock( 148 + struct xfs_mount *mp, 149 + xfs_rtxnum_t rtx) 150 + { 151 + return rtx >> mp->m_blkbit_log; 152 + } 153 + 154 + /* Convert an rt extent number to a word offset within an rt bitmap block. */ 155 + static inline unsigned int 156 + xfs_rtx_to_rbmword( 157 + struct xfs_mount *mp, 158 + xfs_rtxnum_t rtx) 159 + { 160 + return (rtx >> XFS_NBWORDLOG) & (mp->m_blockwsize - 1); 161 + } 162 + 163 + /* Convert a file block offset in the rt bitmap file to an rt extent number. */ 164 + static inline xfs_rtxnum_t 165 + xfs_rbmblock_to_rtx( 166 + struct xfs_mount *mp, 167 + xfs_fileoff_t rbmoff) 168 + { 169 + return rbmoff << mp->m_blkbit_log; 170 + } 171 + 172 + /* Return a pointer to a bitmap word within a rt bitmap block. */ 173 + static inline union xfs_rtword_raw * 174 + xfs_rbmblock_wordptr( 175 + struct xfs_rtalloc_args *args, 176 + unsigned int index) 177 + { 178 + union xfs_rtword_raw *words = args->rbmbp->b_addr; 179 + 180 + return words + index; 181 + } 182 + 183 + /* Convert an ondisk bitmap word to its incore representation. */ 184 + static inline xfs_rtword_t 185 + xfs_rtbitmap_getword( 186 + struct xfs_rtalloc_args *args, 187 + unsigned int index) 188 + { 189 + union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); 190 + 191 + return word->old; 192 + } 193 + 194 + /* Set an ondisk bitmap word from an incore representation. */ 195 + static inline void 196 + xfs_rtbitmap_setword( 197 + struct xfs_rtalloc_args *args, 198 + unsigned int index, 199 + xfs_rtword_t value) 200 + { 201 + union xfs_rtword_raw *word = xfs_rbmblock_wordptr(args, index); 202 + 203 + word->old = value; 204 + } 205 + 206 + /* 207 + * Convert a rt extent length and rt bitmap block number to a xfs_suminfo_t 208 + * offset within the rt summary file. 209 + */ 210 + static inline xfs_rtsumoff_t 211 + xfs_rtsumoffs( 212 + struct xfs_mount *mp, 213 + int log2_len, 214 + xfs_fileoff_t rbmoff) 215 + { 216 + return log2_len * mp->m_sb.sb_rbmblocks + rbmoff; 217 + } 218 + 219 + /* 220 + * Convert an xfs_suminfo_t offset to a file block offset within the rt summary 221 + * file. 222 + */ 223 + static inline xfs_fileoff_t 224 + xfs_rtsumoffs_to_block( 225 + struct xfs_mount *mp, 226 + xfs_rtsumoff_t rsumoff) 227 + { 228 + return XFS_B_TO_FSBT(mp, rsumoff * sizeof(xfs_suminfo_t)); 229 + } 230 + 231 + /* 232 + * Convert an xfs_suminfo_t offset to an info word offset within an rt summary 233 + * block. 234 + */ 235 + static inline unsigned int 236 + xfs_rtsumoffs_to_infoword( 237 + struct xfs_mount *mp, 238 + xfs_rtsumoff_t rsumoff) 239 + { 240 + unsigned int mask = mp->m_blockmask >> XFS_SUMINFOLOG; 241 + 242 + return rsumoff & mask; 243 + } 244 + 245 + /* Return a pointer to a summary info word within a rt summary block. */ 246 + static inline union xfs_suminfo_raw * 247 + xfs_rsumblock_infoptr( 248 + struct xfs_rtalloc_args *args, 249 + unsigned int index) 250 + { 251 + union xfs_suminfo_raw *info = args->sumbp->b_addr; 252 + 253 + return info + index; 254 + } 255 + 256 + /* Get the current value of a summary counter. */ 257 + static inline xfs_suminfo_t 258 + xfs_suminfo_get( 259 + struct xfs_rtalloc_args *args, 260 + unsigned int index) 261 + { 262 + union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); 263 + 264 + return info->old; 265 + } 266 + 267 + /* Add to the current value of a summary counter and return the new value. */ 268 + static inline xfs_suminfo_t 269 + xfs_suminfo_add( 270 + struct xfs_rtalloc_args *args, 271 + unsigned int index, 272 + int delta) 273 + { 274 + union xfs_suminfo_raw *info = xfs_rsumblock_infoptr(args, index); 275 + 276 + info->old += delta; 277 + return info->old; 278 + } 279 + 280 + /* 281 + * Functions for walking free space rtextents in the realtime bitmap. 282 + */ 283 + struct xfs_rtalloc_rec { 284 + xfs_rtxnum_t ar_startext; 285 + xfs_rtbxlen_t ar_extcount; 286 + }; 287 + 288 + typedef int (*xfs_rtalloc_query_range_fn)( 289 + struct xfs_mount *mp, 290 + struct xfs_trans *tp, 291 + const struct xfs_rtalloc_rec *rec, 292 + void *priv); 293 + 294 + #ifdef CONFIG_XFS_RT 295 + void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args); 296 + 297 + int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block, 298 + int issum); 299 + 300 + static inline int 301 + xfs_rtbitmap_read_buf( 302 + struct xfs_rtalloc_args *args, 303 + xfs_fileoff_t block) 304 + { 305 + return xfs_rtbuf_get(args, block, 0); 306 + } 307 + 308 + static inline int 309 + xfs_rtsummary_read_buf( 310 + struct xfs_rtalloc_args *args, 311 + xfs_fileoff_t block) 312 + { 313 + return xfs_rtbuf_get(args, block, 1); 314 + } 315 + 316 + int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 317 + xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat); 318 + int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 319 + xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 320 + int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 321 + xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 322 + int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 323 + xfs_rtxlen_t len, int val); 324 + int xfs_rtmodify_summary_int(struct xfs_rtalloc_args *args, int log, 325 + xfs_fileoff_t bbno, int delta, xfs_suminfo_t *sum); 326 + int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log, 327 + xfs_fileoff_t bbno, int delta); 328 + int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 329 + xfs_rtxlen_t len); 330 + int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, 331 + const struct xfs_rtalloc_rec *low_rec, 332 + const struct xfs_rtalloc_rec *high_rec, 333 + xfs_rtalloc_query_range_fn fn, void *priv); 334 + int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, 335 + xfs_rtalloc_query_range_fn fn, 336 + void *priv); 337 + int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, 338 + xfs_rtxnum_t start, xfs_rtxlen_t len, 339 + bool *is_free); 340 + /* 341 + * Free an extent in the realtime subvolume. Length is expressed in 342 + * realtime extents, as is the block number. 343 + */ 344 + int /* error */ 345 + xfs_rtfree_extent( 346 + struct xfs_trans *tp, /* transaction pointer */ 347 + xfs_rtxnum_t start, /* starting rtext number to free */ 348 + xfs_rtxlen_t len); /* length of extent freed */ 349 + 350 + /* Same as above, but in units of rt blocks. */ 351 + int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno, 352 + xfs_filblks_t rtlen); 353 + 354 + xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t 355 + rtextents); 356 + unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, 357 + xfs_rtbxlen_t rtextents); 358 + 359 + xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, 360 + unsigned int rsumlevels, xfs_extlen_t rbmblocks); 361 + unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, 362 + unsigned int rsumlevels, xfs_extlen_t rbmblocks); 363 + #else /* CONFIG_XFS_RT */ 364 + # define xfs_rtfree_extent(t,b,l) (-ENOSYS) 365 + # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) 366 + # define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS) 367 + # define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS) 368 + # define xfs_rtbitmap_read_buf(a,b) (-ENOSYS) 369 + # define xfs_rtsummary_read_buf(a,b) (-ENOSYS) 370 + # define xfs_rtbuf_cache_relse(a) (0) 371 + # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) 372 + static inline xfs_filblks_t 373 + xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents) 374 + { 375 + /* shut up gcc */ 376 + return 0; 377 + } 378 + # define xfs_rtbitmap_wordcount(mp, r) (0) 379 + # define xfs_rtsummary_blockcount(mp, l, b) (0) 380 + # define xfs_rtsummary_wordcount(mp, l, b) (0) 381 + #endif /* CONFIG_XFS_RT */ 382 + 383 + #endif /* __XFS_RTBITMAP_H__ */
+2
fs/xfs/libxfs/xfs_sb.c
··· 975 975 mp->m_blockmask = sbp->sb_blocksize - 1; 976 976 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; 977 977 mp->m_blockwmask = mp->m_blockwsize - 1; 978 + mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); 979 + mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); 978 980 979 981 mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); 980 982 mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
+1 -1
fs/xfs/libxfs/xfs_sb.h
··· 25 25 26 26 extern int xfs_update_secondary_sbs(struct xfs_mount *mp); 27 27 28 - #define XFS_FS_GEOM_MAX_STRUCT_VER (4) 28 + #define XFS_FS_GEOM_MAX_STRUCT_VER (5) 29 29 extern void xfs_fs_geometry(struct xfs_mount *mp, struct xfs_fsop_geom *geo, 30 30 int struct_version); 31 31 extern int xfs_sb_read_secondary(struct xfs_mount *mp,
+6 -4
fs/xfs/libxfs/xfs_trans_resv.c
··· 19 19 #include "xfs_trans.h" 20 20 #include "xfs_qm.h" 21 21 #include "xfs_trans_space.h" 22 + #include "xfs_rtbitmap.h" 22 23 23 24 #define _ALLOC true 24 25 #define _FREE false ··· 218 217 struct xfs_mount *mp, 219 218 unsigned int num_ops) 220 219 { 221 - unsigned int blksz = XFS_FSB_TO_B(mp, 1); 222 - unsigned int rtbmp_bytes; 220 + unsigned int rtbmp_blocks; 221 + xfs_rtxlen_t rtxlen; 223 222 224 - rtbmp_bytes = (XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize) / NBBY; 225 - return (howmany(rtbmp_bytes, blksz) + 1) * num_ops; 223 + rtxlen = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN); 224 + rtbmp_blocks = xfs_rtbitmap_blockcount(mp, rtxlen); 225 + return (rtbmp_blocks + 1) * num_ops; 226 226 } 227 227 228 228 /*
+2 -2
fs/xfs/libxfs/xfs_types.c
··· 148 148 149 149 /* Verify that a realtime device extent is fully contained inside the volume. */ 150 150 bool 151 - xfs_verify_rtext( 151 + xfs_verify_rtbext( 152 152 struct xfs_mount *mp, 153 153 xfs_rtblock_t rtbno, 154 - xfs_rtblock_t len) 154 + xfs_filblks_t len) 155 155 { 156 156 if (rtbno + len <= rtbno) 157 157 return false;
+8 -2
fs/xfs/libxfs/xfs_types.h
··· 11 11 typedef uint32_t xfs_agblock_t; /* blockno in alloc. group */ 12 12 typedef uint32_t xfs_agino_t; /* inode # within allocation grp */ 13 13 typedef uint32_t xfs_extlen_t; /* extent length in blocks */ 14 + typedef uint32_t xfs_rtxlen_t; /* file extent length in rtextents */ 14 15 typedef uint32_t xfs_agnumber_t; /* allocation group number */ 15 16 typedef uint64_t xfs_extnum_t; /* # of extents in a file */ 16 17 typedef uint32_t xfs_aextnum_t; /* # extents in an attribute fork */ ··· 19 18 typedef uint64_t xfs_ufsize_t; /* unsigned bytes in a file */ 20 19 21 20 typedef int32_t xfs_suminfo_t; /* type of bitmap summary info */ 21 + typedef uint32_t xfs_rtsumoff_t; /* offset of an rtsummary info word */ 22 22 typedef uint32_t xfs_rtword_t; /* word type for bitmap manipulations */ 23 23 24 24 typedef int64_t xfs_lsn_t; /* log sequence number */ ··· 33 31 typedef uint64_t xfs_rtblock_t; /* extent (block) in realtime area */ 34 32 typedef uint64_t xfs_fileoff_t; /* block number in a file */ 35 33 typedef uint64_t xfs_filblks_t; /* number of blocks in a file */ 34 + typedef uint64_t xfs_rtxnum_t; /* rtextent number */ 35 + typedef uint64_t xfs_rtbxlen_t; /* rtbitmap extent length in rtextents */ 36 36 37 37 typedef int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ 38 38 ··· 51 47 #define NULLRFSBLOCK ((xfs_rfsblock_t)-1) 52 48 #define NULLRTBLOCK ((xfs_rtblock_t)-1) 53 49 #define NULLFILEOFF ((xfs_fileoff_t)-1) 50 + #define NULLRTEXTNO ((xfs_rtxnum_t)-1) 54 51 55 52 #define NULLAGBLOCK ((xfs_agblock_t)-1) 56 53 #define NULLAGNUMBER ((xfs_agnumber_t)-1) ··· 150 145 */ 151 146 #define XFS_NBBYLOG 3 /* log2(NBBY) */ 152 147 #define XFS_WORDLOG 2 /* log2(sizeof(xfs_rtword_t)) */ 148 + #define XFS_SUMINFOLOG 2 /* log2(sizeof(xfs_suminfo_t)) */ 153 149 #define XFS_NBWORDLOG (XFS_NBBYLOG + XFS_WORDLOG) 154 150 #define XFS_NBWORD (1 << XFS_NBWORDLOG) 155 151 #define XFS_WORDMASK ((1 << XFS_WORDLOG) - 1) ··· 235 229 bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino); 236 230 bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino); 237 231 bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno); 238 - bool xfs_verify_rtext(struct xfs_mount *mp, xfs_rtblock_t rtbno, 239 - xfs_rtblock_t len); 232 + bool xfs_verify_rtbext(struct xfs_mount *mp, xfs_rtblock_t rtbno, 233 + xfs_filblks_t len); 240 234 bool xfs_verify_icount(struct xfs_mount *mp, unsigned long long icount); 241 235 bool xfs_verify_dablk(struct xfs_mount *mp, xfs_fileoff_t off); 242 236 void xfs_icount_range(struct xfs_mount *mp, unsigned long long *min,
+1 -1
fs/xfs/scrub/bmap.c
··· 410 410 411 411 /* Make sure the extent points to a valid place. */ 412 412 if (info->is_rt && 413 - !xfs_verify_rtext(mp, irec->br_startblock, irec->br_blockcount)) 413 + !xfs_verify_rtbext(mp, irec->br_startblock, irec->br_blockcount)) 414 414 xchk_fblock_set_corrupt(info->sc, info->whichfork, 415 415 irec->br_startoff); 416 416 if (!info->is_rt &&
+1 -1
fs/xfs/scrub/fscounters.c
··· 16 16 #include "xfs_health.h" 17 17 #include "xfs_btree.h" 18 18 #include "xfs_ag.h" 19 - #include "xfs_rtalloc.h" 19 + #include "xfs_rtbitmap.h" 20 20 #include "xfs_inode.h" 21 21 #include "xfs_icache.h" 22 22 #include "scrub/scrub.h"
+2 -1
fs/xfs/scrub/inode.c
··· 20 20 #include "xfs_reflink.h" 21 21 #include "xfs_rmap.h" 22 22 #include "xfs_bmap_util.h" 23 + #include "xfs_rtbitmap.h" 23 24 #include "scrub/scrub.h" 24 25 #include "scrub/common.h" 25 26 #include "scrub/btree.h" ··· 226 225 */ 227 226 if ((flags & XFS_DIFLAG_RTINHERIT) && 228 227 (flags & XFS_DIFLAG_EXTSZINHERIT) && 229 - value % sc->mp->m_sb.sb_rextsize > 0) 228 + xfs_extlen_to_rtxmod(sc->mp, value) > 0) 230 229 xchk_ino_set_warning(sc, ino); 231 230 } 232 231
+12 -16
fs/xfs/scrub/rtbitmap.c
··· 11 11 #include "xfs_mount.h" 12 12 #include "xfs_log_format.h" 13 13 #include "xfs_trans.h" 14 - #include "xfs_rtalloc.h" 14 + #include "xfs_rtbitmap.h" 15 15 #include "xfs_inode.h" 16 16 #include "xfs_bmap.h" 17 17 #include "scrub/scrub.h" ··· 48 48 { 49 49 struct xfs_scrub *sc = priv; 50 50 xfs_rtblock_t startblock; 51 - xfs_rtblock_t blockcount; 51 + xfs_filblks_t blockcount; 52 52 53 - startblock = rec->ar_startext * mp->m_sb.sb_rextsize; 54 - blockcount = rec->ar_extcount * mp->m_sb.sb_rextsize; 53 + startblock = xfs_rtx_to_rtb(mp, rec->ar_startext); 54 + blockcount = xfs_rtx_to_rtb(mp, rec->ar_extcount); 55 55 56 - if (!xfs_verify_rtext(mp, startblock, blockcount)) 56 + if (!xfs_verify_rtbext(mp, startblock, blockcount)) 57 57 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); 58 58 return 0; 59 59 } ··· 128 128 void 129 129 xchk_xref_is_used_rt_space( 130 130 struct xfs_scrub *sc, 131 - xfs_rtblock_t fsbno, 131 + xfs_rtblock_t rtbno, 132 132 xfs_extlen_t len) 133 133 { 134 - xfs_rtblock_t startext; 135 - xfs_rtblock_t endext; 136 - xfs_rtblock_t extcount; 134 + xfs_rtxnum_t startext; 135 + xfs_rtxnum_t endext; 137 136 bool is_free; 138 137 int error; 139 138 140 139 if (xchk_skip_xref(sc->sm)) 141 140 return; 142 141 143 - startext = fsbno; 144 - endext = fsbno + len - 1; 145 - do_div(startext, sc->mp->m_sb.sb_rextsize); 146 - do_div(endext, sc->mp->m_sb.sb_rextsize); 147 - extcount = endext - startext + 1; 142 + startext = xfs_rtb_to_rtx(sc->mp, rtbno); 143 + endext = xfs_rtb_to_rtx(sc->mp, rtbno + len - 1); 148 144 xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); 149 - error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount, 150 - &is_free); 145 + error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, 146 + endext - startext + 1, &is_free); 151 147 if (!xchk_should_check_xref(sc, &error, NULL)) 152 148 goto out_unlock; 153 149 if (is_free)
+44 -28
fs/xfs/scrub/rtsummary.c
··· 13 13 #include "xfs_inode.h" 14 14 #include "xfs_log_format.h" 15 15 #include "xfs_trans.h" 16 - #include "xfs_rtalloc.h" 16 + #include "xfs_rtbitmap.h" 17 17 #include "xfs_bit.h" 18 18 #include "xfs_bmap.h" 19 19 #include "scrub/scrub.h" ··· 81 81 static inline int 82 82 xfsum_load( 83 83 struct xfs_scrub *sc, 84 - xchk_rtsumoff_t sumoff, 85 - xfs_suminfo_t *info) 84 + xfs_rtsumoff_t sumoff, 85 + union xfs_suminfo_raw *rawinfo) 86 86 { 87 - return xfile_obj_load(sc->xfile, info, sizeof(xfs_suminfo_t), 87 + return xfile_obj_load(sc->xfile, rawinfo, 88 + sizeof(union xfs_suminfo_raw), 88 89 sumoff << XFS_WORDLOG); 89 90 } 90 91 91 92 static inline int 92 93 xfsum_store( 93 94 struct xfs_scrub *sc, 94 - xchk_rtsumoff_t sumoff, 95 - const xfs_suminfo_t info) 95 + xfs_rtsumoff_t sumoff, 96 + const union xfs_suminfo_raw rawinfo) 96 97 { 97 - return xfile_obj_store(sc->xfile, &info, sizeof(xfs_suminfo_t), 98 + return xfile_obj_store(sc->xfile, &rawinfo, 99 + sizeof(union xfs_suminfo_raw), 98 100 sumoff << XFS_WORDLOG); 99 101 } 100 102 101 103 static inline int 102 104 xfsum_copyout( 103 105 struct xfs_scrub *sc, 104 - xchk_rtsumoff_t sumoff, 105 - xfs_suminfo_t *info, 106 + xfs_rtsumoff_t sumoff, 107 + union xfs_suminfo_raw *rawinfo, 106 108 unsigned int nr_words) 107 109 { 108 - return xfile_obj_load(sc->xfile, info, nr_words << XFS_WORDLOG, 110 + return xfile_obj_load(sc->xfile, rawinfo, nr_words << XFS_WORDLOG, 109 111 sumoff << XFS_WORDLOG); 112 + } 113 + 114 + static inline xfs_suminfo_t 115 + xchk_rtsum_inc( 116 + struct xfs_mount *mp, 117 + union xfs_suminfo_raw *v) 118 + { 119 + v->old += 1; 120 + return v->old; 110 121 } 111 122 112 123 /* Update the summary file to reflect the free extent that we've accumulated. */ ··· 132 121 xfs_fileoff_t rbmoff; 133 122 xfs_rtblock_t rtbno; 134 123 xfs_filblks_t rtlen; 135 - xchk_rtsumoff_t offs; 124 + xfs_rtsumoff_t offs; 136 125 unsigned int lenlog; 137 - xfs_suminfo_t v = 0; 126 + union xfs_suminfo_raw v; 127 + xfs_suminfo_t value; 138 128 int error = 0; 139 129 140 130 if (xchk_should_terminate(sc, &error)) 141 131 return error; 142 132 143 133 /* Compute the relevant location in the rtsum file. */ 144 - rbmoff = XFS_BITTOBLOCK(mp, rec->ar_startext); 134 + rbmoff = xfs_rtx_to_rbmblock(mp, rec->ar_startext); 145 135 lenlog = XFS_RTBLOCKLOG(rec->ar_extcount); 146 - offs = XFS_SUMOFFS(mp, lenlog, rbmoff); 136 + offs = xfs_rtsumoffs(mp, lenlog, rbmoff); 147 137 148 - rtbno = rec->ar_startext * mp->m_sb.sb_rextsize; 149 - rtlen = rec->ar_extcount * mp->m_sb.sb_rextsize; 138 + rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); 139 + rtlen = xfs_rtx_to_rtb(mp, rec->ar_extcount); 150 140 151 - if (!xfs_verify_rtext(mp, rtbno, rtlen)) { 141 + if (!xfs_verify_rtbext(mp, rtbno, rtlen)) { 152 142 xchk_ino_xref_set_corrupt(sc, mp->m_rbmip->i_ino); 153 143 return -EFSCORRUPTED; 154 144 } ··· 159 147 if (error) 160 148 return error; 161 149 162 - v++; 150 + value = xchk_rtsum_inc(sc->mp, &v); 163 151 trace_xchk_rtsum_record_free(mp, rec->ar_startext, rec->ar_extcount, 164 - lenlog, offs, v); 152 + lenlog, offs, value); 165 153 166 154 return xfsum_store(sc, offs, v); 167 155 } ··· 172 160 struct xfs_scrub *sc) 173 161 { 174 162 struct xfs_mount *mp = sc->mp; 175 - unsigned long long rtbmp_bytes; 163 + unsigned long long rtbmp_blocks; 176 164 177 165 /* If the bitmap size doesn't match the computed size, bail. */ 178 - rtbmp_bytes = howmany_64(mp->m_sb.sb_rextents, NBBY); 179 - if (roundup_64(rtbmp_bytes, mp->m_sb.sb_blocksize) != 180 - mp->m_rbmip->i_disk_size) 166 + rtbmp_blocks = xfs_rtbitmap_blockcount(mp, mp->m_sb.sb_rextents); 167 + if (XFS_FSB_TO_B(mp, rtbmp_blocks) != mp->m_rbmip->i_disk_size) 181 168 return -EFSCORRUPTED; 182 169 183 170 return xfs_rtalloc_query_all(sc->mp, sc->tp, xchk_rtsum_record_free, ··· 188 177 xchk_rtsum_compare( 189 178 struct xfs_scrub *sc) 190 179 { 180 + struct xfs_rtalloc_args args = { 181 + .mp = sc->mp, 182 + .tp = sc->tp, 183 + }; 191 184 struct xfs_mount *mp = sc->mp; 192 - struct xfs_buf *bp; 193 185 struct xfs_bmbt_irec map; 194 186 xfs_fileoff_t off; 195 187 xchk_rtsumoff_t sumoff = 0; 196 188 int nmap; 197 189 198 190 for (off = 0; off < XFS_B_TO_FSB(mp, mp->m_rsumsize); off++) { 191 + union xfs_suminfo_raw *ondisk_info; 199 192 int error = 0; 200 193 201 194 if (xchk_should_terminate(sc, &error)) ··· 220 205 } 221 206 222 207 /* Read a block's worth of ondisk rtsummary file. */ 223 - error = xfs_rtbuf_get(mp, sc->tp, off, 1, &bp); 208 + error = xfs_rtsummary_read_buf(&args, off); 224 209 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, off, &error)) 225 210 return error; 226 211 227 212 /* Read a block's worth of computed rtsummary file. */ 228 213 error = xfsum_copyout(sc, sumoff, sc->buf, mp->m_blockwsize); 229 214 if (error) { 230 - xfs_trans_brelse(sc->tp, bp); 215 + xfs_rtbuf_cache_relse(&args); 231 216 return error; 232 217 } 233 218 234 - if (memcmp(bp->b_addr, sc->buf, 219 + ondisk_info = xfs_rsumblock_infoptr(&args, 0); 220 + if (memcmp(ondisk_info, sc->buf, 235 221 mp->m_blockwsize << XFS_WORDLOG) != 0) 236 222 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, off); 237 223 238 - xfs_trans_brelse(sc->tp, bp); 224 + xfs_rtbuf_cache_relse(&args); 239 225 sumoff += mp->m_blockwsize; 240 226 } 241 227
+1
fs/xfs/scrub/trace.c
··· 13 13 #include "xfs_inode.h" 14 14 #include "xfs_btree.h" 15 15 #include "xfs_ag.h" 16 + #include "xfs_rtbitmap.h" 16 17 #include "scrub/scrub.h" 17 18 #include "scrub/xfile.h" 18 19 #include "scrub/xfarray.h"
+8 -7
fs/xfs/scrub/trace.h
··· 1036 1036 1037 1037 #ifdef CONFIG_XFS_RT 1038 1038 TRACE_EVENT(xchk_rtsum_record_free, 1039 - TP_PROTO(struct xfs_mount *mp, xfs_rtblock_t start, 1040 - uint64_t len, unsigned int log, loff_t pos, xfs_suminfo_t v), 1041 - TP_ARGS(mp, start, len, log, pos, v), 1039 + TP_PROTO(struct xfs_mount *mp, xfs_rtxnum_t start, 1040 + xfs_rtbxlen_t len, unsigned int log, loff_t pos, 1041 + xfs_suminfo_t value), 1042 + TP_ARGS(mp, start, len, log, pos, value), 1042 1043 TP_STRUCT__entry( 1043 1044 __field(dev_t, dev) 1044 1045 __field(dev_t, rtdev) 1045 - __field(xfs_rtblock_t, start) 1046 + __field(xfs_rtxnum_t, start) 1046 1047 __field(unsigned long long, len) 1047 1048 __field(unsigned int, log) 1048 1049 __field(loff_t, pos) 1049 - __field(xfs_suminfo_t, v) 1050 + __field(xfs_suminfo_t, value) 1050 1051 ), 1051 1052 TP_fast_assign( 1052 1053 __entry->dev = mp->m_super->s_dev; ··· 1056 1055 __entry->len = len; 1057 1056 __entry->log = log; 1058 1057 __entry->pos = pos; 1059 - __entry->v = v; 1058 + __entry->value = value; 1060 1059 ), 1061 1060 TP_printk("dev %d:%d rtdev %d:%d rtx 0x%llx rtxcount 0x%llx log %u rsumpos 0x%llx sumcount %u", 1062 1061 MAJOR(__entry->dev), MINOR(__entry->dev), ··· 1065 1064 __entry->len, 1066 1065 __entry->log, 1067 1066 __entry->pos, 1068 - __entry->v) 1067 + __entry->value) 1069 1068 ); 1070 1069 #endif /* CONFIG_XFS_RT */ 1071 1070
+34 -40
fs/xfs/xfs_bmap_util.c
··· 28 28 #include "xfs_icache.h" 29 29 #include "xfs_iomap.h" 30 30 #include "xfs_reflink.h" 31 + #include "xfs_rtbitmap.h" 31 32 32 33 /* Kernel only BMAP related definitions and functions */ 33 34 ··· 76 75 { 77 76 struct xfs_mount *mp = ap->ip->i_mount; 78 77 xfs_fileoff_t orig_offset = ap->offset; 79 - xfs_rtblock_t rtb; 80 - xfs_extlen_t prod = 0; /* product factor for allocators */ 78 + xfs_rtxnum_t rtx; 79 + xfs_rtxlen_t prod = 0; /* product factor for allocators */ 81 80 xfs_extlen_t mod = 0; /* product factor for allocators */ 82 - xfs_extlen_t ralen = 0; /* realtime allocation length */ 81 + xfs_rtxlen_t ralen = 0; /* realtime allocation length */ 83 82 xfs_extlen_t align; /* minimum allocation alignment */ 84 83 xfs_extlen_t orig_length = ap->length; 85 84 xfs_extlen_t minlen = mp->m_sb.sb_rextsize; 86 - xfs_extlen_t raminlen; 85 + xfs_rtxlen_t raminlen; 87 86 bool rtlocked = false; 88 87 bool ignore_locality = false; 89 88 int error; 90 89 91 90 align = xfs_get_extsz_hint(ap->ip); 92 91 retry: 93 - prod = align / mp->m_sb.sb_rextsize; 92 + prod = xfs_extlen_to_rtxlen(mp, align); 94 93 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, 95 94 align, 1, ap->eof, 0, 96 95 ap->conv, &ap->offset, &ap->length); 97 96 if (error) 98 97 return error; 99 98 ASSERT(ap->length); 100 - ASSERT(ap->length % mp->m_sb.sb_rextsize == 0); 99 + ASSERT(xfs_extlen_to_rtxmod(mp, ap->length) == 0); 101 100 102 101 /* 103 102 * If we shifted the file offset downward to satisfy an extent size ··· 117 116 prod = 1; 118 117 /* 119 118 * Set ralen to be the actual requested length in rtextents. 120 - */ 121 - ralen = ap->length / mp->m_sb.sb_rextsize; 122 - /* 119 + * 123 120 * If the old value was close enough to XFS_BMBT_MAX_EXTLEN that 124 121 * we rounded up to it, cut it back so it's valid again. 125 122 * Note that if it's a really large request (bigger than 126 123 * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't 127 124 * adjust the starting point to match it. 128 125 */ 129 - if (ralen * mp->m_sb.sb_rextsize >= XFS_MAX_BMBT_EXTLEN) 130 - ralen = XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize; 126 + ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN)); 131 127 132 128 /* 133 129 * Lock out modifications to both the RT bitmap and summary inodes ··· 142 144 * pick an extent that will space things out in the rt area. 143 145 */ 144 146 if (ap->eof && ap->offset == 0) { 145 - xfs_rtblock_t rtx; /* realtime extent no */ 146 - 147 147 error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); 148 148 if (error) 149 149 return error; 150 - ap->blkno = rtx * mp->m_sb.sb_rextsize; 150 + ap->blkno = xfs_rtx_to_rtb(mp, rtx); 151 151 } else { 152 152 ap->blkno = 0; 153 153 } ··· 156 160 * Realtime allocation, done through xfs_rtallocate_extent. 157 161 */ 158 162 if (ignore_locality) 159 - ap->blkno = 0; 163 + rtx = 0; 160 164 else 161 - do_div(ap->blkno, mp->m_sb.sb_rextsize); 162 - rtb = ap->blkno; 163 - ap->length = ralen; 164 - raminlen = max_t(xfs_extlen_t, 1, minlen / mp->m_sb.sb_rextsize); 165 - error = xfs_rtallocate_extent(ap->tp, ap->blkno, raminlen, ap->length, 166 - &ralen, ap->wasdel, prod, &rtb); 165 + rtx = xfs_rtb_to_rtx(mp, ap->blkno); 166 + raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); 167 + error = xfs_rtallocate_extent(ap->tp, rtx, raminlen, ralen, &ralen, 168 + ap->wasdel, prod, &rtx); 167 169 if (error) 168 170 return error; 169 171 170 - if (rtb != NULLRTBLOCK) { 171 - ap->blkno = rtb * mp->m_sb.sb_rextsize; 172 - ap->length = ralen * mp->m_sb.sb_rextsize; 172 + if (rtx != NULLRTEXTNO) { 173 + ap->blkno = xfs_rtx_to_rtb(mp, rtx); 174 + ap->length = xfs_rtxlen_to_extlen(mp, ralen); 173 175 ap->ip->i_nblocks += ap->length; 174 176 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); 175 177 if (ap->wasdel) ··· 684 690 */ 685 691 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); 686 692 if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) 687 - end_fsb = roundup_64(end_fsb, mp->m_sb.sb_rextsize); 693 + end_fsb = xfs_rtb_roundup_rtx(mp, end_fsb); 688 694 last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); 689 695 if (last_fsb <= end_fsb) 690 696 return false; ··· 774 780 { 775 781 xfs_mount_t *mp = ip->i_mount; 776 782 xfs_off_t count; 777 - xfs_filblks_t allocated_fsb; 778 783 xfs_filblks_t allocatesize_fsb; 779 784 xfs_extlen_t extsz, temp; 780 785 xfs_fileoff_t startoffset_fsb; 781 786 xfs_fileoff_t endoffset_fsb; 782 - int nimaps; 783 787 int rt; 784 788 xfs_trans_t *tp; 785 789 xfs_bmbt_irec_t imaps[1], *imapp; ··· 800 808 801 809 count = len; 802 810 imapp = &imaps[0]; 803 - nimaps = 1; 804 811 startoffset_fsb = XFS_B_TO_FSBT(mp, offset); 805 812 endoffset_fsb = XFS_B_TO_FSB(mp, offset + count); 806 813 allocatesize_fsb = endoffset_fsb - startoffset_fsb; ··· 810 819 while (allocatesize_fsb && !error) { 811 820 xfs_fileoff_t s, e; 812 821 unsigned int dblocks, rblocks, resblks; 822 + int nimaps = 1; 813 823 814 824 /* 815 825 * Determine space reservations for data/realtime. ··· 876 884 if (error) 877 885 break; 878 886 879 - allocated_fsb = imapp->br_blockcount; 880 - 881 - if (nimaps == 0) { 882 - error = -ENOSPC; 883 - break; 887 + /* 888 + * If the allocator cannot find a single free extent large 889 + * enough to cover the start block of the requested range, 890 + * xfs_bmapi_write will return 0 but leave *nimaps set to 0. 891 + * 892 + * In that case we simply need to keep looping with the same 893 + * startoffset_fsb so that one of the following allocations 894 + * will eventually reach the requested range. 895 + */ 896 + if (nimaps) { 897 + startoffset_fsb += imapp->br_blockcount; 898 + allocatesize_fsb -= imapp->br_blockcount; 884 899 } 885 - 886 - startoffset_fsb += allocated_fsb; 887 - allocatesize_fsb -= allocated_fsb; 888 900 } 889 901 890 902 return error; ··· 985 989 986 990 /* We can only free complete realtime extents. */ 987 991 if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) { 988 - startoffset_fsb = roundup_64(startoffset_fsb, 989 - mp->m_sb.sb_rextsize); 990 - endoffset_fsb = rounddown_64(endoffset_fsb, 991 - mp->m_sb.sb_rextsize); 992 + startoffset_fsb = xfs_rtb_roundup_rtx(mp, startoffset_fsb); 993 + endoffset_fsb = xfs_rtb_rounddown_rtx(mp, endoffset_fsb); 992 994 } 993 995 994 996 /*
+50 -13
fs/xfs/xfs_file.c
··· 214 214 return 0; 215 215 } 216 216 217 + static int 218 + xfs_ilock_iocb_for_write( 219 + struct kiocb *iocb, 220 + unsigned int *lock_mode) 221 + { 222 + ssize_t ret; 223 + struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp)); 224 + 225 + ret = xfs_ilock_iocb(iocb, *lock_mode); 226 + if (ret) 227 + return ret; 228 + 229 + if (*lock_mode == XFS_IOLOCK_EXCL) 230 + return 0; 231 + if (!xfs_iflags_test(ip, XFS_IREMAPPING)) 232 + return 0; 233 + 234 + xfs_iunlock(ip, *lock_mode); 235 + *lock_mode = XFS_IOLOCK_EXCL; 236 + return xfs_ilock_iocb(iocb, *lock_mode); 237 + } 238 + 239 + static unsigned int 240 + xfs_ilock_for_write_fault( 241 + struct xfs_inode *ip) 242 + { 243 + /* get a shared lock if no remapping in progress */ 244 + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); 245 + if (!xfs_iflags_test(ip, XFS_IREMAPPING)) 246 + return XFS_MMAPLOCK_SHARED; 247 + 248 + /* wait for remapping to complete */ 249 + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); 250 + xfs_ilock(ip, XFS_MMAPLOCK_EXCL); 251 + return XFS_MMAPLOCK_EXCL; 252 + } 253 + 217 254 STATIC ssize_t 218 255 xfs_file_dio_read( 219 256 struct kiocb *iocb, ··· 588 551 unsigned int iolock = XFS_IOLOCK_SHARED; 589 552 ssize_t ret; 590 553 591 - ret = xfs_ilock_iocb(iocb, iolock); 554 + ret = xfs_ilock_iocb_for_write(iocb, &iolock); 592 555 if (ret) 593 556 return ret; 594 557 ret = xfs_file_write_checks(iocb, from, &iolock); ··· 655 618 flags = IOMAP_DIO_FORCE_WAIT; 656 619 } 657 620 658 - ret = xfs_ilock_iocb(iocb, iolock); 621 + ret = xfs_ilock_iocb_for_write(iocb, &iolock); 659 622 if (ret) 660 623 return ret; 661 624 ··· 1217 1180 if (xfs_file_sync_writes(file_in) || xfs_file_sync_writes(file_out)) 1218 1181 xfs_log_force_inode(dest); 1219 1182 out_unlock: 1220 - xfs_iunlock2_io_mmap(src, dest); 1183 + xfs_iunlock2_remapping(src, dest); 1221 1184 if (ret) 1222 1185 trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_); 1223 1186 return remapped > 0 ? remapped : ret; ··· 1365 1328 struct inode *inode = file_inode(vmf->vma->vm_file); 1366 1329 struct xfs_inode *ip = XFS_I(inode); 1367 1330 vm_fault_t ret; 1331 + unsigned int lock_mode = 0; 1368 1332 1369 1333 trace_xfs_filemap_fault(ip, order, write_fault); 1370 1334 ··· 1374 1336 file_update_time(vmf->vma->vm_file); 1375 1337 } 1376 1338 1339 + if (IS_DAX(inode) || write_fault) 1340 + lock_mode = xfs_ilock_for_write_fault(XFS_I(inode)); 1341 + 1377 1342 if (IS_DAX(inode)) { 1378 1343 pfn_t pfn; 1379 1344 1380 - xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); 1381 1345 ret = xfs_dax_fault(vmf, order, write_fault, &pfn); 1382 1346 if (ret & VM_FAULT_NEEDDSYNC) 1383 1347 ret = dax_finish_sync_fault(vmf, order, pfn); 1384 - xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); 1348 + } else if (write_fault) { 1349 + ret = iomap_page_mkwrite(vmf, &xfs_page_mkwrite_iomap_ops); 1385 1350 } else { 1386 - if (write_fault) { 1387 - xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); 1388 - ret = iomap_page_mkwrite(vmf, 1389 - &xfs_page_mkwrite_iomap_ops); 1390 - xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); 1391 - } else { 1392 - ret = filemap_fault(vmf); 1393 - } 1351 + ret = filemap_fault(vmf); 1394 1352 } 1353 + 1354 + if (lock_mode) 1355 + xfs_iunlock(XFS_I(inode), lock_mode); 1395 1356 1396 1357 if (write_fault) 1397 1358 sb_end_pagefault(inode->i_sb);
+6 -9
fs/xfs/xfs_fsmap.c
··· 23 23 #include "xfs_refcount.h" 24 24 #include "xfs_refcount_btree.h" 25 25 #include "xfs_alloc_btree.h" 26 - #include "xfs_rtalloc.h" 26 + #include "xfs_rtbitmap.h" 27 27 #include "xfs_ag.h" 28 28 29 29 /* Convert an xfs_fsmap to an fsmap. */ ··· 483 483 xfs_rtblock_t rtbno; 484 484 xfs_daddr_t rec_daddr, len_daddr; 485 485 486 - rtbno = rec->ar_startext * mp->m_sb.sb_rextsize; 486 + rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); 487 487 rec_daddr = XFS_FSB_TO_BB(mp, rtbno); 488 488 irec.rm_startblock = rtbno; 489 489 490 - rtbno = rec->ar_extcount * mp->m_sb.sb_rextsize; 490 + rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount); 491 491 len_daddr = XFS_FSB_TO_BB(mp, rtbno); 492 492 irec.rm_blockcount = rtbno; 493 493 ··· 514 514 uint64_t eofs; 515 515 int error; 516 516 517 - eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rextents * mp->m_sb.sb_rextsize); 517 + eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents)); 518 518 if (keys[0].fmr_physical >= eofs) 519 519 return 0; 520 520 start_rtb = XFS_BB_TO_FSBT(mp, ··· 539 539 * Set up query parameters to return free rtextents covering the range 540 540 * we want. 541 541 */ 542 - alow.ar_startext = start_rtb; 543 - ahigh.ar_startext = end_rtb; 544 - do_div(alow.ar_startext, mp->m_sb.sb_rextsize); 545 - if (do_div(ahigh.ar_startext, mp->m_sb.sb_rextsize)) 546 - ahigh.ar_startext++; 542 + alow.ar_startext = xfs_rtb_to_rtx(mp, start_rtb); 543 + ahigh.ar_startext = xfs_rtb_to_rtxup(mp, end_rtb); 547 544 error = xfs_rtalloc_query_range(mp, tp, &alow, &ahigh, 548 545 xfs_getfsmap_rtdev_rtbitmap_helper, info); 549 546 if (error)
+24
fs/xfs/xfs_inode.c
··· 918 918 xfs_trans_t *tp, 919 919 xfs_inode_t *ip) 920 920 { 921 + if (VFS_I(ip)->i_nlink == 0) { 922 + xfs_alert(ip->i_mount, 923 + "%s: Attempt to drop inode (%llu) with nlink zero.", 924 + __func__, ip->i_ino); 925 + return -EFSCORRUPTED; 926 + } 927 + 921 928 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); 922 929 923 930 drop_nlink(VFS_I(ip)); ··· 3626 3619 inode_unlock(VFS_I(ip2)); 3627 3620 if (ip1 != ip2) 3628 3621 inode_unlock(VFS_I(ip1)); 3622 + } 3623 + 3624 + /* Drop the MMAPLOCK and the IOLOCK after a remap completes. */ 3625 + void 3626 + xfs_iunlock2_remapping( 3627 + struct xfs_inode *ip1, 3628 + struct xfs_inode *ip2) 3629 + { 3630 + xfs_iflags_clear(ip1, XFS_IREMAPPING); 3631 + 3632 + if (ip1 != ip2) 3633 + xfs_iunlock(ip1, XFS_MMAPLOCK_SHARED); 3634 + xfs_iunlock(ip2, XFS_MMAPLOCK_EXCL); 3635 + 3636 + if (ip1 != ip2) 3637 + inode_unlock_shared(VFS_I(ip1)); 3638 + inode_unlock(VFS_I(ip2)); 3629 3639 } 3630 3640 3631 3641 /*
+9
fs/xfs/xfs_inode.h
··· 347 347 /* Quotacheck is running but inode has not been added to quota counts. */ 348 348 #define XFS_IQUOTAUNCHECKED (1 << 14) 349 349 350 + /* 351 + * Remap in progress. Callers that wish to update file data while 352 + * holding a shared IOLOCK or MMAPLOCK must drop the lock and retake 353 + * the lock in exclusive mode. Relocking the file will block until 354 + * IREMAPPING is cleared. 355 + */ 356 + #define XFS_IREMAPPING (1U << 15) 357 + 350 358 /* All inode state flags related to inode reclaim. */ 351 359 #define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \ 352 360 XFS_IRECLAIM | \ ··· 603 595 604 596 int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); 605 597 void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); 598 + void xfs_iunlock2_remapping(struct xfs_inode *ip1, struct xfs_inode *ip2); 606 599 607 600 static inline bool 608 601 xfs_inode_unlinked_incomplete(
+2 -1
fs/xfs/xfs_inode_item.c
··· 19 19 #include "xfs_log.h" 20 20 #include "xfs_log_priv.h" 21 21 #include "xfs_error.h" 22 + #include "xfs_rtbitmap.h" 22 23 23 24 #include <linux/iversion.h> 24 25 ··· 108 107 */ 109 108 if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) && 110 109 (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) && 111 - (ip->i_extsize % ip->i_mount->m_sb.sb_rextsize) > 0) { 110 + xfs_extlen_to_rtxmod(ip->i_mount, ip->i_extsize) > 0) { 112 111 ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE | 113 112 XFS_DIFLAG_EXTSZINHERIT); 114 113 ip->i_extsize = 0;
+3 -2
fs/xfs/xfs_ioctl.c
··· 38 38 #include "xfs_reflink.h" 39 39 #include "xfs_ioctl.h" 40 40 #include "xfs_xattr.h" 41 + #include "xfs_rtbitmap.h" 41 42 42 43 #include <linux/mount.h> 43 44 #include <linux/namei.h> ··· 1005 1004 * later. 1006 1005 */ 1007 1006 if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) && 1008 - ip->i_extsize % mp->m_sb.sb_rextsize > 0) { 1007 + xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) { 1009 1008 fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | 1010 1009 FS_XFLAG_EXTSZINHERIT); 1011 1010 fa->fsx_extsize = 0; ··· 1131 1130 /* If realtime flag is set then must have realtime device */ 1132 1131 if (fa->fsx_xflags & FS_XFLAG_REALTIME) { 1133 1132 if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 || 1134 - (ip->i_extsize % mp->m_sb.sb_rextsize)) 1133 + xfs_extlen_to_rtxmod(mp, ip->i_extsize)) 1135 1134 return -EINVAL; 1136 1135 } 1137 1136
+12
fs/xfs/xfs_linux.h
··· 198 198 return x; 199 199 } 200 200 201 + /* If @b is a power of 2, return log2(b). Else return -1. */ 202 + static inline int8_t log2_if_power2(unsigned long b) 203 + { 204 + return is_power_of_2(b) ? ilog2(b) : -1; 205 + } 206 + 207 + /* If @b is a power of 2, return a mask of the lower bits, else return zero. */ 208 + static inline unsigned long long mask64_if_power2(unsigned long b) 209 + { 210 + return is_power_of_2(b) ? b - 1 : 0; 211 + } 212 + 201 213 int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count, 202 214 char *data, enum req_op op); 203 215
+5 -3
fs/xfs/xfs_mount.h
··· 101 101 102 102 /* 103 103 * Optional cache of rt summary level per bitmap block with the 104 - * invariant that m_rsum_cache[bbno] <= the minimum i for which 105 - * rsum[i][bbno] != 0. Reads and writes are serialized by the rsumip 106 - * inode lock. 104 + * invariant that m_rsum_cache[bbno] > the maximum i for which 105 + * rsum[i][bbno] != 0, or 0 if rsum[i][bbno] == 0 for all i. 106 + * Reads and writes are serialized by the rsumip inode lock. 107 107 */ 108 108 uint8_t *m_rsum_cache; 109 109 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ ··· 119 119 uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ 120 120 uint8_t m_agno_log; /* log #ag's */ 121 121 uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ 122 + int8_t m_rtxblklog; /* log2 of rextsize, if possible */ 122 123 uint m_blockmask; /* sb_blocksize-1 */ 123 124 uint m_blockwsize; /* sb_blocksize in words */ 124 125 uint m_blockwmask; /* blockwsize-1 */ ··· 153 152 uint64_t m_features; /* active filesystem features */ 154 153 uint64_t m_low_space[XFS_LOWSP_MAX]; 155 154 uint64_t m_low_rtexts[XFS_LOWSP_MAX]; 155 + uint64_t m_rtxblkmask; /* rt extent block mask */ 156 156 struct xfs_ino_geometry m_ino_geo; /* inode geometry */ 157 157 struct xfs_trans_resv m_resv; /* precomputed res values */ 158 158 /* low free space thresholds */
+4
fs/xfs/xfs_ondisk.h
··· 72 72 XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_map_t, 4); 73 73 XFS_CHECK_STRUCT_SIZE(xfs_attr_leaf_name_local_t, 4); 74 74 75 + /* realtime structures */ 76 + XFS_CHECK_STRUCT_SIZE(union xfs_rtword_raw, 4); 77 + XFS_CHECK_STRUCT_SIZE(union xfs_suminfo_raw, 4); 78 + 75 79 /* 76 80 * m68k has problems with xfs_attr_leaf_name_remote_t, but we pad it to 77 81 * 4 bytes anyway so it's not obviously a problem. Hence for the moment
+4
fs/xfs/xfs_reflink.c
··· 1540 1540 if (ret) 1541 1541 goto out_unlock; 1542 1542 1543 + xfs_iflags_set(src, XFS_IREMAPPING); 1544 + if (inode_in != inode_out) 1545 + xfs_ilock_demote(src, XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL); 1546 + 1543 1547 return 0; 1544 1548 out_unlock: 1545 1549 xfs_iunlock2_io_mmap(src, dest);
+312 -318
fs/xfs/xfs_rtalloc.c
··· 19 19 #include "xfs_icache.h" 20 20 #include "xfs_rtalloc.h" 21 21 #include "xfs_sb.h" 22 + #include "xfs_rtbitmap.h" 22 23 23 24 /* 24 25 * Read and return the summary information for a given extent size, ··· 29 28 */ 30 29 static int 31 30 xfs_rtget_summary( 32 - xfs_mount_t *mp, /* file system mount structure */ 33 - xfs_trans_t *tp, /* transaction pointer */ 34 - int log, /* log2 of extent size */ 35 - xfs_rtblock_t bbno, /* bitmap block number */ 36 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 37 - xfs_fsblock_t *rsb, /* in/out: summary block number */ 38 - xfs_suminfo_t *sum) /* out: summary info for this block */ 31 + struct xfs_rtalloc_args *args, 32 + int log, /* log2 of extent size */ 33 + xfs_fileoff_t bbno, /* bitmap block number */ 34 + xfs_suminfo_t *sum) /* out: summary info for this block */ 39 35 { 40 - return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum); 36 + return xfs_rtmodify_summary_int(args, log, bbno, 0, sum); 41 37 } 42 38 43 39 /* 44 40 * Return whether there are any free extents in the size range given 45 41 * by low and high, for the bitmap block bbno. 46 42 */ 47 - STATIC int /* error */ 43 + STATIC int 48 44 xfs_rtany_summary( 49 - xfs_mount_t *mp, /* file system mount structure */ 50 - xfs_trans_t *tp, /* transaction pointer */ 51 - int low, /* low log2 extent size */ 52 - int high, /* high log2 extent size */ 53 - xfs_rtblock_t bbno, /* bitmap block number */ 54 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 55 - xfs_fsblock_t *rsb, /* in/out: summary block number */ 56 - int *stat) /* out: any good extents here? */ 45 + struct xfs_rtalloc_args *args, 46 + int low, /* low log2 extent size */ 47 + int high, /* high log2 extent size */ 48 + xfs_fileoff_t bbno, /* bitmap block number */ 49 + int *maxlog) /* out: max log2 extent size free */ 57 50 { 58 - int error; /* error value */ 59 - int log; /* loop counter, log2 of ext. size */ 60 - xfs_suminfo_t sum; /* summary data */ 51 + struct xfs_mount *mp = args->mp; 52 + int error; 53 + int log; /* loop counter, log2 of ext. size */ 54 + xfs_suminfo_t sum; /* summary data */ 61 55 62 - /* There are no extents at levels < m_rsum_cache[bbno]. */ 63 - if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno]) 64 - low = mp->m_rsum_cache[bbno]; 56 + /* There are no extents at levels >= m_rsum_cache[bbno]. */ 57 + if (mp->m_rsum_cache) { 58 + high = min(high, mp->m_rsum_cache[bbno] - 1); 59 + if (low > high) { 60 + *maxlog = -1; 61 + return 0; 62 + } 63 + } 65 64 66 65 /* 67 66 * Loop over logs of extent sizes. 68 67 */ 69 - for (log = low; log <= high; log++) { 68 + for (log = high; log >= low; log--) { 70 69 /* 71 70 * Get one summary datum. 72 71 */ 73 - error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum); 72 + error = xfs_rtget_summary(args, log, bbno, &sum); 74 73 if (error) { 75 74 return error; 76 75 } ··· 78 77 * If there are any, return success. 79 78 */ 80 79 if (sum) { 81 - *stat = 1; 80 + *maxlog = log; 82 81 goto out; 83 82 } 84 83 } 85 84 /* 86 85 * Found nothing, return failure. 87 86 */ 88 - *stat = 0; 87 + *maxlog = -1; 89 88 out: 90 - /* There were no extents at levels < log. */ 91 - if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno]) 92 - mp->m_rsum_cache[bbno] = log; 89 + /* There were no extents at levels > log. */ 90 + if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno]) 91 + mp->m_rsum_cache[bbno] = log + 1; 93 92 return 0; 94 93 } 95 94 ··· 98 97 * Copy and transform the summary file, given the old and new 99 98 * parameters in the mount structures. 100 99 */ 101 - STATIC int /* error */ 100 + STATIC int 102 101 xfs_rtcopy_summary( 103 - xfs_mount_t *omp, /* old file system mount point */ 104 - xfs_mount_t *nmp, /* new file system mount point */ 105 - xfs_trans_t *tp) /* transaction pointer */ 102 + struct xfs_rtalloc_args *oargs, 103 + struct xfs_rtalloc_args *nargs) 106 104 { 107 - xfs_rtblock_t bbno; /* bitmap block number */ 108 - struct xfs_buf *bp; /* summary buffer */ 109 - int error; /* error return value */ 110 - int log; /* summary level number (log length) */ 111 - xfs_suminfo_t sum; /* summary data */ 112 - xfs_fsblock_t sumbno; /* summary block number */ 105 + xfs_fileoff_t bbno; /* bitmap block number */ 106 + int error; 107 + int log; /* summary level number (log length) */ 108 + xfs_suminfo_t sum; /* summary data */ 113 109 114 - bp = NULL; 115 - for (log = omp->m_rsumlevels - 1; log >= 0; log--) { 116 - for (bbno = omp->m_sb.sb_rbmblocks - 1; 110 + for (log = oargs->mp->m_rsumlevels - 1; log >= 0; log--) { 111 + for (bbno = oargs->mp->m_sb.sb_rbmblocks - 1; 117 112 (xfs_srtblock_t)bbno >= 0; 118 113 bbno--) { 119 - error = xfs_rtget_summary(omp, tp, log, bbno, &bp, 120 - &sumbno, &sum); 114 + error = xfs_rtget_summary(oargs, log, bbno, &sum); 121 115 if (error) 122 - return error; 116 + goto out; 123 117 if (sum == 0) 124 118 continue; 125 - error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum, 126 - &bp, &sumbno); 119 + error = xfs_rtmodify_summary(oargs, log, bbno, -sum); 127 120 if (error) 128 - return error; 129 - error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum, 130 - &bp, &sumbno); 121 + goto out; 122 + error = xfs_rtmodify_summary(nargs, log, bbno, sum); 131 123 if (error) 132 - return error; 124 + goto out; 133 125 ASSERT(sum > 0); 134 126 } 135 127 } 128 + error = 0; 129 + out: 130 + xfs_rtbuf_cache_relse(oargs); 136 131 return 0; 137 132 } 138 133 /* 139 134 * Mark an extent specified by start and len allocated. 140 135 * Updates all the summary information as well as the bitmap. 141 136 */ 142 - STATIC int /* error */ 137 + STATIC int 143 138 xfs_rtallocate_range( 144 - xfs_mount_t *mp, /* file system mount point */ 145 - xfs_trans_t *tp, /* transaction pointer */ 146 - xfs_rtblock_t start, /* start block to allocate */ 147 - xfs_extlen_t len, /* length to allocate */ 148 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 149 - xfs_fsblock_t *rsb) /* in/out: summary block number */ 139 + struct xfs_rtalloc_args *args, 140 + xfs_rtxnum_t start, /* start rtext to allocate */ 141 + xfs_rtxlen_t len) /* in/out: summary block number */ 150 142 { 151 - xfs_rtblock_t end; /* end of the allocated extent */ 152 - int error; /* error value */ 153 - xfs_rtblock_t postblock = 0; /* first block allocated > end */ 154 - xfs_rtblock_t preblock = 0; /* first block allocated < start */ 143 + struct xfs_mount *mp = args->mp; 144 + xfs_rtxnum_t end; /* end of the allocated rtext */ 145 + int error; 146 + xfs_rtxnum_t postblock = 0; /* first rtext allocated > end */ 147 + xfs_rtxnum_t preblock = 0; /* first rtext allocated < start */ 155 148 156 149 end = start + len - 1; 157 150 /* ··· 153 158 * We need to find the beginning and end of the extent so we can 154 159 * properly update the summary. 155 160 */ 156 - error = xfs_rtfind_back(mp, tp, start, 0, &preblock); 161 + error = xfs_rtfind_back(args, start, 0, &preblock); 157 162 if (error) { 158 163 return error; 159 164 } 160 165 /* 161 166 * Find the next allocated block (end of free extent). 162 167 */ 163 - error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, 164 - &postblock); 168 + error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1, 169 + &postblock); 165 170 if (error) { 166 171 return error; 167 172 } ··· 169 174 * Decrement the summary information corresponding to the entire 170 175 * (old) free extent. 171 176 */ 172 - error = xfs_rtmodify_summary(mp, tp, 173 - XFS_RTBLOCKLOG(postblock + 1 - preblock), 174 - XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); 177 + error = xfs_rtmodify_summary(args, 178 + XFS_RTBLOCKLOG(postblock + 1 - preblock), 179 + xfs_rtx_to_rbmblock(mp, preblock), -1); 175 180 if (error) { 176 181 return error; 177 182 } ··· 180 185 * old extent, add summary data for them to be free. 181 186 */ 182 187 if (preblock < start) { 183 - error = xfs_rtmodify_summary(mp, tp, 184 - XFS_RTBLOCKLOG(start - preblock), 185 - XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); 188 + error = xfs_rtmodify_summary(args, 189 + XFS_RTBLOCKLOG(start - preblock), 190 + xfs_rtx_to_rbmblock(mp, preblock), 1); 186 191 if (error) { 187 192 return error; 188 193 } ··· 192 197 * old extent, add summary data for them to be free. 193 198 */ 194 199 if (postblock > end) { 195 - error = xfs_rtmodify_summary(mp, tp, 196 - XFS_RTBLOCKLOG(postblock - end), 197 - XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb); 200 + error = xfs_rtmodify_summary(args, 201 + XFS_RTBLOCKLOG(postblock - end), 202 + xfs_rtx_to_rbmblock(mp, end + 1), 1); 198 203 if (error) { 199 204 return error; 200 205 } ··· 202 207 /* 203 208 * Modify the bitmap to mark this extent allocated. 204 209 */ 205 - error = xfs_rtmodify_range(mp, tp, start, len, 0); 210 + error = xfs_rtmodify_range(args, start, len, 0); 206 211 return error; 212 + } 213 + 214 + /* 215 + * Make sure we don't run off the end of the rt volume. Be careful that 216 + * adjusting maxlen downwards doesn't cause us to fail the alignment checks. 217 + */ 218 + static inline xfs_rtxlen_t 219 + xfs_rtallocate_clamp_len( 220 + struct xfs_mount *mp, 221 + xfs_rtxnum_t startrtx, 222 + xfs_rtxlen_t rtxlen, 223 + xfs_rtxlen_t prod) 224 + { 225 + xfs_rtxlen_t ret; 226 + 227 + ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx; 228 + return rounddown(ret, prod); 207 229 } 208 230 209 231 /* 210 232 * Attempt to allocate an extent minlen<=len<=maxlen starting from 211 233 * bitmap block bbno. If we don't get maxlen then use prod to trim 212 - * the length, if given. Returns error; returns starting block in *rtblock. 234 + * the length, if given. Returns error; returns starting block in *rtx. 213 235 * The lengths are all in rtextents. 214 236 */ 215 - STATIC int /* error */ 237 + STATIC int 216 238 xfs_rtallocate_extent_block( 217 - xfs_mount_t *mp, /* file system mount point */ 218 - xfs_trans_t *tp, /* transaction pointer */ 219 - xfs_rtblock_t bbno, /* bitmap block number */ 220 - xfs_extlen_t minlen, /* minimum length to allocate */ 221 - xfs_extlen_t maxlen, /* maximum length to allocate */ 222 - xfs_extlen_t *len, /* out: actual length allocated */ 223 - xfs_rtblock_t *nextp, /* out: next block to try */ 224 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 225 - xfs_fsblock_t *rsb, /* in/out: summary block number */ 226 - xfs_extlen_t prod, /* extent product factor */ 227 - xfs_rtblock_t *rtblock) /* out: start block allocated */ 239 + struct xfs_rtalloc_args *args, 240 + xfs_fileoff_t bbno, /* bitmap block number */ 241 + xfs_rtxlen_t minlen, /* minimum length to allocate */ 242 + xfs_rtxlen_t maxlen, /* maximum length to allocate */ 243 + xfs_rtxlen_t *len, /* out: actual length allocated */ 244 + xfs_rtxnum_t *nextp, /* out: next rtext to try */ 245 + xfs_rtxlen_t prod, /* extent product factor */ 246 + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ 228 247 { 229 - xfs_rtblock_t besti; /* best rtblock found so far */ 230 - xfs_rtblock_t bestlen; /* best length found so far */ 231 - xfs_rtblock_t end; /* last rtblock in chunk */ 232 - int error; /* error value */ 233 - xfs_rtblock_t i; /* current rtblock trying */ 234 - xfs_rtblock_t next; /* next rtblock to try */ 235 - int stat; /* status from internal calls */ 248 + struct xfs_mount *mp = args->mp; 249 + xfs_rtxnum_t besti; /* best rtext found so far */ 250 + xfs_rtxnum_t bestlen;/* best length found so far */ 251 + xfs_rtxnum_t end; /* last rtext in chunk */ 252 + int error; 253 + xfs_rtxnum_t i; /* current rtext trying */ 254 + xfs_rtxnum_t next; /* next rtext to try */ 255 + int stat; /* status from internal calls */ 236 256 237 257 /* 238 258 * Loop over all the extents starting in this bitmap block, 239 259 * looking for one that's long enough. 240 260 */ 241 - for (i = XFS_BLOCKTOBIT(mp, bbno), besti = -1, bestlen = 0, 242 - end = XFS_BLOCKTOBIT(mp, bbno + 1) - 1; 261 + for (i = xfs_rbmblock_to_rtx(mp, bbno), besti = -1, bestlen = 0, 262 + end = xfs_rbmblock_to_rtx(mp, bbno + 1) - 1; 243 263 i <= end; 244 264 i++) { 245 265 /* Make sure we don't scan off the end of the rt volume. */ 246 - maxlen = min(mp->m_sb.sb_rextents, i + maxlen) - i; 266 + maxlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod); 247 267 248 268 /* 249 269 * See if there's a free extent of maxlen starting at i. 250 270 * If it's not so then next will contain the first non-free. 251 271 */ 252 - error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, &next, &stat); 272 + error = xfs_rtcheck_range(args, i, maxlen, 1, &next, &stat); 253 273 if (error) { 254 274 return error; 255 275 } ··· 272 262 /* 273 263 * i for maxlen is all free, allocate and return that. 274 264 */ 275 - error = xfs_rtallocate_range(mp, tp, i, maxlen, rbpp, 276 - rsb); 265 + error = xfs_rtallocate_range(args, i, maxlen); 277 266 if (error) { 278 267 return error; 279 268 } 280 269 *len = maxlen; 281 - *rtblock = i; 270 + *rtx = i; 282 271 return 0; 283 272 } 284 273 /* ··· 287 278 * so far, remember it. 288 279 */ 289 280 if (minlen < maxlen) { 290 - xfs_rtblock_t thislen; /* this extent size */ 281 + xfs_rtxnum_t thislen; /* this extent size */ 291 282 292 283 thislen = next - i; 293 284 if (thislen >= minlen && thislen > bestlen) { ··· 299 290 * If not done yet, find the start of the next free space. 300 291 */ 301 292 if (next < end) { 302 - error = xfs_rtfind_forw(mp, tp, next, end, &i); 293 + error = xfs_rtfind_forw(args, next, end, &i); 303 294 if (error) { 304 295 return error; 305 296 } ··· 310 301 * Searched the whole thing & didn't find a maxlen free extent. 311 302 */ 312 303 if (minlen < maxlen && besti != -1) { 313 - xfs_extlen_t p; /* amount to trim length by */ 304 + xfs_rtxlen_t p; /* amount to trim length by */ 314 305 315 306 /* 316 307 * If size should be a multiple of prod, make that so. ··· 324 315 /* 325 316 * Allocate besti for bestlen & return that. 326 317 */ 327 - error = xfs_rtallocate_range(mp, tp, besti, bestlen, rbpp, rsb); 318 + error = xfs_rtallocate_range(args, besti, bestlen); 328 319 if (error) { 329 320 return error; 330 321 } 331 322 *len = bestlen; 332 - *rtblock = besti; 323 + *rtx = besti; 333 324 return 0; 334 325 } 335 326 /* 336 327 * Allocation failed. Set *nextp to the next block to try. 337 328 */ 338 329 *nextp = next; 339 - *rtblock = NULLRTBLOCK; 330 + *rtx = NULLRTEXTNO; 340 331 return 0; 341 332 } 342 333 343 334 /* 344 335 * Allocate an extent of length minlen<=len<=maxlen, starting at block 345 336 * bno. If we don't get maxlen then use prod to trim the length, if given. 346 - * Returns error; returns starting block in *rtblock. 337 + * Returns error; returns starting block in *rtx. 347 338 * The lengths are all in rtextents. 348 339 */ 349 - STATIC int /* error */ 340 + STATIC int 350 341 xfs_rtallocate_extent_exact( 351 - xfs_mount_t *mp, /* file system mount point */ 352 - xfs_trans_t *tp, /* transaction pointer */ 353 - xfs_rtblock_t bno, /* starting block number to allocate */ 354 - xfs_extlen_t minlen, /* minimum length to allocate */ 355 - xfs_extlen_t maxlen, /* maximum length to allocate */ 356 - xfs_extlen_t *len, /* out: actual length allocated */ 357 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 358 - xfs_fsblock_t *rsb, /* in/out: summary block number */ 359 - xfs_extlen_t prod, /* extent product factor */ 360 - xfs_rtblock_t *rtblock) /* out: start block allocated */ 342 + struct xfs_rtalloc_args *args, 343 + xfs_rtxnum_t start, /* starting rtext number to allocate */ 344 + xfs_rtxlen_t minlen, /* minimum length to allocate */ 345 + xfs_rtxlen_t maxlen, /* maximum length to allocate */ 346 + xfs_rtxlen_t *len, /* out: actual length allocated */ 347 + xfs_rtxlen_t prod, /* extent product factor */ 348 + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ 361 349 { 362 - int error; /* error value */ 363 - xfs_extlen_t i; /* extent length trimmed due to prod */ 364 - int isfree; /* extent is free */ 365 - xfs_rtblock_t next; /* next block to try (dummy) */ 350 + int error; 351 + xfs_rtxlen_t i; /* extent length trimmed due to prod */ 352 + int isfree; /* extent is free */ 353 + xfs_rtxnum_t next; /* next rtext to try (dummy) */ 366 354 367 - ASSERT(minlen % prod == 0 && maxlen % prod == 0); 355 + ASSERT(minlen % prod == 0); 356 + ASSERT(maxlen % prod == 0); 368 357 /* 369 358 * Check if the range in question (for maxlen) is free. 370 359 */ 371 - error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, &next, &isfree); 360 + error = xfs_rtcheck_range(args, start, maxlen, 1, &next, &isfree); 372 361 if (error) { 373 362 return error; 374 363 } ··· 374 367 /* 375 368 * If it is, allocate it and return success. 376 369 */ 377 - error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb); 370 + error = xfs_rtallocate_range(args, start, maxlen); 378 371 if (error) { 379 372 return error; 380 373 } 381 374 *len = maxlen; 382 - *rtblock = bno; 375 + *rtx = start; 383 376 return 0; 384 377 } 385 378 /* 386 379 * If not, allocate what there is, if it's at least minlen. 387 380 */ 388 - maxlen = next - bno; 381 + maxlen = next - start; 389 382 if (maxlen < minlen) { 390 383 /* 391 384 * Failed, return failure status. 392 385 */ 393 - *rtblock = NULLRTBLOCK; 386 + *rtx = NULLRTEXTNO; 394 387 return 0; 395 388 } 396 389 /* ··· 402 395 /* 403 396 * Now we can't do it, return failure status. 404 397 */ 405 - *rtblock = NULLRTBLOCK; 398 + *rtx = NULLRTEXTNO; 406 399 return 0; 407 400 } 408 401 } 409 402 /* 410 403 * Allocate what we can and return it. 411 404 */ 412 - error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb); 405 + error = xfs_rtallocate_range(args, start, maxlen); 413 406 if (error) { 414 407 return error; 415 408 } 416 409 *len = maxlen; 417 - *rtblock = bno; 410 + *rtx = start; 418 411 return 0; 419 412 } 420 413 421 414 /* 422 415 * Allocate an extent of length minlen<=len<=maxlen, starting as near 423 - * to bno as possible. If we don't get maxlen then use prod to trim 416 + * to start as possible. If we don't get maxlen then use prod to trim 424 417 * the length, if given. The lengths are all in rtextents. 425 418 */ 426 - STATIC int /* error */ 419 + STATIC int 427 420 xfs_rtallocate_extent_near( 428 - xfs_mount_t *mp, /* file system mount point */ 429 - xfs_trans_t *tp, /* transaction pointer */ 430 - xfs_rtblock_t bno, /* starting block number to allocate */ 431 - xfs_extlen_t minlen, /* minimum length to allocate */ 432 - xfs_extlen_t maxlen, /* maximum length to allocate */ 433 - xfs_extlen_t *len, /* out: actual length allocated */ 434 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 435 - xfs_fsblock_t *rsb, /* in/out: summary block number */ 436 - xfs_extlen_t prod, /* extent product factor */ 437 - xfs_rtblock_t *rtblock) /* out: start block allocated */ 421 + struct xfs_rtalloc_args *args, 422 + xfs_rtxnum_t start, /* starting rtext number to allocate */ 423 + xfs_rtxlen_t minlen, /* minimum length to allocate */ 424 + xfs_rtxlen_t maxlen, /* maximum length to allocate */ 425 + xfs_rtxlen_t *len, /* out: actual length allocated */ 426 + xfs_rtxlen_t prod, /* extent product factor */ 427 + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ 438 428 { 439 - int any; /* any useful extents from summary */ 440 - xfs_rtblock_t bbno; /* bitmap block number */ 441 - int error; /* error value */ 442 - int i; /* bitmap block offset (loop control) */ 443 - int j; /* secondary loop control */ 444 - int log2len; /* log2 of minlen */ 445 - xfs_rtblock_t n; /* next block to try */ 446 - xfs_rtblock_t r; /* result block */ 429 + struct xfs_mount *mp = args->mp; 430 + int maxlog; /* max useful extent from summary */ 431 + xfs_fileoff_t bbno; /* bitmap block number */ 432 + int error; 433 + int i; /* bitmap block offset (loop control) */ 434 + int j; /* secondary loop control */ 435 + int log2len; /* log2 of minlen */ 436 + xfs_rtxnum_t n; /* next rtext to try */ 437 + xfs_rtxnum_t r; /* result rtext */ 447 438 448 - ASSERT(minlen % prod == 0 && maxlen % prod == 0); 439 + ASSERT(minlen % prod == 0); 440 + ASSERT(maxlen % prod == 0); 441 + 449 442 /* 450 443 * If the block number given is off the end, silently set it to 451 444 * the last block. 452 445 */ 453 - if (bno >= mp->m_sb.sb_rextents) 454 - bno = mp->m_sb.sb_rextents - 1; 446 + if (start >= mp->m_sb.sb_rextents) 447 + start = mp->m_sb.sb_rextents - 1; 455 448 456 449 /* Make sure we don't run off the end of the rt volume. */ 457 - maxlen = min(mp->m_sb.sb_rextents, bno + maxlen) - bno; 450 + maxlen = xfs_rtallocate_clamp_len(mp, start, maxlen, prod); 458 451 if (maxlen < minlen) { 459 - *rtblock = NULLRTBLOCK; 452 + *rtx = NULLRTEXTNO; 460 453 return 0; 461 454 } 462 455 463 456 /* 464 457 * Try the exact allocation first. 465 458 */ 466 - error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, len, 467 - rbpp, rsb, prod, &r); 459 + error = xfs_rtallocate_extent_exact(args, start, minlen, maxlen, len, 460 + prod, &r); 468 461 if (error) { 469 462 return error; 470 463 } 471 464 /* 472 465 * If the exact allocation worked, return that. 473 466 */ 474 - if (r != NULLRTBLOCK) { 475 - *rtblock = r; 467 + if (r != NULLRTEXTNO) { 468 + *rtx = r; 476 469 return 0; 477 470 } 478 - bbno = XFS_BITTOBLOCK(mp, bno); 471 + bbno = xfs_rtx_to_rbmblock(mp, start); 479 472 i = 0; 473 + j = -1; 480 474 ASSERT(minlen != 0); 481 475 log2len = xfs_highbit32(minlen); 482 476 /* ··· 488 480 * Get summary information of extents of all useful levels 489 481 * starting in this bitmap block. 490 482 */ 491 - error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1, 492 - bbno + i, rbpp, rsb, &any); 483 + error = xfs_rtany_summary(args, log2len, mp->m_rsumlevels - 1, 484 + bbno + i, &maxlog); 493 485 if (error) { 494 486 return error; 495 487 } ··· 497 489 * If there are any useful extents starting here, try 498 490 * allocating one. 499 491 */ 500 - if (any) { 492 + if (maxlog >= 0) { 493 + xfs_extlen_t maxavail = 494 + min_t(xfs_rtblock_t, maxlen, 495 + (1ULL << (maxlog + 1)) - 1); 501 496 /* 502 497 * On the positive side of the starting location. 503 498 */ ··· 509 498 * Try to allocate an extent starting in 510 499 * this block. 511 500 */ 512 - error = xfs_rtallocate_extent_block(mp, tp, 513 - bbno + i, minlen, maxlen, len, &n, rbpp, 514 - rsb, prod, &r); 501 + error = xfs_rtallocate_extent_block(args, 502 + bbno + i, minlen, maxavail, len, 503 + &n, prod, &r); 515 504 if (error) { 516 505 return error; 517 506 } 518 507 /* 519 508 * If it worked, return it. 520 509 */ 521 - if (r != NULLRTBLOCK) { 522 - *rtblock = r; 510 + if (r != NULLRTEXTNO) { 511 + *rtx = r; 523 512 return 0; 524 513 } 525 514 } ··· 527 516 * On the negative side of the starting location. 528 517 */ 529 518 else { /* i < 0 */ 519 + int maxblocks; 520 + 530 521 /* 531 - * Loop backwards through the bitmap blocks from 532 - * the starting point-1 up to where we are now. 533 - * There should be an extent which ends in this 534 - * bitmap block and is long enough. 522 + * Loop backwards to find the end of the extent 523 + * we found in the realtime summary. 524 + * 525 + * maxblocks is the maximum possible number of 526 + * bitmap blocks from the start of the extent 527 + * to the end of the extent. 535 528 */ 536 - for (j = -1; j > i; j--) { 537 - /* 538 - * Grab the summary information for 539 - * this bitmap block. 540 - */ 541 - error = xfs_rtany_summary(mp, tp, 542 - log2len, mp->m_rsumlevels - 1, 543 - bbno + j, rbpp, rsb, &any); 544 - if (error) { 545 - return error; 546 - } 547 - /* 548 - * If there's no extent given in the 549 - * summary that means the extent we 550 - * found must carry over from an 551 - * earlier block. If there is an 552 - * extent given, we've already tried 553 - * that allocation, don't do it again. 554 - */ 555 - if (any) 556 - continue; 557 - error = xfs_rtallocate_extent_block(mp, 558 - tp, bbno + j, minlen, maxlen, 559 - len, &n, rbpp, rsb, prod, &r); 529 + if (maxlog == 0) 530 + maxblocks = 0; 531 + else if (maxlog < mp->m_blkbit_log) 532 + maxblocks = 1; 533 + else 534 + maxblocks = 2 << (maxlog - mp->m_blkbit_log); 535 + 536 + /* 537 + * We need to check bbno + i + maxblocks down to 538 + * bbno + i. We already checked bbno down to 539 + * bbno + j + 1, so we don't need to check those 540 + * again. 541 + */ 542 + j = min(i + maxblocks, j); 543 + for (; j >= i; j--) { 544 + error = xfs_rtallocate_extent_block(args, 545 + bbno + j, minlen, 546 + maxavail, len, &n, prod, 547 + &r); 560 548 if (error) { 561 549 return error; 562 550 } 563 551 /* 564 552 * If it works, return the extent. 565 553 */ 566 - if (r != NULLRTBLOCK) { 567 - *rtblock = r; 554 + if (r != NULLRTEXTNO) { 555 + *rtx = r; 568 556 return 0; 569 557 } 570 - } 571 - /* 572 - * There weren't intervening bitmap blocks 573 - * with a long enough extent, or the 574 - * allocation didn't work for some reason 575 - * (i.e. it's a little * too short). 576 - * Try to allocate from the summary block 577 - * that we found. 578 - */ 579 - error = xfs_rtallocate_extent_block(mp, tp, 580 - bbno + i, minlen, maxlen, len, &n, rbpp, 581 - rsb, prod, &r); 582 - if (error) { 583 - return error; 584 - } 585 - /* 586 - * If it works, return the extent. 587 - */ 588 - if (r != NULLRTBLOCK) { 589 - *rtblock = r; 590 - return 0; 591 558 } 592 559 } 593 560 } ··· 599 610 else 600 611 break; 601 612 } 602 - *rtblock = NULLRTBLOCK; 613 + *rtx = NULLRTEXTNO; 603 614 return 0; 604 615 } 605 616 ··· 608 619 * specified. If we don't get maxlen then use prod to trim 609 620 * the length, if given. The lengths are all in rtextents. 610 621 */ 611 - STATIC int /* error */ 622 + STATIC int 612 623 xfs_rtallocate_extent_size( 613 - xfs_mount_t *mp, /* file system mount point */ 614 - xfs_trans_t *tp, /* transaction pointer */ 615 - xfs_extlen_t minlen, /* minimum length to allocate */ 616 - xfs_extlen_t maxlen, /* maximum length to allocate */ 617 - xfs_extlen_t *len, /* out: actual length allocated */ 618 - struct xfs_buf **rbpp, /* in/out: summary block buffer */ 619 - xfs_fsblock_t *rsb, /* in/out: summary block number */ 620 - xfs_extlen_t prod, /* extent product factor */ 621 - xfs_rtblock_t *rtblock) /* out: start block allocated */ 624 + struct xfs_rtalloc_args *args, 625 + xfs_rtxlen_t minlen, /* minimum length to allocate */ 626 + xfs_rtxlen_t maxlen, /* maximum length to allocate */ 627 + xfs_rtxlen_t *len, /* out: actual length allocated */ 628 + xfs_rtxlen_t prod, /* extent product factor */ 629 + xfs_rtxnum_t *rtx) /* out: start rtext allocated */ 622 630 { 623 - int error; /* error value */ 624 - int i; /* bitmap block number */ 625 - int l; /* level number (loop control) */ 626 - xfs_rtblock_t n; /* next block to be tried */ 627 - xfs_rtblock_t r; /* result block number */ 628 - xfs_suminfo_t sum; /* summary information for extents */ 631 + struct xfs_mount *mp = args->mp; 632 + int error; 633 + xfs_fileoff_t i; /* bitmap block number */ 634 + int l; /* level number (loop control) */ 635 + xfs_rtxnum_t n; /* next rtext to be tried */ 636 + xfs_rtxnum_t r; /* result rtext number */ 637 + xfs_suminfo_t sum; /* summary information for extents */ 629 638 630 - ASSERT(minlen % prod == 0 && maxlen % prod == 0); 639 + ASSERT(minlen % prod == 0); 640 + ASSERT(maxlen % prod == 0); 631 641 ASSERT(maxlen != 0); 632 642 633 643 /* ··· 644 656 /* 645 657 * Get the summary for this level/block. 646 658 */ 647 - error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb, 648 - &sum); 659 + error = xfs_rtget_summary(args, l, i, &sum); 649 660 if (error) { 650 661 return error; 651 662 } ··· 656 669 /* 657 670 * Try allocating the extent. 658 671 */ 659 - error = xfs_rtallocate_extent_block(mp, tp, i, maxlen, 660 - maxlen, len, &n, rbpp, rsb, prod, &r); 672 + error = xfs_rtallocate_extent_block(args, i, maxlen, 673 + maxlen, len, &n, prod, &r); 661 674 if (error) { 662 675 return error; 663 676 } 664 677 /* 665 678 * If it worked, return that. 666 679 */ 667 - if (r != NULLRTBLOCK) { 668 - *rtblock = r; 680 + if (r != NULLRTEXTNO) { 681 + *rtx = r; 669 682 return 0; 670 683 } 671 684 /* ··· 673 686 * allocator is beyond the next bitmap block, 674 687 * skip to that bitmap block. 675 688 */ 676 - if (XFS_BITTOBLOCK(mp, n) > i + 1) 677 - i = XFS_BITTOBLOCK(mp, n) - 1; 689 + if (xfs_rtx_to_rbmblock(mp, n) > i + 1) 690 + i = xfs_rtx_to_rbmblock(mp, n) - 1; 678 691 } 679 692 } 680 693 /* ··· 682 695 * we're asking for a fixed size extent. 683 696 */ 684 697 if (minlen > --maxlen) { 685 - *rtblock = NULLRTBLOCK; 698 + *rtx = NULLRTEXTNO; 686 699 return 0; 687 700 } 688 701 ASSERT(minlen != 0); ··· 702 715 /* 703 716 * Get the summary information for this level/block. 704 717 */ 705 - error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb, 706 - &sum); 718 + error = xfs_rtget_summary(args, l, i, &sum); 707 719 if (error) { 708 720 return error; 709 721 } ··· 716 730 * minlen/maxlen are in the possible range for 717 731 * this summary level. 718 732 */ 719 - error = xfs_rtallocate_extent_block(mp, tp, i, 733 + error = xfs_rtallocate_extent_block(args, i, 720 734 XFS_RTMAX(minlen, 1 << l), 721 735 XFS_RTMIN(maxlen, (1 << (l + 1)) - 1), 722 - len, &n, rbpp, rsb, prod, &r); 736 + len, &n, prod, &r); 723 737 if (error) { 724 738 return error; 725 739 } 726 740 /* 727 741 * If it worked, return that extent. 728 742 */ 729 - if (r != NULLRTBLOCK) { 730 - *rtblock = r; 743 + if (r != NULLRTEXTNO) { 744 + *rtx = r; 731 745 return 0; 732 746 } 733 747 /* ··· 735 749 * allocator is beyond the next bitmap block, 736 750 * skip to that bitmap block. 737 751 */ 738 - if (XFS_BITTOBLOCK(mp, n) > i + 1) 739 - i = XFS_BITTOBLOCK(mp, n) - 1; 752 + if (xfs_rtx_to_rbmblock(mp, n) > i + 1) 753 + i = xfs_rtx_to_rbmblock(mp, n) - 1; 740 754 } 741 755 } 742 756 /* 743 757 * Got nothing, return failure. 744 758 */ 745 - *rtblock = NULLRTBLOCK; 759 + *rtx = NULLRTEXTNO; 746 760 return 0; 747 761 } 748 762 ··· 872 886 xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */ 873 887 { 874 888 /* 875 - * The rsum cache is initialized to all zeroes, which is trivially a 876 - * lower bound on the minimum level with any free extents. We can 877 - * continue without the cache if it couldn't be allocated. 889 + * The rsum cache is initialized to the maximum value, which is 890 + * trivially an upper bound on the maximum level with any free extents. 891 + * We can continue without the cache if it couldn't be allocated. 878 892 */ 879 - mp->m_rsum_cache = kvzalloc(rbmblocks, GFP_KERNEL); 880 - if (!mp->m_rsum_cache) 893 + mp->m_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL); 894 + if (mp->m_rsum_cache) 895 + memset(mp->m_rsum_cache, -1, rbmblocks); 896 + else 881 897 xfs_warn(mp, "could not allocate realtime summary cache"); 882 898 } 883 899 ··· 895 907 xfs_mount_t *mp, /* mount point for filesystem */ 896 908 xfs_growfs_rt_t *in) /* growfs rt input struct */ 897 909 { 898 - xfs_rtblock_t bmbno; /* bitmap block number */ 910 + xfs_fileoff_t bmbno; /* bitmap block number */ 899 911 struct xfs_buf *bp; /* temporary buffer */ 900 912 int error; /* error return value */ 901 913 xfs_mount_t *nmp; /* new (fake) mount structure */ 902 914 xfs_rfsblock_t nrblocks; /* new number of realtime blocks */ 903 915 xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */ 904 - xfs_rtblock_t nrextents; /* new number of realtime extents */ 916 + xfs_rtxnum_t nrextents; /* new number of realtime extents */ 905 917 uint8_t nrextslog; /* new log2 of sb_rextents */ 906 918 xfs_extlen_t nrsumblocks; /* new number of summary blocks */ 907 919 uint nrsumlevels; /* new rt summary levels */ ··· 910 922 xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ 911 923 xfs_extlen_t rsumblocks; /* current number of rt summary blks */ 912 924 xfs_sb_t *sbp; /* old superblock */ 913 - xfs_fsblock_t sumbno; /* summary block number */ 914 925 uint8_t *rsum_cache; /* old summary cache */ 915 926 916 927 sbp = &mp->m_sb; ··· 941 954 return -EINVAL; 942 955 943 956 /* Unsupported realtime features. */ 944 - if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp)) 957 + if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp) || xfs_has_quota(mp)) 945 958 return -EOPNOTSUPP; 946 959 947 960 nrblocks = in->newblocks; ··· 963 976 */ 964 977 nrextents = nrblocks; 965 978 do_div(nrextents, in->extsize); 966 - nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize); 979 + nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); 967 980 nrextslog = xfs_highbit32(nrextents); 968 981 nrsumlevels = nrextslog + 1; 969 - nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks; 970 - nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize); 982 + nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, nrbmblocks); 971 983 nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); 972 984 /* 973 985 * New summary size can't be more than half the size of ··· 1009 1023 ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); 1010 1024 bmbno < nrbmblocks; 1011 1025 bmbno++) { 1026 + struct xfs_rtalloc_args args = { 1027 + .mp = mp, 1028 + }; 1029 + struct xfs_rtalloc_args nargs = { 1030 + .mp = nmp, 1031 + }; 1012 1032 struct xfs_trans *tp; 1013 1033 xfs_rfsblock_t nrblocks_step; 1014 1034 ··· 1024 1032 * Calculate new sb and mount fields for this round. 1025 1033 */ 1026 1034 nsbp->sb_rextsize = in->extsize; 1035 + nmp->m_rtxblklog = -1; /* don't use shift or masking */ 1027 1036 nsbp->sb_rbmblocks = bmbno + 1; 1028 1037 nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize * 1029 1038 nsbp->sb_rextsize; 1030 1039 nsbp->sb_rblocks = min(nrblocks, nrblocks_step); 1031 - nsbp->sb_rextents = nsbp->sb_rblocks; 1032 - do_div(nsbp->sb_rextents, nsbp->sb_rextsize); 1040 + nsbp->sb_rextents = xfs_rtb_to_rtx(nmp, nsbp->sb_rblocks); 1033 1041 ASSERT(nsbp->sb_rextents != 0); 1034 1042 nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); 1035 1043 nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; 1036 - nrsumsize = 1037 - (uint)sizeof(xfs_suminfo_t) * nrsumlevels * 1038 - nsbp->sb_rbmblocks; 1039 - nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize); 1044 + nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, 1045 + nsbp->sb_rbmblocks); 1040 1046 nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); 1041 1047 /* 1042 1048 * Start a transaction, get the log reservation. ··· 1043 1053 &tp); 1044 1054 if (error) 1045 1055 break; 1056 + args.tp = tp; 1057 + nargs.tp = tp; 1058 + 1046 1059 /* 1047 1060 * Lock out other callers by grabbing the bitmap inode lock. 1048 1061 */ ··· 1079 1086 */ 1080 1087 if (sbp->sb_rbmblocks != nsbp->sb_rbmblocks || 1081 1088 mp->m_rsumlevels != nmp->m_rsumlevels) { 1082 - error = xfs_rtcopy_summary(mp, nmp, tp); 1089 + error = xfs_rtcopy_summary(&args, &nargs); 1083 1090 if (error) 1084 1091 goto error_cancel; 1085 1092 } ··· 1104 1111 /* 1105 1112 * Free new extent. 1106 1113 */ 1107 - bp = NULL; 1108 - error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, 1109 - nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); 1114 + error = xfs_rtfree_range(&nargs, sbp->sb_rextents, 1115 + nsbp->sb_rextents - sbp->sb_rextents); 1116 + xfs_rtbuf_cache_relse(&nargs); 1110 1117 if (error) { 1111 1118 error_cancel: 1112 1119 xfs_trans_cancel(tp); ··· 1164 1171 * parameters. The length units are all in realtime extents, as is the 1165 1172 * result block number. 1166 1173 */ 1167 - int /* error */ 1174 + int 1168 1175 xfs_rtallocate_extent( 1169 - xfs_trans_t *tp, /* transaction pointer */ 1170 - xfs_rtblock_t bno, /* starting block number to allocate */ 1171 - xfs_extlen_t minlen, /* minimum length to allocate */ 1172 - xfs_extlen_t maxlen, /* maximum length to allocate */ 1173 - xfs_extlen_t *len, /* out: actual length allocated */ 1174 - int wasdel, /* was a delayed allocation extent */ 1175 - xfs_extlen_t prod, /* extent product factor */ 1176 - xfs_rtblock_t *rtblock) /* out: start block allocated */ 1176 + struct xfs_trans *tp, 1177 + xfs_rtxnum_t start, /* starting rtext number to allocate */ 1178 + xfs_rtxlen_t minlen, /* minimum length to allocate */ 1179 + xfs_rtxlen_t maxlen, /* maximum length to allocate */ 1180 + xfs_rtxlen_t *len, /* out: actual length allocated */ 1181 + int wasdel, /* was a delayed allocation extent */ 1182 + xfs_rtxlen_t prod, /* extent product factor */ 1183 + xfs_rtxnum_t *rtblock) /* out: start rtext allocated */ 1177 1184 { 1178 - xfs_mount_t *mp = tp->t_mountp; 1179 - int error; /* error value */ 1180 - xfs_rtblock_t r; /* result allocated block */ 1181 - xfs_fsblock_t sb; /* summary file block number */ 1182 - struct xfs_buf *sumbp; /* summary file block buffer */ 1185 + struct xfs_rtalloc_args args = { 1186 + .mp = tp->t_mountp, 1187 + .tp = tp, 1188 + }; 1189 + int error; /* error value */ 1190 + xfs_rtxnum_t r; /* result allocated rtext */ 1183 1191 1184 - ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); 1192 + ASSERT(xfs_isilocked(args.mp->m_rbmip, XFS_ILOCK_EXCL)); 1185 1193 ASSERT(minlen > 0 && minlen <= maxlen); 1186 1194 1187 1195 /* 1188 1196 * If prod is set then figure out what to do to minlen and maxlen. 1189 1197 */ 1190 1198 if (prod > 1) { 1191 - xfs_extlen_t i; 1199 + xfs_rtxlen_t i; 1192 1200 1193 1201 if ((i = maxlen % prod)) 1194 1202 maxlen -= i; 1195 1203 if ((i = minlen % prod)) 1196 1204 minlen += prod - i; 1197 1205 if (maxlen < minlen) { 1198 - *rtblock = NULLRTBLOCK; 1206 + *rtblock = NULLRTEXTNO; 1199 1207 return 0; 1200 1208 } 1201 1209 } 1202 1210 1203 1211 retry: 1204 - sumbp = NULL; 1205 - if (bno == 0) { 1206 - error = xfs_rtallocate_extent_size(mp, tp, minlen, maxlen, len, 1207 - &sumbp, &sb, prod, &r); 1212 + if (start == 0) { 1213 + error = xfs_rtallocate_extent_size(&args, minlen, 1214 + maxlen, len, prod, &r); 1208 1215 } else { 1209 - error = xfs_rtallocate_extent_near(mp, tp, bno, minlen, maxlen, 1210 - len, &sumbp, &sb, prod, &r); 1216 + error = xfs_rtallocate_extent_near(&args, start, minlen, 1217 + maxlen, len, prod, &r); 1211 1218 } 1212 1219 1220 + xfs_rtbuf_cache_relse(&args); 1213 1221 if (error) 1214 1222 return error; 1215 1223 1216 1224 /* 1217 1225 * If it worked, update the superblock. 1218 1226 */ 1219 - if (r != NULLRTBLOCK) { 1227 + if (r != NULLRTEXTNO) { 1220 1228 long slen = (long)*len; 1221 1229 1222 1230 ASSERT(*len >= minlen && *len <= maxlen); ··· 1244 1250 struct xfs_buf *bp; /* buffer for last block of subvolume */ 1245 1251 struct xfs_sb *sbp; /* filesystem superblock copy in mount */ 1246 1252 xfs_daddr_t d; /* address of last block of subvolume */ 1253 + unsigned int rsumblocks; 1247 1254 int error; 1248 1255 1249 1256 sbp = &mp->m_sb; ··· 1256 1261 return -ENODEV; 1257 1262 } 1258 1263 mp->m_rsumlevels = sbp->sb_rextslog + 1; 1259 - mp->m_rsumsize = 1260 - (uint)sizeof(xfs_suminfo_t) * mp->m_rsumlevels * 1261 - sbp->sb_rbmblocks; 1262 - mp->m_rsumsize = roundup(mp->m_rsumsize, sbp->sb_blocksize); 1264 + rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, 1265 + mp->m_sb.sb_rbmblocks); 1266 + mp->m_rsumsize = XFS_FSB_TO_B(mp, rsumblocks); 1263 1267 mp->m_rbmip = mp->m_rsumip = NULL; 1264 1268 /* 1265 1269 * Check that the realtime section is an ok size. ··· 1412 1418 * of rtextents and the fraction. 1413 1419 * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ... 1414 1420 */ 1415 - int /* error */ 1421 + int /* error */ 1416 1422 xfs_rtpick_extent( 1417 1423 xfs_mount_t *mp, /* file system mount point */ 1418 1424 xfs_trans_t *tp, /* transaction pointer */ 1419 - xfs_extlen_t len, /* allocation length (rtextents) */ 1420 - xfs_rtblock_t *pick) /* result rt extent */ 1421 - { 1422 - xfs_rtblock_t b; /* result block */ 1425 + xfs_rtxlen_t len, /* allocation length (rtextents) */ 1426 + xfs_rtxnum_t *pick) /* result rt extent */ 1427 + { 1428 + xfs_rtxnum_t b; /* result rtext */ 1423 1429 int log2; /* log of sequence number */ 1424 1430 uint64_t resid; /* residual after log removed */ 1425 1431 uint64_t seq; /* sequence number of file creation */ 1426 - struct timespec64 ts; /* temporary timespec64 storage */ 1432 + struct timespec64 ts; /* timespec in inode */ 1427 1433 1428 1434 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); 1429 1435 1436 + ts = inode_get_atime(VFS_I(mp->m_rbmip)); 1430 1437 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) { 1431 1438 mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; 1432 1439 seq = 0; 1433 1440 } else { 1434 - ts = inode_get_atime(VFS_I(mp->m_rbmip)); 1435 - seq = (uint64_t)ts.tv_sec; 1441 + seq = ts.tv_sec; 1436 1442 } 1437 1443 if ((log2 = xfs_highbit64(seq)) == -1) 1438 1444 b = 0; ··· 1445 1451 if (b + len > mp->m_sb.sb_rextents) 1446 1452 b = mp->m_sb.sb_rextents - len; 1447 1453 } 1448 - ts.tv_sec = (time64_t)seq + 1; 1454 + ts.tv_sec = seq + 1; 1449 1455 inode_set_atime_to_ts(VFS_I(mp->m_rbmip), ts); 1450 1456 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); 1451 1457 *pick = b;
+13 -81
fs/xfs/xfs_rtalloc.h
··· 11 11 struct xfs_mount; 12 12 struct xfs_trans; 13 13 14 - /* 15 - * XXX: Most of the realtime allocation functions deal in units of realtime 16 - * extents, not realtime blocks. This looks funny when paired with the type 17 - * name and screams for a larger cleanup. 18 - */ 19 - struct xfs_rtalloc_rec { 20 - xfs_rtblock_t ar_startext; 21 - xfs_rtblock_t ar_extcount; 22 - }; 23 - 24 - typedef int (*xfs_rtalloc_query_range_fn)( 25 - struct xfs_mount *mp, 26 - struct xfs_trans *tp, 27 - const struct xfs_rtalloc_rec *rec, 28 - void *priv); 29 - 30 14 #ifdef CONFIG_XFS_RT 31 15 /* 32 16 * Function prototypes for exported functions. ··· 24 40 int /* error */ 25 41 xfs_rtallocate_extent( 26 42 struct xfs_trans *tp, /* transaction pointer */ 27 - xfs_rtblock_t bno, /* starting block number to allocate */ 28 - xfs_extlen_t minlen, /* minimum length to allocate */ 29 - xfs_extlen_t maxlen, /* maximum length to allocate */ 30 - xfs_extlen_t *len, /* out: actual length allocated */ 43 + xfs_rtxnum_t start, /* starting rtext number to allocate */ 44 + xfs_rtxlen_t minlen, /* minimum length to allocate */ 45 + xfs_rtxlen_t maxlen, /* maximum length to allocate */ 46 + xfs_rtxlen_t *len, /* out: actual length allocated */ 31 47 int wasdel, /* was a delayed allocation extent */ 32 - xfs_extlen_t prod, /* extent product factor */ 33 - xfs_rtblock_t *rtblock); /* out: start block allocated */ 48 + xfs_rtxlen_t prod, /* extent product factor */ 49 + xfs_rtxnum_t *rtblock); /* out: start rtext allocated */ 34 50 35 - /* 36 - * Free an extent in the realtime subvolume. Length is expressed in 37 - * realtime extents, as is the block number. 38 - */ 39 - int /* error */ 40 - xfs_rtfree_extent( 41 - struct xfs_trans *tp, /* transaction pointer */ 42 - xfs_rtblock_t bno, /* starting block number to free */ 43 - xfs_extlen_t len); /* length of extent freed */ 44 51 45 52 /* 46 53 * Initialize realtime fields in the mount structure. ··· 62 87 xfs_rtpick_extent( 63 88 struct xfs_mount *mp, /* file system mount point */ 64 89 struct xfs_trans *tp, /* transaction pointer */ 65 - xfs_extlen_t len, /* allocation length (rtextents) */ 66 - xfs_rtblock_t *pick); /* result rt extent */ 90 + xfs_rtxlen_t len, /* allocation length (rtextents) */ 91 + xfs_rtxnum_t *pick); /* result rt extent */ 67 92 68 93 /* 69 94 * Grow the realtime area of the filesystem. ··· 73 98 struct xfs_mount *mp, /* file system mount structure */ 74 99 xfs_growfs_rt_t *in); /* user supplied growfs struct */ 75 100 76 - /* 77 - * From xfs_rtbitmap.c 78 - */ 79 - int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, 80 - xfs_rtblock_t block, int issum, struct xfs_buf **bpp); 81 - int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, 82 - xfs_rtblock_t start, xfs_extlen_t len, int val, 83 - xfs_rtblock_t *new, int *stat); 84 - int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, 85 - xfs_rtblock_t start, xfs_rtblock_t limit, 86 - xfs_rtblock_t *rtblock); 87 - int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, 88 - xfs_rtblock_t start, xfs_rtblock_t limit, 89 - xfs_rtblock_t *rtblock); 90 - int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, 91 - xfs_rtblock_t start, xfs_extlen_t len, int val); 92 - int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, 93 - int log, xfs_rtblock_t bbno, int delta, 94 - struct xfs_buf **rbpp, xfs_fsblock_t *rsb, 95 - xfs_suminfo_t *sum); 96 - int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, 97 - xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp, 98 - xfs_fsblock_t *rsb); 99 - int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, 100 - xfs_rtblock_t start, xfs_extlen_t len, 101 - struct xfs_buf **rbpp, xfs_fsblock_t *rsb); 102 - int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, 103 - const struct xfs_rtalloc_rec *low_rec, 104 - const struct xfs_rtalloc_rec *high_rec, 105 - xfs_rtalloc_query_range_fn fn, void *priv); 106 - int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, 107 - xfs_rtalloc_query_range_fn fn, 108 - void *priv); 109 - bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno); 110 - int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp, 111 - xfs_rtblock_t start, xfs_extlen_t len, 112 - bool *is_free); 113 101 int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp); 114 102 #else 115 - # define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS) 116 - # define xfs_rtfree_extent(t,b,l) (ENOSYS) 117 - # define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) 118 - # define xfs_growfs_rt(mp,in) (ENOSYS) 119 - # define xfs_rtalloc_query_range(t,l,h,f,p) (ENOSYS) 120 - # define xfs_rtalloc_query_all(m,t,f,p) (ENOSYS) 121 - # define xfs_rtbuf_get(m,t,b,i,p) (ENOSYS) 122 - # define xfs_verify_rtbno(m, r) (false) 123 - # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (ENOSYS) 124 - # define xfs_rtalloc_reinit_frextents(m) (0) 103 + # define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (-ENOSYS) 104 + # define xfs_rtpick_extent(m,t,l,rb) (-ENOSYS) 105 + # define xfs_growfs_rt(mp,in) (-ENOSYS) 106 + # define xfs_rtalloc_reinit_frextents(m) (0) 125 107 static inline int /* error */ 126 108 xfs_rtmount_init( 127 109 xfs_mount_t *mp) /* file system mount structure */ ··· 89 157 xfs_warn(mp, "Not built with CONFIG_XFS_RT"); 90 158 return -ENOSYS; 91 159 } 92 - # define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS)) 160 + # define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (-ENOSYS)) 93 161 # define xfs_rtunmount_inodes(m) 94 162 #endif /* CONFIG_XFS_RT */ 95 163
+2 -1
fs/xfs/xfs_super.c
··· 42 42 #include "xfs_xattr.h" 43 43 #include "xfs_iunlink_item.h" 44 44 #include "xfs_dahash_test.h" 45 + #include "xfs_rtbitmap.h" 45 46 #include "scrub/stats.h" 46 47 47 48 #include <linux/magic.h> ··· 897 896 898 897 statp->f_blocks = sbp->sb_rblocks; 899 898 freertx = percpu_counter_sum_positive(&mp->m_frextents); 900 - statp->f_bavail = statp->f_bfree = freertx * sbp->sb_rextsize; 899 + statp->f_bavail = statp->f_bfree = xfs_rtx_to_rtb(mp, freertx); 901 900 } 902 901 903 902 return 0;
+6 -1
fs/xfs/xfs_trans.c
··· 24 24 #include "xfs_dquot_item.h" 25 25 #include "xfs_dquot.h" 26 26 #include "xfs_icache.h" 27 + #include "xfs_rtbitmap.h" 27 28 28 29 struct kmem_cache *xfs_trans_cache; 29 30 ··· 656 655 mp->m_sb.sb_agcount += tp->t_agcount_delta; 657 656 mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta; 658 657 mp->m_sb.sb_rextsize += tp->t_rextsize_delta; 658 + if (tp->t_rextsize_delta) { 659 + mp->m_rtxblklog = log2_if_power2(mp->m_sb.sb_rextsize); 660 + mp->m_rtxblkmask = mask64_if_power2(mp->m_sb.sb_rextsize); 661 + } 659 662 mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta; 660 663 mp->m_sb.sb_rblocks += tp->t_rblocks_delta; 661 664 mp->m_sb.sb_rextents += tp->t_rextents_delta; ··· 1201 1196 1202 1197 retry: 1203 1198 error = xfs_trans_alloc(mp, resv, dblocks, 1204 - rblocks / mp->m_sb.sb_rextsize, 1199 + xfs_extlen_to_rtxlen(mp, rblocks), 1205 1200 force ? XFS_TRANS_RESERVE : 0, &tp); 1206 1201 if (error) 1207 1202 return error;