1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_bit.h" 13 #include "xfs_mount.h" 14 #include "xfs_inode.h" 15 #include "xfs_bmap.h" 16 #include "xfs_trans.h" 17 #include "xfs_rtalloc.h" 18 19 20 /* 21 * Realtime allocator bitmap functions shared with userspace. 22 */ 23 24 /* 25 * Real time buffers need verifiers to avoid runtime warnings during IO. 26 * We don't have anything to verify, however, so these are just dummy 27 * operations. 28 */ 29 static void 30 xfs_rtbuf_verify_read( 31 struct xfs_buf *bp) 32 { 33 return; 34 } 35 36 static void 37 xfs_rtbuf_verify_write( 38 struct xfs_buf *bp) 39 { 40 return; 41 } 42 43 const struct xfs_buf_ops xfs_rtbuf_ops = { 44 .name = "rtbuf", 45 .verify_read = xfs_rtbuf_verify_read, 46 .verify_write = xfs_rtbuf_verify_write, 47 }; 48 49 /* 50 * Get a buffer for the bitmap or summary file block specified. 51 * The buffer is returned read and locked. 52 */ 53 int 54 xfs_rtbuf_get( 55 xfs_mount_t *mp, /* file system mount structure */ 56 xfs_trans_t *tp, /* transaction pointer */ 57 xfs_rtblock_t block, /* block number in bitmap or summary */ 58 int issum, /* is summary not bitmap */ 59 xfs_buf_t **bpp) /* output: buffer for the block */ 60 { 61 xfs_buf_t *bp; /* block buffer, result */ 62 xfs_inode_t *ip; /* bitmap or summary inode */ 63 xfs_bmbt_irec_t map; 64 int nmap = 1; 65 int error; /* error value */ 66 67 ip = issum ? mp->m_rsumip : mp->m_rbmip; 68 69 error = xfs_bmapi_read(ip, block, 1, &map, &nmap, XFS_DATA_FORK); 70 if (error) 71 return error; 72 73 if (nmap == 0 || !xfs_bmap_is_real_extent(&map)) 74 return -EFSCORRUPTED; 75 76 ASSERT(map.br_startblock != NULLFSBLOCK); 77 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 78 XFS_FSB_TO_DADDR(mp, map.br_startblock), 79 mp->m_bsize, 0, &bp, &xfs_rtbuf_ops); 80 if (error) 81 return error; 82 83 xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF 84 : XFS_BLFT_RTBITMAP_BUF); 85 *bpp = bp; 86 return 0; 87 } 88 89 /* 90 * Searching backward from start to limit, find the first block whose 91 * allocated/free state is different from start's. 92 */ 93 int 94 xfs_rtfind_back( 95 xfs_mount_t *mp, /* file system mount point */ 96 xfs_trans_t *tp, /* transaction pointer */ 97 xfs_rtblock_t start, /* starting block to look at */ 98 xfs_rtblock_t limit, /* last block to look at */ 99 xfs_rtblock_t *rtblock) /* out: start block found */ 100 { 101 xfs_rtword_t *b; /* current word in buffer */ 102 int bit; /* bit number in the word */ 103 xfs_rtblock_t block; /* bitmap block number */ 104 xfs_buf_t *bp; /* buf for the block */ 105 xfs_rtword_t *bufp; /* starting word in buffer */ 106 int error; /* error value */ 107 xfs_rtblock_t firstbit; /* first useful bit in the word */ 108 xfs_rtblock_t i; /* current bit number rel. to start */ 109 xfs_rtblock_t len; /* length of inspected area */ 110 xfs_rtword_t mask; /* mask of relevant bits for value */ 111 xfs_rtword_t want; /* mask for "good" values */ 112 xfs_rtword_t wdiff; /* difference from wanted value */ 113 int word; /* word number in the buffer */ 114 115 /* 116 * Compute and read in starting bitmap block for starting block. 117 */ 118 block = XFS_BITTOBLOCK(mp, start); 119 error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 120 if (error) { 121 return error; 122 } 123 bufp = bp->b_addr; 124 /* 125 * Get the first word's index & point to it. 126 */ 127 word = XFS_BITTOWORD(mp, start); 128 b = &bufp[word]; 129 bit = (int)(start & (XFS_NBWORD - 1)); 130 len = start - limit + 1; 131 /* 132 * Compute match value, based on the bit at start: if 1 (free) 133 * then all-ones, else all-zeroes. 134 */ 135 want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; 136 /* 137 * If the starting position is not word-aligned, deal with the 138 * partial word. 139 */ 140 if (bit < XFS_NBWORD - 1) { 141 /* 142 * Calculate first (leftmost) bit number to look at, 143 * and mask for all the relevant bits in this word. 144 */ 145 firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0); 146 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) << 147 firstbit; 148 /* 149 * Calculate the difference between the value there 150 * and what we're looking for. 151 */ 152 if ((wdiff = (*b ^ want) & mask)) { 153 /* 154 * Different. Mark where we are and return. 155 */ 156 xfs_trans_brelse(tp, bp); 157 i = bit - XFS_RTHIBIT(wdiff); 158 *rtblock = start - i + 1; 159 return 0; 160 } 161 i = bit - firstbit + 1; 162 /* 163 * Go on to previous block if that's where the previous word is 164 * and we need the previous word. 165 */ 166 if (--word == -1 && i < len) { 167 /* 168 * If done with this block, get the previous one. 169 */ 170 xfs_trans_brelse(tp, bp); 171 error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); 172 if (error) { 173 return error; 174 } 175 bufp = bp->b_addr; 176 word = XFS_BLOCKWMASK(mp); 177 b = &bufp[word]; 178 } else { 179 /* 180 * Go on to the previous word in the buffer. 181 */ 182 b--; 183 } 184 } else { 185 /* 186 * Starting on a word boundary, no partial word. 187 */ 188 i = 0; 189 } 190 /* 191 * Loop over whole words in buffers. When we use up one buffer 192 * we move on to the previous one. 193 */ 194 while (len - i >= XFS_NBWORD) { 195 /* 196 * Compute difference between actual and desired value. 197 */ 198 if ((wdiff = *b ^ want)) { 199 /* 200 * Different, mark where we are and return. 201 */ 202 xfs_trans_brelse(tp, bp); 203 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); 204 *rtblock = start - i + 1; 205 return 0; 206 } 207 i += XFS_NBWORD; 208 /* 209 * Go on to previous block if that's where the previous word is 210 * and we need the previous word. 211 */ 212 if (--word == -1 && i < len) { 213 /* 214 * If done with this block, get the previous one. 215 */ 216 xfs_trans_brelse(tp, bp); 217 error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); 218 if (error) { 219 return error; 220 } 221 bufp = bp->b_addr; 222 word = XFS_BLOCKWMASK(mp); 223 b = &bufp[word]; 224 } else { 225 /* 226 * Go on to the previous word in the buffer. 227 */ 228 b--; 229 } 230 } 231 /* 232 * If not ending on a word boundary, deal with the last 233 * (partial) word. 234 */ 235 if (len - i) { 236 /* 237 * Calculate first (leftmost) bit number to look at, 238 * and mask for all the relevant bits in this word. 239 */ 240 firstbit = XFS_NBWORD - (len - i); 241 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit; 242 /* 243 * Compute difference between actual and desired value. 244 */ 245 if ((wdiff = (*b ^ want) & mask)) { 246 /* 247 * Different, mark where we are and return. 248 */ 249 xfs_trans_brelse(tp, bp); 250 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); 251 *rtblock = start - i + 1; 252 return 0; 253 } else 254 i = len; 255 } 256 /* 257 * No match, return that we scanned the whole area. 258 */ 259 xfs_trans_brelse(tp, bp); 260 *rtblock = start - i + 1; 261 return 0; 262 } 263 264 /* 265 * Searching forward from start to limit, find the first block whose 266 * allocated/free state is different from start's. 267 */ 268 int 269 xfs_rtfind_forw( 270 xfs_mount_t *mp, /* file system mount point */ 271 xfs_trans_t *tp, /* transaction pointer */ 272 xfs_rtblock_t start, /* starting block to look at */ 273 xfs_rtblock_t limit, /* last block to look at */ 274 xfs_rtblock_t *rtblock) /* out: start block found */ 275 { 276 xfs_rtword_t *b; /* current word in buffer */ 277 int bit; /* bit number in the word */ 278 xfs_rtblock_t block; /* bitmap block number */ 279 xfs_buf_t *bp; /* buf for the block */ 280 xfs_rtword_t *bufp; /* starting word in buffer */ 281 int error; /* error value */ 282 xfs_rtblock_t i; /* current bit number rel. to start */ 283 xfs_rtblock_t lastbit; /* last useful bit in the word */ 284 xfs_rtblock_t len; /* length of inspected area */ 285 xfs_rtword_t mask; /* mask of relevant bits for value */ 286 xfs_rtword_t want; /* mask for "good" values */ 287 xfs_rtword_t wdiff; /* difference from wanted value */ 288 int word; /* word number in the buffer */ 289 290 /* 291 * Compute and read in starting bitmap block for starting block. 292 */ 293 block = XFS_BITTOBLOCK(mp, start); 294 error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 295 if (error) { 296 return error; 297 } 298 bufp = bp->b_addr; 299 /* 300 * Get the first word's index & point to it. 301 */ 302 word = XFS_BITTOWORD(mp, start); 303 b = &bufp[word]; 304 bit = (int)(start & (XFS_NBWORD - 1)); 305 len = limit - start + 1; 306 /* 307 * Compute match value, based on the bit at start: if 1 (free) 308 * then all-ones, else all-zeroes. 309 */ 310 want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0; 311 /* 312 * If the starting position is not word-aligned, deal with the 313 * partial word. 314 */ 315 if (bit) { 316 /* 317 * Calculate last (rightmost) bit number to look at, 318 * and mask for all the relevant bits in this word. 319 */ 320 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); 321 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; 322 /* 323 * Calculate the difference between the value there 324 * and what we're looking for. 325 */ 326 if ((wdiff = (*b ^ want) & mask)) { 327 /* 328 * Different. Mark where we are and return. 329 */ 330 xfs_trans_brelse(tp, bp); 331 i = XFS_RTLOBIT(wdiff) - bit; 332 *rtblock = start + i - 1; 333 return 0; 334 } 335 i = lastbit - bit; 336 /* 337 * Go on to next block if that's where the next word is 338 * and we need the next word. 339 */ 340 if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 341 /* 342 * If done with this block, get the previous one. 343 */ 344 xfs_trans_brelse(tp, bp); 345 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 346 if (error) { 347 return error; 348 } 349 b = bufp = bp->b_addr; 350 word = 0; 351 } else { 352 /* 353 * Go on to the previous word in the buffer. 354 */ 355 b++; 356 } 357 } else { 358 /* 359 * Starting on a word boundary, no partial word. 360 */ 361 i = 0; 362 } 363 /* 364 * Loop over whole words in buffers. When we use up one buffer 365 * we move on to the next one. 366 */ 367 while (len - i >= XFS_NBWORD) { 368 /* 369 * Compute difference between actual and desired value. 370 */ 371 if ((wdiff = *b ^ want)) { 372 /* 373 * Different, mark where we are and return. 374 */ 375 xfs_trans_brelse(tp, bp); 376 i += XFS_RTLOBIT(wdiff); 377 *rtblock = start + i - 1; 378 return 0; 379 } 380 i += XFS_NBWORD; 381 /* 382 * Go on to next block if that's where the next word is 383 * and we need the next word. 384 */ 385 if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 386 /* 387 * If done with this block, get the next one. 388 */ 389 xfs_trans_brelse(tp, bp); 390 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 391 if (error) { 392 return error; 393 } 394 b = bufp = bp->b_addr; 395 word = 0; 396 } else { 397 /* 398 * Go on to the next word in the buffer. 399 */ 400 b++; 401 } 402 } 403 /* 404 * If not ending on a word boundary, deal with the last 405 * (partial) word. 406 */ 407 if ((lastbit = len - i)) { 408 /* 409 * Calculate mask for all the relevant bits in this word. 410 */ 411 mask = ((xfs_rtword_t)1 << lastbit) - 1; 412 /* 413 * Compute difference between actual and desired value. 414 */ 415 if ((wdiff = (*b ^ want) & mask)) { 416 /* 417 * Different, mark where we are and return. 418 */ 419 xfs_trans_brelse(tp, bp); 420 i += XFS_RTLOBIT(wdiff); 421 *rtblock = start + i - 1; 422 return 0; 423 } else 424 i = len; 425 } 426 /* 427 * No match, return that we scanned the whole area. 428 */ 429 xfs_trans_brelse(tp, bp); 430 *rtblock = start + i - 1; 431 return 0; 432 } 433 434 /* 435 * Read and/or modify the summary information for a given extent size, 436 * bitmap block combination. 437 * Keeps track of a current summary block, so we don't keep reading 438 * it from the buffer cache. 439 * 440 * Summary information is returned in *sum if specified. 441 * If no delta is specified, returns summary only. 442 */ 443 int 444 xfs_rtmodify_summary_int( 445 xfs_mount_t *mp, /* file system mount structure */ 446 xfs_trans_t *tp, /* transaction pointer */ 447 int log, /* log2 of extent size */ 448 xfs_rtblock_t bbno, /* bitmap block number */ 449 int delta, /* change to make to summary info */ 450 xfs_buf_t **rbpp, /* in/out: summary block buffer */ 451 xfs_fsblock_t *rsb, /* in/out: summary block number */ 452 xfs_suminfo_t *sum) /* out: summary info for this block */ 453 { 454 xfs_buf_t *bp; /* buffer for the summary block */ 455 int error; /* error value */ 456 xfs_fsblock_t sb; /* summary fsblock */ 457 int so; /* index into the summary file */ 458 xfs_suminfo_t *sp; /* pointer to returned data */ 459 460 /* 461 * Compute entry number in the summary file. 462 */ 463 so = XFS_SUMOFFS(mp, log, bbno); 464 /* 465 * Compute the block number in the summary file. 466 */ 467 sb = XFS_SUMOFFSTOBLOCK(mp, so); 468 /* 469 * If we have an old buffer, and the block number matches, use that. 470 */ 471 if (*rbpp && *rsb == sb) 472 bp = *rbpp; 473 /* 474 * Otherwise we have to get the buffer. 475 */ 476 else { 477 /* 478 * If there was an old one, get rid of it first. 479 */ 480 if (*rbpp) 481 xfs_trans_brelse(tp, *rbpp); 482 error = xfs_rtbuf_get(mp, tp, sb, 1, &bp); 483 if (error) { 484 return error; 485 } 486 /* 487 * Remember this buffer and block for the next call. 488 */ 489 *rbpp = bp; 490 *rsb = sb; 491 } 492 /* 493 * Point to the summary information, modify/log it, and/or copy it out. 494 */ 495 sp = XFS_SUMPTR(mp, bp, so); 496 if (delta) { 497 uint first = (uint)((char *)sp - (char *)bp->b_addr); 498 499 *sp += delta; 500 if (mp->m_rsum_cache) { 501 if (*sp == 0 && log == mp->m_rsum_cache[bbno]) 502 mp->m_rsum_cache[bbno]++; 503 if (*sp != 0 && log < mp->m_rsum_cache[bbno]) 504 mp->m_rsum_cache[bbno] = log; 505 } 506 xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1); 507 } 508 if (sum) 509 *sum = *sp; 510 return 0; 511 } 512 513 int 514 xfs_rtmodify_summary( 515 xfs_mount_t *mp, /* file system mount structure */ 516 xfs_trans_t *tp, /* transaction pointer */ 517 int log, /* log2 of extent size */ 518 xfs_rtblock_t bbno, /* bitmap block number */ 519 int delta, /* change to make to summary info */ 520 xfs_buf_t **rbpp, /* in/out: summary block buffer */ 521 xfs_fsblock_t *rsb) /* in/out: summary block number */ 522 { 523 return xfs_rtmodify_summary_int(mp, tp, log, bbno, 524 delta, rbpp, rsb, NULL); 525 } 526 527 /* 528 * Set the given range of bitmap bits to the given value. 529 * Do whatever I/O and logging is required. 530 */ 531 int 532 xfs_rtmodify_range( 533 xfs_mount_t *mp, /* file system mount point */ 534 xfs_trans_t *tp, /* transaction pointer */ 535 xfs_rtblock_t start, /* starting block to modify */ 536 xfs_extlen_t len, /* length of extent to modify */ 537 int val) /* 1 for free, 0 for allocated */ 538 { 539 xfs_rtword_t *b; /* current word in buffer */ 540 int bit; /* bit number in the word */ 541 xfs_rtblock_t block; /* bitmap block number */ 542 xfs_buf_t *bp; /* buf for the block */ 543 xfs_rtword_t *bufp; /* starting word in buffer */ 544 int error; /* error value */ 545 xfs_rtword_t *first; /* first used word in the buffer */ 546 int i; /* current bit number rel. to start */ 547 int lastbit; /* last useful bit in word */ 548 xfs_rtword_t mask; /* mask o frelevant bits for value */ 549 int word; /* word number in the buffer */ 550 551 /* 552 * Compute starting bitmap block number. 553 */ 554 block = XFS_BITTOBLOCK(mp, start); 555 /* 556 * Read the bitmap block, and point to its data. 557 */ 558 error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 559 if (error) { 560 return error; 561 } 562 bufp = bp->b_addr; 563 /* 564 * Compute the starting word's address, and starting bit. 565 */ 566 word = XFS_BITTOWORD(mp, start); 567 first = b = &bufp[word]; 568 bit = (int)(start & (XFS_NBWORD - 1)); 569 /* 570 * 0 (allocated) => all zeroes; 1 (free) => all ones. 571 */ 572 val = -val; 573 /* 574 * If not starting on a word boundary, deal with the first 575 * (partial) word. 576 */ 577 if (bit) { 578 /* 579 * Compute first bit not changed and mask of relevant bits. 580 */ 581 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); 582 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; 583 /* 584 * Set/clear the active bits. 585 */ 586 if (val) 587 *b |= mask; 588 else 589 *b &= ~mask; 590 i = lastbit - bit; 591 /* 592 * Go on to the next block if that's where the next word is 593 * and we need the next word. 594 */ 595 if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 596 /* 597 * Log the changed part of this block. 598 * Get the next one. 599 */ 600 xfs_trans_log_buf(tp, bp, 601 (uint)((char *)first - (char *)bufp), 602 (uint)((char *)b - (char *)bufp)); 603 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 604 if (error) { 605 return error; 606 } 607 first = b = bufp = bp->b_addr; 608 word = 0; 609 } else { 610 /* 611 * Go on to the next word in the buffer 612 */ 613 b++; 614 } 615 } else { 616 /* 617 * Starting on a word boundary, no partial word. 618 */ 619 i = 0; 620 } 621 /* 622 * Loop over whole words in buffers. When we use up one buffer 623 * we move on to the next one. 624 */ 625 while (len - i >= XFS_NBWORD) { 626 /* 627 * Set the word value correctly. 628 */ 629 *b = val; 630 i += XFS_NBWORD; 631 /* 632 * Go on to the next block if that's where the next word is 633 * and we need the next word. 634 */ 635 if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 636 /* 637 * Log the changed part of this block. 638 * Get the next one. 639 */ 640 xfs_trans_log_buf(tp, bp, 641 (uint)((char *)first - (char *)bufp), 642 (uint)((char *)b - (char *)bufp)); 643 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 644 if (error) { 645 return error; 646 } 647 first = b = bufp = bp->b_addr; 648 word = 0; 649 } else { 650 /* 651 * Go on to the next word in the buffer 652 */ 653 b++; 654 } 655 } 656 /* 657 * If not ending on a word boundary, deal with the last 658 * (partial) word. 659 */ 660 if ((lastbit = len - i)) { 661 /* 662 * Compute a mask of relevant bits. 663 */ 664 mask = ((xfs_rtword_t)1 << lastbit) - 1; 665 /* 666 * Set/clear the active bits. 667 */ 668 if (val) 669 *b |= mask; 670 else 671 *b &= ~mask; 672 b++; 673 } 674 /* 675 * Log any remaining changed bytes. 676 */ 677 if (b > first) 678 xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), 679 (uint)((char *)b - (char *)bufp - 1)); 680 return 0; 681 } 682 683 /* 684 * Mark an extent specified by start and len freed. 685 * Updates all the summary information as well as the bitmap. 686 */ 687 int 688 xfs_rtfree_range( 689 xfs_mount_t *mp, /* file system mount point */ 690 xfs_trans_t *tp, /* transaction pointer */ 691 xfs_rtblock_t start, /* starting block to free */ 692 xfs_extlen_t len, /* length to free */ 693 xfs_buf_t **rbpp, /* in/out: summary block buffer */ 694 xfs_fsblock_t *rsb) /* in/out: summary block number */ 695 { 696 xfs_rtblock_t end; /* end of the freed extent */ 697 int error; /* error value */ 698 xfs_rtblock_t postblock; /* first block freed > end */ 699 xfs_rtblock_t preblock; /* first block freed < start */ 700 701 end = start + len - 1; 702 /* 703 * Modify the bitmap to mark this extent freed. 704 */ 705 error = xfs_rtmodify_range(mp, tp, start, len, 1); 706 if (error) { 707 return error; 708 } 709 /* 710 * Assume we're freeing out of the middle of an allocated extent. 711 * We need to find the beginning and end of the extent so we can 712 * properly update the summary. 713 */ 714 error = xfs_rtfind_back(mp, tp, start, 0, &preblock); 715 if (error) { 716 return error; 717 } 718 /* 719 * Find the next allocated block (end of allocated extent). 720 */ 721 error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, 722 &postblock); 723 if (error) 724 return error; 725 /* 726 * If there are blocks not being freed at the front of the 727 * old extent, add summary data for them to be allocated. 728 */ 729 if (preblock < start) { 730 error = xfs_rtmodify_summary(mp, tp, 731 XFS_RTBLOCKLOG(start - preblock), 732 XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); 733 if (error) { 734 return error; 735 } 736 } 737 /* 738 * If there are blocks not being freed at the end of the 739 * old extent, add summary data for them to be allocated. 740 */ 741 if (postblock > end) { 742 error = xfs_rtmodify_summary(mp, tp, 743 XFS_RTBLOCKLOG(postblock - end), 744 XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb); 745 if (error) { 746 return error; 747 } 748 } 749 /* 750 * Increment the summary information corresponding to the entire 751 * (new) free extent. 752 */ 753 error = xfs_rtmodify_summary(mp, tp, 754 XFS_RTBLOCKLOG(postblock + 1 - preblock), 755 XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); 756 return error; 757 } 758 759 /* 760 * Check that the given range is either all allocated (val = 0) or 761 * all free (val = 1). 762 */ 763 int 764 xfs_rtcheck_range( 765 xfs_mount_t *mp, /* file system mount point */ 766 xfs_trans_t *tp, /* transaction pointer */ 767 xfs_rtblock_t start, /* starting block number of extent */ 768 xfs_extlen_t len, /* length of extent */ 769 int val, /* 1 for free, 0 for allocated */ 770 xfs_rtblock_t *new, /* out: first block not matching */ 771 int *stat) /* out: 1 for matches, 0 for not */ 772 { 773 xfs_rtword_t *b; /* current word in buffer */ 774 int bit; /* bit number in the word */ 775 xfs_rtblock_t block; /* bitmap block number */ 776 xfs_buf_t *bp; /* buf for the block */ 777 xfs_rtword_t *bufp; /* starting word in buffer */ 778 int error; /* error value */ 779 xfs_rtblock_t i; /* current bit number rel. to start */ 780 xfs_rtblock_t lastbit; /* last useful bit in word */ 781 xfs_rtword_t mask; /* mask of relevant bits for value */ 782 xfs_rtword_t wdiff; /* difference from wanted value */ 783 int word; /* word number in the buffer */ 784 785 /* 786 * Compute starting bitmap block number 787 */ 788 block = XFS_BITTOBLOCK(mp, start); 789 /* 790 * Read the bitmap block. 791 */ 792 error = xfs_rtbuf_get(mp, tp, block, 0, &bp); 793 if (error) { 794 return error; 795 } 796 bufp = bp->b_addr; 797 /* 798 * Compute the starting word's address, and starting bit. 799 */ 800 word = XFS_BITTOWORD(mp, start); 801 b = &bufp[word]; 802 bit = (int)(start & (XFS_NBWORD - 1)); 803 /* 804 * 0 (allocated) => all zero's; 1 (free) => all one's. 805 */ 806 val = -val; 807 /* 808 * If not starting on a word boundary, deal with the first 809 * (partial) word. 810 */ 811 if (bit) { 812 /* 813 * Compute first bit not examined. 814 */ 815 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD); 816 /* 817 * Mask of relevant bits. 818 */ 819 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit; 820 /* 821 * Compute difference between actual and desired value. 822 */ 823 if ((wdiff = (*b ^ val) & mask)) { 824 /* 825 * Different, compute first wrong bit and return. 826 */ 827 xfs_trans_brelse(tp, bp); 828 i = XFS_RTLOBIT(wdiff) - bit; 829 *new = start + i; 830 *stat = 0; 831 return 0; 832 } 833 i = lastbit - bit; 834 /* 835 * Go on to next block if that's where the next word is 836 * and we need the next word. 837 */ 838 if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 839 /* 840 * If done with this block, get the next one. 841 */ 842 xfs_trans_brelse(tp, bp); 843 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 844 if (error) { 845 return error; 846 } 847 b = bufp = bp->b_addr; 848 word = 0; 849 } else { 850 /* 851 * Go on to the next word in the buffer. 852 */ 853 b++; 854 } 855 } else { 856 /* 857 * Starting on a word boundary, no partial word. 858 */ 859 i = 0; 860 } 861 /* 862 * Loop over whole words in buffers. When we use up one buffer 863 * we move on to the next one. 864 */ 865 while (len - i >= XFS_NBWORD) { 866 /* 867 * Compute difference between actual and desired value. 868 */ 869 if ((wdiff = *b ^ val)) { 870 /* 871 * Different, compute first wrong bit and return. 872 */ 873 xfs_trans_brelse(tp, bp); 874 i += XFS_RTLOBIT(wdiff); 875 *new = start + i; 876 *stat = 0; 877 return 0; 878 } 879 i += XFS_NBWORD; 880 /* 881 * Go on to next block if that's where the next word is 882 * and we need the next word. 883 */ 884 if (++word == XFS_BLOCKWSIZE(mp) && i < len) { 885 /* 886 * If done with this block, get the next one. 887 */ 888 xfs_trans_brelse(tp, bp); 889 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); 890 if (error) { 891 return error; 892 } 893 b = bufp = bp->b_addr; 894 word = 0; 895 } else { 896 /* 897 * Go on to the next word in the buffer. 898 */ 899 b++; 900 } 901 } 902 /* 903 * If not ending on a word boundary, deal with the last 904 * (partial) word. 905 */ 906 if ((lastbit = len - i)) { 907 /* 908 * Mask of relevant bits. 909 */ 910 mask = ((xfs_rtword_t)1 << lastbit) - 1; 911 /* 912 * Compute difference between actual and desired value. 913 */ 914 if ((wdiff = (*b ^ val) & mask)) { 915 /* 916 * Different, compute first wrong bit and return. 917 */ 918 xfs_trans_brelse(tp, bp); 919 i += XFS_RTLOBIT(wdiff); 920 *new = start + i; 921 *stat = 0; 922 return 0; 923 } else 924 i = len; 925 } 926 /* 927 * Successful, return. 928 */ 929 xfs_trans_brelse(tp, bp); 930 *new = start + i; 931 *stat = 1; 932 return 0; 933 } 934 935 #ifdef DEBUG 936 /* 937 * Check that the given extent (block range) is allocated already. 938 */ 939 STATIC int /* error */ 940 xfs_rtcheck_alloc_range( 941 xfs_mount_t *mp, /* file system mount point */ 942 xfs_trans_t *tp, /* transaction pointer */ 943 xfs_rtblock_t bno, /* starting block number of extent */ 944 xfs_extlen_t len) /* length of extent */ 945 { 946 xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */ 947 int stat; 948 int error; 949 950 error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat); 951 if (error) 952 return error; 953 ASSERT(stat); 954 return 0; 955 } 956 #else 957 #define xfs_rtcheck_alloc_range(m,t,b,l) (0) 958 #endif 959 /* 960 * Free an extent in the realtime subvolume. Length is expressed in 961 * realtime extents, as is the block number. 962 */ 963 int /* error */ 964 xfs_rtfree_extent( 965 xfs_trans_t *tp, /* transaction pointer */ 966 xfs_rtblock_t bno, /* starting block number to free */ 967 xfs_extlen_t len) /* length of extent freed */ 968 { 969 int error; /* error value */ 970 xfs_mount_t *mp; /* file system mount structure */ 971 xfs_fsblock_t sb; /* summary file block number */ 972 xfs_buf_t *sumbp = NULL; /* summary file block buffer */ 973 974 mp = tp->t_mountp; 975 976 ASSERT(mp->m_rbmip->i_itemp != NULL); 977 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); 978 979 error = xfs_rtcheck_alloc_range(mp, tp, bno, len); 980 if (error) 981 return error; 982 983 /* 984 * Free the range of realtime blocks. 985 */ 986 error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb); 987 if (error) { 988 return error; 989 } 990 /* 991 * Mark more blocks free in the superblock. 992 */ 993 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len); 994 /* 995 * If we've now freed all the blocks, reset the file sequence 996 * number to 0. 997 */ 998 if (tp->t_frextents_delta + mp->m_sb.sb_frextents == 999 mp->m_sb.sb_rextents) { 1000 if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) 1001 mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; 1002 *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0; 1003 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); 1004 } 1005 return 0; 1006 } 1007 1008 /* Find all the free records within a given range. */ 1009 int 1010 xfs_rtalloc_query_range( 1011 struct xfs_trans *tp, 1012 struct xfs_rtalloc_rec *low_rec, 1013 struct xfs_rtalloc_rec *high_rec, 1014 xfs_rtalloc_query_range_fn fn, 1015 void *priv) 1016 { 1017 struct xfs_rtalloc_rec rec; 1018 struct xfs_mount *mp = tp->t_mountp; 1019 xfs_rtblock_t rtstart; 1020 xfs_rtblock_t rtend; 1021 xfs_rtblock_t rem; 1022 int is_free; 1023 int error = 0; 1024 1025 if (low_rec->ar_startext > high_rec->ar_startext) 1026 return -EINVAL; 1027 if (low_rec->ar_startext >= mp->m_sb.sb_rextents || 1028 low_rec->ar_startext == high_rec->ar_startext) 1029 return 0; 1030 if (high_rec->ar_startext > mp->m_sb.sb_rextents) 1031 high_rec->ar_startext = mp->m_sb.sb_rextents; 1032 1033 /* Iterate the bitmap, looking for discrepancies. */ 1034 rtstart = low_rec->ar_startext; 1035 rem = high_rec->ar_startext - rtstart; 1036 while (rem) { 1037 /* Is the first block free? */ 1038 error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend, 1039 &is_free); 1040 if (error) 1041 break; 1042 1043 /* How long does the extent go for? */ 1044 error = xfs_rtfind_forw(mp, tp, rtstart, 1045 high_rec->ar_startext - 1, &rtend); 1046 if (error) 1047 break; 1048 1049 if (is_free) { 1050 rec.ar_startext = rtstart; 1051 rec.ar_extcount = rtend - rtstart + 1; 1052 1053 error = fn(tp, &rec, priv); 1054 if (error) 1055 break; 1056 } 1057 1058 rem -= rtend - rtstart + 1; 1059 rtstart = rtend + 1; 1060 } 1061 1062 return error; 1063 } 1064 1065 /* Find all the free records. */ 1066 int 1067 xfs_rtalloc_query_all( 1068 struct xfs_trans *tp, 1069 xfs_rtalloc_query_range_fn fn, 1070 void *priv) 1071 { 1072 struct xfs_rtalloc_rec keys[2]; 1073 1074 keys[0].ar_startext = 0; 1075 keys[1].ar_startext = tp->t_mountp->m_sb.sb_rextents - 1; 1076 keys[0].ar_extcount = keys[1].ar_extcount = 0; 1077 1078 return xfs_rtalloc_query_range(tp, &keys[0], &keys[1], fn, priv); 1079 } 1080 1081 /* Is the given extent all free? */ 1082 int 1083 xfs_rtalloc_extent_is_free( 1084 struct xfs_mount *mp, 1085 struct xfs_trans *tp, 1086 xfs_rtblock_t start, 1087 xfs_extlen_t len, 1088 bool *is_free) 1089 { 1090 xfs_rtblock_t end; 1091 int matches; 1092 int error; 1093 1094 error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches); 1095 if (error) 1096 return error; 1097 1098 *is_free = matches; 1099 return 0; 1100 } 1101