/linux-2.6.33/kernel/linux-2.6.33/fs/xfs/xfs_alloc.c
C | 2603 lines | 1813 code | 129 blank | 661 comment | 461 complexity | b4fb12d2c36e8ce1ccae689878f96e90 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1/* 2 * Copyright (c) 2000-2002,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_types.h" 21#include "xfs_bit.h" 22#include "xfs_log.h" 23#include "xfs_inum.h" 24#include "xfs_trans.h" 25#include "xfs_sb.h" 26#include "xfs_ag.h" 27#include "xfs_dir2.h" 28#include "xfs_dmapi.h" 29#include "xfs_mount.h" 30#include "xfs_bmap_btree.h" 31#include "xfs_alloc_btree.h" 32#include "xfs_ialloc_btree.h" 33#include "xfs_dir2_sf.h" 34#include "xfs_attr_sf.h" 35#include "xfs_dinode.h" 36#include "xfs_inode.h" 37#include "xfs_btree.h" 38#include "xfs_ialloc.h" 39#include "xfs_alloc.h" 40#include "xfs_error.h" 41#include "xfs_trace.h" 42 43 44#define XFS_ABSDIFF(a,b) (((a) <= (b)) ? ((b) - (a)) : ((a) - (b))) 45 46#define XFSA_FIXUP_BNO_OK 1 47#define XFSA_FIXUP_CNT_OK 2 48 49STATIC void 50xfs_alloc_search_busy(xfs_trans_t *tp, 51 xfs_agnumber_t agno, 52 xfs_agblock_t bno, 53 xfs_extlen_t len); 54 55/* 56 * Prototypes for per-ag allocation routines 57 */ 58 59STATIC int xfs_alloc_ag_vextent_exact(xfs_alloc_arg_t *); 60STATIC int xfs_alloc_ag_vextent_near(xfs_alloc_arg_t *); 61STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); 62STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, 63 xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); 64 65/* 66 * Internal functions. 67 */ 68 69/* 70 * Lookup the record equal to [bno, len] in the btree given by cur. 71 */ 72STATIC int /* error */ 73xfs_alloc_lookup_eq( 74 struct xfs_btree_cur *cur, /* btree cursor */ 75 xfs_agblock_t bno, /* starting block of extent */ 76 xfs_extlen_t len, /* length of extent */ 77 int *stat) /* success/failure */ 78{ 79 cur->bc_rec.a.ar_startblock = bno; 80 cur->bc_rec.a.ar_blockcount = len; 81 return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); 82} 83 84/* 85 * Lookup the first record greater than or equal to [bno, len] 86 * in the btree given by cur. 87 */ 88STATIC int /* error */ 89xfs_alloc_lookup_ge( 90 struct xfs_btree_cur *cur, /* btree cursor */ 91 xfs_agblock_t bno, /* starting block of extent */ 92 xfs_extlen_t len, /* length of extent */ 93 int *stat) /* success/failure */ 94{ 95 cur->bc_rec.a.ar_startblock = bno; 96 cur->bc_rec.a.ar_blockcount = len; 97 return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); 98} 99 100/* 101 * Lookup the first record less than or equal to [bno, len] 102 * in the btree given by cur. 103 */ 104STATIC int /* error */ 105xfs_alloc_lookup_le( 106 struct xfs_btree_cur *cur, /* btree cursor */ 107 xfs_agblock_t bno, /* starting block of extent */ 108 xfs_extlen_t len, /* length of extent */ 109 int *stat) /* success/failure */ 110{ 111 cur->bc_rec.a.ar_startblock = bno; 112 cur->bc_rec.a.ar_blockcount = len; 113 return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); 114} 115 116/* 117 * Update the record referred to by cur to the value given 118 * by [bno, len]. 119 * This either works (return 0) or gets an EFSCORRUPTED error. 120 */ 121STATIC int /* error */ 122xfs_alloc_update( 123 struct xfs_btree_cur *cur, /* btree cursor */ 124 xfs_agblock_t bno, /* starting block of extent */ 125 xfs_extlen_t len) /* length of extent */ 126{ 127 union xfs_btree_rec rec; 128 129 rec.alloc.ar_startblock = cpu_to_be32(bno); 130 rec.alloc.ar_blockcount = cpu_to_be32(len); 131 return xfs_btree_update(cur, &rec); 132} 133 134/* 135 * Get the data from the pointed-to record. 136 */ 137STATIC int /* error */ 138xfs_alloc_get_rec( 139 struct xfs_btree_cur *cur, /* btree cursor */ 140 xfs_agblock_t *bno, /* output: starting block of extent */ 141 xfs_extlen_t *len, /* output: length of extent */ 142 int *stat) /* output: success/failure */ 143{ 144 union xfs_btree_rec *rec; 145 int error; 146 147 error = xfs_btree_get_rec(cur, &rec, stat); 148 if (!error && *stat == 1) { 149 *bno = be32_to_cpu(rec->alloc.ar_startblock); 150 *len = be32_to_cpu(rec->alloc.ar_blockcount); 151 } 152 return error; 153} 154 155/* 156 * Compute aligned version of the found extent. 157 * Takes alignment and min length into account. 158 */ 159STATIC void 160xfs_alloc_compute_aligned( 161 xfs_agblock_t foundbno, /* starting block in found extent */ 162 xfs_extlen_t foundlen, /* length in found extent */ 163 xfs_extlen_t alignment, /* alignment for allocation */ 164 xfs_extlen_t minlen, /* minimum length for allocation */ 165 xfs_agblock_t *resbno, /* result block number */ 166 xfs_extlen_t *reslen) /* result length */ 167{ 168 xfs_agblock_t bno; 169 xfs_extlen_t diff; 170 xfs_extlen_t len; 171 172 if (alignment > 1 && foundlen >= minlen) { 173 bno = roundup(foundbno, alignment); 174 diff = bno - foundbno; 175 len = diff >= foundlen ? 0 : foundlen - diff; 176 } else { 177 bno = foundbno; 178 len = foundlen; 179 } 180 *resbno = bno; 181 *reslen = len; 182} 183 184/* 185 * Compute best start block and diff for "near" allocations. 186 * freelen >= wantlen already checked by caller. 187 */ 188STATIC xfs_extlen_t /* difference value (absolute) */ 189xfs_alloc_compute_diff( 190 xfs_agblock_t wantbno, /* target starting block */ 191 xfs_extlen_t wantlen, /* target length */ 192 xfs_extlen_t alignment, /* target alignment */ 193 xfs_agblock_t freebno, /* freespace's starting block */ 194 xfs_extlen_t freelen, /* freespace's length */ 195 xfs_agblock_t *newbnop) /* result: best start block from free */ 196{ 197 xfs_agblock_t freeend; /* end of freespace extent */ 198 xfs_agblock_t newbno1; /* return block number */ 199 xfs_agblock_t newbno2; /* other new block number */ 200 xfs_extlen_t newlen1=0; /* length with newbno1 */ 201 xfs_extlen_t newlen2=0; /* length with newbno2 */ 202 xfs_agblock_t wantend; /* end of target extent */ 203 204 ASSERT(freelen >= wantlen); 205 freeend = freebno + freelen; 206 wantend = wantbno + wantlen; 207 if (freebno >= wantbno) { 208 if ((newbno1 = roundup(freebno, alignment)) >= freeend) 209 newbno1 = NULLAGBLOCK; 210 } else if (freeend >= wantend && alignment > 1) { 211 newbno1 = roundup(wantbno, alignment); 212 newbno2 = newbno1 - alignment; 213 if (newbno1 >= freeend) 214 newbno1 = NULLAGBLOCK; 215 else 216 newlen1 = XFS_EXTLEN_MIN(wantlen, freeend - newbno1); 217 if (newbno2 < freebno) 218 newbno2 = NULLAGBLOCK; 219 else 220 newlen2 = XFS_EXTLEN_MIN(wantlen, freeend - newbno2); 221 if (newbno1 != NULLAGBLOCK && newbno2 != NULLAGBLOCK) { 222 if (newlen1 < newlen2 || 223 (newlen1 == newlen2 && 224 XFS_ABSDIFF(newbno1, wantbno) > 225 XFS_ABSDIFF(newbno2, wantbno))) 226 newbno1 = newbno2; 227 } else if (newbno2 != NULLAGBLOCK) 228 newbno1 = newbno2; 229 } else if (freeend >= wantend) { 230 newbno1 = wantbno; 231 } else if (alignment > 1) { 232 newbno1 = roundup(freeend - wantlen, alignment); 233 if (newbno1 > freeend - wantlen && 234 newbno1 - alignment >= freebno) 235 newbno1 -= alignment; 236 else if (newbno1 >= freeend) 237 newbno1 = NULLAGBLOCK; 238 } else 239 newbno1 = freeend - wantlen; 240 *newbnop = newbno1; 241 return newbno1 == NULLAGBLOCK ? 0 : XFS_ABSDIFF(newbno1, wantbno); 242} 243 244/* 245 * Fix up the length, based on mod and prod. 246 * len should be k * prod + mod for some k. 247 * If len is too small it is returned unchanged. 248 * If len hits maxlen it is left alone. 249 */ 250STATIC void 251xfs_alloc_fix_len( 252 xfs_alloc_arg_t *args) /* allocation argument structure */ 253{ 254 xfs_extlen_t k; 255 xfs_extlen_t rlen; 256 257 ASSERT(args->mod < args->prod); 258 rlen = args->len; 259 ASSERT(rlen >= args->minlen); 260 ASSERT(rlen <= args->maxlen); 261 if (args->prod <= 1 || rlen < args->mod || rlen == args->maxlen || 262 (args->mod == 0 && rlen < args->prod)) 263 return; 264 k = rlen % args->prod; 265 if (k == args->mod) 266 return; 267 if (k > args->mod) { 268 if ((int)(rlen = rlen - k - args->mod) < (int)args->minlen) 269 return; 270 } else { 271 if ((int)(rlen = rlen - args->prod - (args->mod - k)) < 272 (int)args->minlen) 273 return; 274 } 275 ASSERT(rlen >= args->minlen); 276 ASSERT(rlen <= args->maxlen); 277 args->len = rlen; 278} 279 280/* 281 * Fix up length if there is too little space left in the a.g. 282 * Return 1 if ok, 0 if too little, should give up. 283 */ 284STATIC int 285xfs_alloc_fix_minleft( 286 xfs_alloc_arg_t *args) /* allocation argument structure */ 287{ 288 xfs_agf_t *agf; /* a.g. freelist header */ 289 int diff; /* free space difference */ 290 291 if (args->minleft == 0) 292 return 1; 293 agf = XFS_BUF_TO_AGF(args->agbp); 294 diff = be32_to_cpu(agf->agf_freeblks) 295 + be32_to_cpu(agf->agf_flcount) 296 - args->len - args->minleft; 297 if (diff >= 0) 298 return 1; 299 args->len += diff; /* shrink the allocated space */ 300 if (args->len >= args->minlen) 301 return 1; 302 args->agbno = NULLAGBLOCK; 303 return 0; 304} 305 306/* 307 * Update the two btrees, logically removing from freespace the extent 308 * starting at rbno, rlen blocks. The extent is contained within the 309 * actual (current) free extent fbno for flen blocks. 310 * Flags are passed in indicating whether the cursors are set to the 311 * relevant records. 312 */ 313STATIC int /* error code */ 314xfs_alloc_fixup_trees( 315 xfs_btree_cur_t *cnt_cur, /* cursor for by-size btree */ 316 xfs_btree_cur_t *bno_cur, /* cursor for by-block btree */ 317 xfs_agblock_t fbno, /* starting block of free extent */ 318 xfs_extlen_t flen, /* length of free extent */ 319 xfs_agblock_t rbno, /* starting block of returned extent */ 320 xfs_extlen_t rlen, /* length of returned extent */ 321 int flags) /* flags, XFSA_FIXUP_... */ 322{ 323 int error; /* error code */ 324 int i; /* operation results */ 325 xfs_agblock_t nfbno1; /* first new free startblock */ 326 xfs_agblock_t nfbno2; /* second new free startblock */ 327 xfs_extlen_t nflen1=0; /* first new free length */ 328 xfs_extlen_t nflen2=0; /* second new free length */ 329 330 /* 331 * Look up the record in the by-size tree if necessary. 332 */ 333 if (flags & XFSA_FIXUP_CNT_OK) { 334#ifdef DEBUG 335 if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i))) 336 return error; 337 XFS_WANT_CORRUPTED_RETURN( 338 i == 1 && nfbno1 == fbno && nflen1 == flen); 339#endif 340 } else { 341 if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i))) 342 return error; 343 XFS_WANT_CORRUPTED_RETURN(i == 1); 344 } 345 /* 346 * Look up the record in the by-block tree if necessary. 347 */ 348 if (flags & XFSA_FIXUP_BNO_OK) { 349#ifdef DEBUG 350 if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i))) 351 return error; 352 XFS_WANT_CORRUPTED_RETURN( 353 i == 1 && nfbno1 == fbno && nflen1 == flen); 354#endif 355 } else { 356 if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i))) 357 return error; 358 XFS_WANT_CORRUPTED_RETURN(i == 1); 359 } 360 361#ifdef DEBUG 362 if (bno_cur->bc_nlevels == 1 && cnt_cur->bc_nlevels == 1) { 363 struct xfs_btree_block *bnoblock; 364 struct xfs_btree_block *cntblock; 365 366 bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]); 367 cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); 368 369 XFS_WANT_CORRUPTED_RETURN( 370 bnoblock->bb_numrecs == cntblock->bb_numrecs); 371 } 372#endif 373 374 /* 375 * Deal with all four cases: the allocated record is contained 376 * within the freespace record, so we can have new freespace 377 * at either (or both) end, or no freespace remaining. 378 */ 379 if (rbno == fbno && rlen == flen) 380 nfbno1 = nfbno2 = NULLAGBLOCK; 381 else if (rbno == fbno) { 382 nfbno1 = rbno + rlen; 383 nflen1 = flen - rlen; 384 nfbno2 = NULLAGBLOCK; 385 } else if (rbno + rlen == fbno + flen) { 386 nfbno1 = fbno; 387 nflen1 = flen - rlen; 388 nfbno2 = NULLAGBLOCK; 389 } else { 390 nfbno1 = fbno; 391 nflen1 = rbno - fbno; 392 nfbno2 = rbno + rlen; 393 nflen2 = (fbno + flen) - nfbno2; 394 } 395 /* 396 * Delete the entry from the by-size btree. 397 */ 398 if ((error = xfs_btree_delete(cnt_cur, &i))) 399 return error; 400 XFS_WANT_CORRUPTED_RETURN(i == 1); 401 /* 402 * Add new by-size btree entry(s). 403 */ 404 if (nfbno1 != NULLAGBLOCK) { 405 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) 406 return error; 407 XFS_WANT_CORRUPTED_RETURN(i == 0); 408 if ((error = xfs_btree_insert(cnt_cur, &i))) 409 return error; 410 XFS_WANT_CORRUPTED_RETURN(i == 1); 411 } 412 if (nfbno2 != NULLAGBLOCK) { 413 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) 414 return error; 415 XFS_WANT_CORRUPTED_RETURN(i == 0); 416 if ((error = xfs_btree_insert(cnt_cur, &i))) 417 return error; 418 XFS_WANT_CORRUPTED_RETURN(i == 1); 419 } 420 /* 421 * Fix up the by-block btree entry(s). 422 */ 423 if (nfbno1 == NULLAGBLOCK) { 424 /* 425 * No remaining freespace, just delete the by-block tree entry. 426 */ 427 if ((error = xfs_btree_delete(bno_cur, &i))) 428 return error; 429 XFS_WANT_CORRUPTED_RETURN(i == 1); 430 } else { 431 /* 432 * Update the by-block entry to start later|be shorter. 433 */ 434 if ((error = xfs_alloc_update(bno_cur, nfbno1, nflen1))) 435 return error; 436 } 437 if (nfbno2 != NULLAGBLOCK) { 438 /* 439 * 2 resulting free entries, need to add one. 440 */ 441 if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) 442 return error; 443 XFS_WANT_CORRUPTED_RETURN(i == 0); 444 if ((error = xfs_btree_insert(bno_cur, &i))) 445 return error; 446 XFS_WANT_CORRUPTED_RETURN(i == 1); 447 } 448 return 0; 449} 450 451/* 452 * Read in the allocation group free block array. 453 */ 454STATIC int /* error */ 455xfs_alloc_read_agfl( 456 xfs_mount_t *mp, /* mount point structure */ 457 xfs_trans_t *tp, /* transaction pointer */ 458 xfs_agnumber_t agno, /* allocation group number */ 459 xfs_buf_t **bpp) /* buffer for the ag free block array */ 460{ 461 xfs_buf_t *bp; /* return value */ 462 int error; 463 464 ASSERT(agno != NULLAGNUMBER); 465 error = xfs_trans_read_buf( 466 mp, tp, mp->m_ddev_targp, 467 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), 468 XFS_FSS_TO_BB(mp, 1), 0, &bp); 469 if (error) 470 return error; 471 ASSERT(bp); 472 ASSERT(!XFS_BUF_GETERROR(bp)); 473 XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF); 474 *bpp = bp; 475 return 0; 476} 477 478/* 479 * Allocation group level functions. 480 */ 481 482/* 483 * Allocate a variable extent in the allocation group agno. 484 * Type and bno are used to determine where in the allocation group the 485 * extent will start. 486 * Extent's length (returned in *len) will be between minlen and maxlen, 487 * and of the form k * prod + mod unless there's nothing that large. 488 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. 489 */ 490STATIC int /* error */ 491xfs_alloc_ag_vextent( 492 xfs_alloc_arg_t *args) /* argument structure for allocation */ 493{ 494 int error=0; 495 496 ASSERT(args->minlen > 0); 497 ASSERT(args->maxlen > 0); 498 ASSERT(args->minlen <= args->maxlen); 499 ASSERT(args->mod < args->prod); 500 ASSERT(args->alignment > 0); 501 /* 502 * Branch to correct routine based on the type. 503 */ 504 args->wasfromfl = 0; 505 switch (args->type) { 506 case XFS_ALLOCTYPE_THIS_AG: 507 error = xfs_alloc_ag_vextent_size(args); 508 break; 509 case XFS_ALLOCTYPE_NEAR_BNO: 510 error = xfs_alloc_ag_vextent_near(args); 511 break; 512 case XFS_ALLOCTYPE_THIS_BNO: 513 error = xfs_alloc_ag_vextent_exact(args); 514 break; 515 default: 516 ASSERT(0); 517 /* NOTREACHED */ 518 } 519 if (error) 520 return error; 521 /* 522 * If the allocation worked, need to change the agf structure 523 * (and log it), and the superblock. 524 */ 525 if (args->agbno != NULLAGBLOCK) { 526 xfs_agf_t *agf; /* allocation group freelist header */ 527 long slen = (long)args->len; 528 529 ASSERT(args->len >= args->minlen && args->len <= args->maxlen); 530 ASSERT(!(args->wasfromfl) || !args->isfl); 531 ASSERT(args->agbno % args->alignment == 0); 532 if (!(args->wasfromfl)) { 533 534 agf = XFS_BUF_TO_AGF(args->agbp); 535 be32_add_cpu(&agf->agf_freeblks, -(args->len)); 536 xfs_trans_agblocks_delta(args->tp, 537 -((long)(args->len))); 538 args->pag->pagf_freeblks -= args->len; 539 ASSERT(be32_to_cpu(agf->agf_freeblks) <= 540 be32_to_cpu(agf->agf_length)); 541 xfs_alloc_log_agf(args->tp, args->agbp, 542 XFS_AGF_FREEBLKS); 543 /* search the busylist for these blocks */ 544 xfs_alloc_search_busy(args->tp, args->agno, 545 args->agbno, args->len); 546 } 547 if (!args->isfl) 548 xfs_trans_mod_sb(args->tp, 549 args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS : 550 XFS_TRANS_SB_FDBLOCKS, -slen); 551 XFS_STATS_INC(xs_allocx); 552 XFS_STATS_ADD(xs_allocb, args->len); 553 } 554 return 0; 555} 556 557/* 558 * Allocate a variable extent at exactly agno/bno. 559 * Extent's length (returned in *len) will be between minlen and maxlen, 560 * and of the form k * prod + mod unless there's nothing that large. 561 * Return the starting a.g. block (bno), or NULLAGBLOCK if we can't do it. 562 */ 563STATIC int /* error */ 564xfs_alloc_ag_vextent_exact( 565 xfs_alloc_arg_t *args) /* allocation argument structure */ 566{ 567 xfs_btree_cur_t *bno_cur;/* by block-number btree cursor */ 568 xfs_btree_cur_t *cnt_cur;/* by count btree cursor */ 569 xfs_agblock_t end; /* end of allocated extent */ 570 int error; 571 xfs_agblock_t fbno; /* start block of found extent */ 572 xfs_agblock_t fend; /* end block of found extent */ 573 xfs_extlen_t flen; /* length of found extent */ 574 int i; /* success/failure of operation */ 575 xfs_agblock_t maxend; /* end of maximal extent */ 576 xfs_agblock_t minend; /* end of minimal extent */ 577 xfs_extlen_t rlen; /* length of returned extent */ 578 579 ASSERT(args->alignment == 1); 580 /* 581 * Allocate/initialize a cursor for the by-number freespace btree. 582 */ 583 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 584 args->agno, XFS_BTNUM_BNO); 585 /* 586 * Lookup bno and minlen in the btree (minlen is irrelevant, really). 587 * Look for the closest free block <= bno, it must contain bno 588 * if any free block does. 589 */ 590 if ((error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i))) 591 goto error0; 592 if (!i) { 593 /* 594 * Didn't find it, return null. 595 */ 596 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); 597 args->agbno = NULLAGBLOCK; 598 return 0; 599 } 600 /* 601 * Grab the freespace record. 602 */ 603 if ((error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i))) 604 goto error0; 605 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 606 ASSERT(fbno <= args->agbno); 607 minend = args->agbno + args->minlen; 608 maxend = args->agbno + args->maxlen; 609 fend = fbno + flen; 610 /* 611 * Give up if the freespace isn't long enough for the minimum request. 612 */ 613 if (fend < minend) { 614 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); 615 args->agbno = NULLAGBLOCK; 616 return 0; 617 } 618 /* 619 * End of extent will be smaller of the freespace end and the 620 * maximal requested end. 621 */ 622 end = XFS_AGBLOCK_MIN(fend, maxend); 623 /* 624 * Fix the length according to mod and prod if given. 625 */ 626 args->len = end - args->agbno; 627 xfs_alloc_fix_len(args); 628 if (!xfs_alloc_fix_minleft(args)) { 629 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); 630 return 0; 631 } 632 rlen = args->len; 633 ASSERT(args->agbno + rlen <= fend); 634 end = args->agbno + rlen; 635 /* 636 * We are allocating agbno for rlen [agbno .. end] 637 * Allocate/initialize a cursor for the by-size btree. 638 */ 639 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 640 args->agno, XFS_BTNUM_CNT); 641 ASSERT(args->agbno + args->len <= 642 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 643 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, 644 args->agbno, args->len, XFSA_FIXUP_BNO_OK))) { 645 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); 646 goto error0; 647 } 648 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); 649 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 650 651 trace_xfs_alloc_exact_done(args); 652 args->wasfromfl = 0; 653 return 0; 654 655error0: 656 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); 657 trace_xfs_alloc_exact_error(args); 658 return error; 659} 660 661/* 662 * Allocate a variable extent near bno in the allocation group agno. 663 * Extent's length (returned in len) will be between minlen and maxlen, 664 * and of the form k * prod + mod unless there's nothing that large. 665 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. 666 */ 667STATIC int /* error */ 668xfs_alloc_ag_vextent_near( 669 xfs_alloc_arg_t *args) /* allocation argument structure */ 670{ 671 xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */ 672 xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */ 673 xfs_btree_cur_t *cnt_cur; /* cursor for count btree */ 674 xfs_agblock_t gtbno; /* start bno of right side entry */ 675 xfs_agblock_t gtbnoa; /* aligned ... */ 676 xfs_extlen_t gtdiff; /* difference to right side entry */ 677 xfs_extlen_t gtlen; /* length of right side entry */ 678 xfs_extlen_t gtlena; /* aligned ... */ 679 xfs_agblock_t gtnew; /* useful start bno of right side */ 680 int error; /* error code */ 681 int i; /* result code, temporary */ 682 int j; /* result code, temporary */ 683 xfs_agblock_t ltbno; /* start bno of left side entry */ 684 xfs_agblock_t ltbnoa; /* aligned ... */ 685 xfs_extlen_t ltdiff; /* difference to left side entry */ 686 /*REFERENCED*/ 687 xfs_agblock_t ltend; /* end bno of left side entry */ 688 xfs_extlen_t ltlen; /* length of left side entry */ 689 xfs_extlen_t ltlena; /* aligned ... */ 690 xfs_agblock_t ltnew; /* useful start bno of left side */ 691 xfs_extlen_t rlen; /* length of returned extent */ 692#if defined(DEBUG) && defined(__KERNEL__) 693 /* 694 * Randomly don't execute the first algorithm. 695 */ 696 int dofirst; /* set to do first algorithm */ 697 698 dofirst = random32() & 1; 699#endif 700 /* 701 * Get a cursor for the by-size btree. 702 */ 703 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 704 args->agno, XFS_BTNUM_CNT); 705 ltlen = 0; 706 bno_cur_lt = bno_cur_gt = NULL; 707 /* 708 * See if there are any free extents as big as maxlen. 709 */ 710 if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i))) 711 goto error0; 712 /* 713 * If none, then pick up the last entry in the tree unless the 714 * tree is empty. 715 */ 716 if (!i) { 717 if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, <bno, 718 <len, &i))) 719 goto error0; 720 if (i == 0 || ltlen == 0) { 721 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 722 return 0; 723 } 724 ASSERT(i == 1); 725 } 726 args->wasfromfl = 0; 727 /* 728 * First algorithm. 729 * If the requested extent is large wrt the freespaces available 730 * in this a.g., then the cursor will be pointing to a btree entry 731 * near the right edge of the tree. If it's in the last btree leaf 732 * block, then we just examine all the entries in that block 733 * that are big enough, and pick the best one. 734 * This is written as a while loop so we can break out of it, 735 * but we never loop back to the top. 736 */ 737 while (xfs_btree_islastblock(cnt_cur, 0)) { 738 xfs_extlen_t bdiff; 739 int besti=0; 740 xfs_extlen_t blen=0; 741 xfs_agblock_t bnew=0; 742 743#if defined(DEBUG) && defined(__KERNEL__) 744 if (!dofirst) 745 break; 746#endif 747 /* 748 * Start from the entry that lookup found, sequence through 749 * all larger free blocks. If we're actually pointing at a 750 * record smaller than maxlen, go to the start of this block, 751 * and skip all those smaller than minlen. 752 */ 753 if (ltlen || args->alignment > 1) { 754 cnt_cur->bc_ptrs[0] = 1; 755 do { 756 if ((error = xfs_alloc_get_rec(cnt_cur, <bno, 757 <len, &i))) 758 goto error0; 759 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 760 if (ltlen >= args->minlen) 761 break; 762 if ((error = xfs_btree_increment(cnt_cur, 0, &i))) 763 goto error0; 764 } while (i); 765 ASSERT(ltlen >= args->minlen); 766 if (!i) 767 break; 768 } 769 i = cnt_cur->bc_ptrs[0]; 770 for (j = 1, blen = 0, bdiff = 0; 771 !error && j && (blen < args->maxlen || bdiff > 0); 772 error = xfs_btree_increment(cnt_cur, 0, &j)) { 773 /* 774 * For each entry, decide if it's better than 775 * the previous best entry. 776 */ 777 if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) 778 goto error0; 779 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 780 xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, 781 args->minlen, <bnoa, <lena); 782 if (ltlena < args->minlen) 783 continue; 784 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 785 xfs_alloc_fix_len(args); 786 ASSERT(args->len >= args->minlen); 787 if (args->len < blen) 788 continue; 789 ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, 790 args->alignment, ltbno, ltlen, <new); 791 if (ltnew != NULLAGBLOCK && 792 (args->len > blen || ltdiff < bdiff)) { 793 bdiff = ltdiff; 794 bnew = ltnew; 795 blen = args->len; 796 besti = cnt_cur->bc_ptrs[0]; 797 } 798 } 799 /* 800 * It didn't work. We COULD be in a case where 801 * there's a good record somewhere, so try again. 802 */ 803 if (blen == 0) 804 break; 805 /* 806 * Point at the best entry, and retrieve it again. 807 */ 808 cnt_cur->bc_ptrs[0] = besti; 809 if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) 810 goto error0; 811 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 812 ltend = ltbno + ltlen; 813 ASSERT(ltend <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 814 args->len = blen; 815 if (!xfs_alloc_fix_minleft(args)) { 816 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 817 trace_xfs_alloc_near_nominleft(args); 818 return 0; 819 } 820 blen = args->len; 821 /* 822 * We are allocating starting at bnew for blen blocks. 823 */ 824 args->agbno = bnew; 825 ASSERT(bnew >= ltbno); 826 ASSERT(bnew + blen <= ltend); 827 /* 828 * Set up a cursor for the by-bno tree. 829 */ 830 bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, 831 args->agbp, args->agno, XFS_BTNUM_BNO); 832 /* 833 * Fix up the btree entries. 834 */ 835 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, 836 ltlen, bnew, blen, XFSA_FIXUP_CNT_OK))) 837 goto error0; 838 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 839 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); 840 841 trace_xfs_alloc_near_first(args); 842 return 0; 843 } 844 /* 845 * Second algorithm. 846 * Search in the by-bno tree to the left and to the right 847 * simultaneously, until in each case we find a space big enough, 848 * or run into the edge of the tree. When we run into the edge, 849 * we deallocate that cursor. 850 * If both searches succeed, we compare the two spaces and pick 851 * the better one. 852 * With alignment, it's possible for both to fail; the upper 853 * level algorithm that picks allocation groups for allocations 854 * is not supposed to do this. 855 */ 856 /* 857 * Allocate and initialize the cursor for the leftward search. 858 */ 859 bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 860 args->agno, XFS_BTNUM_BNO); 861 /* 862 * Lookup <= bno to find the leftward search's starting point. 863 */ 864 if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i))) 865 goto error0; 866 if (!i) { 867 /* 868 * Didn't find anything; use this cursor for the rightward 869 * search. 870 */ 871 bno_cur_gt = bno_cur_lt; 872 bno_cur_lt = NULL; 873 } 874 /* 875 * Found something. Duplicate the cursor for the rightward search. 876 */ 877 else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt))) 878 goto error0; 879 /* 880 * Increment the cursor, so we will point at the entry just right 881 * of the leftward entry if any, or to the leftmost entry. 882 */ 883 if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) 884 goto error0; 885 if (!i) { 886 /* 887 * It failed, there are no rightward entries. 888 */ 889 xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR); 890 bno_cur_gt = NULL; 891 } 892 /* 893 * Loop going left with the leftward cursor, right with the 894 * rightward cursor, until either both directions give up or 895 * we find an entry at least as big as minlen. 896 */ 897 do { 898 if (bno_cur_lt) { 899 if ((error = xfs_alloc_get_rec(bno_cur_lt, <bno, <len, &i))) 900 goto error0; 901 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 902 xfs_alloc_compute_aligned(ltbno, ltlen, args->alignment, 903 args->minlen, <bnoa, <lena); 904 if (ltlena >= args->minlen) 905 break; 906 if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i))) 907 goto error0; 908 if (!i) { 909 xfs_btree_del_cursor(bno_cur_lt, 910 XFS_BTREE_NOERROR); 911 bno_cur_lt = NULL; 912 } 913 } 914 if (bno_cur_gt) { 915 if ((error = xfs_alloc_get_rec(bno_cur_gt, >bno, >len, &i))) 916 goto error0; 917 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 918 xfs_alloc_compute_aligned(gtbno, gtlen, args->alignment, 919 args->minlen, >bnoa, >lena); 920 if (gtlena >= args->minlen) 921 break; 922 if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) 923 goto error0; 924 if (!i) { 925 xfs_btree_del_cursor(bno_cur_gt, 926 XFS_BTREE_NOERROR); 927 bno_cur_gt = NULL; 928 } 929 } 930 } while (bno_cur_lt || bno_cur_gt); 931 /* 932 * Got both cursors still active, need to find better entry. 933 */ 934 if (bno_cur_lt && bno_cur_gt) { 935 /* 936 * Left side is long enough, look for a right side entry. 937 */ 938 if (ltlena >= args->minlen) { 939 /* 940 * Fix up the length. 941 */ 942 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 943 xfs_alloc_fix_len(args); 944 rlen = args->len; 945 ltdiff = xfs_alloc_compute_diff(args->agbno, rlen, 946 args->alignment, ltbno, ltlen, <new); 947 /* 948 * Not perfect. 949 */ 950 if (ltdiff) { 951 /* 952 * Look until we find a better one, run out of 953 * space, or run off the end. 954 */ 955 while (bno_cur_lt && bno_cur_gt) { 956 if ((error = xfs_alloc_get_rec( 957 bno_cur_gt, >bno, 958 >len, &i))) 959 goto error0; 960 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 961 xfs_alloc_compute_aligned(gtbno, gtlen, 962 args->alignment, args->minlen, 963 >bnoa, >lena); 964 /* 965 * The left one is clearly better. 966 */ 967 if (gtbnoa >= args->agbno + ltdiff) { 968 xfs_btree_del_cursor( 969 bno_cur_gt, 970 XFS_BTREE_NOERROR); 971 bno_cur_gt = NULL; 972 break; 973 } 974 /* 975 * If we reach a big enough entry, 976 * compare the two and pick the best. 977 */ 978 if (gtlena >= args->minlen) { 979 args->len = 980 XFS_EXTLEN_MIN(gtlena, 981 args->maxlen); 982 xfs_alloc_fix_len(args); 983 rlen = args->len; 984 gtdiff = xfs_alloc_compute_diff( 985 args->agbno, rlen, 986 args->alignment, 987 gtbno, gtlen, >new); 988 /* 989 * Right side is better. 990 */ 991 if (gtdiff < ltdiff) { 992 xfs_btree_del_cursor( 993 bno_cur_lt, 994 XFS_BTREE_NOERROR); 995 bno_cur_lt = NULL; 996 } 997 /* 998 * Left side is better. 999 */ 1000 else { 1001 xfs_btree_del_cursor( 1002 bno_cur_gt, 1003 XFS_BTREE_NOERROR); 1004 bno_cur_gt = NULL; 1005 } 1006 break; 1007 } 1008 /* 1009 * Fell off the right end. 1010 */ 1011 if ((error = xfs_btree_increment( 1012 bno_cur_gt, 0, &i))) 1013 goto error0; 1014 if (!i) { 1015 xfs_btree_del_cursor( 1016 bno_cur_gt, 1017 XFS_BTREE_NOERROR); 1018 bno_cur_gt = NULL; 1019 break; 1020 } 1021 } 1022 } 1023 /* 1024 * The left side is perfect, trash the right side. 1025 */ 1026 else { 1027 xfs_btree_del_cursor(bno_cur_gt, 1028 XFS_BTREE_NOERROR); 1029 bno_cur_gt = NULL; 1030 } 1031 } 1032 /* 1033 * It's the right side that was found first, look left. 1034 */ 1035 else { 1036 /* 1037 * Fix up the length. 1038 */ 1039 args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen); 1040 xfs_alloc_fix_len(args); 1041 rlen = args->len; 1042 gtdiff = xfs_alloc_compute_diff(args->agbno, rlen, 1043 args->alignment, gtbno, gtlen, >new); 1044 /* 1045 * Right side entry isn't perfect. 1046 */ 1047 if (gtdiff) { 1048 /* 1049 * Look until we find a better one, run out of 1050 * space, or run off the end. 1051 */ 1052 while (bno_cur_lt && bno_cur_gt) { 1053 if ((error = xfs_alloc_get_rec( 1054 bno_cur_lt, <bno, 1055 <len, &i))) 1056 goto error0; 1057 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1058 xfs_alloc_compute_aligned(ltbno, ltlen, 1059 args->alignment, args->minlen, 1060 <bnoa, <lena); 1061 /* 1062 * The right one is clearly better. 1063 */ 1064 if (ltbnoa <= args->agbno - gtdiff) { 1065 xfs_btree_del_cursor( 1066 bno_cur_lt, 1067 XFS_BTREE_NOERROR); 1068 bno_cur_lt = NULL; 1069 break; 1070 } 1071 /* 1072 * If we reach a big enough entry, 1073 * compare the two and pick the best. 1074 */ 1075 if (ltlena >= args->minlen) { 1076 args->len = XFS_EXTLEN_MIN( 1077 ltlena, args->maxlen); 1078 xfs_alloc_fix_len(args); 1079 rlen = args->len; 1080 ltdiff = xfs_alloc_compute_diff( 1081 args->agbno, rlen, 1082 args->alignment, 1083 ltbno, ltlen, <new); 1084 /* 1085 * Left side is better. 1086 */ 1087 if (ltdiff < gtdiff) { 1088 xfs_btree_del_cursor( 1089 bno_cur_gt, 1090 XFS_BTREE_NOERROR); 1091 bno_cur_gt = NULL; 1092 } 1093 /* 1094 * Right side is better. 1095 */ 1096 else { 1097 xfs_btree_del_cursor( 1098 bno_cur_lt, 1099 XFS_BTREE_NOERROR); 1100 bno_cur_lt = NULL; 1101 } 1102 break; 1103 } 1104 /* 1105 * Fell off the left end. 1106 */ 1107 if ((error = xfs_btree_decrement( 1108 bno_cur_lt, 0, &i))) 1109 goto error0; 1110 if (!i) { 1111 xfs_btree_del_cursor(bno_cur_lt, 1112 XFS_BTREE_NOERROR); 1113 bno_cur_lt = NULL; 1114 break; 1115 } 1116 } 1117 } 1118 /* 1119 * The right side is perfect, trash the left side. 1120 */ 1121 else { 1122 xfs_btree_del_cursor(bno_cur_lt, 1123 XFS_BTREE_NOERROR); 1124 bno_cur_lt = NULL; 1125 } 1126 } 1127 } 1128 /* 1129 * If we couldn't get anything, give up. 1130 */ 1131 if (bno_cur_lt == NULL && bno_cur_gt == NULL) { 1132 trace_xfs_alloc_size_neither(args); 1133 args->agbno = NULLAGBLOCK; 1134 return 0; 1135 } 1136 /* 1137 * At this point we have selected a freespace entry, either to the 1138 * left or to the right. If it's on the right, copy all the 1139 * useful variables to the "left" set so we only have one 1140 * copy of this code. 1141 */ 1142 if (bno_cur_gt) { 1143 bno_cur_lt = bno_cur_gt; 1144 bno_cur_gt = NULL; 1145 ltbno = gtbno; 1146 ltbnoa = gtbnoa; 1147 ltlen = gtlen; 1148 ltlena = gtlena; 1149 j = 1; 1150 } else 1151 j = 0; 1152 /* 1153 * Fix up the length and compute the useful address. 1154 */ 1155 ltend = ltbno + ltlen; 1156 args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 1157 xfs_alloc_fix_len(args); 1158 if (!xfs_alloc_fix_minleft(args)) { 1159 trace_xfs_alloc_near_nominleft(args); 1160 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); 1161 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1162 return 0; 1163 } 1164 rlen = args->len; 1165 (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, ltbno, 1166 ltlen, <new); 1167 ASSERT(ltnew >= ltbno); 1168 ASSERT(ltnew + rlen <= ltend); 1169 ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 1170 args->agbno = ltnew; 1171 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, 1172 ltnew, rlen, XFSA_FIXUP_BNO_OK))) 1173 goto error0; 1174 1175 if (j) 1176 trace_xfs_alloc_near_greater(args); 1177 else 1178 trace_xfs_alloc_near_lesser(args); 1179 1180 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1181 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); 1182 return 0; 1183 1184 error0: 1185 trace_xfs_alloc_near_error(args); 1186 if (cnt_cur != NULL) 1187 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); 1188 if (bno_cur_lt != NULL) 1189 xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR); 1190 if (bno_cur_gt != NULL) 1191 xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR); 1192 return error; 1193} 1194 1195/* 1196 * Allocate a variable extent anywhere in the allocation group agno. 1197 * Extent's length (returned in len) will be between minlen and maxlen, 1198 * and of the form k * prod + mod unless there's nothing that large. 1199 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. 1200 */ 1201STATIC int /* error */ 1202xfs_alloc_ag_vextent_size( 1203 xfs_alloc_arg_t *args) /* allocation argument structure */ 1204{ 1205 xfs_btree_cur_t *bno_cur; /* cursor for bno btree */ 1206 xfs_btree_cur_t *cnt_cur; /* cursor for cnt btree */ 1207 int error; /* error result */ 1208 xfs_agblock_t fbno; /* start of found freespace */ 1209 xfs_extlen_t flen; /* length of found freespace */ 1210 int i; /* temp status variable */ 1211 xfs_agblock_t rbno; /* returned block number */ 1212 xfs_extlen_t rlen; /* length of returned extent */ 1213 1214 /* 1215 * Allocate and initialize a cursor for the by-size btree. 1216 */ 1217 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 1218 args->agno, XFS_BTNUM_CNT); 1219 bno_cur = NULL; 1220 /* 1221 * Look for an entry >= maxlen+alignment-1 blocks. 1222 */ 1223 if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, 1224 args->maxlen + args->alignment - 1, &i))) 1225 goto error0; 1226 /* 1227 * If none, then pick up the last entry in the tree unless the 1228 * tree is empty. 1229 */ 1230 if (!i) { 1231 if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &fbno, 1232 &flen, &i))) 1233 goto error0; 1234 if (i == 0 || flen == 0) { 1235 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1236 trace_xfs_alloc_size_noentry(args); 1237 return 0; 1238 } 1239 ASSERT(i == 1); 1240 } 1241 /* 1242 * There's a freespace as big as maxlen+alignment-1, get it. 1243 */ 1244 else { 1245 if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i))) 1246 goto error0; 1247 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1248 } 1249 /* 1250 * In the first case above, we got the last entry in the 1251 * by-size btree. Now we check to see if the space hits maxlen 1252 * once aligned; if not, we search left for something better. 1253 * This can't happen in the second case above. 1254 */ 1255 xfs_alloc_compute_aligned(fbno, flen, args->alignment, args->minlen, 1256 &rbno, &rlen); 1257 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); 1258 XFS_WANT_CORRUPTED_GOTO(rlen == 0 || 1259 (rlen <= flen && rbno + rlen <= fbno + flen), error0); 1260 if (rlen < args->maxlen) { 1261 xfs_agblock_t bestfbno; 1262 xfs_extlen_t bestflen; 1263 xfs_agblock_t bestrbno; 1264 xfs_extlen_t bestrlen; 1265 1266 bestrlen = rlen; 1267 bestrbno = rbno; 1268 bestflen = flen; 1269 bestfbno = fbno; 1270 for (;;) { 1271 if ((error = xfs_btree_decrement(cnt_cur, 0, &i))) 1272 goto error0; 1273 if (i == 0) 1274 break; 1275 if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, 1276 &i))) 1277 goto error0; 1278 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1279 if (flen < bestrlen) 1280 break; 1281 xfs_alloc_compute_aligned(fbno, flen, args->alignment, 1282 args->minlen, &rbno, &rlen); 1283 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); 1284 XFS_WANT_CORRUPTED_GOTO(rlen == 0 || 1285 (rlen <= flen && rbno + rlen <= fbno + flen), 1286 error0); 1287 if (rlen > bestrlen) { 1288 bestrlen = rlen; 1289 bestrbno = rbno; 1290 bestflen = flen; 1291 bestfbno = fbno; 1292 if (rlen == args->maxlen) 1293 break; 1294 } 1295 } 1296 if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen, 1297 &i))) 1298 goto error0; 1299 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1300 rlen = bestrlen; 1301 rbno = bestrbno; 1302 flen = bestflen; 1303 fbno = bestfbno; 1304 } 1305 args->wasfromfl = 0; 1306 /* 1307 * Fix up the length. 1308 */ 1309 args->len = rlen; 1310 xfs_alloc_fix_len(args); 1311 if (rlen < args->minlen || !xfs_alloc_fix_minleft(args)) { 1312 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1313 trace_xfs_alloc_size_nominleft(args); 1314 args->agbno = NULLAGBLOCK; 1315 return 0; 1316 } 1317 rlen = args->len; 1318 XFS_WANT_CORRUPTED_GOTO(rlen <= flen, error0); 1319 /* 1320 * Allocate and initialize a cursor for the by-block tree. 1321 */ 1322 bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 1323 args->agno, XFS_BTNUM_BNO); 1324 if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, 1325 rbno, rlen, XFSA_FIXUP_CNT_OK))) 1326 goto error0; 1327 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1328 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); 1329 cnt_cur = bno_cur = NULL; 1330 args->len = rlen; 1331 args->agbno = rbno; 1332 XFS_WANT_CORRUPTED_GOTO( 1333 args->agbno + args->len <= 1334 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), 1335 error0); 1336 trace_xfs_alloc_size_done(args); 1337 return 0; 1338 1339error0: 1340 trace_xfs_alloc_size_error(args); 1341 if (cnt_cur) 1342 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); 1343 if (bno_cur) 1344 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); 1345 return error; 1346} 1347 1348/* 1349 * Deal with the case where only small freespaces remain. 1350 * Either return the contents of the last freespace record, 1351 * or allocate space from the freelist if there is nothing in the tree. 1352 */ 1353STATIC int /* error */ 1354xfs_alloc_ag_vextent_small( 1355 xfs_alloc_arg_t *args, /* allocation argument structure */ 1356 xfs_btree_cur_t *ccur, /* by-size cursor */ 1357 xfs_agblock_t *fbnop, /* result block number */ 1358 xfs_extlen_t *flenp, /* result length */ 1359 int *stat) /* status: 0-freelist, 1-normal/none */ 1360{ 1361 int error; 1362 xfs_agblock_t fbno; 1363 xfs_extlen_t flen; 1364 int i; 1365 1366 if ((error = xfs_btree_decrement(ccur, 0, &i))) 1367 goto error0; 1368 if (i) { 1369 if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) 1370 goto error0; 1371 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1372 } 1373 /* 1374 * Nothing in the btree, try the freelist. Make sure 1375 * to respect minleft even when pulling from the 1376 * freelist. 1377 */ 1378 else if (args->minlen == 1 && args->alignment == 1 && !args->isfl && 1379 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) 1380 > args->minleft)) { 1381 error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0); 1382 if (error) 1383 goto error0; 1384 if (fbno != NULLAGBLOCK) { 1385 if (args->userdata) { 1386 xfs_buf_t *bp; 1387 1388 bp = xfs_btree_get_bufs(args->mp, args->tp, 1389 args->agno, fbno, 0); 1390 xfs_trans_binval(args->tp, bp); 1391 } 1392 args->len = 1; 1393 args->agbno = fbno; 1394 XFS_WANT_CORRUPTED_GOTO( 1395 args->agbno + args->len <= 1396 be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), 1397 error0); 1398 args->wasfromfl = 1; 1399 trace_xfs_alloc_small_freelist(args); 1400 *stat = 0; 1401 return 0; 1402 } 1403 /* 1404 * Nothing in the freelist. 1405 */ 1406 else 1407 flen = 0; 1408 } 1409 /* 1410 * Can't allocate from the freelist for some reason. 1411 */ 1412 else { 1413 fbno = NULLAGBLOCK; 1414 flen = 0; 1415 } 1416 /* 1417 * Can't do the allocation, give up. 1418 */ 1419 if (flen < args->minlen) { 1420 args->agbno = NULLAGBLOCK; 1421 trace_xfs_alloc_small_notenough(args); 1422 flen = 0; 1423 } 1424 *fbnop = fbno; 1425 *flenp = flen; 1426 *stat = 1; 1427 trace_xfs_alloc_small_done(args); 1428 return 0; 1429 1430error0: 1431 trace_xfs_alloc_small_error(args); 1432 return error; 1433} 1434 1435/* 1436 * Free the extent starting at agno/bno for length. 1437 */ 1438STATIC int /* error */ 1439xfs_free_ag_extent( 1440 xfs_trans_t *tp, /* transaction pointer */ 1441 xfs_buf_t *agbp, /* buffer for a.g. freelist header */ 1442 xfs_agnumber_t agno, /* allocation group number */ 1443 xfs_agblock_t bno, /* starting block number */ 1444 xfs_extlen_t len, /* length of extent */ 1445 int isfl) /* set if is freelist blocks - no sb acctg */ 1446{ 1447 xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ 1448 xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */ 1449 int error; /* error return value */ 1450 xfs_agblock_t gtbno; /* start of right neighbor block */ 1451 xfs_extlen_t gtlen; /* length of right neighbor block */ 1452 int haveleft; /* have a left neighbor block */ 1453 int haveright; /* have a right neighbor block */ 1454 int i; /* temp, result code */ 1455 xfs_agblock_t ltbno; /* start of left neighbor block */ 1456 xfs_extlen_t ltlen; /* length of left neighbor block */ 1457 xfs_mount_t *mp; /* mount point struct for filesystem */ 1458 xfs_agblock_t nbno; /* new starting block of freespace */ 1459 xfs_extlen_t nlen; /* new length of freespace */ 1460 1461 mp = tp->t_mountp; 1462 /* 1463 * Allocate and initialize a cursor for the by-block btree. 1464 */ 1465 bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO); 1466 cnt_cur = NULL; 1467 /* 1468 * Look for a neighboring block on the left (lower block numbers) 1469 * that is contiguous with this space. 1470 */ 1471 if ((error = xfs_alloc_lookup_le(bno_cur, bno, len, &haveleft))) 1472 goto error0; 1473 if (haveleft) { 1474 /* 1475 * There is a block to our left. 1476 */ 1477 if ((error = xfs_alloc_get_rec(bno_cur, <bno, <len, &i))) 1478 goto error0; 1479 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1480 /* 1481 * It's not contiguous, though. 1482 */ 1483 if (ltbno + ltlen < bno) 1484 haveleft = 0; 1485 else { 1486 /* 1487 * If this failure happens the request to free this 1488 * space was invalid, it's (partly) already free. 1489 * Very bad. 1490 */ 1491 XFS_WANT_CORRUPTED_GOTO(ltbno + ltlen <= bno, error0); 1492 } 1493 } 1494 /* 1495 * Look for a neighboring block on the right (higher block numbers) 1496 * that is contiguous with this space. 1497 */ 1498 if ((error = xfs_btree_increment(bno_cur, 0, &haveright))) 1499 goto error0; 1500 if (haveright) { 1501 /* 1502 * There is a block to our right. 1503 */ 1504 if ((error = xfs_alloc_get_rec(bno_cur, >bno, >len, &i))) 1505 goto error0; 1506 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1507 /* 1508 * It's not contiguous, though. 1509 */ 1510 if (bno + len < gtbno) 1511 haveright = 0; 1512 else { 1513 /* 1514 * If this failure happens the request to free this 1515 * space was invalid, it's (partly) already free. 1516 * Very bad. 1517 */ 1518 XFS_WANT_CORRUPTED_GOTO(gtbno >= bno + len, error0); 1519 } 1520 } 1521 /* 1522 * Now allocate and initialize a cursor for the by-size tree. 1523 */ 1524 cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT); 1525 /* 1526 * Have both left and right contiguous neighbors. 1527 * Merge all three into a single free block. 1528 */ 1529 if (haveleft && haveright) { 1530 /* 1531 * Delete the old by-size entry on the left. 1532 */ 1533 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) 1534 goto error0; 1535 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1536 if ((error = xfs_btree_delete(cnt_cur, &i))) 1537 goto error0; 1538 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1539 /* 1540 * Delete the old by-size entry on the right. 1541 */ 1542 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) 1543 goto error0; 1544 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1545 if ((error = xfs_btree_delete(cnt_cur, &i))) 1546 goto error0; 1547 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1548 /* 1549 * Delete the old by-block entry for the right block. 1550 */ 1551 if ((error = xfs_btree_delete(bno_cur, &i))) 1552 goto error0; 1553 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1554 /* 1555 * Move the by-block cursor back to the left neighbor. 1556 */ 1557 if ((error = xfs_btree_decrement(bno_cur, 0, &i))) 1558 goto error0; 1559 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1560#ifdef DEBUG 1561 /* 1562 * Check that this is the right record: delete didn't 1563 * mangle the cursor. 1564 */ 1565 { 1566 xfs_agblock_t xxbno; 1567 xfs_extlen_t xxlen; 1568 1569 if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen, 1570 &i))) 1571 goto error0; 1572 XFS_WANT_CORRUPTED_GOTO( 1573 i == 1 && xxbno == ltbno && xxlen == ltlen, 1574 error0); 1575 } 1576#endif 1577 /* 1578 * Update remaining by-block entry to the new, joined block. 1579 */ 1580 nbno = ltbno; 1581 nlen = len + ltlen + gtlen; 1582 if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) 1583 goto error0; 1584 } 1585 /* 1586 * Have only a left contiguous neighbor. 1587 * Merge it together with the new freespace. 1588 */ 1589 else if (haveleft) { 1590 /* 1591 * Delete the old by-size entry on the left. 1592 */ 1593 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) 1594 goto error0; 1595 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1596 if ((error = xfs_btree_delete(cnt_cur, &i))) 1597 goto error0; 1598 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1599 /* 1600 * Back up the by-block cursor to the left neighbor, and 1601 * update its length. 1602 */ 1603 if ((error = xfs_btree_decrement(bno_cur, 0, &i))) 1604 goto error0; 1605 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1606 nbno = ltbno; 1607 nlen = len + ltlen; 1608 if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) 1609 goto error0; 1610 } 1611 /* 1612 * Have only a right contiguous neighbor. 1613 * Merge it together with the new freespace. 1614 */ 1615 else if (haveright) { 1616 /* 1617 * Delete the old by-size entry on the right. 1618 */ 1619 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) 1620 goto error0; 1621 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1622 if ((error = xfs_btree_delete(cnt_cur, &i))) 1623 goto error0; 1624 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1625 /* 1626 * Update the starting block and length of the right 1627 * neighbor in the by-block tree. 1628 */ 1629 nbno = bno; 1630 nlen = len + gtlen; 1631 if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) 1632 goto error0; 1633 } 1634 /* 1635 * No contiguous neighbors. 1636 * Insert the new freespace into the by-block tree. 1637 */ 1638 else { 1639 nbno = bno; 1640 nlen = len; 1641 if ((error = xfs_btree_insert(bno_cur, &i))) 1642 goto error0; 1643 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1644 } 1645 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); 1646 bno_cur = NULL; 1647 /* 1648 * In all cases we need to insert the new freespace in the by-size tree. 1649 */ 1650 if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) 1651 goto error0; 1652 XFS_WANT_CORRUPTED_GOTO(i == 0, error0); 1653 if ((error = xfs_btree_insert(cnt_cur, &i))) 1654 goto error0; 1655 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1656 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1657 cnt_cur = NULL; 1658 /* 1659 * Update the freespace totals in the ag and superblock. 1660 */ 1661 { 1662 xfs_agf_t *agf; 1663 xfs_perag_t *pag; /* per allocation group data */ 1664 1665 agf = XFS_BUF_TO_AGF(agbp); 1666 pag = &mp->m_perag[agno]; 1667 be32_add_cpu(&agf->agf_freeblks, len); 1668 xfs_trans_agblocks_delta(tp, len); 1669 pag->pagf_freeblks += len; 1670 XFS_WANT_CORRUPTED_GOTO( 1671 be32_to_cpu(agf->agf_freeblks) <= 1672 be32_to_cpu(agf->agf_length), 1673 error0); 1674 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); 1675 if (!isfl) 1676 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); 1677 XFS_STATS_INC(xs_freex); 1678 XFS_STATS_ADD(xs_freeb, len); 1679 } 1680 1681 trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); 1682 1683 /* 1684 * Since blocks move to the free list without the coordination 1685 * used in xfs_bmap_finish, we can't allow block to be available 1686 * for reallocation and non-transaction writing (user data) 1687 * until we know that the transaction that moved it to the free 1688 * list is permanently on disk. We track the blocks by declaring 1689 * these blocks as "busy"; the busy list is maintained on a per-ag 1690 * basis and each transaction records which entries should be removed 1691 * when the iclog commits to disk. If a busy block is allocated, 1692 * the iclog is pushed up to the LSN that freed the block. 1693 */ 1694 xfs_alloc_mark_busy(tp, agno, bno, len); 1695 return 0; 1696 1697 error0: 1698 trace_xfs_free_extent(mp, agno, bno, len, isfl, -1, -1); 1699 if (bno_cur) 1700 xfs_btree_del_cursor(bno_cur, XFS_BTREE_ERROR); 1701 if (cnt_cur) 1702 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); 1703 return error; 1704} 1705 1706/* 1707 * Visible (exported) allocation/free functions. 1708 * Some of these are used just by xfs_alloc_btree.c and this file. 1709 */ 1710 1711/* 1712 * Compute and fill in value of m_ag_maxlevels. 1713 */ 1714void 1715xfs_alloc_compute_maxlevels( 1716 xfs_mount_t *mp) /* file system mount structure */ 1717{ 1718 int level; 1719 uint maxblocks; 1720 uint maxleafents; 1721 int minleafrecs; 1722 int minnoderecs; 1723 1724 maxleafents = (mp->m_sb.sb_agblocks + 1) / 2; 1725 minleafrecs = mp->m_alloc_mnr[0]; 1726 minnoderecs = mp->m_alloc_mnr[1]; 1727 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; 1728 for (level = 1; maxblocks > 1; level++) 1729 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; 1730 mp->m_ag_maxlevels = level; 1731} 1732 1733/* 1734 * Find the length of the longest extent in an AG. 1735 */ 1736xfs_extlen_t 1737xfs_alloc_longest_free_extent( 1738 struct xfs_mount *mp, 1739 struct xfs_perag *pag) 1740{ 1741 xfs_extlen_t need, delta = 0; 1742 1743 need = XFS_MIN_FREELIST_PAG(pag, mp); 1744 if (need > pag->pagf_flcount) 1745 delta = need - pag->pagf_flcount; 1746 1747 if (pag->pagf_longest > delta) 1748 return pag->pagf_longest - delta; 1749 return pag->pagf_flcount > 0 || pag->pagf_longest > 0; 1750} 1751 1752/* 1753 * Decide whether to use this allocation group for this allocation. 1754 * If so, fix up the btree freelist's size. 1755 */ 1756STATIC int /* error */ 1757xfs_alloc_fix_freelist( 1758 xfs_alloc_arg_t *args, /* allocation argument structure */ 1759 int flags) /* XFS_ALLOC_FLAG_... */ 1760{ 1761 xfs_buf_t *agbp; /* agf buffer pointer */ 1762 xfs_agf_t *agf; /* a.g. freespace structure pointer */ 1763 xfs_buf_t *agflbp;/* agfl buffer pointer */ 1764 xfs_agblock_t bno; /* freelist block */ 1765 xfs_extlen_t delta; /* new blocks needed in freelist */ 1766 int error; /* error result code *…
Large files files are truncated, but you can click here to view the full file