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