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