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

Configure Feed

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

at v2.6.14-rc2 6285 lines 195 kB view raw
1/* 2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 59 21 * Temple Place - Suite 330, Boston MA 02111-1307, USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ 31 */ 32 33#include "xfs.h" 34 35#include "xfs_macros.h" 36#include "xfs_types.h" 37#include "xfs_inum.h" 38#include "xfs_log.h" 39#include "xfs_trans.h" 40#include "xfs_sb.h" 41#include "xfs_ag.h" 42#include "xfs_dir.h" 43#include "xfs_dir2.h" 44#include "xfs_dmapi.h" 45#include "xfs_mount.h" 46#include "xfs_alloc_btree.h" 47#include "xfs_bmap_btree.h" 48#include "xfs_ialloc_btree.h" 49#include "xfs_btree.h" 50#include "xfs_ialloc.h" 51#include "xfs_attr_sf.h" 52#include "xfs_dir_sf.h" 53#include "xfs_dir2_sf.h" 54#include "xfs_dinode.h" 55#include "xfs_inode_item.h" 56#include "xfs_inode.h" 57#include "xfs_itable.h" 58#include "xfs_extfree_item.h" 59#include "xfs_alloc.h" 60#include "xfs_bmap.h" 61#include "xfs_rtalloc.h" 62#include "xfs_error.h" 63#include "xfs_da_btree.h" 64#include "xfs_dir_leaf.h" 65#include "xfs_bit.h" 66#include "xfs_rw.h" 67#include "xfs_quota.h" 68#include "xfs_trans_space.h" 69#include "xfs_buf_item.h" 70 71 72#ifdef DEBUG 73STATIC void 74xfs_bmap_check_leaf_extents(xfs_btree_cur_t *cur, xfs_inode_t *ip, int whichfork); 75#endif 76 77kmem_zone_t *xfs_bmap_free_item_zone; 78 79/* 80 * Prototypes for internal bmap routines. 81 */ 82 83 84/* 85 * Called from xfs_bmap_add_attrfork to handle extents format files. 86 */ 87STATIC int /* error */ 88xfs_bmap_add_attrfork_extents( 89 xfs_trans_t *tp, /* transaction pointer */ 90 xfs_inode_t *ip, /* incore inode pointer */ 91 xfs_fsblock_t *firstblock, /* first block allocated */ 92 xfs_bmap_free_t *flist, /* blocks to free at commit */ 93 int *flags); /* inode logging flags */ 94 95/* 96 * Called from xfs_bmap_add_attrfork to handle local format files. 97 */ 98STATIC int /* error */ 99xfs_bmap_add_attrfork_local( 100 xfs_trans_t *tp, /* transaction pointer */ 101 xfs_inode_t *ip, /* incore inode pointer */ 102 xfs_fsblock_t *firstblock, /* first block allocated */ 103 xfs_bmap_free_t *flist, /* blocks to free at commit */ 104 int *flags); /* inode logging flags */ 105 106/* 107 * Called by xfs_bmapi to update extent list structure and the btree 108 * after allocating space (or doing a delayed allocation). 109 */ 110STATIC int /* error */ 111xfs_bmap_add_extent( 112 xfs_inode_t *ip, /* incore inode pointer */ 113 xfs_extnum_t idx, /* extent number to update/insert */ 114 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 115 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 116 xfs_fsblock_t *first, /* pointer to firstblock variable */ 117 xfs_bmap_free_t *flist, /* list of extents to be freed */ 118 int *logflagsp, /* inode logging flags */ 119 int whichfork, /* data or attr fork */ 120 int rsvd); /* OK to allocate reserved blocks */ 121 122/* 123 * Called by xfs_bmap_add_extent to handle cases converting a delayed 124 * allocation to a real allocation. 125 */ 126STATIC int /* error */ 127xfs_bmap_add_extent_delay_real( 128 xfs_inode_t *ip, /* incore inode pointer */ 129 xfs_extnum_t idx, /* extent number to update/insert */ 130 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 131 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 132 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 133 xfs_fsblock_t *first, /* pointer to firstblock variable */ 134 xfs_bmap_free_t *flist, /* list of extents to be freed */ 135 int *logflagsp, /* inode logging flags */ 136 int rsvd); /* OK to allocate reserved blocks */ 137 138/* 139 * Called by xfs_bmap_add_extent to handle cases converting a hole 140 * to a delayed allocation. 141 */ 142STATIC int /* error */ 143xfs_bmap_add_extent_hole_delay( 144 xfs_inode_t *ip, /* incore inode pointer */ 145 xfs_extnum_t idx, /* extent number to update/insert */ 146 xfs_btree_cur_t *cur, /* if null, not a btree */ 147 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 148 int *logflagsp,/* inode logging flags */ 149 int rsvd); /* OK to allocate reserved blocks */ 150 151/* 152 * Called by xfs_bmap_add_extent to handle cases converting a hole 153 * to a real allocation. 154 */ 155STATIC int /* error */ 156xfs_bmap_add_extent_hole_real( 157 xfs_inode_t *ip, /* incore inode pointer */ 158 xfs_extnum_t idx, /* extent number to update/insert */ 159 xfs_btree_cur_t *cur, /* if null, not a btree */ 160 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 161 int *logflagsp, /* inode logging flags */ 162 int whichfork); /* data or attr fork */ 163 164/* 165 * Called by xfs_bmap_add_extent to handle cases converting an unwritten 166 * allocation to a real allocation or vice versa. 167 */ 168STATIC int /* error */ 169xfs_bmap_add_extent_unwritten_real( 170 xfs_inode_t *ip, /* incore inode pointer */ 171 xfs_extnum_t idx, /* extent number to update/insert */ 172 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 173 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 174 int *logflagsp); /* inode logging flags */ 175 176/* 177 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 178 * It figures out where to ask the underlying allocator to put the new extent. 179 */ 180STATIC int /* error */ 181xfs_bmap_alloc( 182 xfs_bmalloca_t *ap); /* bmap alloc argument struct */ 183 184/* 185 * Transform a btree format file with only one leaf node, where the 186 * extents list will fit in the inode, into an extents format file. 187 * Since the extent list is already in-core, all we have to do is 188 * give up the space for the btree root and pitch the leaf block. 189 */ 190STATIC int /* error */ 191xfs_bmap_btree_to_extents( 192 xfs_trans_t *tp, /* transaction pointer */ 193 xfs_inode_t *ip, /* incore inode pointer */ 194 xfs_btree_cur_t *cur, /* btree cursor */ 195 int *logflagsp, /* inode logging flags */ 196 int whichfork); /* data or attr fork */ 197 198#ifdef DEBUG 199/* 200 * Check that the extents list for the inode ip is in the right order. 201 */ 202STATIC void 203xfs_bmap_check_extents( 204 xfs_inode_t *ip, /* incore inode pointer */ 205 int whichfork); /* data or attr fork */ 206#endif 207 208/* 209 * Called by xfs_bmapi to update extent list structure and the btree 210 * after removing space (or undoing a delayed allocation). 211 */ 212STATIC int /* error */ 213xfs_bmap_del_extent( 214 xfs_inode_t *ip, /* incore inode pointer */ 215 xfs_trans_t *tp, /* current trans pointer */ 216 xfs_extnum_t idx, /* extent number to update/insert */ 217 xfs_bmap_free_t *flist, /* list of extents to be freed */ 218 xfs_btree_cur_t *cur, /* if null, not a btree */ 219 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 220 int *logflagsp,/* inode logging flags */ 221 int whichfork, /* data or attr fork */ 222 int rsvd); /* OK to allocate reserved blocks */ 223 224/* 225 * Remove the entry "free" from the free item list. Prev points to the 226 * previous entry, unless "free" is the head of the list. 227 */ 228STATIC void 229xfs_bmap_del_free( 230 xfs_bmap_free_t *flist, /* free item list header */ 231 xfs_bmap_free_item_t *prev, /* previous item on list, if any */ 232 xfs_bmap_free_item_t *free); /* list item to be freed */ 233 234/* 235 * Remove count entries from the extents array for inode "ip", starting 236 * at index "idx". Copies the remaining items down over the deleted ones, 237 * and gives back the excess memory. 238 */ 239STATIC void 240xfs_bmap_delete_exlist( 241 xfs_inode_t *ip, /* incode inode pointer */ 242 xfs_extnum_t idx, /* starting delete index */ 243 xfs_extnum_t count, /* count of items to delete */ 244 int whichfork); /* data or attr fork */ 245 246/* 247 * Convert an extents-format file into a btree-format file. 248 * The new file will have a root block (in the inode) and a single child block. 249 */ 250STATIC int /* error */ 251xfs_bmap_extents_to_btree( 252 xfs_trans_t *tp, /* transaction pointer */ 253 xfs_inode_t *ip, /* incore inode pointer */ 254 xfs_fsblock_t *firstblock, /* first-block-allocated */ 255 xfs_bmap_free_t *flist, /* blocks freed in xaction */ 256 xfs_btree_cur_t **curp, /* cursor returned to caller */ 257 int wasdel, /* converting a delayed alloc */ 258 int *logflagsp, /* inode logging flags */ 259 int whichfork); /* data or attr fork */ 260 261/* 262 * Insert new item(s) in the extent list for inode "ip". 263 * Count new items are inserted at offset idx. 264 */ 265STATIC void 266xfs_bmap_insert_exlist( 267 xfs_inode_t *ip, /* incore inode pointer */ 268 xfs_extnum_t idx, /* starting index of new items */ 269 xfs_extnum_t count, /* number of inserted items */ 270 xfs_bmbt_irec_t *new, /* items to insert */ 271 int whichfork); /* data or attr fork */ 272 273/* 274 * Convert a local file to an extents file. 275 * This code is sort of bogus, since the file data needs to get 276 * logged so it won't be lost. The bmap-level manipulations are ok, though. 277 */ 278STATIC int /* error */ 279xfs_bmap_local_to_extents( 280 xfs_trans_t *tp, /* transaction pointer */ 281 xfs_inode_t *ip, /* incore inode pointer */ 282 xfs_fsblock_t *firstblock, /* first block allocated in xaction */ 283 xfs_extlen_t total, /* total blocks needed by transaction */ 284 int *logflagsp, /* inode logging flags */ 285 int whichfork); /* data or attr fork */ 286 287/* 288 * Search the extents list for the inode, for the extent containing bno. 289 * If bno lies in a hole, point to the next entry. If bno lies past eof, 290 * *eofp will be set, and *prevp will contain the last entry (null if none). 291 * Else, *lastxp will be set to the index of the found 292 * entry; *gotp will contain the entry. 293 */ 294STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ 295xfs_bmap_search_extents( 296 xfs_inode_t *ip, /* incore inode pointer */ 297 xfs_fileoff_t bno, /* block number searched for */ 298 int whichfork, /* data or attr fork */ 299 int *eofp, /* out: end of file found */ 300 xfs_extnum_t *lastxp, /* out: last extent index */ 301 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 302 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */ 303 304/* 305 * Check the last inode extent to determine whether this allocation will result 306 * in blocks being allocated at the end of the file. When we allocate new data 307 * blocks at the end of the file which do not start at the previous data block, 308 * we will try to align the new blocks at stripe unit boundaries. 309 */ 310STATIC int /* error */ 311xfs_bmap_isaeof( 312 xfs_inode_t *ip, /* incore inode pointer */ 313 xfs_fileoff_t off, /* file offset in fsblocks */ 314 int whichfork, /* data or attribute fork */ 315 char *aeof); /* return value */ 316 317#ifdef XFS_BMAP_TRACE 318/* 319 * Add a bmap trace buffer entry. Base routine for the others. 320 */ 321STATIC void 322xfs_bmap_trace_addentry( 323 int opcode, /* operation */ 324 char *fname, /* function name */ 325 char *desc, /* operation description */ 326 xfs_inode_t *ip, /* incore inode pointer */ 327 xfs_extnum_t idx, /* index of entry(ies) */ 328 xfs_extnum_t cnt, /* count of entries, 1 or 2 */ 329 xfs_bmbt_rec_t *r1, /* first record */ 330 xfs_bmbt_rec_t *r2, /* second record or null */ 331 int whichfork); /* data or attr fork */ 332 333/* 334 * Add bmap trace entry prior to a call to xfs_bmap_delete_exlist. 335 */ 336STATIC void 337xfs_bmap_trace_delete( 338 char *fname, /* function name */ 339 char *desc, /* operation description */ 340 xfs_inode_t *ip, /* incore inode pointer */ 341 xfs_extnum_t idx, /* index of entry(entries) deleted */ 342 xfs_extnum_t cnt, /* count of entries deleted, 1 or 2 */ 343 int whichfork); /* data or attr fork */ 344 345/* 346 * Add bmap trace entry prior to a call to xfs_bmap_insert_exlist, or 347 * reading in the extents list from the disk (in the btree). 348 */ 349STATIC void 350xfs_bmap_trace_insert( 351 char *fname, /* function name */ 352 char *desc, /* operation description */ 353 xfs_inode_t *ip, /* incore inode pointer */ 354 xfs_extnum_t idx, /* index of entry(entries) inserted */ 355 xfs_extnum_t cnt, /* count of entries inserted, 1 or 2 */ 356 xfs_bmbt_irec_t *r1, /* inserted record 1 */ 357 xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ 358 int whichfork); /* data or attr fork */ 359 360/* 361 * Add bmap trace entry after updating an extent list entry in place. 362 */ 363STATIC void 364xfs_bmap_trace_post_update( 365 char *fname, /* function name */ 366 char *desc, /* operation description */ 367 xfs_inode_t *ip, /* incore inode pointer */ 368 xfs_extnum_t idx, /* index of entry updated */ 369 int whichfork); /* data or attr fork */ 370 371/* 372 * Add bmap trace entry prior to updating an extent list entry in place. 373 */ 374STATIC void 375xfs_bmap_trace_pre_update( 376 char *fname, /* function name */ 377 char *desc, /* operation description */ 378 xfs_inode_t *ip, /* incore inode pointer */ 379 xfs_extnum_t idx, /* index of entry to be updated */ 380 int whichfork); /* data or attr fork */ 381 382#else 383#define xfs_bmap_trace_delete(f,d,ip,i,c,w) 384#define xfs_bmap_trace_insert(f,d,ip,i,c,r1,r2,w) 385#define xfs_bmap_trace_post_update(f,d,ip,i,w) 386#define xfs_bmap_trace_pre_update(f,d,ip,i,w) 387#endif /* XFS_BMAP_TRACE */ 388 389/* 390 * Compute the worst-case number of indirect blocks that will be used 391 * for ip's delayed extent of length "len". 392 */ 393STATIC xfs_filblks_t 394xfs_bmap_worst_indlen( 395 xfs_inode_t *ip, /* incore inode pointer */ 396 xfs_filblks_t len); /* delayed extent length */ 397 398#ifdef DEBUG 399/* 400 * Perform various validation checks on the values being returned 401 * from xfs_bmapi(). 402 */ 403STATIC void 404xfs_bmap_validate_ret( 405 xfs_fileoff_t bno, 406 xfs_filblks_t len, 407 int flags, 408 xfs_bmbt_irec_t *mval, 409 int nmap, 410 int ret_nmap); 411#else 412#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) 413#endif /* DEBUG */ 414 415#if defined(XFS_RW_TRACE) 416STATIC void 417xfs_bunmap_trace( 418 xfs_inode_t *ip, 419 xfs_fileoff_t bno, 420 xfs_filblks_t len, 421 int flags, 422 inst_t *ra); 423#else 424#define xfs_bunmap_trace(ip, bno, len, flags, ra) 425#endif /* XFS_RW_TRACE */ 426 427STATIC int 428xfs_bmap_count_tree( 429 xfs_mount_t *mp, 430 xfs_trans_t *tp, 431 xfs_fsblock_t blockno, 432 int levelin, 433 int *count); 434 435STATIC int 436xfs_bmap_count_leaves( 437 xfs_bmbt_rec_t *frp, 438 int numrecs, 439 int *count); 440 441/* 442 * Bmap internal routines. 443 */ 444 445/* 446 * Called from xfs_bmap_add_attrfork to handle btree format files. 447 */ 448STATIC int /* error */ 449xfs_bmap_add_attrfork_btree( 450 xfs_trans_t *tp, /* transaction pointer */ 451 xfs_inode_t *ip, /* incore inode pointer */ 452 xfs_fsblock_t *firstblock, /* first block allocated */ 453 xfs_bmap_free_t *flist, /* blocks to free at commit */ 454 int *flags) /* inode logging flags */ 455{ 456 xfs_btree_cur_t *cur; /* btree cursor */ 457 int error; /* error return value */ 458 xfs_mount_t *mp; /* file system mount struct */ 459 int stat; /* newroot status */ 460 461 mp = ip->i_mount; 462 if (ip->i_df.if_broot_bytes <= XFS_IFORK_DSIZE(ip)) 463 *flags |= XFS_ILOG_DBROOT; 464 else { 465 cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip, 466 XFS_DATA_FORK); 467 cur->bc_private.b.flist = flist; 468 cur->bc_private.b.firstblock = *firstblock; 469 if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) 470 goto error0; 471 ASSERT(stat == 1); /* must be at least one entry */ 472 if ((error = xfs_bmbt_newroot(cur, flags, &stat))) 473 goto error0; 474 if (stat == 0) { 475 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 476 return XFS_ERROR(ENOSPC); 477 } 478 *firstblock = cur->bc_private.b.firstblock; 479 cur->bc_private.b.allocated = 0; 480 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 481 } 482 return 0; 483error0: 484 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); 485 return error; 486} 487 488/* 489 * Called from xfs_bmap_add_attrfork to handle extents format files. 490 */ 491STATIC int /* error */ 492xfs_bmap_add_attrfork_extents( 493 xfs_trans_t *tp, /* transaction pointer */ 494 xfs_inode_t *ip, /* incore inode pointer */ 495 xfs_fsblock_t *firstblock, /* first block allocated */ 496 xfs_bmap_free_t *flist, /* blocks to free at commit */ 497 int *flags) /* inode logging flags */ 498{ 499 xfs_btree_cur_t *cur; /* bmap btree cursor */ 500 int error; /* error return value */ 501 502 if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) 503 return 0; 504 cur = NULL; 505 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, &cur, 0, 506 flags, XFS_DATA_FORK); 507 if (cur) { 508 cur->bc_private.b.allocated = 0; 509 xfs_btree_del_cursor(cur, 510 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 511 } 512 return error; 513} 514 515/* 516 * Called from xfs_bmap_add_attrfork to handle local format files. 517 */ 518STATIC int /* error */ 519xfs_bmap_add_attrfork_local( 520 xfs_trans_t *tp, /* transaction pointer */ 521 xfs_inode_t *ip, /* incore inode pointer */ 522 xfs_fsblock_t *firstblock, /* first block allocated */ 523 xfs_bmap_free_t *flist, /* blocks to free at commit */ 524 int *flags) /* inode logging flags */ 525{ 526 xfs_da_args_t dargs; /* args for dir/attr code */ 527 int error; /* error return value */ 528 xfs_mount_t *mp; /* mount structure pointer */ 529 530 if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) 531 return 0; 532 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 533 mp = ip->i_mount; 534 memset(&dargs, 0, sizeof(dargs)); 535 dargs.dp = ip; 536 dargs.firstblock = firstblock; 537 dargs.flist = flist; 538 dargs.total = mp->m_dirblkfsbs; 539 dargs.whichfork = XFS_DATA_FORK; 540 dargs.trans = tp; 541 error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); 542 } else 543 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, 544 XFS_DATA_FORK); 545 return error; 546} 547 548/* 549 * Called by xfs_bmapi to update extent list structure and the btree 550 * after allocating space (or doing a delayed allocation). 551 */ 552STATIC int /* error */ 553xfs_bmap_add_extent( 554 xfs_inode_t *ip, /* incore inode pointer */ 555 xfs_extnum_t idx, /* extent number to update/insert */ 556 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 557 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 558 xfs_fsblock_t *first, /* pointer to firstblock variable */ 559 xfs_bmap_free_t *flist, /* list of extents to be freed */ 560 int *logflagsp, /* inode logging flags */ 561 int whichfork, /* data or attr fork */ 562 int rsvd) /* OK to use reserved data blocks */ 563{ 564 xfs_btree_cur_t *cur; /* btree cursor or null */ 565 xfs_filblks_t da_new; /* new count del alloc blocks used */ 566 xfs_filblks_t da_old; /* old count del alloc blocks used */ 567 int error; /* error return value */ 568#ifdef XFS_BMAP_TRACE 569 static char fname[] = "xfs_bmap_add_extent"; 570#endif 571 xfs_ifork_t *ifp; /* inode fork ptr */ 572 int logflags; /* returned value */ 573 xfs_extnum_t nextents; /* number of extents in file now */ 574 575 XFS_STATS_INC(xs_add_exlist); 576 cur = *curp; 577 ifp = XFS_IFORK_PTR(ip, whichfork); 578 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 579 ASSERT(idx <= nextents); 580 da_old = da_new = 0; 581 error = 0; 582 /* 583 * This is the first extent added to a new/empty file. 584 * Special case this one, so other routines get to assume there are 585 * already extents in the list. 586 */ 587 if (nextents == 0) { 588 xfs_bmap_trace_insert(fname, "insert empty", ip, 0, 1, new, 589 NULL, whichfork); 590 xfs_bmap_insert_exlist(ip, 0, 1, new, whichfork); 591 ASSERT(cur == NULL); 592 ifp->if_lastex = 0; 593 if (!ISNULLSTARTBLOCK(new->br_startblock)) { 594 XFS_IFORK_NEXT_SET(ip, whichfork, 1); 595 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 596 } else 597 logflags = 0; 598 } 599 /* 600 * Any kind of new delayed allocation goes here. 601 */ 602 else if (ISNULLSTARTBLOCK(new->br_startblock)) { 603 if (cur) 604 ASSERT((cur->bc_private.b.flags & 605 XFS_BTCUR_BPRV_WASDEL) == 0); 606 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, 607 &logflags, rsvd))) 608 goto done; 609 } 610 /* 611 * Real allocation off the end of the file. 612 */ 613 else if (idx == nextents) { 614 if (cur) 615 ASSERT((cur->bc_private.b.flags & 616 XFS_BTCUR_BPRV_WASDEL) == 0); 617 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 618 &logflags, whichfork))) 619 goto done; 620 } else { 621 xfs_bmbt_irec_t prev; /* old extent at offset idx */ 622 623 /* 624 * Get the record referred to by idx. 625 */ 626 xfs_bmbt_get_all(&ifp->if_u1.if_extents[idx], &prev); 627 /* 628 * If it's a real allocation record, and the new allocation ends 629 * after the start of the referred to record, then we're filling 630 * in a delayed or unwritten allocation with a real one, or 631 * converting real back to unwritten. 632 */ 633 if (!ISNULLSTARTBLOCK(new->br_startblock) && 634 new->br_startoff + new->br_blockcount > prev.br_startoff) { 635 if (prev.br_state != XFS_EXT_UNWRITTEN && 636 ISNULLSTARTBLOCK(prev.br_startblock)) { 637 da_old = STARTBLOCKVAL(prev.br_startblock); 638 if (cur) 639 ASSERT(cur->bc_private.b.flags & 640 XFS_BTCUR_BPRV_WASDEL); 641 if ((error = xfs_bmap_add_extent_delay_real(ip, 642 idx, &cur, new, &da_new, first, flist, 643 &logflags, rsvd))) 644 goto done; 645 } else if (new->br_state == XFS_EXT_NORM) { 646 ASSERT(new->br_state == XFS_EXT_NORM); 647 if ((error = xfs_bmap_add_extent_unwritten_real( 648 ip, idx, &cur, new, &logflags))) 649 goto done; 650 } else { 651 ASSERT(new->br_state == XFS_EXT_UNWRITTEN); 652 if ((error = xfs_bmap_add_extent_unwritten_real( 653 ip, idx, &cur, new, &logflags))) 654 goto done; 655 } 656 ASSERT(*curp == cur || *curp == NULL); 657 } 658 /* 659 * Otherwise we're filling in a hole with an allocation. 660 */ 661 else { 662 if (cur) 663 ASSERT((cur->bc_private.b.flags & 664 XFS_BTCUR_BPRV_WASDEL) == 0); 665 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 666 new, &logflags, whichfork))) 667 goto done; 668 } 669 } 670 671 ASSERT(*curp == cur || *curp == NULL); 672 /* 673 * Convert to a btree if necessary. 674 */ 675 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 676 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) { 677 int tmp_logflags; /* partial log flag return val */ 678 679 ASSERT(cur == NULL); 680 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, 681 flist, &cur, da_old > 0, &tmp_logflags, whichfork); 682 logflags |= tmp_logflags; 683 if (error) 684 goto done; 685 } 686 /* 687 * Adjust for changes in reserved delayed indirect blocks. 688 * Nothing to do for disk quotas here. 689 */ 690 if (da_old || da_new) { 691 xfs_filblks_t nblks; 692 693 nblks = da_new; 694 if (cur) 695 nblks += cur->bc_private.b.allocated; 696 ASSERT(nblks <= da_old); 697 if (nblks < da_old) 698 xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, 699 (int)(da_old - nblks), rsvd); 700 } 701 /* 702 * Clear out the allocated field, done with it now in any case. 703 */ 704 if (cur) { 705 cur->bc_private.b.allocated = 0; 706 *curp = cur; 707 } 708done: 709#ifdef DEBUG 710 if (!error) 711 xfs_bmap_check_leaf_extents(*curp, ip, whichfork); 712#endif 713 *logflagsp = logflags; 714 return error; 715} 716 717/* 718 * Called by xfs_bmap_add_extent to handle cases converting a delayed 719 * allocation to a real allocation. 720 */ 721STATIC int /* error */ 722xfs_bmap_add_extent_delay_real( 723 xfs_inode_t *ip, /* incore inode pointer */ 724 xfs_extnum_t idx, /* extent number to update/insert */ 725 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 726 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 727 xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */ 728 xfs_fsblock_t *first, /* pointer to firstblock variable */ 729 xfs_bmap_free_t *flist, /* list of extents to be freed */ 730 int *logflagsp, /* inode logging flags */ 731 int rsvd) /* OK to use reserved data block allocation */ 732{ 733 xfs_bmbt_rec_t *base; /* base of extent entry list */ 734 xfs_btree_cur_t *cur; /* btree cursor */ 735 int diff; /* temp value */ 736 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 737 int error; /* error return value */ 738#ifdef XFS_BMAP_TRACE 739 static char fname[] = "xfs_bmap_add_extent_delay_real"; 740#endif 741 int i; /* temp state */ 742 xfs_fileoff_t new_endoff; /* end offset of new entry */ 743 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ 744 /* left is 0, right is 1, prev is 2 */ 745 int rval=0; /* return value (logging flags) */ 746 int state = 0;/* state bits, accessed thru macros */ 747 xfs_filblks_t temp; /* value for dnew calculations */ 748 xfs_filblks_t temp2; /* value for dnew calculations */ 749 int tmp_rval; /* partial logging flags */ 750 enum { /* bit number definitions for state */ 751 LEFT_CONTIG, RIGHT_CONTIG, 752 LEFT_FILLING, RIGHT_FILLING, 753 LEFT_DELAY, RIGHT_DELAY, 754 LEFT_VALID, RIGHT_VALID 755 }; 756 757#define LEFT r[0] 758#define RIGHT r[1] 759#define PREV r[2] 760#define MASK(b) (1 << (b)) 761#define MASK2(a,b) (MASK(a) | MASK(b)) 762#define MASK3(a,b,c) (MASK2(a,b) | MASK(c)) 763#define MASK4(a,b,c,d) (MASK3(a,b,c) | MASK(d)) 764#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) 765#define STATE_TEST(b) (state & MASK(b)) 766#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ 767 ((state &= ~MASK(b)), 0)) 768#define SWITCH_STATE \ 769 (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG)) 770 771 /* 772 * Set up a bunch of variables to make the tests simpler. 773 */ 774 cur = *curp; 775 base = ip->i_df.if_u1.if_extents; 776 ep = &base[idx]; 777 xfs_bmbt_get_all(ep, &PREV); 778 new_endoff = new->br_startoff + new->br_blockcount; 779 ASSERT(PREV.br_startoff <= new->br_startoff); 780 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); 781 /* 782 * Set flags determining what part of the previous delayed allocation 783 * extent is being replaced by a real allocation. 784 */ 785 STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff); 786 STATE_SET(RIGHT_FILLING, 787 PREV.br_startoff + PREV.br_blockcount == new_endoff); 788 /* 789 * Check and set flags if this segment has a left neighbor. 790 * Don't set contiguous if the combined extent would be too large. 791 */ 792 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 793 xfs_bmbt_get_all(ep - 1, &LEFT); 794 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); 795 } 796 STATE_SET(LEFT_CONTIG, 797 STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && 798 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && 799 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && 800 LEFT.br_state == new->br_state && 801 LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN); 802 /* 803 * Check and set flags if this segment has a right neighbor. 804 * Don't set contiguous if the combined extent would be too large. 805 * Also check for all-three-contiguous being too large. 806 */ 807 if (STATE_SET_TEST(RIGHT_VALID, 808 idx < 809 ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { 810 xfs_bmbt_get_all(ep + 1, &RIGHT); 811 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); 812 } 813 STATE_SET(RIGHT_CONTIG, 814 STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && 815 new_endoff == RIGHT.br_startoff && 816 new->br_startblock + new->br_blockcount == 817 RIGHT.br_startblock && 818 new->br_state == RIGHT.br_state && 819 new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && 820 ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) != 821 MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) || 822 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount 823 <= MAXEXTLEN)); 824 error = 0; 825 /* 826 * Switch out based on the FILLING and CONTIG state bits. 827 */ 828 switch (SWITCH_STATE) { 829 830 case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 831 /* 832 * Filling in all of a previously delayed allocation extent. 833 * The left and right neighbors are both contiguous with new. 834 */ 835 xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, 836 XFS_DATA_FORK); 837 xfs_bmbt_set_blockcount(ep - 1, 838 LEFT.br_blockcount + PREV.br_blockcount + 839 RIGHT.br_blockcount); 840 xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, 841 XFS_DATA_FORK); 842 xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, 843 XFS_DATA_FORK); 844 xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK); 845 ip->i_df.if_lastex = idx - 1; 846 ip->i_d.di_nextents--; 847 if (cur == NULL) 848 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 849 else { 850 rval = XFS_ILOG_CORE; 851 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 852 RIGHT.br_startblock, 853 RIGHT.br_blockcount, &i))) 854 goto done; 855 ASSERT(i == 1); 856 if ((error = xfs_bmbt_delete(cur, &i))) 857 goto done; 858 ASSERT(i == 1); 859 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 860 goto done; 861 ASSERT(i == 1); 862 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 863 LEFT.br_startblock, 864 LEFT.br_blockcount + 865 PREV.br_blockcount + 866 RIGHT.br_blockcount, LEFT.br_state))) 867 goto done; 868 } 869 *dnew = 0; 870 break; 871 872 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 873 /* 874 * Filling in all of a previously delayed allocation extent. 875 * The left neighbor is contiguous, the right is not. 876 */ 877 xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, 878 XFS_DATA_FORK); 879 xfs_bmbt_set_blockcount(ep - 1, 880 LEFT.br_blockcount + PREV.br_blockcount); 881 xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, 882 XFS_DATA_FORK); 883 ip->i_df.if_lastex = idx - 1; 884 xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, 885 XFS_DATA_FORK); 886 xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); 887 if (cur == NULL) 888 rval = XFS_ILOG_DEXT; 889 else { 890 rval = 0; 891 if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, 892 LEFT.br_startblock, LEFT.br_blockcount, 893 &i))) 894 goto done; 895 ASSERT(i == 1); 896 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 897 LEFT.br_startblock, 898 LEFT.br_blockcount + 899 PREV.br_blockcount, LEFT.br_state))) 900 goto done; 901 } 902 *dnew = 0; 903 break; 904 905 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 906 /* 907 * Filling in all of a previously delayed allocation extent. 908 * The right neighbor is contiguous, the left is not. 909 */ 910 xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx, 911 XFS_DATA_FORK); 912 xfs_bmbt_set_startblock(ep, new->br_startblock); 913 xfs_bmbt_set_blockcount(ep, 914 PREV.br_blockcount + RIGHT.br_blockcount); 915 xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx, 916 XFS_DATA_FORK); 917 ip->i_df.if_lastex = idx; 918 xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, 919 XFS_DATA_FORK); 920 xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK); 921 if (cur == NULL) 922 rval = XFS_ILOG_DEXT; 923 else { 924 rval = 0; 925 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 926 RIGHT.br_startblock, 927 RIGHT.br_blockcount, &i))) 928 goto done; 929 ASSERT(i == 1); 930 if ((error = xfs_bmbt_update(cur, PREV.br_startoff, 931 new->br_startblock, 932 PREV.br_blockcount + 933 RIGHT.br_blockcount, PREV.br_state))) 934 goto done; 935 } 936 *dnew = 0; 937 break; 938 939 case MASK2(LEFT_FILLING, RIGHT_FILLING): 940 /* 941 * Filling in all of a previously delayed allocation extent. 942 * Neither the left nor right neighbors are contiguous with 943 * the new one. 944 */ 945 xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx, 946 XFS_DATA_FORK); 947 xfs_bmbt_set_startblock(ep, new->br_startblock); 948 xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx, 949 XFS_DATA_FORK); 950 ip->i_df.if_lastex = idx; 951 ip->i_d.di_nextents++; 952 if (cur == NULL) 953 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 954 else { 955 rval = XFS_ILOG_CORE; 956 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 957 new->br_startblock, new->br_blockcount, 958 &i))) 959 goto done; 960 ASSERT(i == 0); 961 cur->bc_rec.b.br_state = XFS_EXT_NORM; 962 if ((error = xfs_bmbt_insert(cur, &i))) 963 goto done; 964 ASSERT(i == 1); 965 } 966 *dnew = 0; 967 break; 968 969 case MASK2(LEFT_FILLING, LEFT_CONTIG): 970 /* 971 * Filling in the first part of a previous delayed allocation. 972 * The left neighbor is contiguous. 973 */ 974 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, 975 XFS_DATA_FORK); 976 xfs_bmbt_set_blockcount(ep - 1, 977 LEFT.br_blockcount + new->br_blockcount); 978 xfs_bmbt_set_startoff(ep, 979 PREV.br_startoff + new->br_blockcount); 980 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1, 981 XFS_DATA_FORK); 982 temp = PREV.br_blockcount - new->br_blockcount; 983 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx, 984 XFS_DATA_FORK); 985 xfs_bmbt_set_blockcount(ep, temp); 986 ip->i_df.if_lastex = idx - 1; 987 if (cur == NULL) 988 rval = XFS_ILOG_DEXT; 989 else { 990 rval = 0; 991 if ((error = xfs_bmbt_lookup_eq(cur, LEFT.br_startoff, 992 LEFT.br_startblock, LEFT.br_blockcount, 993 &i))) 994 goto done; 995 ASSERT(i == 1); 996 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 997 LEFT.br_startblock, 998 LEFT.br_blockcount + 999 new->br_blockcount, 1000 LEFT.br_state))) 1001 goto done; 1002 } 1003 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 1004 STARTBLOCKVAL(PREV.br_startblock)); 1005 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1006 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, 1007 XFS_DATA_FORK); 1008 *dnew = temp; 1009 break; 1010 1011 case MASK(LEFT_FILLING): 1012 /* 1013 * Filling in the first part of a previous delayed allocation. 1014 * The left neighbor is not contiguous. 1015 */ 1016 xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK); 1017 xfs_bmbt_set_startoff(ep, new_endoff); 1018 temp = PREV.br_blockcount - new->br_blockcount; 1019 xfs_bmbt_set_blockcount(ep, temp); 1020 xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, 1021 XFS_DATA_FORK); 1022 xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); 1023 ip->i_df.if_lastex = idx; 1024 ip->i_d.di_nextents++; 1025 if (cur == NULL) 1026 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1027 else { 1028 rval = XFS_ILOG_CORE; 1029 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 1030 new->br_startblock, new->br_blockcount, 1031 &i))) 1032 goto done; 1033 ASSERT(i == 0); 1034 cur->bc_rec.b.br_state = XFS_EXT_NORM; 1035 if ((error = xfs_bmbt_insert(cur, &i))) 1036 goto done; 1037 ASSERT(i == 1); 1038 } 1039 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 1040 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 1041 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, 1042 first, flist, &cur, 1, &tmp_rval, 1043 XFS_DATA_FORK); 1044 rval |= tmp_rval; 1045 if (error) 1046 goto done; 1047 } 1048 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 1049 STARTBLOCKVAL(PREV.br_startblock) - 1050 (cur ? cur->bc_private.b.allocated : 0)); 1051 base = ip->i_df.if_u1.if_extents; 1052 ep = &base[idx + 1]; 1053 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1054 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, 1055 XFS_DATA_FORK); 1056 *dnew = temp; 1057 break; 1058 1059 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1060 /* 1061 * Filling in the last part of a previous delayed allocation. 1062 * The right neighbor is contiguous with the new allocation. 1063 */ 1064 temp = PREV.br_blockcount - new->br_blockcount; 1065 xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx, 1066 XFS_DATA_FORK); 1067 xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1, 1068 XFS_DATA_FORK); 1069 xfs_bmbt_set_blockcount(ep, temp); 1070 xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock, 1071 new->br_blockcount + RIGHT.br_blockcount, 1072 RIGHT.br_state); 1073 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, 1074 XFS_DATA_FORK); 1075 ip->i_df.if_lastex = idx + 1; 1076 if (cur == NULL) 1077 rval = XFS_ILOG_DEXT; 1078 else { 1079 rval = 0; 1080 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 1081 RIGHT.br_startblock, 1082 RIGHT.br_blockcount, &i))) 1083 goto done; 1084 ASSERT(i == 1); 1085 if ((error = xfs_bmbt_update(cur, new->br_startoff, 1086 new->br_startblock, 1087 new->br_blockcount + 1088 RIGHT.br_blockcount, 1089 RIGHT.br_state))) 1090 goto done; 1091 } 1092 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 1093 STARTBLOCKVAL(PREV.br_startblock)); 1094 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1095 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, 1096 XFS_DATA_FORK); 1097 *dnew = temp; 1098 break; 1099 1100 case MASK(RIGHT_FILLING): 1101 /* 1102 * Filling in the last part of a previous delayed allocation. 1103 * The right neighbor is not contiguous. 1104 */ 1105 temp = PREV.br_blockcount - new->br_blockcount; 1106 xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1107 xfs_bmbt_set_blockcount(ep, temp); 1108 xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, 1109 new, NULL, XFS_DATA_FORK); 1110 xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK); 1111 ip->i_df.if_lastex = idx + 1; 1112 ip->i_d.di_nextents++; 1113 if (cur == NULL) 1114 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1115 else { 1116 rval = XFS_ILOG_CORE; 1117 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 1118 new->br_startblock, new->br_blockcount, 1119 &i))) 1120 goto done; 1121 ASSERT(i == 0); 1122 cur->bc_rec.b.br_state = XFS_EXT_NORM; 1123 if ((error = xfs_bmbt_insert(cur, &i))) 1124 goto done; 1125 ASSERT(i == 1); 1126 } 1127 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 1128 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 1129 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, 1130 first, flist, &cur, 1, &tmp_rval, 1131 XFS_DATA_FORK); 1132 rval |= tmp_rval; 1133 if (error) 1134 goto done; 1135 } 1136 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 1137 STARTBLOCKVAL(PREV.br_startblock) - 1138 (cur ? cur->bc_private.b.allocated : 0)); 1139 base = ip->i_df.if_u1.if_extents; 1140 ep = &base[idx]; 1141 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1142 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1143 *dnew = temp; 1144 break; 1145 1146 case 0: 1147 /* 1148 * Filling in the middle part of a previous delayed allocation. 1149 * Contiguity is impossible here. 1150 * This case is avoided almost all the time. 1151 */ 1152 temp = new->br_startoff - PREV.br_startoff; 1153 xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); 1154 xfs_bmbt_set_blockcount(ep, temp); 1155 r[0] = *new; 1156 r[1].br_startoff = new_endoff; 1157 temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; 1158 r[1].br_blockcount = temp2; 1159 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], 1160 XFS_DATA_FORK); 1161 xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK); 1162 ip->i_df.if_lastex = idx + 1; 1163 ip->i_d.di_nextents++; 1164 if (cur == NULL) 1165 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1166 else { 1167 rval = XFS_ILOG_CORE; 1168 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 1169 new->br_startblock, new->br_blockcount, 1170 &i))) 1171 goto done; 1172 ASSERT(i == 0); 1173 cur->bc_rec.b.br_state = XFS_EXT_NORM; 1174 if ((error = xfs_bmbt_insert(cur, &i))) 1175 goto done; 1176 ASSERT(i == 1); 1177 } 1178 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 1179 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 1180 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, 1181 first, flist, &cur, 1, &tmp_rval, 1182 XFS_DATA_FORK); 1183 rval |= tmp_rval; 1184 if (error) 1185 goto done; 1186 } 1187 temp = xfs_bmap_worst_indlen(ip, temp); 1188 temp2 = xfs_bmap_worst_indlen(ip, temp2); 1189 diff = (int)(temp + temp2 - STARTBLOCKVAL(PREV.br_startblock) - 1190 (cur ? cur->bc_private.b.allocated : 0)); 1191 if (diff > 0 && 1192 xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -diff, rsvd)) { 1193 /* 1194 * Ick gross gag me with a spoon. 1195 */ 1196 ASSERT(0); /* want to see if this ever happens! */ 1197 while (diff > 0) { 1198 if (temp) { 1199 temp--; 1200 diff--; 1201 if (!diff || 1202 !xfs_mod_incore_sb(ip->i_mount, 1203 XFS_SBS_FDBLOCKS, -diff, rsvd)) 1204 break; 1205 } 1206 if (temp2) { 1207 temp2--; 1208 diff--; 1209 if (!diff || 1210 !xfs_mod_incore_sb(ip->i_mount, 1211 XFS_SBS_FDBLOCKS, -diff, rsvd)) 1212 break; 1213 } 1214 } 1215 } 1216 base = ip->i_df.if_u1.if_extents; 1217 ep = &base[idx]; 1218 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1219 xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK); 1220 xfs_bmap_trace_pre_update(fname, "0", ip, idx + 2, 1221 XFS_DATA_FORK); 1222 xfs_bmbt_set_startblock(ep + 2, NULLSTARTBLOCK((int)temp2)); 1223 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, 1224 XFS_DATA_FORK); 1225 *dnew = temp + temp2; 1226 break; 1227 1228 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1229 case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1230 case MASK2(LEFT_FILLING, RIGHT_CONTIG): 1231 case MASK2(RIGHT_FILLING, LEFT_CONTIG): 1232 case MASK2(LEFT_CONTIG, RIGHT_CONTIG): 1233 case MASK(LEFT_CONTIG): 1234 case MASK(RIGHT_CONTIG): 1235 /* 1236 * These cases are all impossible. 1237 */ 1238 ASSERT(0); 1239 } 1240 *curp = cur; 1241done: 1242 *logflagsp = rval; 1243 return error; 1244#undef LEFT 1245#undef RIGHT 1246#undef PREV 1247#undef MASK 1248#undef MASK2 1249#undef MASK3 1250#undef MASK4 1251#undef STATE_SET 1252#undef STATE_TEST 1253#undef STATE_SET_TEST 1254#undef SWITCH_STATE 1255} 1256 1257/* 1258 * Called by xfs_bmap_add_extent to handle cases converting an unwritten 1259 * allocation to a real allocation or vice versa. 1260 */ 1261STATIC int /* error */ 1262xfs_bmap_add_extent_unwritten_real( 1263 xfs_inode_t *ip, /* incore inode pointer */ 1264 xfs_extnum_t idx, /* extent number to update/insert */ 1265 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1266 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 1267 int *logflagsp) /* inode logging flags */ 1268{ 1269 xfs_bmbt_rec_t *base; /* base of extent entry list */ 1270 xfs_btree_cur_t *cur; /* btree cursor */ 1271 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 1272 int error; /* error return value */ 1273#ifdef XFS_BMAP_TRACE 1274 static char fname[] = "xfs_bmap_add_extent_unwritten_real"; 1275#endif 1276 int i; /* temp state */ 1277 xfs_fileoff_t new_endoff; /* end offset of new entry */ 1278 xfs_exntst_t newext; /* new extent state */ 1279 xfs_exntst_t oldext; /* old extent state */ 1280 xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ 1281 /* left is 0, right is 1, prev is 2 */ 1282 int rval=0; /* return value (logging flags) */ 1283 int state = 0;/* state bits, accessed thru macros */ 1284 enum { /* bit number definitions for state */ 1285 LEFT_CONTIG, RIGHT_CONTIG, 1286 LEFT_FILLING, RIGHT_FILLING, 1287 LEFT_DELAY, RIGHT_DELAY, 1288 LEFT_VALID, RIGHT_VALID 1289 }; 1290 1291#define LEFT r[0] 1292#define RIGHT r[1] 1293#define PREV r[2] 1294#define MASK(b) (1 << (b)) 1295#define MASK2(a,b) (MASK(a) | MASK(b)) 1296#define MASK3(a,b,c) (MASK2(a,b) | MASK(c)) 1297#define MASK4(a,b,c,d) (MASK3(a,b,c) | MASK(d)) 1298#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) 1299#define STATE_TEST(b) (state & MASK(b)) 1300#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ 1301 ((state &= ~MASK(b)), 0)) 1302#define SWITCH_STATE \ 1303 (state & MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG)) 1304 1305 /* 1306 * Set up a bunch of variables to make the tests simpler. 1307 */ 1308 error = 0; 1309 cur = *curp; 1310 base = ip->i_df.if_u1.if_extents; 1311 ep = &base[idx]; 1312 xfs_bmbt_get_all(ep, &PREV); 1313 newext = new->br_state; 1314 oldext = (newext == XFS_EXT_UNWRITTEN) ? 1315 XFS_EXT_NORM : XFS_EXT_UNWRITTEN; 1316 ASSERT(PREV.br_state == oldext); 1317 new_endoff = new->br_startoff + new->br_blockcount; 1318 ASSERT(PREV.br_startoff <= new->br_startoff); 1319 ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff); 1320 /* 1321 * Set flags determining what part of the previous oldext allocation 1322 * extent is being replaced by a newext allocation. 1323 */ 1324 STATE_SET(LEFT_FILLING, PREV.br_startoff == new->br_startoff); 1325 STATE_SET(RIGHT_FILLING, 1326 PREV.br_startoff + PREV.br_blockcount == new_endoff); 1327 /* 1328 * Check and set flags if this segment has a left neighbor. 1329 * Don't set contiguous if the combined extent would be too large. 1330 */ 1331 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 1332 xfs_bmbt_get_all(ep - 1, &LEFT); 1333 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); 1334 } 1335 STATE_SET(LEFT_CONTIG, 1336 STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && 1337 LEFT.br_startoff + LEFT.br_blockcount == new->br_startoff && 1338 LEFT.br_startblock + LEFT.br_blockcount == new->br_startblock && 1339 LEFT.br_state == newext && 1340 LEFT.br_blockcount + new->br_blockcount <= MAXEXTLEN); 1341 /* 1342 * Check and set flags if this segment has a right neighbor. 1343 * Don't set contiguous if the combined extent would be too large. 1344 * Also check for all-three-contiguous being too large. 1345 */ 1346 if (STATE_SET_TEST(RIGHT_VALID, 1347 idx < 1348 ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { 1349 xfs_bmbt_get_all(ep + 1, &RIGHT); 1350 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); 1351 } 1352 STATE_SET(RIGHT_CONTIG, 1353 STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && 1354 new_endoff == RIGHT.br_startoff && 1355 new->br_startblock + new->br_blockcount == 1356 RIGHT.br_startblock && 1357 newext == RIGHT.br_state && 1358 new->br_blockcount + RIGHT.br_blockcount <= MAXEXTLEN && 1359 ((state & MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING)) != 1360 MASK3(LEFT_CONTIG, LEFT_FILLING, RIGHT_FILLING) || 1361 LEFT.br_blockcount + new->br_blockcount + RIGHT.br_blockcount 1362 <= MAXEXTLEN)); 1363 /* 1364 * Switch out based on the FILLING and CONTIG state bits. 1365 */ 1366 switch (SWITCH_STATE) { 1367 1368 case MASK4(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1369 /* 1370 * Setting all of a previous oldext extent to newext. 1371 * The left and right neighbors are both contiguous with new. 1372 */ 1373 xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, 1374 XFS_DATA_FORK); 1375 xfs_bmbt_set_blockcount(ep - 1, 1376 LEFT.br_blockcount + PREV.br_blockcount + 1377 RIGHT.br_blockcount); 1378 xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, 1379 XFS_DATA_FORK); 1380 xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, 1381 XFS_DATA_FORK); 1382 xfs_bmap_delete_exlist(ip, idx, 2, XFS_DATA_FORK); 1383 ip->i_df.if_lastex = idx - 1; 1384 ip->i_d.di_nextents -= 2; 1385 if (cur == NULL) 1386 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1387 else { 1388 rval = XFS_ILOG_CORE; 1389 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 1390 RIGHT.br_startblock, 1391 RIGHT.br_blockcount, &i))) 1392 goto done; 1393 ASSERT(i == 1); 1394 if ((error = xfs_bmbt_delete(cur, &i))) 1395 goto done; 1396 ASSERT(i == 1); 1397 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1398 goto done; 1399 ASSERT(i == 1); 1400 if ((error = xfs_bmbt_delete(cur, &i))) 1401 goto done; 1402 ASSERT(i == 1); 1403 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1404 goto done; 1405 ASSERT(i == 1); 1406 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 1407 LEFT.br_startblock, 1408 LEFT.br_blockcount + PREV.br_blockcount + 1409 RIGHT.br_blockcount, LEFT.br_state))) 1410 goto done; 1411 } 1412 break; 1413 1414 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 1415 /* 1416 * Setting all of a previous oldext extent to newext. 1417 * The left neighbor is contiguous, the right is not. 1418 */ 1419 xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, 1420 XFS_DATA_FORK); 1421 xfs_bmbt_set_blockcount(ep - 1, 1422 LEFT.br_blockcount + PREV.br_blockcount); 1423 xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, 1424 XFS_DATA_FORK); 1425 ip->i_df.if_lastex = idx - 1; 1426 xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, 1427 XFS_DATA_FORK); 1428 xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); 1429 ip->i_d.di_nextents--; 1430 if (cur == NULL) 1431 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1432 else { 1433 rval = XFS_ILOG_CORE; 1434 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 1435 PREV.br_startblock, PREV.br_blockcount, 1436 &i))) 1437 goto done; 1438 ASSERT(i == 1); 1439 if ((error = xfs_bmbt_delete(cur, &i))) 1440 goto done; 1441 ASSERT(i == 1); 1442 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1443 goto done; 1444 ASSERT(i == 1); 1445 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 1446 LEFT.br_startblock, 1447 LEFT.br_blockcount + PREV.br_blockcount, 1448 LEFT.br_state))) 1449 goto done; 1450 } 1451 break; 1452 1453 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 1454 /* 1455 * Setting all of a previous oldext extent to newext. 1456 * The right neighbor is contiguous, the left is not. 1457 */ 1458 xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx, 1459 XFS_DATA_FORK); 1460 xfs_bmbt_set_blockcount(ep, 1461 PREV.br_blockcount + RIGHT.br_blockcount); 1462 xfs_bmbt_set_state(ep, newext); 1463 xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx, 1464 XFS_DATA_FORK); 1465 ip->i_df.if_lastex = idx; 1466 xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, 1467 XFS_DATA_FORK); 1468 xfs_bmap_delete_exlist(ip, idx + 1, 1, XFS_DATA_FORK); 1469 ip->i_d.di_nextents--; 1470 if (cur == NULL) 1471 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1472 else { 1473 rval = XFS_ILOG_CORE; 1474 if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff, 1475 RIGHT.br_startblock, 1476 RIGHT.br_blockcount, &i))) 1477 goto done; 1478 ASSERT(i == 1); 1479 if ((error = xfs_bmbt_delete(cur, &i))) 1480 goto done; 1481 ASSERT(i == 1); 1482 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1483 goto done; 1484 ASSERT(i == 1); 1485 if ((error = xfs_bmbt_update(cur, new->br_startoff, 1486 new->br_startblock, 1487 new->br_blockcount + RIGHT.br_blockcount, 1488 newext))) 1489 goto done; 1490 } 1491 break; 1492 1493 case MASK2(LEFT_FILLING, RIGHT_FILLING): 1494 /* 1495 * Setting all of a previous oldext extent to newext. 1496 * Neither the left nor right neighbors are contiguous with 1497 * the new one. 1498 */ 1499 xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx, 1500 XFS_DATA_FORK); 1501 xfs_bmbt_set_state(ep, newext); 1502 xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx, 1503 XFS_DATA_FORK); 1504 ip->i_df.if_lastex = idx; 1505 if (cur == NULL) 1506 rval = XFS_ILOG_DEXT; 1507 else { 1508 rval = 0; 1509 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 1510 new->br_startblock, new->br_blockcount, 1511 &i))) 1512 goto done; 1513 ASSERT(i == 1); 1514 if ((error = xfs_bmbt_update(cur, new->br_startoff, 1515 new->br_startblock, new->br_blockcount, 1516 newext))) 1517 goto done; 1518 } 1519 break; 1520 1521 case MASK2(LEFT_FILLING, LEFT_CONTIG): 1522 /* 1523 * Setting the first part of a previous oldext extent to newext. 1524 * The left neighbor is contiguous. 1525 */ 1526 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, 1527 XFS_DATA_FORK); 1528 xfs_bmbt_set_blockcount(ep - 1, 1529 LEFT.br_blockcount + new->br_blockcount); 1530 xfs_bmbt_set_startoff(ep, 1531 PREV.br_startoff + new->br_blockcount); 1532 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1, 1533 XFS_DATA_FORK); 1534 xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx, 1535 XFS_DATA_FORK); 1536 xfs_bmbt_set_startblock(ep, 1537 new->br_startblock + new->br_blockcount); 1538 xfs_bmbt_set_blockcount(ep, 1539 PREV.br_blockcount - new->br_blockcount); 1540 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, 1541 XFS_DATA_FORK); 1542 ip->i_df.if_lastex = idx - 1; 1543 if (cur == NULL) 1544 rval = XFS_ILOG_DEXT; 1545 else { 1546 rval = 0; 1547 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 1548 PREV.br_startblock, PREV.br_blockcount, 1549 &i))) 1550 goto done; 1551 ASSERT(i == 1); 1552 if ((error = xfs_bmbt_update(cur, 1553 PREV.br_startoff + new->br_blockcount, 1554 PREV.br_startblock + new->br_blockcount, 1555 PREV.br_blockcount - new->br_blockcount, 1556 oldext))) 1557 goto done; 1558 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1559 goto done; 1560 if (xfs_bmbt_update(cur, LEFT.br_startoff, 1561 LEFT.br_startblock, 1562 LEFT.br_blockcount + new->br_blockcount, 1563 LEFT.br_state)) 1564 goto done; 1565 } 1566 break; 1567 1568 case MASK(LEFT_FILLING): 1569 /* 1570 * Setting the first part of a previous oldext extent to newext. 1571 * The left neighbor is not contiguous. 1572 */ 1573 xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK); 1574 ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); 1575 xfs_bmbt_set_startoff(ep, new_endoff); 1576 xfs_bmbt_set_blockcount(ep, 1577 PREV.br_blockcount - new->br_blockcount); 1578 xfs_bmbt_set_startblock(ep, 1579 new->br_startblock + new->br_blockcount); 1580 xfs_bmap_trace_post_update(fname, "LF", ip, idx, XFS_DATA_FORK); 1581 xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, 1582 XFS_DATA_FORK); 1583 xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); 1584 ip->i_df.if_lastex = idx; 1585 ip->i_d.di_nextents++; 1586 if (cur == NULL) 1587 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1588 else { 1589 rval = XFS_ILOG_CORE; 1590 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 1591 PREV.br_startblock, PREV.br_blockcount, 1592 &i))) 1593 goto done; 1594 ASSERT(i == 1); 1595 if ((error = xfs_bmbt_update(cur, 1596 PREV.br_startoff + new->br_blockcount, 1597 PREV.br_startblock + new->br_blockcount, 1598 PREV.br_blockcount - new->br_blockcount, 1599 oldext))) 1600 goto done; 1601 cur->bc_rec.b = *new; 1602 if ((error = xfs_bmbt_insert(cur, &i))) 1603 goto done; 1604 ASSERT(i == 1); 1605 } 1606 break; 1607 1608 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1609 /* 1610 * Setting the last part of a previous oldext extent to newext. 1611 * The right neighbor is contiguous with the new allocation. 1612 */ 1613 xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx, 1614 XFS_DATA_FORK); 1615 xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1, 1616 XFS_DATA_FORK); 1617 xfs_bmbt_set_blockcount(ep, 1618 PREV.br_blockcount - new->br_blockcount); 1619 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, 1620 XFS_DATA_FORK); 1621 xfs_bmbt_set_allf(ep + 1, new->br_startoff, new->br_startblock, 1622 new->br_blockcount + RIGHT.br_blockcount, newext); 1623 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, 1624 XFS_DATA_FORK); 1625 ip->i_df.if_lastex = idx + 1; 1626 if (cur == NULL) 1627 rval = XFS_ILOG_DEXT; 1628 else { 1629 rval = 0; 1630 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 1631 PREV.br_startblock, 1632 PREV.br_blockcount, &i))) 1633 goto done; 1634 ASSERT(i == 1); 1635 if ((error = xfs_bmbt_update(cur, PREV.br_startoff, 1636 PREV.br_startblock, 1637 PREV.br_blockcount - new->br_blockcount, 1638 oldext))) 1639 goto done; 1640 if ((error = xfs_bmbt_increment(cur, 0, &i))) 1641 goto done; 1642 if ((error = xfs_bmbt_update(cur, new->br_startoff, 1643 new->br_startblock, 1644 new->br_blockcount + RIGHT.br_blockcount, 1645 newext))) 1646 goto done; 1647 } 1648 break; 1649 1650 case MASK(RIGHT_FILLING): 1651 /* 1652 * Setting the last part of a previous oldext extent to newext. 1653 * The right neighbor is not contiguous. 1654 */ 1655 xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1656 xfs_bmbt_set_blockcount(ep, 1657 PREV.br_blockcount - new->br_blockcount); 1658 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1659 xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, 1660 new, NULL, XFS_DATA_FORK); 1661 xfs_bmap_insert_exlist(ip, idx + 1, 1, new, XFS_DATA_FORK); 1662 ip->i_df.if_lastex = idx + 1; 1663 ip->i_d.di_nextents++; 1664 if (cur == NULL) 1665 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1666 else { 1667 rval = XFS_ILOG_CORE; 1668 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 1669 PREV.br_startblock, PREV.br_blockcount, 1670 &i))) 1671 goto done; 1672 ASSERT(i == 1); 1673 if ((error = xfs_bmbt_update(cur, PREV.br_startoff, 1674 PREV.br_startblock, 1675 PREV.br_blockcount - new->br_blockcount, 1676 oldext))) 1677 goto done; 1678 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 1679 new->br_startblock, new->br_blockcount, 1680 &i))) 1681 goto done; 1682 ASSERT(i == 0); 1683 cur->bc_rec.b.br_state = XFS_EXT_NORM; 1684 if ((error = xfs_bmbt_insert(cur, &i))) 1685 goto done; 1686 ASSERT(i == 1); 1687 } 1688 break; 1689 1690 case 0: 1691 /* 1692 * Setting the middle part of a previous oldext extent to 1693 * newext. Contiguity is impossible here. 1694 * One extent becomes three extents. 1695 */ 1696 xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); 1697 xfs_bmbt_set_blockcount(ep, 1698 new->br_startoff - PREV.br_startoff); 1699 xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK); 1700 r[0] = *new; 1701 r[1].br_startoff = new_endoff; 1702 r[1].br_blockcount = 1703 PREV.br_startoff + PREV.br_blockcount - new_endoff; 1704 r[1].br_startblock = new->br_startblock + new->br_blockcount; 1705 r[1].br_state = oldext; 1706 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], 1707 XFS_DATA_FORK); 1708 xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK); 1709 ip->i_df.if_lastex = idx + 1; 1710 ip->i_d.di_nextents += 2; 1711 if (cur == NULL) 1712 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; 1713 else { 1714 rval = XFS_ILOG_CORE; 1715 if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff, 1716 PREV.br_startblock, PREV.br_blockcount, 1717 &i))) 1718 goto done; 1719 ASSERT(i == 1); 1720 /* new right extent - oldext */ 1721 if ((error = xfs_bmbt_update(cur, r[1].br_startoff, 1722 r[1].br_startblock, r[1].br_blockcount, 1723 r[1].br_state))) 1724 goto done; 1725 /* new left extent - oldext */ 1726 PREV.br_blockcount = 1727 new->br_startoff - PREV.br_startoff; 1728 cur->bc_rec.b = PREV; 1729 if ((error = xfs_bmbt_insert(cur, &i))) 1730 goto done; 1731 ASSERT(i == 1); 1732 if ((error = xfs_bmbt_increment(cur, 0, &i))) 1733 goto done; 1734 ASSERT(i == 1); 1735 /* new middle extent - newext */ 1736 cur->bc_rec.b = *new; 1737 if ((error = xfs_bmbt_insert(cur, &i))) 1738 goto done; 1739 ASSERT(i == 1); 1740 } 1741 break; 1742 1743 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1744 case MASK3(RIGHT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1745 case MASK2(LEFT_FILLING, RIGHT_CONTIG): 1746 case MASK2(RIGHT_FILLING, LEFT_CONTIG): 1747 case MASK2(LEFT_CONTIG, RIGHT_CONTIG): 1748 case MASK(LEFT_CONTIG): 1749 case MASK(RIGHT_CONTIG): 1750 /* 1751 * These cases are all impossible. 1752 */ 1753 ASSERT(0); 1754 } 1755 *curp = cur; 1756done: 1757 *logflagsp = rval; 1758 return error; 1759#undef LEFT 1760#undef RIGHT 1761#undef PREV 1762#undef MASK 1763#undef MASK2 1764#undef MASK3 1765#undef MASK4 1766#undef STATE_SET 1767#undef STATE_TEST 1768#undef STATE_SET_TEST 1769#undef SWITCH_STATE 1770} 1771 1772/* 1773 * Called by xfs_bmap_add_extent to handle cases converting a hole 1774 * to a delayed allocation. 1775 */ 1776/*ARGSUSED*/ 1777STATIC int /* error */ 1778xfs_bmap_add_extent_hole_delay( 1779 xfs_inode_t *ip, /* incore inode pointer */ 1780 xfs_extnum_t idx, /* extent number to update/insert */ 1781 xfs_btree_cur_t *cur, /* if null, not a btree */ 1782 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 1783 int *logflagsp, /* inode logging flags */ 1784 int rsvd) /* OK to allocate reserved blocks */ 1785{ 1786 xfs_bmbt_rec_t *base; /* base of extent entry list */ 1787 xfs_bmbt_rec_t *ep; /* extent list entry for idx */ 1788#ifdef XFS_BMAP_TRACE 1789 static char fname[] = "xfs_bmap_add_extent_hole_delay"; 1790#endif 1791 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 1792 xfs_filblks_t newlen=0; /* new indirect size */ 1793 xfs_filblks_t oldlen=0; /* old indirect size */ 1794 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 1795 int state; /* state bits, accessed thru macros */ 1796 xfs_filblks_t temp; /* temp for indirect calculations */ 1797 enum { /* bit number definitions for state */ 1798 LEFT_CONTIG, RIGHT_CONTIG, 1799 LEFT_DELAY, RIGHT_DELAY, 1800 LEFT_VALID, RIGHT_VALID 1801 }; 1802 1803#define MASK(b) (1 << (b)) 1804#define MASK2(a,b) (MASK(a) | MASK(b)) 1805#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) 1806#define STATE_TEST(b) (state & MASK(b)) 1807#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ 1808 ((state &= ~MASK(b)), 0)) 1809#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG)) 1810 1811 base = ip->i_df.if_u1.if_extents; 1812 ep = &base[idx]; 1813 state = 0; 1814 ASSERT(ISNULLSTARTBLOCK(new->br_startblock)); 1815 /* 1816 * Check and set flags if this segment has a left neighbor 1817 */ 1818 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 1819 xfs_bmbt_get_all(ep - 1, &left); 1820 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); 1821 } 1822 /* 1823 * Check and set flags if the current (right) segment exists. 1824 * If it doesn't exist, we're converting the hole at end-of-file. 1825 */ 1826 if (STATE_SET_TEST(RIGHT_VALID, 1827 idx < 1828 ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { 1829 xfs_bmbt_get_all(ep, &right); 1830 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(right.br_startblock)); 1831 } 1832 /* 1833 * Set contiguity flags on the left and right neighbors. 1834 * Don't let extents get too large, even if the pieces are contiguous. 1835 */ 1836 STATE_SET(LEFT_CONTIG, 1837 STATE_TEST(LEFT_VALID) && STATE_TEST(LEFT_DELAY) && 1838 left.br_startoff + left.br_blockcount == new->br_startoff && 1839 left.br_blockcount + new->br_blockcount <= MAXEXTLEN); 1840 STATE_SET(RIGHT_CONTIG, 1841 STATE_TEST(RIGHT_VALID) && STATE_TEST(RIGHT_DELAY) && 1842 new->br_startoff + new->br_blockcount == right.br_startoff && 1843 new->br_blockcount + right.br_blockcount <= MAXEXTLEN && 1844 (!STATE_TEST(LEFT_CONTIG) || 1845 (left.br_blockcount + new->br_blockcount + 1846 right.br_blockcount <= MAXEXTLEN))); 1847 /* 1848 * Switch out based on the contiguity flags. 1849 */ 1850 switch (SWITCH_STATE) { 1851 1852 case MASK2(LEFT_CONTIG, RIGHT_CONTIG): 1853 /* 1854 * New allocation is contiguous with delayed allocations 1855 * on the left and on the right. 1856 * Merge all three into a single extent list entry. 1857 */ 1858 temp = left.br_blockcount + new->br_blockcount + 1859 right.br_blockcount; 1860 xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, 1861 XFS_DATA_FORK); 1862 xfs_bmbt_set_blockcount(ep - 1, temp); 1863 oldlen = STARTBLOCKVAL(left.br_startblock) + 1864 STARTBLOCKVAL(new->br_startblock) + 1865 STARTBLOCKVAL(right.br_startblock); 1866 newlen = xfs_bmap_worst_indlen(ip, temp); 1867 xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen)); 1868 xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, 1869 XFS_DATA_FORK); 1870 xfs_bmap_trace_delete(fname, "LC|RC", ip, idx, 1, 1871 XFS_DATA_FORK); 1872 xfs_bmap_delete_exlist(ip, idx, 1, XFS_DATA_FORK); 1873 ip->i_df.if_lastex = idx - 1; 1874 break; 1875 1876 case MASK(LEFT_CONTIG): 1877 /* 1878 * New allocation is contiguous with a delayed allocation 1879 * on the left. 1880 * Merge the new allocation with the left neighbor. 1881 */ 1882 temp = left.br_blockcount + new->br_blockcount; 1883 xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, 1884 XFS_DATA_FORK); 1885 xfs_bmbt_set_blockcount(ep - 1, temp); 1886 oldlen = STARTBLOCKVAL(left.br_startblock) + 1887 STARTBLOCKVAL(new->br_startblock); 1888 newlen = xfs_bmap_worst_indlen(ip, temp); 1889 xfs_bmbt_set_startblock(ep - 1, NULLSTARTBLOCK((int)newlen)); 1890 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, 1891 XFS_DATA_FORK); 1892 ip->i_df.if_lastex = idx - 1; 1893 break; 1894 1895 case MASK(RIGHT_CONTIG): 1896 /* 1897 * New allocation is contiguous with a delayed allocation 1898 * on the right. 1899 * Merge the new allocation with the right neighbor. 1900 */ 1901 xfs_bmap_trace_pre_update(fname, "RC", ip, idx, XFS_DATA_FORK); 1902 temp = new->br_blockcount + right.br_blockcount; 1903 oldlen = STARTBLOCKVAL(new->br_startblock) + 1904 STARTBLOCKVAL(right.br_startblock); 1905 newlen = xfs_bmap_worst_indlen(ip, temp); 1906 xfs_bmbt_set_allf(ep, new->br_startoff, 1907 NULLSTARTBLOCK((int)newlen), temp, right.br_state); 1908 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); 1909 ip->i_df.if_lastex = idx; 1910 break; 1911 1912 case 0: 1913 /* 1914 * New allocation is not contiguous with another 1915 * delayed allocation. 1916 * Insert a new entry. 1917 */ 1918 oldlen = newlen = 0; 1919 xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, 1920 XFS_DATA_FORK); 1921 xfs_bmap_insert_exlist(ip, idx, 1, new, XFS_DATA_FORK); 1922 ip->i_df.if_lastex = idx; 1923 break; 1924 } 1925 if (oldlen != newlen) { 1926 ASSERT(oldlen > newlen); 1927 xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, 1928 (int)(oldlen - newlen), rsvd); 1929 /* 1930 * Nothing to do for disk quota accounting here. 1931 */ 1932 } 1933 *logflagsp = 0; 1934 return 0; 1935#undef MASK 1936#undef MASK2 1937#undef STATE_SET 1938#undef STATE_TEST 1939#undef STATE_SET_TEST 1940#undef SWITCH_STATE 1941} 1942 1943/* 1944 * Called by xfs_bmap_add_extent to handle cases converting a hole 1945 * to a real allocation. 1946 */ 1947STATIC int /* error */ 1948xfs_bmap_add_extent_hole_real( 1949 xfs_inode_t *ip, /* incore inode pointer */ 1950 xfs_extnum_t idx, /* extent number to update/insert */ 1951 xfs_btree_cur_t *cur, /* if null, not a btree */ 1952 xfs_bmbt_irec_t *new, /* new data to put in extent list */ 1953 int *logflagsp, /* inode logging flags */ 1954 int whichfork) /* data or attr fork */ 1955{ 1956 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ 1957 int error; /* error return value */ 1958#ifdef XFS_BMAP_TRACE 1959 static char fname[] = "xfs_bmap_add_extent_hole_real"; 1960#endif 1961 int i; /* temp state */ 1962 xfs_ifork_t *ifp; /* inode fork pointer */ 1963 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 1964 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 1965 int state; /* state bits, accessed thru macros */ 1966 enum { /* bit number definitions for state */ 1967 LEFT_CONTIG, RIGHT_CONTIG, 1968 LEFT_DELAY, RIGHT_DELAY, 1969 LEFT_VALID, RIGHT_VALID 1970 }; 1971 1972#define MASK(b) (1 << (b)) 1973#define MASK2(a,b) (MASK(a) | MASK(b)) 1974#define STATE_SET(b,v) ((v) ? (state |= MASK(b)) : (state &= ~MASK(b))) 1975#define STATE_TEST(b) (state & MASK(b)) 1976#define STATE_SET_TEST(b,v) ((v) ? ((state |= MASK(b)), 1) : \ 1977 ((state &= ~MASK(b)), 0)) 1978#define SWITCH_STATE (state & MASK2(LEFT_CONTIG, RIGHT_CONTIG)) 1979 1980 ifp = XFS_IFORK_PTR(ip, whichfork); 1981 ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t)); 1982 ep = &ifp->if_u1.if_extents[idx]; 1983 state = 0; 1984 /* 1985 * Check and set flags if this segment has a left neighbor. 1986 */ 1987 if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { 1988 xfs_bmbt_get_all(ep - 1, &left); 1989 STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); 1990 } 1991 /* 1992 * Check and set flags if this segment has a current value. 1993 * Not true if we're inserting into the "hole" at eof. 1994 */ 1995 if (STATE_SET_TEST(RIGHT_VALID, 1996 idx < 1997 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { 1998 xfs_bmbt_get_all(ep, &right); 1999 STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(right.br_startblock)); 2000 } 2001 /* 2002 * We're inserting a real allocation between "left" and "right". 2003 * Set the contiguity flags. Don't let extents get too large. 2004 */ 2005 STATE_SET(LEFT_CONTIG, 2006 STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && 2007 left.br_startoff + left.br_blockcount == new->br_startoff && 2008 left.br_startblock + left.br_blockcount == new->br_startblock && 2009 left.br_state == new->br_state && 2010 left.br_blockcount + new->br_blockcount <= MAXEXTLEN); 2011 STATE_SET(RIGHT_CONTIG, 2012 STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && 2013 new->br_startoff + new->br_blockcount == right.br_startoff && 2014 new->br_startblock + new->br_blockcount == 2015 right.br_startblock && 2016 new->br_state == right.br_state && 2017 new->br_blockcount + right.br_blockcount <= MAXEXTLEN && 2018 (!STATE_TEST(LEFT_CONTIG) || 2019 left.br_blockcount + new->br_blockcount + 2020 right.br_blockcount <= MAXEXTLEN)); 2021 2022 /* 2023 * Select which case we're in here, and implement it. 2024 */ 2025 switch (SWITCH_STATE) { 2026 2027 case MASK2(LEFT_CONTIG, RIGHT_CONTIG): 2028 /* 2029 * New allocation is contiguous with real allocations on the 2030 * left and on the right. 2031 * Merge all three into a single extent list entry. 2032 */ 2033 xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, 2034 whichfork); 2035 xfs_bmbt_set_blockcount(ep - 1, 2036 left.br_blockcount + new->br_blockcount + 2037 right.br_blockcount); 2038 xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, 2039 whichfork); 2040 xfs_bmap_trace_delete(fname, "LC|RC", ip, 2041 idx, 1, whichfork); 2042 xfs_bmap_delete_exlist(ip, idx, 1, whichfork); 2043 ifp->if_lastex = idx - 1; 2044 XFS_IFORK_NEXT_SET(ip, whichfork, 2045 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2046 if (cur == NULL) { 2047 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2048 return 0; 2049 } 2050 *logflagsp = XFS_ILOG_CORE; 2051 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2052 right.br_startblock, right.br_blockcount, &i))) 2053 return error; 2054 ASSERT(i == 1); 2055 if ((error = xfs_bmbt_delete(cur, &i))) 2056 return error; 2057 ASSERT(i == 1); 2058 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 2059 return error; 2060 ASSERT(i == 1); 2061 error = xfs_bmbt_update(cur, left.br_startoff, 2062 left.br_startblock, 2063 left.br_blockcount + new->br_blockcount + 2064 right.br_blockcount, left.br_state); 2065 return error; 2066 2067 case MASK(LEFT_CONTIG): 2068 /* 2069 * New allocation is contiguous with a real allocation 2070 * on the left. 2071 * Merge the new allocation with the left neighbor. 2072 */ 2073 xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, whichfork); 2074 xfs_bmbt_set_blockcount(ep - 1, 2075 left.br_blockcount + new->br_blockcount); 2076 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); 2077 ifp->if_lastex = idx - 1; 2078 if (cur == NULL) { 2079 *logflagsp = XFS_ILOG_FEXT(whichfork); 2080 return 0; 2081 } 2082 *logflagsp = 0; 2083 if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, 2084 left.br_startblock, left.br_blockcount, &i))) 2085 return error; 2086 ASSERT(i == 1); 2087 error = xfs_bmbt_update(cur, left.br_startoff, 2088 left.br_startblock, 2089 left.br_blockcount + new->br_blockcount, 2090 left.br_state); 2091 return error; 2092 2093 case MASK(RIGHT_CONTIG): 2094 /* 2095 * New allocation is contiguous with a real allocation 2096 * on the right. 2097 * Merge the new allocation with the right neighbor. 2098 */ 2099 xfs_bmap_trace_pre_update(fname, "RC", ip, idx, whichfork); 2100 xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, 2101 new->br_blockcount + right.br_blockcount, 2102 right.br_state); 2103 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); 2104 ifp->if_lastex = idx; 2105 if (cur == NULL) { 2106 *logflagsp = XFS_ILOG_FEXT(whichfork); 2107 return 0; 2108 } 2109 *logflagsp = 0; 2110 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2111 right.br_startblock, right.br_blockcount, &i))) 2112 return error; 2113 ASSERT(i == 1); 2114 error = xfs_bmbt_update(cur, new->br_startoff, 2115 new->br_startblock, 2116 new->br_blockcount + right.br_blockcount, 2117 right.br_state); 2118 return error; 2119 2120 case 0: 2121 /* 2122 * New allocation is not contiguous with another 2123 * real allocation. 2124 * Insert a new entry. 2125 */ 2126 xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, 2127 whichfork); 2128 xfs_bmap_insert_exlist(ip, idx, 1, new, whichfork); 2129 ifp->if_lastex = idx; 2130 XFS_IFORK_NEXT_SET(ip, whichfork, 2131 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 2132 if (cur == NULL) { 2133 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2134 return 0; 2135 } 2136 *logflagsp = XFS_ILOG_CORE; 2137 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2138 new->br_startblock, new->br_blockcount, &i))) 2139 return error; 2140 ASSERT(i == 0); 2141 cur->bc_rec.b.br_state = new->br_state; 2142 if ((error = xfs_bmbt_insert(cur, &i))) 2143 return error; 2144 ASSERT(i == 1); 2145 return 0; 2146 } 2147#undef MASK 2148#undef MASK2 2149#undef STATE_SET 2150#undef STATE_TEST 2151#undef STATE_SET_TEST 2152#undef SWITCH_STATE 2153 /* NOTREACHED */ 2154 ASSERT(0); 2155 return 0; /* keep gcc quite */ 2156} 2157 2158#define XFS_ALLOC_GAP_UNITS 4 2159 2160/* 2161 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 2162 * It figures out where to ask the underlying allocator to put the new extent. 2163 */ 2164STATIC int /* error */ 2165xfs_bmap_alloc( 2166 xfs_bmalloca_t *ap) /* bmap alloc argument struct */ 2167{ 2168 xfs_fsblock_t adjust; /* adjustment to block numbers */ 2169 xfs_alloctype_t atype=0; /* type for allocation routines */ 2170 int error; /* error return value */ 2171 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ 2172 xfs_mount_t *mp; /* mount point structure */ 2173 int nullfb; /* true if ap->firstblock isn't set */ 2174 int rt; /* true if inode is realtime */ 2175#ifdef __KERNEL__ 2176 xfs_extlen_t prod=0; /* product factor for allocators */ 2177 xfs_extlen_t ralen=0; /* realtime allocation length */ 2178#endif 2179 2180#define ISVALID(x,y) \ 2181 (rt ? \ 2182 (x) < mp->m_sb.sb_rblocks : \ 2183 XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ 2184 XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ 2185 XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) 2186 2187 /* 2188 * Set up variables. 2189 */ 2190 mp = ap->ip->i_mount; 2191 nullfb = ap->firstblock == NULLFSBLOCK; 2192 rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata; 2193 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); 2194#ifdef __KERNEL__ 2195 if (rt) { 2196 xfs_extlen_t extsz; /* file extent size for rt */ 2197 xfs_fileoff_t nexto; /* next file offset */ 2198 xfs_extlen_t orig_alen; /* original ap->alen */ 2199 xfs_fileoff_t orig_end; /* original off+len */ 2200 xfs_fileoff_t orig_off; /* original ap->off */ 2201 xfs_extlen_t mod_off; /* modulus calculations */ 2202 xfs_fileoff_t prevo; /* previous file offset */ 2203 xfs_rtblock_t rtx; /* realtime extent number */ 2204 xfs_extlen_t temp; /* temp for rt calculations */ 2205 2206 /* 2207 * Set prod to match the realtime extent size. 2208 */ 2209 if (!(extsz = ap->ip->i_d.di_extsize)) 2210 extsz = mp->m_sb.sb_rextsize; 2211 prod = extsz / mp->m_sb.sb_rextsize; 2212 orig_off = ap->off; 2213 orig_alen = ap->alen; 2214 orig_end = orig_off + orig_alen; 2215 /* 2216 * If the file offset is unaligned vs. the extent size 2217 * we need to align it. This will be possible unless 2218 * the file was previously written with a kernel that didn't 2219 * perform this alignment. 2220 */ 2221 mod_off = do_mod(orig_off, extsz); 2222 if (mod_off) { 2223 ap->alen += mod_off; 2224 ap->off -= mod_off; 2225 } 2226 /* 2227 * Same adjustment for the end of the requested area. 2228 */ 2229 if ((temp = (ap->alen % extsz))) 2230 ap->alen += extsz - temp; 2231 /* 2232 * If the previous block overlaps with this proposed allocation 2233 * then move the start forward without adjusting the length. 2234 */ 2235 prevo = 2236 ap->prevp->br_startoff == NULLFILEOFF ? 2237 0 : 2238 (ap->prevp->br_startoff + 2239 ap->prevp->br_blockcount); 2240 if (ap->off != orig_off && ap->off < prevo) 2241 ap->off = prevo; 2242 /* 2243 * If the next block overlaps with this proposed allocation 2244 * then move the start back without adjusting the length, 2245 * but not before offset 0. 2246 * This may of course make the start overlap previous block, 2247 * and if we hit the offset 0 limit then the next block 2248 * can still overlap too. 2249 */ 2250 nexto = (ap->eof || ap->gotp->br_startoff == NULLFILEOFF) ? 2251 NULLFILEOFF : ap->gotp->br_startoff; 2252 if (!ap->eof && 2253 ap->off + ap->alen != orig_end && 2254 ap->off + ap->alen > nexto) 2255 ap->off = nexto > ap->alen ? nexto - ap->alen : 0; 2256 /* 2257 * If we're now overlapping the next or previous extent that 2258 * means we can't fit an extsz piece in this hole. Just move 2259 * the start forward to the first valid spot and set 2260 * the length so we hit the end. 2261 */ 2262 if ((ap->off != orig_off && ap->off < prevo) || 2263 (ap->off + ap->alen != orig_end && 2264 ap->off + ap->alen > nexto)) { 2265 ap->off = prevo; 2266 ap->alen = nexto - prevo; 2267 } 2268 /* 2269 * If the result isn't a multiple of rtextents we need to 2270 * remove blocks until it is. 2271 */ 2272 if ((temp = (ap->alen % mp->m_sb.sb_rextsize))) { 2273 /* 2274 * We're not covering the original request, or 2275 * we won't be able to once we fix the length. 2276 */ 2277 if (orig_off < ap->off || 2278 orig_end > ap->off + ap->alen || 2279 ap->alen - temp < orig_alen) 2280 return XFS_ERROR(EINVAL); 2281 /* 2282 * Try to fix it by moving the start up. 2283 */ 2284 if (ap->off + temp <= orig_off) { 2285 ap->alen -= temp; 2286 ap->off += temp; 2287 } 2288 /* 2289 * Try to fix it by moving the end in. 2290 */ 2291 else if (ap->off + ap->alen - temp >= orig_end) 2292 ap->alen -= temp; 2293 /* 2294 * Set the start to the minimum then trim the length. 2295 */ 2296 else { 2297 ap->alen -= orig_off - ap->off; 2298 ap->off = orig_off; 2299 ap->alen -= ap->alen % mp->m_sb.sb_rextsize; 2300 } 2301 /* 2302 * Result doesn't cover the request, fail it. 2303 */ 2304 if (orig_off < ap->off || orig_end > ap->off + ap->alen) 2305 return XFS_ERROR(EINVAL); 2306 } 2307 ASSERT(ap->alen % mp->m_sb.sb_rextsize == 0); 2308 /* 2309 * If the offset & length are not perfectly aligned 2310 * then kill prod, it will just get us in trouble. 2311 */ 2312 if (do_mod(ap->off, extsz) || ap->alen % extsz) 2313 prod = 1; 2314 /* 2315 * Set ralen to be the actual requested length in rtextents. 2316 */ 2317 ralen = ap->alen / mp->m_sb.sb_rextsize; 2318 /* 2319 * If the old value was close enough to MAXEXTLEN that 2320 * we rounded up to it, cut it back so it's valid again. 2321 * Note that if it's a really large request (bigger than 2322 * MAXEXTLEN), we don't hear about that number, and can't 2323 * adjust the starting point to match it. 2324 */ 2325 if (ralen * mp->m_sb.sb_rextsize >= MAXEXTLEN) 2326 ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; 2327 /* 2328 * If it's an allocation to an empty file at offset 0, 2329 * pick an extent that will space things out in the rt area. 2330 */ 2331 if (ap->eof && ap->off == 0) { 2332 error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); 2333 if (error) 2334 return error; 2335 ap->rval = rtx * mp->m_sb.sb_rextsize; 2336 } else 2337 ap->rval = 0; 2338 } 2339#else 2340 if (rt) 2341 ap->rval = 0; 2342#endif /* __KERNEL__ */ 2343 else if (nullfb) 2344 ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); 2345 else 2346 ap->rval = ap->firstblock; 2347 /* 2348 * If allocating at eof, and there's a previous real block, 2349 * try to use it's last block as our starting point. 2350 */ 2351 if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF && 2352 !ISNULLSTARTBLOCK(ap->prevp->br_startblock) && 2353 ISVALID(ap->prevp->br_startblock + ap->prevp->br_blockcount, 2354 ap->prevp->br_startblock)) { 2355 ap->rval = ap->prevp->br_startblock + ap->prevp->br_blockcount; 2356 /* 2357 * Adjust for the gap between prevp and us. 2358 */ 2359 adjust = ap->off - 2360 (ap->prevp->br_startoff + ap->prevp->br_blockcount); 2361 if (adjust && 2362 ISVALID(ap->rval + adjust, ap->prevp->br_startblock)) 2363 ap->rval += adjust; 2364 } 2365 /* 2366 * If not at eof, then compare the two neighbor blocks. 2367 * Figure out whether either one gives us a good starting point, 2368 * and pick the better one. 2369 */ 2370 else if (!ap->eof) { 2371 xfs_fsblock_t gotbno; /* right side block number */ 2372 xfs_fsblock_t gotdiff=0; /* right side difference */ 2373 xfs_fsblock_t prevbno; /* left side block number */ 2374 xfs_fsblock_t prevdiff=0; /* left side difference */ 2375 2376 /* 2377 * If there's a previous (left) block, select a requested 2378 * start block based on it. 2379 */ 2380 if (ap->prevp->br_startoff != NULLFILEOFF && 2381 !ISNULLSTARTBLOCK(ap->prevp->br_startblock) && 2382 (prevbno = ap->prevp->br_startblock + 2383 ap->prevp->br_blockcount) && 2384 ISVALID(prevbno, ap->prevp->br_startblock)) { 2385 /* 2386 * Calculate gap to end of previous block. 2387 */ 2388 adjust = prevdiff = ap->off - 2389 (ap->prevp->br_startoff + 2390 ap->prevp->br_blockcount); 2391 /* 2392 * Figure the startblock based on the previous block's 2393 * end and the gap size. 2394 * Heuristic! 2395 * If the gap is large relative to the piece we're 2396 * allocating, or using it gives us an invalid block 2397 * number, then just use the end of the previous block. 2398 */ 2399 if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && 2400 ISVALID(prevbno + prevdiff, 2401 ap->prevp->br_startblock)) 2402 prevbno += adjust; 2403 else 2404 prevdiff += adjust; 2405 /* 2406 * If the firstblock forbids it, can't use it, 2407 * must use default. 2408 */ 2409 if (!rt && !nullfb && 2410 XFS_FSB_TO_AGNO(mp, prevbno) != fb_agno) 2411 prevbno = NULLFSBLOCK; 2412 } 2413 /* 2414 * No previous block or can't follow it, just default. 2415 */ 2416 else 2417 prevbno = NULLFSBLOCK; 2418 /* 2419 * If there's a following (right) block, select a requested 2420 * start block based on it. 2421 */ 2422 if (!ISNULLSTARTBLOCK(ap->gotp->br_startblock)) { 2423 /* 2424 * Calculate gap to start of next block. 2425 */ 2426 adjust = gotdiff = ap->gotp->br_startoff - ap->off; 2427 /* 2428 * Figure the startblock based on the next block's 2429 * start and the gap size. 2430 */ 2431 gotbno = ap->gotp->br_startblock; 2432 /* 2433 * Heuristic! 2434 * If the gap is large relative to the piece we're 2435 * allocating, or using it gives us an invalid block 2436 * number, then just use the start of the next block 2437 * offset by our length. 2438 */ 2439 if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->alen && 2440 ISVALID(gotbno - gotdiff, gotbno)) 2441 gotbno -= adjust; 2442 else if (ISVALID(gotbno - ap->alen, gotbno)) { 2443 gotbno -= ap->alen; 2444 gotdiff += adjust - ap->alen; 2445 } else 2446 gotdiff += adjust; 2447 /* 2448 * If the firstblock forbids it, can't use it, 2449 * must use default. 2450 */ 2451 if (!rt && !nullfb && 2452 XFS_FSB_TO_AGNO(mp, gotbno) != fb_agno) 2453 gotbno = NULLFSBLOCK; 2454 } 2455 /* 2456 * No next block, just default. 2457 */ 2458 else 2459 gotbno = NULLFSBLOCK; 2460 /* 2461 * If both valid, pick the better one, else the only good 2462 * one, else ap->rval is already set (to 0 or the inode block). 2463 */ 2464 if (prevbno != NULLFSBLOCK && gotbno != NULLFSBLOCK) 2465 ap->rval = prevdiff <= gotdiff ? prevbno : gotbno; 2466 else if (prevbno != NULLFSBLOCK) 2467 ap->rval = prevbno; 2468 else if (gotbno != NULLFSBLOCK) 2469 ap->rval = gotbno; 2470 } 2471 /* 2472 * If allowed, use ap->rval; otherwise must use firstblock since 2473 * it's in the right allocation group. 2474 */ 2475 if (nullfb || rt || XFS_FSB_TO_AGNO(mp, ap->rval) == fb_agno) 2476 ; 2477 else 2478 ap->rval = ap->firstblock; 2479 /* 2480 * Realtime allocation, done through xfs_rtallocate_extent. 2481 */ 2482 if (rt) { 2483#ifndef __KERNEL__ 2484 ASSERT(0); 2485#else 2486 xfs_rtblock_t rtb; 2487 2488 atype = ap->rval == 0 ? 2489 XFS_ALLOCTYPE_ANY_AG : XFS_ALLOCTYPE_NEAR_BNO; 2490 do_div(ap->rval, mp->m_sb.sb_rextsize); 2491 rtb = ap->rval; 2492 ap->alen = ralen; 2493 if ((error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, ap->alen, 2494 &ralen, atype, ap->wasdel, prod, &rtb))) 2495 return error; 2496 if (rtb == NULLFSBLOCK && prod > 1 && 2497 (error = xfs_rtallocate_extent(ap->tp, ap->rval, 1, 2498 ap->alen, &ralen, atype, 2499 ap->wasdel, 1, &rtb))) 2500 return error; 2501 ap->rval = rtb; 2502 if (ap->rval != NULLFSBLOCK) { 2503 ap->rval *= mp->m_sb.sb_rextsize; 2504 ralen *= mp->m_sb.sb_rextsize; 2505 ap->alen = ralen; 2506 ap->ip->i_d.di_nblocks += ralen; 2507 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); 2508 if (ap->wasdel) 2509 ap->ip->i_delayed_blks -= ralen; 2510 /* 2511 * Adjust the disk quota also. This was reserved 2512 * earlier. 2513 */ 2514 XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, 2515 ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : 2516 XFS_TRANS_DQ_RTBCOUNT, 2517 (long) ralen); 2518 } else 2519 ap->alen = 0; 2520#endif /* __KERNEL__ */ 2521 } 2522 /* 2523 * Normal allocation, done through xfs_alloc_vextent. 2524 */ 2525 else { 2526 xfs_agnumber_t ag; 2527 xfs_alloc_arg_t args; 2528 xfs_extlen_t blen; 2529 xfs_extlen_t delta; 2530 int isaligned; 2531 xfs_extlen_t longest; 2532 xfs_extlen_t need; 2533 xfs_extlen_t nextminlen=0; 2534 int notinit; 2535 xfs_perag_t *pag; 2536 xfs_agnumber_t startag; 2537 int tryagain; 2538 2539 tryagain = isaligned = 0; 2540 args.tp = ap->tp; 2541 args.mp = mp; 2542 args.fsbno = ap->rval; 2543 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); 2544 blen = 0; 2545 if (nullfb) { 2546 args.type = XFS_ALLOCTYPE_START_BNO; 2547 args.total = ap->total; 2548 /* 2549 * Find the longest available space. 2550 * We're going to try for the whole allocation at once. 2551 */ 2552 startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno); 2553 notinit = 0; 2554 down_read(&mp->m_peraglock); 2555 while (blen < ap->alen) { 2556 pag = &mp->m_perag[ag]; 2557 if (!pag->pagf_init && 2558 (error = xfs_alloc_pagf_init(mp, args.tp, 2559 ag, XFS_ALLOC_FLAG_TRYLOCK))) { 2560 up_read(&mp->m_peraglock); 2561 return error; 2562 } 2563 /* 2564 * See xfs_alloc_fix_freelist... 2565 */ 2566 if (pag->pagf_init) { 2567 need = XFS_MIN_FREELIST_PAG(pag, mp); 2568 delta = need > pag->pagf_flcount ? 2569 need - pag->pagf_flcount : 0; 2570 longest = (pag->pagf_longest > delta) ? 2571 (pag->pagf_longest - delta) : 2572 (pag->pagf_flcount > 0 || 2573 pag->pagf_longest > 0); 2574 if (blen < longest) 2575 blen = longest; 2576 } else 2577 notinit = 1; 2578 if (++ag == mp->m_sb.sb_agcount) 2579 ag = 0; 2580 if (ag == startag) 2581 break; 2582 } 2583 up_read(&mp->m_peraglock); 2584 /* 2585 * Since the above loop did a BUF_TRYLOCK, it is 2586 * possible that there is space for this request. 2587 */ 2588 if (notinit || blen < ap->minlen) 2589 args.minlen = ap->minlen; 2590 /* 2591 * If the best seen length is less than the request 2592 * length, use the best as the minimum. 2593 */ 2594 else if (blen < ap->alen) 2595 args.minlen = blen; 2596 /* 2597 * Otherwise we've seen an extent as big as alen, 2598 * use that as the minimum. 2599 */ 2600 else 2601 args.minlen = ap->alen; 2602 } else if (ap->low) { 2603 args.type = XFS_ALLOCTYPE_FIRST_AG; 2604 args.total = args.minlen = ap->minlen; 2605 } else { 2606 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2607 args.total = ap->total; 2608 args.minlen = ap->minlen; 2609 } 2610 if (ap->ip->i_d.di_extsize) { 2611 args.prod = ap->ip->i_d.di_extsize; 2612 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) 2613 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2614 } else if (mp->m_sb.sb_blocksize >= NBPP) { 2615 args.prod = 1; 2616 args.mod = 0; 2617 } else { 2618 args.prod = NBPP >> mp->m_sb.sb_blocklog; 2619 if ((args.mod = (xfs_extlen_t)(do_mod(ap->off, args.prod)))) 2620 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2621 } 2622 /* 2623 * If we are not low on available data blocks, and the 2624 * underlying logical volume manager is a stripe, and 2625 * the file offset is zero then try to allocate data 2626 * blocks on stripe unit boundary. 2627 * NOTE: ap->aeof is only set if the allocation length 2628 * is >= the stripe unit and the allocation offset is 2629 * at the end of file. 2630 */ 2631 if (!ap->low && ap->aeof) { 2632 if (!ap->off) { 2633 args.alignment = mp->m_dalign; 2634 atype = args.type; 2635 isaligned = 1; 2636 /* 2637 * Adjust for alignment 2638 */ 2639 if (blen > args.alignment && blen <= ap->alen) 2640 args.minlen = blen - args.alignment; 2641 args.minalignslop = 0; 2642 } else { 2643 /* 2644 * First try an exact bno allocation. 2645 * If it fails then do a near or start bno 2646 * allocation with alignment turned on. 2647 */ 2648 atype = args.type; 2649 tryagain = 1; 2650 args.type = XFS_ALLOCTYPE_THIS_BNO; 2651 args.alignment = 1; 2652 /* 2653 * Compute the minlen+alignment for the 2654 * next case. Set slop so that the value 2655 * of minlen+alignment+slop doesn't go up 2656 * between the calls. 2657 */ 2658 if (blen > mp->m_dalign && blen <= ap->alen) 2659 nextminlen = blen - mp->m_dalign; 2660 else 2661 nextminlen = args.minlen; 2662 if (nextminlen + mp->m_dalign > args.minlen + 1) 2663 args.minalignslop = 2664 nextminlen + mp->m_dalign - 2665 args.minlen - 1; 2666 else 2667 args.minalignslop = 0; 2668 } 2669 } else { 2670 args.alignment = 1; 2671 args.minalignslop = 0; 2672 } 2673 args.minleft = ap->minleft; 2674 args.wasdel = ap->wasdel; 2675 args.isfl = 0; 2676 args.userdata = ap->userdata; 2677 if ((error = xfs_alloc_vextent(&args))) 2678 return error; 2679 if (tryagain && args.fsbno == NULLFSBLOCK) { 2680 /* 2681 * Exact allocation failed. Now try with alignment 2682 * turned on. 2683 */ 2684 args.type = atype; 2685 args.fsbno = ap->rval; 2686 args.alignment = mp->m_dalign; 2687 args.minlen = nextminlen; 2688 args.minalignslop = 0; 2689 isaligned = 1; 2690 if ((error = xfs_alloc_vextent(&args))) 2691 return error; 2692 } 2693 if (isaligned && args.fsbno == NULLFSBLOCK) { 2694 /* 2695 * allocation failed, so turn off alignment and 2696 * try again. 2697 */ 2698 args.type = atype; 2699 args.fsbno = ap->rval; 2700 args.alignment = 0; 2701 if ((error = xfs_alloc_vextent(&args))) 2702 return error; 2703 } 2704 if (args.fsbno == NULLFSBLOCK && nullfb && 2705 args.minlen > ap->minlen) { 2706 args.minlen = ap->minlen; 2707 args.type = XFS_ALLOCTYPE_START_BNO; 2708 args.fsbno = ap->rval; 2709 if ((error = xfs_alloc_vextent(&args))) 2710 return error; 2711 } 2712 if (args.fsbno == NULLFSBLOCK && nullfb) { 2713 args.fsbno = 0; 2714 args.type = XFS_ALLOCTYPE_FIRST_AG; 2715 args.total = ap->minlen; 2716 args.minleft = 0; 2717 if ((error = xfs_alloc_vextent(&args))) 2718 return error; 2719 ap->low = 1; 2720 } 2721 if (args.fsbno != NULLFSBLOCK) { 2722 ap->firstblock = ap->rval = args.fsbno; 2723 ASSERT(nullfb || fb_agno == args.agno || 2724 (ap->low && fb_agno < args.agno)); 2725 ap->alen = args.len; 2726 ap->ip->i_d.di_nblocks += args.len; 2727 xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); 2728 if (ap->wasdel) 2729 ap->ip->i_delayed_blks -= args.len; 2730 /* 2731 * Adjust the disk quota also. This was reserved 2732 * earlier. 2733 */ 2734 XFS_TRANS_MOD_DQUOT_BYINO(mp, ap->tp, ap->ip, 2735 ap->wasdel ? XFS_TRANS_DQ_DELBCOUNT : 2736 XFS_TRANS_DQ_BCOUNT, 2737 (long) args.len); 2738 } else { 2739 ap->rval = NULLFSBLOCK; 2740 ap->alen = 0; 2741 } 2742 } 2743 return 0; 2744#undef ISVALID 2745} 2746 2747/* 2748 * Transform a btree format file with only one leaf node, where the 2749 * extents list will fit in the inode, into an extents format file. 2750 * Since the extent list is already in-core, all we have to do is 2751 * give up the space for the btree root and pitch the leaf block. 2752 */ 2753STATIC int /* error */ 2754xfs_bmap_btree_to_extents( 2755 xfs_trans_t *tp, /* transaction pointer */ 2756 xfs_inode_t *ip, /* incore inode pointer */ 2757 xfs_btree_cur_t *cur, /* btree cursor */ 2758 int *logflagsp, /* inode logging flags */ 2759 int whichfork) /* data or attr fork */ 2760{ 2761 /* REFERENCED */ 2762 xfs_bmbt_block_t *cblock;/* child btree block */ 2763 xfs_fsblock_t cbno; /* child block number */ 2764 xfs_buf_t *cbp; /* child block's buffer */ 2765 int error; /* error return value */ 2766 xfs_ifork_t *ifp; /* inode fork data */ 2767 xfs_mount_t *mp; /* mount point structure */ 2768 xfs_bmbt_ptr_t *pp; /* ptr to block address */ 2769 xfs_bmbt_block_t *rblock;/* root btree block */ 2770 2771 ifp = XFS_IFORK_PTR(ip, whichfork); 2772 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 2773 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); 2774 rblock = ifp->if_broot; 2775 ASSERT(INT_GET(rblock->bb_level, ARCH_CONVERT) == 1); 2776 ASSERT(INT_GET(rblock->bb_numrecs, ARCH_CONVERT) == 1); 2777 ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1); 2778 mp = ip->i_mount; 2779 pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes); 2780 *logflagsp = 0; 2781#ifdef DEBUG 2782 if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1))) 2783 return error; 2784#endif 2785 cbno = INT_GET(*pp, ARCH_CONVERT); 2786 if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, 2787 XFS_BMAP_BTREE_REF))) 2788 return error; 2789 cblock = XFS_BUF_TO_BMBT_BLOCK(cbp); 2790 if ((error = xfs_btree_check_lblock(cur, cblock, 0, cbp))) 2791 return error; 2792 xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); 2793 ip->i_d.di_nblocks--; 2794 XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); 2795 xfs_trans_binval(tp, cbp); 2796 if (cur->bc_bufs[0] == cbp) 2797 cur->bc_bufs[0] = NULL; 2798 xfs_iroot_realloc(ip, -1, whichfork); 2799 ASSERT(ifp->if_broot == NULL); 2800 ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); 2801 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); 2802 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2803 return 0; 2804} 2805 2806/* 2807 * Called by xfs_bmapi to update extent list structure and the btree 2808 * after removing space (or undoing a delayed allocation). 2809 */ 2810STATIC int /* error */ 2811xfs_bmap_del_extent( 2812 xfs_inode_t *ip, /* incore inode pointer */ 2813 xfs_trans_t *tp, /* current transaction pointer */ 2814 xfs_extnum_t idx, /* extent number to update/delete */ 2815 xfs_bmap_free_t *flist, /* list of extents to be freed */ 2816 xfs_btree_cur_t *cur, /* if null, not a btree */ 2817 xfs_bmbt_irec_t *del, /* data to remove from extent list */ 2818 int *logflagsp, /* inode logging flags */ 2819 int whichfork, /* data or attr fork */ 2820 int rsvd) /* OK to allocate reserved blocks */ 2821{ 2822 xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ 2823 xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ 2824 xfs_fsblock_t del_endblock=0; /* first block past del */ 2825 xfs_fileoff_t del_endoff; /* first offset past del */ 2826 int delay; /* current block is delayed allocated */ 2827 int do_fx; /* free extent at end of routine */ 2828 xfs_bmbt_rec_t *ep; /* current extent entry pointer */ 2829 int error; /* error return value */ 2830 int flags; /* inode logging flags */ 2831#ifdef XFS_BMAP_TRACE 2832 static char fname[] = "xfs_bmap_del_extent"; 2833#endif 2834 xfs_bmbt_irec_t got; /* current extent entry */ 2835 xfs_fileoff_t got_endoff; /* first offset past got */ 2836 int i; /* temp state */ 2837 xfs_ifork_t *ifp; /* inode fork pointer */ 2838 xfs_mount_t *mp; /* mount structure */ 2839 xfs_filblks_t nblks; /* quota/sb block count */ 2840 xfs_bmbt_irec_t new; /* new record to be inserted */ 2841 /* REFERENCED */ 2842 xfs_extnum_t nextents; /* number of extents in list */ 2843 uint qfield; /* quota field to update */ 2844 xfs_filblks_t temp; /* for indirect length calculations */ 2845 xfs_filblks_t temp2; /* for indirect length calculations */ 2846 2847 XFS_STATS_INC(xs_del_exlist); 2848 mp = ip->i_mount; 2849 ifp = XFS_IFORK_PTR(ip, whichfork); 2850 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 2851 ASSERT(idx >= 0 && idx < nextents); 2852 ASSERT(del->br_blockcount > 0); 2853 ep = &ifp->if_u1.if_extents[idx]; 2854 xfs_bmbt_get_all(ep, &got); 2855 ASSERT(got.br_startoff <= del->br_startoff); 2856 del_endoff = del->br_startoff + del->br_blockcount; 2857 got_endoff = got.br_startoff + got.br_blockcount; 2858 ASSERT(got_endoff >= del_endoff); 2859 delay = ISNULLSTARTBLOCK(got.br_startblock); 2860 ASSERT(ISNULLSTARTBLOCK(del->br_startblock) == delay); 2861 flags = 0; 2862 qfield = 0; 2863 error = 0; 2864 /* 2865 * If deleting a real allocation, must free up the disk space. 2866 */ 2867 if (!delay) { 2868 flags = XFS_ILOG_CORE; 2869 /* 2870 * Realtime allocation. Free it and record di_nblocks update. 2871 */ 2872 if (whichfork == XFS_DATA_FORK && 2873 (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { 2874 xfs_fsblock_t bno; 2875 xfs_filblks_t len; 2876 2877 ASSERT(do_mod(del->br_blockcount, 2878 mp->m_sb.sb_rextsize) == 0); 2879 ASSERT(do_mod(del->br_startblock, 2880 mp->m_sb.sb_rextsize) == 0); 2881 bno = del->br_startblock; 2882 len = del->br_blockcount; 2883 do_div(bno, mp->m_sb.sb_rextsize); 2884 do_div(len, mp->m_sb.sb_rextsize); 2885 if ((error = xfs_rtfree_extent(ip->i_transp, bno, 2886 (xfs_extlen_t)len))) 2887 goto done; 2888 do_fx = 0; 2889 nblks = len * mp->m_sb.sb_rextsize; 2890 qfield = XFS_TRANS_DQ_RTBCOUNT; 2891 } 2892 /* 2893 * Ordinary allocation. 2894 */ 2895 else { 2896 do_fx = 1; 2897 nblks = del->br_blockcount; 2898 qfield = XFS_TRANS_DQ_BCOUNT; 2899 } 2900 /* 2901 * Set up del_endblock and cur for later. 2902 */ 2903 del_endblock = del->br_startblock + del->br_blockcount; 2904 if (cur) { 2905 if ((error = xfs_bmbt_lookup_eq(cur, got.br_startoff, 2906 got.br_startblock, got.br_blockcount, 2907 &i))) 2908 goto done; 2909 ASSERT(i == 1); 2910 } 2911 da_old = da_new = 0; 2912 } else { 2913 da_old = STARTBLOCKVAL(got.br_startblock); 2914 da_new = 0; 2915 nblks = 0; 2916 do_fx = 0; 2917 } 2918 /* 2919 * Set flag value to use in switch statement. 2920 * Left-contig is 2, right-contig is 1. 2921 */ 2922 switch (((got.br_startoff == del->br_startoff) << 1) | 2923 (got_endoff == del_endoff)) { 2924 case 3: 2925 /* 2926 * Matches the whole extent. Delete the entry. 2927 */ 2928 xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork); 2929 xfs_bmap_delete_exlist(ip, idx, 1, whichfork); 2930 ifp->if_lastex = idx; 2931 if (delay) 2932 break; 2933 XFS_IFORK_NEXT_SET(ip, whichfork, 2934 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2935 flags |= XFS_ILOG_CORE; 2936 if (!cur) { 2937 flags |= XFS_ILOG_FEXT(whichfork); 2938 break; 2939 } 2940 if ((error = xfs_bmbt_delete(cur, &i))) 2941 goto done; 2942 ASSERT(i == 1); 2943 break; 2944 2945 case 2: 2946 /* 2947 * Deleting the first part of the extent. 2948 */ 2949 xfs_bmap_trace_pre_update(fname, "2", ip, idx, whichfork); 2950 xfs_bmbt_set_startoff(ep, del_endoff); 2951 temp = got.br_blockcount - del->br_blockcount; 2952 xfs_bmbt_set_blockcount(ep, temp); 2953 ifp->if_lastex = idx; 2954 if (delay) { 2955 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 2956 da_old); 2957 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 2958 xfs_bmap_trace_post_update(fname, "2", ip, idx, 2959 whichfork); 2960 da_new = temp; 2961 break; 2962 } 2963 xfs_bmbt_set_startblock(ep, del_endblock); 2964 xfs_bmap_trace_post_update(fname, "2", ip, idx, whichfork); 2965 if (!cur) { 2966 flags |= XFS_ILOG_FEXT(whichfork); 2967 break; 2968 } 2969 if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock, 2970 got.br_blockcount - del->br_blockcount, 2971 got.br_state))) 2972 goto done; 2973 break; 2974 2975 case 1: 2976 /* 2977 * Deleting the last part of the extent. 2978 */ 2979 temp = got.br_blockcount - del->br_blockcount; 2980 xfs_bmap_trace_pre_update(fname, "1", ip, idx, whichfork); 2981 xfs_bmbt_set_blockcount(ep, temp); 2982 ifp->if_lastex = idx; 2983 if (delay) { 2984 temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), 2985 da_old); 2986 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 2987 xfs_bmap_trace_post_update(fname, "1", ip, idx, 2988 whichfork); 2989 da_new = temp; 2990 break; 2991 } 2992 xfs_bmap_trace_post_update(fname, "1", ip, idx, whichfork); 2993 if (!cur) { 2994 flags |= XFS_ILOG_FEXT(whichfork); 2995 break; 2996 } 2997 if ((error = xfs_bmbt_update(cur, got.br_startoff, 2998 got.br_startblock, 2999 got.br_blockcount - del->br_blockcount, 3000 got.br_state))) 3001 goto done; 3002 break; 3003 3004 case 0: 3005 /* 3006 * Deleting the middle of the extent. 3007 */ 3008 temp = del->br_startoff - got.br_startoff; 3009 xfs_bmap_trace_pre_update(fname, "0", ip, idx, whichfork); 3010 xfs_bmbt_set_blockcount(ep, temp); 3011 new.br_startoff = del_endoff; 3012 temp2 = got_endoff - del_endoff; 3013 new.br_blockcount = temp2; 3014 new.br_state = got.br_state; 3015 if (!delay) { 3016 new.br_startblock = del_endblock; 3017 flags |= XFS_ILOG_CORE; 3018 if (cur) { 3019 if ((error = xfs_bmbt_update(cur, 3020 got.br_startoff, 3021 got.br_startblock, temp, 3022 got.br_state))) 3023 goto done; 3024 if ((error = xfs_bmbt_increment(cur, 0, &i))) 3025 goto done; 3026 cur->bc_rec.b = new; 3027 error = xfs_bmbt_insert(cur, &i); 3028 if (error && error != ENOSPC) 3029 goto done; 3030 /* 3031 * If get no-space back from btree insert, 3032 * it tried a split, and we have a zero 3033 * block reservation. 3034 * Fix up our state and return the error. 3035 */ 3036 if (error == ENOSPC) { 3037 /* 3038 * Reset the cursor, don't trust 3039 * it after any insert operation. 3040 */ 3041 if ((error = xfs_bmbt_lookup_eq(cur, 3042 got.br_startoff, 3043 got.br_startblock, 3044 temp, &i))) 3045 goto done; 3046 ASSERT(i == 1); 3047 /* 3048 * Update the btree record back 3049 * to the original value. 3050 */ 3051 if ((error = xfs_bmbt_update(cur, 3052 got.br_startoff, 3053 got.br_startblock, 3054 got.br_blockcount, 3055 got.br_state))) 3056 goto done; 3057 /* 3058 * Reset the extent record back 3059 * to the original value. 3060 */ 3061 xfs_bmbt_set_blockcount(ep, 3062 got.br_blockcount); 3063 flags = 0; 3064 error = XFS_ERROR(ENOSPC); 3065 goto done; 3066 } 3067 ASSERT(i == 1); 3068 } else 3069 flags |= XFS_ILOG_FEXT(whichfork); 3070 XFS_IFORK_NEXT_SET(ip, whichfork, 3071 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 3072 } else { 3073 ASSERT(whichfork == XFS_DATA_FORK); 3074 temp = xfs_bmap_worst_indlen(ip, temp); 3075 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 3076 temp2 = xfs_bmap_worst_indlen(ip, temp2); 3077 new.br_startblock = NULLSTARTBLOCK((int)temp2); 3078 da_new = temp + temp2; 3079 while (da_new > da_old) { 3080 if (temp) { 3081 temp--; 3082 da_new--; 3083 xfs_bmbt_set_startblock(ep, 3084 NULLSTARTBLOCK((int)temp)); 3085 } 3086 if (da_new == da_old) 3087 break; 3088 if (temp2) { 3089 temp2--; 3090 da_new--; 3091 new.br_startblock = 3092 NULLSTARTBLOCK((int)temp2); 3093 } 3094 } 3095 } 3096 xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork); 3097 xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL, 3098 whichfork); 3099 xfs_bmap_insert_exlist(ip, idx + 1, 1, &new, whichfork); 3100 ifp->if_lastex = idx + 1; 3101 break; 3102 } 3103 /* 3104 * If we need to, add to list of extents to delete. 3105 */ 3106 if (do_fx) 3107 xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist, 3108 mp); 3109 /* 3110 * Adjust inode # blocks in the file. 3111 */ 3112 if (nblks) 3113 ip->i_d.di_nblocks -= nblks; 3114 /* 3115 * Adjust quota data. 3116 */ 3117 if (qfield) 3118 XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, qfield, (long)-nblks); 3119 3120 /* 3121 * Account for change in delayed indirect blocks. 3122 * Nothing to do for disk quota accounting here. 3123 */ 3124 ASSERT(da_old >= da_new); 3125 if (da_old > da_new) 3126 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), 3127 rsvd); 3128done: 3129 *logflagsp = flags; 3130 return error; 3131} 3132 3133/* 3134 * Remove the entry "free" from the free item list. Prev points to the 3135 * previous entry, unless "free" is the head of the list. 3136 */ 3137STATIC void 3138xfs_bmap_del_free( 3139 xfs_bmap_free_t *flist, /* free item list header */ 3140 xfs_bmap_free_item_t *prev, /* previous item on list, if any */ 3141 xfs_bmap_free_item_t *free) /* list item to be freed */ 3142{ 3143 if (prev) 3144 prev->xbfi_next = free->xbfi_next; 3145 else 3146 flist->xbf_first = free->xbfi_next; 3147 flist->xbf_count--; 3148 kmem_zone_free(xfs_bmap_free_item_zone, free); 3149} 3150 3151/* 3152 * Remove count entries from the extents array for inode "ip", starting 3153 * at index "idx". Copies the remaining items down over the deleted ones, 3154 * and gives back the excess memory. 3155 */ 3156STATIC void 3157xfs_bmap_delete_exlist( 3158 xfs_inode_t *ip, /* incore inode pointer */ 3159 xfs_extnum_t idx, /* starting delete index */ 3160 xfs_extnum_t count, /* count of items to delete */ 3161 int whichfork) /* data or attr fork */ 3162{ 3163 xfs_bmbt_rec_t *base; /* base of extent list */ 3164 xfs_ifork_t *ifp; /* inode fork pointer */ 3165 xfs_extnum_t nextents; /* number of extents in list after */ 3166 3167 ifp = XFS_IFORK_PTR(ip, whichfork); 3168 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 3169 base = ifp->if_u1.if_extents; 3170 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - count; 3171 memmove(&base[idx], &base[idx + count], 3172 (nextents - idx) * sizeof(*base)); 3173 xfs_iext_realloc(ip, -count, whichfork); 3174} 3175 3176/* 3177 * Convert an extents-format file into a btree-format file. 3178 * The new file will have a root block (in the inode) and a single child block. 3179 */ 3180STATIC int /* error */ 3181xfs_bmap_extents_to_btree( 3182 xfs_trans_t *tp, /* transaction pointer */ 3183 xfs_inode_t *ip, /* incore inode pointer */ 3184 xfs_fsblock_t *firstblock, /* first-block-allocated */ 3185 xfs_bmap_free_t *flist, /* blocks freed in xaction */ 3186 xfs_btree_cur_t **curp, /* cursor returned to caller */ 3187 int wasdel, /* converting a delayed alloc */ 3188 int *logflagsp, /* inode logging flags */ 3189 int whichfork) /* data or attr fork */ 3190{ 3191 xfs_bmbt_block_t *ablock; /* allocated (child) bt block */ 3192 xfs_buf_t *abp; /* buffer for ablock */ 3193 xfs_alloc_arg_t args; /* allocation arguments */ 3194 xfs_bmbt_rec_t *arp; /* child record pointer */ 3195 xfs_bmbt_block_t *block; /* btree root block */ 3196 xfs_btree_cur_t *cur; /* bmap btree cursor */ 3197 xfs_bmbt_rec_t *ep; /* extent list pointer */ 3198 int error; /* error return value */ 3199 xfs_extnum_t i, cnt; /* extent list index */ 3200 xfs_ifork_t *ifp; /* inode fork pointer */ 3201 xfs_bmbt_key_t *kp; /* root block key pointer */ 3202 xfs_mount_t *mp; /* mount structure */ 3203 xfs_extnum_t nextents; /* extent list size */ 3204 xfs_bmbt_ptr_t *pp; /* root block address pointer */ 3205 3206 ifp = XFS_IFORK_PTR(ip, whichfork); 3207 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); 3208 ASSERT(ifp->if_ext_max == 3209 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 3210 /* 3211 * Make space in the inode incore. 3212 */ 3213 xfs_iroot_realloc(ip, 1, whichfork); 3214 ifp->if_flags |= XFS_IFBROOT; 3215 /* 3216 * Fill in the root. 3217 */ 3218 block = ifp->if_broot; 3219 INT_SET(block->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC); 3220 INT_SET(block->bb_level, ARCH_CONVERT, 1); 3221 INT_SET(block->bb_numrecs, ARCH_CONVERT, 1); 3222 INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLDFSBNO); 3223 INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLDFSBNO); 3224 /* 3225 * Need a cursor. Can't allocate until bb_level is filled in. 3226 */ 3227 mp = ip->i_mount; 3228 cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip, 3229 whichfork); 3230 cur->bc_private.b.firstblock = *firstblock; 3231 cur->bc_private.b.flist = flist; 3232 cur->bc_private.b.flags = wasdel ? XFS_BTCUR_BPRV_WASDEL : 0; 3233 /* 3234 * Convert to a btree with two levels, one record in root. 3235 */ 3236 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); 3237 args.tp = tp; 3238 args.mp = mp; 3239 if (*firstblock == NULLFSBLOCK) { 3240 args.type = XFS_ALLOCTYPE_START_BNO; 3241 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); 3242 } else if (flist->xbf_low) { 3243 args.type = XFS_ALLOCTYPE_START_BNO; 3244 args.fsbno = *firstblock; 3245 } else { 3246 args.type = XFS_ALLOCTYPE_NEAR_BNO; 3247 args.fsbno = *firstblock; 3248 } 3249 args.minlen = args.maxlen = args.prod = 1; 3250 args.total = args.minleft = args.alignment = args.mod = args.isfl = 3251 args.minalignslop = 0; 3252 args.wasdel = wasdel; 3253 *logflagsp = 0; 3254 if ((error = xfs_alloc_vextent(&args))) { 3255 xfs_iroot_realloc(ip, -1, whichfork); 3256 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); 3257 return error; 3258 } 3259 /* 3260 * Allocation can't fail, the space was reserved. 3261 */ 3262 ASSERT(args.fsbno != NULLFSBLOCK); 3263 ASSERT(*firstblock == NULLFSBLOCK || 3264 args.agno == XFS_FSB_TO_AGNO(mp, *firstblock) || 3265 (flist->xbf_low && 3266 args.agno > XFS_FSB_TO_AGNO(mp, *firstblock))); 3267 *firstblock = cur->bc_private.b.firstblock = args.fsbno; 3268 cur->bc_private.b.allocated++; 3269 ip->i_d.di_nblocks++; 3270 XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); 3271 abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0); 3272 /* 3273 * Fill in the child block. 3274 */ 3275 ablock = XFS_BUF_TO_BMBT_BLOCK(abp); 3276 INT_SET(ablock->bb_magic, ARCH_CONVERT, XFS_BMAP_MAGIC); 3277 ablock->bb_level = 0; 3278 INT_SET(ablock->bb_leftsib, ARCH_CONVERT, NULLDFSBNO); 3279 INT_SET(ablock->bb_rightsib, ARCH_CONVERT, NULLDFSBNO); 3280 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); 3281 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3282 for (ep = ifp->if_u1.if_extents, cnt = i = 0; i < nextents; i++, ep++) { 3283 if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { 3284 arp->l0 = INT_GET(ep->l0, ARCH_CONVERT); 3285 arp->l1 = INT_GET(ep->l1, ARCH_CONVERT); 3286 arp++; cnt++; 3287 } 3288 } 3289 INT_SET(ablock->bb_numrecs, ARCH_CONVERT, cnt); 3290 ASSERT(INT_GET(ablock->bb_numrecs, ARCH_CONVERT) == XFS_IFORK_NEXTENTS(ip, whichfork)); 3291 /* 3292 * Fill in the root key and pointer. 3293 */ 3294 kp = XFS_BMAP_KEY_IADDR(block, 1, cur); 3295 arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); 3296 INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp)); 3297 pp = XFS_BMAP_PTR_IADDR(block, 1, cur); 3298 INT_SET(*pp, ARCH_CONVERT, args.fsbno); 3299 /* 3300 * Do all this logging at the end so that 3301 * the root is at the right level. 3302 */ 3303 xfs_bmbt_log_block(cur, abp, XFS_BB_ALL_BITS); 3304 xfs_bmbt_log_recs(cur, abp, 1, INT_GET(ablock->bb_numrecs, ARCH_CONVERT)); 3305 ASSERT(*curp == NULL); 3306 *curp = cur; 3307 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FBROOT(whichfork); 3308 return 0; 3309} 3310 3311/* 3312 * Insert new item(s) in the extent list for inode "ip". 3313 * Count new items are inserted at offset idx. 3314 */ 3315STATIC void 3316xfs_bmap_insert_exlist( 3317 xfs_inode_t *ip, /* incore inode pointer */ 3318 xfs_extnum_t idx, /* starting index of new items */ 3319 xfs_extnum_t count, /* number of inserted items */ 3320 xfs_bmbt_irec_t *new, /* items to insert */ 3321 int whichfork) /* data or attr fork */ 3322{ 3323 xfs_bmbt_rec_t *base; /* extent list base */ 3324 xfs_ifork_t *ifp; /* inode fork pointer */ 3325 xfs_extnum_t nextents; /* extent list size */ 3326 xfs_extnum_t to; /* extent list index */ 3327 3328 ifp = XFS_IFORK_PTR(ip, whichfork); 3329 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 3330 xfs_iext_realloc(ip, count, whichfork); 3331 base = ifp->if_u1.if_extents; 3332 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3333 memmove(&base[idx + count], &base[idx], 3334 (nextents - (idx + count)) * sizeof(*base)); 3335 for (to = idx; to < idx + count; to++, new++) 3336 xfs_bmbt_set_all(&base[to], new); 3337} 3338 3339/* 3340 * Convert a local file to an extents file. 3341 * This code is out of bounds for data forks of regular files, 3342 * since the file data needs to get logged so things will stay consistent. 3343 * (The bmap-level manipulations are ok, though). 3344 */ 3345STATIC int /* error */ 3346xfs_bmap_local_to_extents( 3347 xfs_trans_t *tp, /* transaction pointer */ 3348 xfs_inode_t *ip, /* incore inode pointer */ 3349 xfs_fsblock_t *firstblock, /* first block allocated in xaction */ 3350 xfs_extlen_t total, /* total blocks needed by transaction */ 3351 int *logflagsp, /* inode logging flags */ 3352 int whichfork) /* data or attr fork */ 3353{ 3354 int error; /* error return value */ 3355 int flags; /* logging flags returned */ 3356#ifdef XFS_BMAP_TRACE 3357 static char fname[] = "xfs_bmap_local_to_extents"; 3358#endif 3359 xfs_ifork_t *ifp; /* inode fork pointer */ 3360 3361 /* 3362 * We don't want to deal with the case of keeping inode data inline yet. 3363 * So sending the data fork of a regular inode is invalid. 3364 */ 3365 ASSERT(!((ip->i_d.di_mode & S_IFMT) == S_IFREG && 3366 whichfork == XFS_DATA_FORK)); 3367 ifp = XFS_IFORK_PTR(ip, whichfork); 3368 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 3369 flags = 0; 3370 error = 0; 3371 if (ifp->if_bytes) { 3372 xfs_alloc_arg_t args; /* allocation arguments */ 3373 xfs_buf_t *bp; /* buffer for extent list block */ 3374 xfs_bmbt_rec_t *ep; /* extent list pointer */ 3375 3376 args.tp = tp; 3377 args.mp = ip->i_mount; 3378 ASSERT(ifp->if_flags & XFS_IFINLINE); 3379 /* 3380 * Allocate a block. We know we need only one, since the 3381 * file currently fits in an inode. 3382 */ 3383 if (*firstblock == NULLFSBLOCK) { 3384 args.fsbno = XFS_INO_TO_FSB(args.mp, ip->i_ino); 3385 args.type = XFS_ALLOCTYPE_START_BNO; 3386 } else { 3387 args.fsbno = *firstblock; 3388 args.type = XFS_ALLOCTYPE_NEAR_BNO; 3389 } 3390 args.total = total; 3391 args.mod = args.minleft = args.alignment = args.wasdel = 3392 args.isfl = args.minalignslop = 0; 3393 args.minlen = args.maxlen = args.prod = 1; 3394 if ((error = xfs_alloc_vextent(&args))) 3395 goto done; 3396 /* 3397 * Can't fail, the space was reserved. 3398 */ 3399 ASSERT(args.fsbno != NULLFSBLOCK); 3400 ASSERT(args.len == 1); 3401 *firstblock = args.fsbno; 3402 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); 3403 memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data, 3404 ifp->if_bytes); 3405 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 3406 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); 3407 xfs_iext_realloc(ip, 1, whichfork); 3408 ep = ifp->if_u1.if_extents; 3409 xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); 3410 xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork); 3411 XFS_IFORK_NEXT_SET(ip, whichfork, 1); 3412 ip->i_d.di_nblocks = 1; 3413 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, 3414 XFS_TRANS_DQ_BCOUNT, 1L); 3415 flags |= XFS_ILOG_FEXT(whichfork); 3416 } else 3417 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); 3418 ifp->if_flags &= ~XFS_IFINLINE; 3419 ifp->if_flags |= XFS_IFEXTENTS; 3420 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); 3421 flags |= XFS_ILOG_CORE; 3422done: 3423 *logflagsp = flags; 3424 return error; 3425} 3426 3427xfs_bmbt_rec_t * /* pointer to found extent entry */ 3428xfs_bmap_do_search_extents( 3429 xfs_bmbt_rec_t *base, /* base of extent list */ 3430 xfs_extnum_t lastx, /* last extent index used */ 3431 xfs_extnum_t nextents, /* extent list size */ 3432 xfs_fileoff_t bno, /* block number searched for */ 3433 int *eofp, /* out: end of file found */ 3434 xfs_extnum_t *lastxp, /* out: last extent index */ 3435 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 3436 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 3437{ 3438 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 3439 xfs_bmbt_irec_t got; /* extent list entry, decoded */ 3440 int high; /* high index of binary search */ 3441 int low; /* low index of binary search */ 3442 3443 /* 3444 * Initialize the extent entry structure to catch access to 3445 * uninitialized br_startblock field. 3446 */ 3447 got.br_startoff = 0xffa5a5a5a5a5a5a5LL; 3448 got.br_blockcount = 0xa55a5a5a5a5a5a5aLL; 3449 got.br_state = XFS_EXT_INVALID; 3450 3451#if XFS_BIG_BLKNOS 3452 got.br_startblock = 0xffffa5a5a5a5a5a5LL; 3453#else 3454 got.br_startblock = 0xffffa5a5; 3455#endif 3456 3457 if (lastx != NULLEXTNUM && lastx < nextents) 3458 ep = base + lastx; 3459 else 3460 ep = NULL; 3461 prevp->br_startoff = NULLFILEOFF; 3462 if (ep && bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep)) && 3463 bno < got.br_startoff + 3464 (got.br_blockcount = xfs_bmbt_get_blockcount(ep))) 3465 *eofp = 0; 3466 else if (ep && lastx < nextents - 1 && 3467 bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep + 1)) && 3468 bno < got.br_startoff + 3469 (got.br_blockcount = xfs_bmbt_get_blockcount(ep + 1))) { 3470 lastx++; 3471 ep++; 3472 *eofp = 0; 3473 } else if (nextents == 0) 3474 *eofp = 1; 3475 else if (bno == 0 && 3476 (got.br_startoff = xfs_bmbt_get_startoff(base)) == 0) { 3477 ep = base; 3478 lastx = 0; 3479 got.br_blockcount = xfs_bmbt_get_blockcount(ep); 3480 *eofp = 0; 3481 } else { 3482 /* binary search the extents array */ 3483 low = 0; 3484 high = nextents - 1; 3485 while (low <= high) { 3486 XFS_STATS_INC(xs_cmp_exlist); 3487 lastx = (low + high) >> 1; 3488 ep = base + lastx; 3489 got.br_startoff = xfs_bmbt_get_startoff(ep); 3490 got.br_blockcount = xfs_bmbt_get_blockcount(ep); 3491 if (bno < got.br_startoff) 3492 high = lastx - 1; 3493 else if (bno >= got.br_startoff + got.br_blockcount) 3494 low = lastx + 1; 3495 else { 3496 got.br_startblock = xfs_bmbt_get_startblock(ep); 3497 got.br_state = xfs_bmbt_get_state(ep); 3498 *eofp = 0; 3499 *lastxp = lastx; 3500 *gotp = got; 3501 return ep; 3502 } 3503 } 3504 if (bno >= got.br_startoff + got.br_blockcount) { 3505 lastx++; 3506 if (lastx == nextents) { 3507 *eofp = 1; 3508 got.br_startblock = xfs_bmbt_get_startblock(ep); 3509 got.br_state = xfs_bmbt_get_state(ep); 3510 *prevp = got; 3511 ep = NULL; 3512 } else { 3513 *eofp = 0; 3514 xfs_bmbt_get_all(ep, prevp); 3515 ep++; 3516 got.br_startoff = xfs_bmbt_get_startoff(ep); 3517 got.br_blockcount = xfs_bmbt_get_blockcount(ep); 3518 } 3519 } else { 3520 *eofp = 0; 3521 if (ep > base) 3522 xfs_bmbt_get_all(ep - 1, prevp); 3523 } 3524 } 3525 if (ep) { 3526 got.br_startblock = xfs_bmbt_get_startblock(ep); 3527 got.br_state = xfs_bmbt_get_state(ep); 3528 } 3529 *lastxp = lastx; 3530 *gotp = got; 3531 return ep; 3532} 3533 3534/* 3535 * Search the extents list for the inode, for the extent containing bno. 3536 * If bno lies in a hole, point to the next entry. If bno lies past eof, 3537 * *eofp will be set, and *prevp will contain the last entry (null if none). 3538 * Else, *lastxp will be set to the index of the found 3539 * entry; *gotp will contain the entry. 3540 */ 3541STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ 3542xfs_bmap_search_extents( 3543 xfs_inode_t *ip, /* incore inode pointer */ 3544 xfs_fileoff_t bno, /* block number searched for */ 3545 int whichfork, /* data or attr fork */ 3546 int *eofp, /* out: end of file found */ 3547 xfs_extnum_t *lastxp, /* out: last extent index */ 3548 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 3549 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 3550{ 3551 xfs_ifork_t *ifp; /* inode fork pointer */ 3552 xfs_bmbt_rec_t *base; /* base of extent list */ 3553 xfs_extnum_t lastx; /* last extent index used */ 3554 xfs_extnum_t nextents; /* extent list size */ 3555 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 3556 int rt; /* realtime flag */ 3557 3558 XFS_STATS_INC(xs_look_exlist); 3559 ifp = XFS_IFORK_PTR(ip, whichfork); 3560 lastx = ifp->if_lastex; 3561 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3562 base = &ifp->if_u1.if_extents[0]; 3563 3564 ep = xfs_bmap_do_search_extents(base, lastx, nextents, bno, eofp, 3565 lastxp, gotp, prevp); 3566 rt = ip->i_d.di_flags & XFS_DIFLAG_REALTIME; 3567 if(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM)) { 3568 cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " 3569 "start_block : %llx start_off : %llx blkcnt : %llx " 3570 "extent-state : %x \n", 3571 (ip->i_mount)->m_fsname,(long long)ip->i_ino, 3572 gotp->br_startblock, gotp->br_startoff, 3573 gotp->br_blockcount,gotp->br_state); 3574 } 3575 return ep; 3576} 3577 3578 3579#ifdef XFS_BMAP_TRACE 3580ktrace_t *xfs_bmap_trace_buf; 3581 3582/* 3583 * Add a bmap trace buffer entry. Base routine for the others. 3584 */ 3585STATIC void 3586xfs_bmap_trace_addentry( 3587 int opcode, /* operation */ 3588 char *fname, /* function name */ 3589 char *desc, /* operation description */ 3590 xfs_inode_t *ip, /* incore inode pointer */ 3591 xfs_extnum_t idx, /* index of entry(ies) */ 3592 xfs_extnum_t cnt, /* count of entries, 1 or 2 */ 3593 xfs_bmbt_rec_t *r1, /* first record */ 3594 xfs_bmbt_rec_t *r2, /* second record or null */ 3595 int whichfork) /* data or attr fork */ 3596{ 3597 xfs_bmbt_rec_t tr2; 3598 3599 ASSERT(cnt == 1 || cnt == 2); 3600 ASSERT(r1 != NULL); 3601 if (cnt == 1) { 3602 ASSERT(r2 == NULL); 3603 r2 = &tr2; 3604 memset(&tr2, 0, sizeof(tr2)); 3605 } else 3606 ASSERT(r2 != NULL); 3607 ktrace_enter(xfs_bmap_trace_buf, 3608 (void *)(__psint_t)(opcode | (whichfork << 16)), 3609 (void *)fname, (void *)desc, (void *)ip, 3610 (void *)(__psint_t)idx, 3611 (void *)(__psint_t)cnt, 3612 (void *)(__psunsigned_t)(ip->i_ino >> 32), 3613 (void *)(__psunsigned_t)(unsigned)ip->i_ino, 3614 (void *)(__psunsigned_t)(r1->l0 >> 32), 3615 (void *)(__psunsigned_t)(unsigned)(r1->l0), 3616 (void *)(__psunsigned_t)(r1->l1 >> 32), 3617 (void *)(__psunsigned_t)(unsigned)(r1->l1), 3618 (void *)(__psunsigned_t)(r2->l0 >> 32), 3619 (void *)(__psunsigned_t)(unsigned)(r2->l0), 3620 (void *)(__psunsigned_t)(r2->l1 >> 32), 3621 (void *)(__psunsigned_t)(unsigned)(r2->l1) 3622 ); 3623 ASSERT(ip->i_xtrace); 3624 ktrace_enter(ip->i_xtrace, 3625 (void *)(__psint_t)(opcode | (whichfork << 16)), 3626 (void *)fname, (void *)desc, (void *)ip, 3627 (void *)(__psint_t)idx, 3628 (void *)(__psint_t)cnt, 3629 (void *)(__psunsigned_t)(ip->i_ino >> 32), 3630 (void *)(__psunsigned_t)(unsigned)ip->i_ino, 3631 (void *)(__psunsigned_t)(r1->l0 >> 32), 3632 (void *)(__psunsigned_t)(unsigned)(r1->l0), 3633 (void *)(__psunsigned_t)(r1->l1 >> 32), 3634 (void *)(__psunsigned_t)(unsigned)(r1->l1), 3635 (void *)(__psunsigned_t)(r2->l0 >> 32), 3636 (void *)(__psunsigned_t)(unsigned)(r2->l0), 3637 (void *)(__psunsigned_t)(r2->l1 >> 32), 3638 (void *)(__psunsigned_t)(unsigned)(r2->l1) 3639 ); 3640} 3641 3642/* 3643 * Add bmap trace entry prior to a call to xfs_bmap_delete_exlist. 3644 */ 3645STATIC void 3646xfs_bmap_trace_delete( 3647 char *fname, /* function name */ 3648 char *desc, /* operation description */ 3649 xfs_inode_t *ip, /* incore inode pointer */ 3650 xfs_extnum_t idx, /* index of entry(entries) deleted */ 3651 xfs_extnum_t cnt, /* count of entries deleted, 1 or 2 */ 3652 int whichfork) /* data or attr fork */ 3653{ 3654 xfs_ifork_t *ifp; /* inode fork pointer */ 3655 3656 ifp = XFS_IFORK_PTR(ip, whichfork); 3657 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_DELETE, fname, desc, ip, idx, 3658 cnt, &ifp->if_u1.if_extents[idx], 3659 cnt == 2 ? &ifp->if_u1.if_extents[idx + 1] : NULL, 3660 whichfork); 3661} 3662 3663/* 3664 * Add bmap trace entry prior to a call to xfs_bmap_insert_exlist, or 3665 * reading in the extents list from the disk (in the btree). 3666 */ 3667STATIC void 3668xfs_bmap_trace_insert( 3669 char *fname, /* function name */ 3670 char *desc, /* operation description */ 3671 xfs_inode_t *ip, /* incore inode pointer */ 3672 xfs_extnum_t idx, /* index of entry(entries) inserted */ 3673 xfs_extnum_t cnt, /* count of entries inserted, 1 or 2 */ 3674 xfs_bmbt_irec_t *r1, /* inserted record 1 */ 3675 xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ 3676 int whichfork) /* data or attr fork */ 3677{ 3678 xfs_bmbt_rec_t tr1; /* compressed record 1 */ 3679 xfs_bmbt_rec_t tr2; /* compressed record 2 if needed */ 3680 3681 xfs_bmbt_set_all(&tr1, r1); 3682 if (cnt == 2) { 3683 ASSERT(r2 != NULL); 3684 xfs_bmbt_set_all(&tr2, r2); 3685 } else { 3686 ASSERT(cnt == 1); 3687 ASSERT(r2 == NULL); 3688 } 3689 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_INSERT, fname, desc, ip, idx, 3690 cnt, &tr1, cnt == 2 ? &tr2 : NULL, whichfork); 3691} 3692 3693/* 3694 * Add bmap trace entry after updating an extent list entry in place. 3695 */ 3696STATIC void 3697xfs_bmap_trace_post_update( 3698 char *fname, /* function name */ 3699 char *desc, /* operation description */ 3700 xfs_inode_t *ip, /* incore inode pointer */ 3701 xfs_extnum_t idx, /* index of entry updated */ 3702 int whichfork) /* data or attr fork */ 3703{ 3704 xfs_ifork_t *ifp; /* inode fork pointer */ 3705 3706 ifp = XFS_IFORK_PTR(ip, whichfork); 3707 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_POST_UP, fname, desc, ip, idx, 3708 1, &ifp->if_u1.if_extents[idx], NULL, whichfork); 3709} 3710 3711/* 3712 * Add bmap trace entry prior to updating an extent list entry in place. 3713 */ 3714STATIC void 3715xfs_bmap_trace_pre_update( 3716 char *fname, /* function name */ 3717 char *desc, /* operation description */ 3718 xfs_inode_t *ip, /* incore inode pointer */ 3719 xfs_extnum_t idx, /* index of entry to be updated */ 3720 int whichfork) /* data or attr fork */ 3721{ 3722 xfs_ifork_t *ifp; /* inode fork pointer */ 3723 3724 ifp = XFS_IFORK_PTR(ip, whichfork); 3725 xfs_bmap_trace_addentry(XFS_BMAP_KTRACE_PRE_UP, fname, desc, ip, idx, 1, 3726 &ifp->if_u1.if_extents[idx], NULL, whichfork); 3727} 3728#endif /* XFS_BMAP_TRACE */ 3729 3730/* 3731 * Compute the worst-case number of indirect blocks that will be used 3732 * for ip's delayed extent of length "len". 3733 */ 3734STATIC xfs_filblks_t 3735xfs_bmap_worst_indlen( 3736 xfs_inode_t *ip, /* incore inode pointer */ 3737 xfs_filblks_t len) /* delayed extent length */ 3738{ 3739 int level; /* btree level number */ 3740 int maxrecs; /* maximum record count at this level */ 3741 xfs_mount_t *mp; /* mount structure */ 3742 xfs_filblks_t rval; /* return value */ 3743 3744 mp = ip->i_mount; 3745 maxrecs = mp->m_bmap_dmxr[0]; 3746 for (level = 0, rval = 0; 3747 level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); 3748 level++) { 3749 len += maxrecs - 1; 3750 do_div(len, maxrecs); 3751 rval += len; 3752 if (len == 1) 3753 return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 3754 level - 1; 3755 if (level == 0) 3756 maxrecs = mp->m_bmap_dmxr[1]; 3757 } 3758 return rval; 3759} 3760 3761#if defined(XFS_RW_TRACE) 3762STATIC void 3763xfs_bunmap_trace( 3764 xfs_inode_t *ip, 3765 xfs_fileoff_t bno, 3766 xfs_filblks_t len, 3767 int flags, 3768 inst_t *ra) 3769{ 3770 if (ip->i_rwtrace == NULL) 3771 return; 3772 ktrace_enter(ip->i_rwtrace, 3773 (void *)(__psint_t)XFS_BUNMAPI, 3774 (void *)ip, 3775 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), 3776 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), 3777 (void *)(__psint_t)(((xfs_dfiloff_t)bno >> 32) & 0xffffffff), 3778 (void *)(__psint_t)((xfs_dfiloff_t)bno & 0xffffffff), 3779 (void *)(__psint_t)len, 3780 (void *)(__psint_t)flags, 3781 (void *)(unsigned long)current_cpu(), 3782 (void *)ra, 3783 (void *)0, 3784 (void *)0, 3785 (void *)0, 3786 (void *)0, 3787 (void *)0, 3788 (void *)0); 3789} 3790#endif 3791 3792/* 3793 * Convert inode from non-attributed to attributed. 3794 * Must not be in a transaction, ip must not be locked. 3795 */ 3796int /* error code */ 3797xfs_bmap_add_attrfork( 3798 xfs_inode_t *ip, /* incore inode pointer */ 3799 int rsvd) /* OK to allocated reserved blocks in trans */ 3800{ 3801 int blks; /* space reservation */ 3802 int committed; /* xaction was committed */ 3803 int error; /* error return value */ 3804 xfs_fsblock_t firstblock; /* 1st block/ag allocated */ 3805 xfs_bmap_free_t flist; /* freed extent list */ 3806 int logflags; /* logging flags */ 3807 xfs_mount_t *mp; /* mount structure */ 3808 unsigned long s; /* spinlock spl value */ 3809 xfs_trans_t *tp; /* transaction pointer */ 3810 3811 ASSERT(ip->i_df.if_ext_max == 3812 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); 3813 if (XFS_IFORK_Q(ip)) 3814 return 0; 3815 mp = ip->i_mount; 3816 ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); 3817 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK); 3818 blks = XFS_ADDAFORK_SPACE_RES(mp); 3819 if (rsvd) 3820 tp->t_flags |= XFS_TRANS_RESERVE; 3821 if ((error = xfs_trans_reserve(tp, blks, XFS_ADDAFORK_LOG_RES(mp), 0, 3822 XFS_TRANS_PERM_LOG_RES, XFS_ADDAFORK_LOG_COUNT))) 3823 goto error0; 3824 xfs_ilock(ip, XFS_ILOCK_EXCL); 3825 error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, blks, 0, rsvd ? 3826 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES : 3827 XFS_QMOPT_RES_REGBLKS); 3828 if (error) { 3829 xfs_iunlock(ip, XFS_ILOCK_EXCL); 3830 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); 3831 return error; 3832 } 3833 if (XFS_IFORK_Q(ip)) 3834 goto error1; 3835 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { 3836 /* 3837 * For inodes coming from pre-6.2 filesystems. 3838 */ 3839 ASSERT(ip->i_d.di_aformat == 0); 3840 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; 3841 } 3842 ASSERT(ip->i_d.di_anextents == 0); 3843 VN_HOLD(XFS_ITOV(ip)); 3844 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 3845 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 3846 switch (ip->i_d.di_format) { 3847 case XFS_DINODE_FMT_DEV: 3848 ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; 3849 break; 3850 case XFS_DINODE_FMT_UUID: 3851 ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3; 3852 break; 3853 case XFS_DINODE_FMT_LOCAL: 3854 case XFS_DINODE_FMT_EXTENTS: 3855 case XFS_DINODE_FMT_BTREE: 3856 ip->i_d.di_forkoff = mp->m_attroffset >> 3; 3857 break; 3858 default: 3859 ASSERT(0); 3860 error = XFS_ERROR(EINVAL); 3861 goto error1; 3862 } 3863 ip->i_df.if_ext_max = 3864 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); 3865 ASSERT(ip->i_afp == NULL); 3866 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); 3867 ip->i_afp->if_ext_max = 3868 XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); 3869 ip->i_afp->if_flags = XFS_IFEXTENTS; 3870 logflags = 0; 3871 XFS_BMAP_INIT(&flist, &firstblock); 3872 switch (ip->i_d.di_format) { 3873 case XFS_DINODE_FMT_LOCAL: 3874 error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist, 3875 &logflags); 3876 break; 3877 case XFS_DINODE_FMT_EXTENTS: 3878 error = xfs_bmap_add_attrfork_extents(tp, ip, &firstblock, 3879 &flist, &logflags); 3880 break; 3881 case XFS_DINODE_FMT_BTREE: 3882 error = xfs_bmap_add_attrfork_btree(tp, ip, &firstblock, &flist, 3883 &logflags); 3884 break; 3885 default: 3886 error = 0; 3887 break; 3888 } 3889 if (logflags) 3890 xfs_trans_log_inode(tp, ip, logflags); 3891 if (error) 3892 goto error2; 3893 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { 3894 s = XFS_SB_LOCK(mp); 3895 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { 3896 XFS_SB_VERSION_ADDATTR(&mp->m_sb); 3897 XFS_SB_UNLOCK(mp, s); 3898 xfs_mod_sb(tp, XFS_SB_VERSIONNUM); 3899 } else 3900 XFS_SB_UNLOCK(mp, s); 3901 } 3902 if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) 3903 goto error2; 3904 error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES, NULL); 3905 ASSERT(ip->i_df.if_ext_max == 3906 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); 3907 return error; 3908error2: 3909 xfs_bmap_cancel(&flist); 3910error1: 3911 ASSERT(ismrlocked(&ip->i_lock,MR_UPDATE)); 3912 xfs_iunlock(ip, XFS_ILOCK_EXCL); 3913error0: 3914 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 3915 ASSERT(ip->i_df.if_ext_max == 3916 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); 3917 return error; 3918} 3919 3920/* 3921 * Add the extent to the list of extents to be free at transaction end. 3922 * The list is maintained sorted (by block number). 3923 */ 3924/* ARGSUSED */ 3925void 3926xfs_bmap_add_free( 3927 xfs_fsblock_t bno, /* fs block number of extent */ 3928 xfs_filblks_t len, /* length of extent */ 3929 xfs_bmap_free_t *flist, /* list of extents */ 3930 xfs_mount_t *mp) /* mount point structure */ 3931{ 3932 xfs_bmap_free_item_t *cur; /* current (next) element */ 3933 xfs_bmap_free_item_t *new; /* new element */ 3934 xfs_bmap_free_item_t *prev; /* previous element */ 3935#ifdef DEBUG 3936 xfs_agnumber_t agno; 3937 xfs_agblock_t agbno; 3938 3939 ASSERT(bno != NULLFSBLOCK); 3940 ASSERT(len > 0); 3941 ASSERT(len <= MAXEXTLEN); 3942 ASSERT(!ISNULLSTARTBLOCK(bno)); 3943 agno = XFS_FSB_TO_AGNO(mp, bno); 3944 agbno = XFS_FSB_TO_AGBNO(mp, bno); 3945 ASSERT(agno < mp->m_sb.sb_agcount); 3946 ASSERT(agbno < mp->m_sb.sb_agblocks); 3947 ASSERT(len < mp->m_sb.sb_agblocks); 3948 ASSERT(agbno + len <= mp->m_sb.sb_agblocks); 3949#endif 3950 ASSERT(xfs_bmap_free_item_zone != NULL); 3951 new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); 3952 new->xbfi_startblock = bno; 3953 new->xbfi_blockcount = (xfs_extlen_t)len; 3954 for (prev = NULL, cur = flist->xbf_first; 3955 cur != NULL; 3956 prev = cur, cur = cur->xbfi_next) { 3957 if (cur->xbfi_startblock >= bno) 3958 break; 3959 } 3960 if (prev) 3961 prev->xbfi_next = new; 3962 else 3963 flist->xbf_first = new; 3964 new->xbfi_next = cur; 3965 flist->xbf_count++; 3966} 3967 3968/* 3969 * Compute and fill in the value of the maximum depth of a bmap btree 3970 * in this filesystem. Done once, during mount. 3971 */ 3972void 3973xfs_bmap_compute_maxlevels( 3974 xfs_mount_t *mp, /* file system mount structure */ 3975 int whichfork) /* data or attr fork */ 3976{ 3977 int level; /* btree level */ 3978 uint maxblocks; /* max blocks at this level */ 3979 uint maxleafents; /* max leaf entries possible */ 3980 int maxrootrecs; /* max records in root block */ 3981 int minleafrecs; /* min records in leaf block */ 3982 int minnoderecs; /* min records in node block */ 3983 int sz; /* root block size */ 3984 3985 /* 3986 * The maximum number of extents in a file, hence the maximum 3987 * number of leaf entries, is controlled by the type of di_nextents 3988 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents 3989 * (a signed 16-bit number, xfs_aextnum_t). 3990 */ 3991 maxleafents = (whichfork == XFS_DATA_FORK) ? MAXEXTNUM : MAXAEXTNUM; 3992 minleafrecs = mp->m_bmap_dmnr[0]; 3993 minnoderecs = mp->m_bmap_dmnr[1]; 3994 sz = (whichfork == XFS_DATA_FORK) ? 3995 mp->m_attroffset : 3996 mp->m_sb.sb_inodesize - mp->m_attroffset; 3997 maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0); 3998 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; 3999 for (level = 1; maxblocks > 1; level++) { 4000 if (maxblocks <= maxrootrecs) 4001 maxblocks = 1; 4002 else 4003 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; 4004 } 4005 mp->m_bm_maxlevels[whichfork] = level; 4006} 4007 4008/* 4009 * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi 4010 * caller. Frees all the extents that need freeing, which must be done 4011 * last due to locking considerations. We never free any extents in 4012 * the first transaction. This is to allow the caller to make the first 4013 * transaction a synchronous one so that the pointers to the data being 4014 * broken in this transaction will be permanent before the data is actually 4015 * freed. This is necessary to prevent blocks from being reallocated 4016 * and written to before the free and reallocation are actually permanent. 4017 * We do not just make the first transaction synchronous here, because 4018 * there are more efficient ways to gain the same protection in some cases 4019 * (see the file truncation code). 4020 * 4021 * Return 1 if the given transaction was committed and a new one 4022 * started, and 0 otherwise in the committed parameter. 4023 */ 4024/*ARGSUSED*/ 4025int /* error */ 4026xfs_bmap_finish( 4027 xfs_trans_t **tp, /* transaction pointer addr */ 4028 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 4029 xfs_fsblock_t firstblock, /* controlled ag for allocs */ 4030 int *committed) /* xact committed or not */ 4031{ 4032 xfs_efd_log_item_t *efd; /* extent free data */ 4033 xfs_efi_log_item_t *efi; /* extent free intention */ 4034 int error; /* error return value */ 4035 xfs_bmap_free_item_t *free; /* free extent list item */ 4036 unsigned int logres; /* new log reservation */ 4037 unsigned int logcount; /* new log count */ 4038 xfs_mount_t *mp; /* filesystem mount structure */ 4039 xfs_bmap_free_item_t *next; /* next item on free list */ 4040 xfs_trans_t *ntp; /* new transaction pointer */ 4041 4042 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); 4043 if (flist->xbf_count == 0) { 4044 *committed = 0; 4045 return 0; 4046 } 4047 ntp = *tp; 4048 efi = xfs_trans_get_efi(ntp, flist->xbf_count); 4049 for (free = flist->xbf_first; free; free = free->xbfi_next) 4050 xfs_trans_log_efi_extent(ntp, efi, free->xbfi_startblock, 4051 free->xbfi_blockcount); 4052 logres = ntp->t_log_res; 4053 logcount = ntp->t_log_count; 4054 ntp = xfs_trans_dup(*tp); 4055 error = xfs_trans_commit(*tp, 0, NULL); 4056 *tp = ntp; 4057 *committed = 1; 4058 /* 4059 * We have a new transaction, so we should return committed=1, 4060 * even though we're returning an error. 4061 */ 4062 if (error) { 4063 return error; 4064 } 4065 if ((error = xfs_trans_reserve(ntp, 0, logres, 0, XFS_TRANS_PERM_LOG_RES, 4066 logcount))) 4067 return error; 4068 efd = xfs_trans_get_efd(ntp, efi, flist->xbf_count); 4069 for (free = flist->xbf_first; free != NULL; free = next) { 4070 next = free->xbfi_next; 4071 if ((error = xfs_free_extent(ntp, free->xbfi_startblock, 4072 free->xbfi_blockcount))) { 4073 /* 4074 * The bmap free list will be cleaned up at a 4075 * higher level. The EFI will be canceled when 4076 * this transaction is aborted. 4077 * Need to force shutdown here to make sure it 4078 * happens, since this transaction may not be 4079 * dirty yet. 4080 */ 4081 mp = ntp->t_mountp; 4082 if (!XFS_FORCED_SHUTDOWN(mp)) 4083 xfs_force_shutdown(mp, 4084 (error == EFSCORRUPTED) ? 4085 XFS_CORRUPT_INCORE : 4086 XFS_METADATA_IO_ERROR); 4087 return error; 4088 } 4089 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, 4090 free->xbfi_blockcount); 4091 xfs_bmap_del_free(flist, NULL, free); 4092 } 4093 return 0; 4094} 4095 4096/* 4097 * Free up any items left in the list. 4098 */ 4099void 4100xfs_bmap_cancel( 4101 xfs_bmap_free_t *flist) /* list of bmap_free_items */ 4102{ 4103 xfs_bmap_free_item_t *free; /* free list item */ 4104 xfs_bmap_free_item_t *next; 4105 4106 if (flist->xbf_count == 0) 4107 return; 4108 ASSERT(flist->xbf_first != NULL); 4109 for (free = flist->xbf_first; free; free = next) { 4110 next = free->xbfi_next; 4111 xfs_bmap_del_free(flist, NULL, free); 4112 } 4113 ASSERT(flist->xbf_count == 0); 4114} 4115 4116/* 4117 * Returns the file-relative block number of the first unused block(s) 4118 * in the file with at least "len" logically contiguous blocks free. 4119 * This is the lowest-address hole if the file has holes, else the first block 4120 * past the end of file. 4121 * Return 0 if the file is currently local (in-inode). 4122 */ 4123int /* error */ 4124xfs_bmap_first_unused( 4125 xfs_trans_t *tp, /* transaction pointer */ 4126 xfs_inode_t *ip, /* incore inode */ 4127 xfs_extlen_t len, /* size of hole to find */ 4128 xfs_fileoff_t *first_unused, /* unused block */ 4129 int whichfork) /* data or attr fork */ 4130{ 4131 xfs_bmbt_rec_t *base; /* base of extent array */ 4132 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ 4133 int error; /* error return value */ 4134 xfs_ifork_t *ifp; /* inode fork pointer */ 4135 xfs_fileoff_t lastaddr; /* last block number seen */ 4136 xfs_fileoff_t lowest; /* lowest useful block */ 4137 xfs_fileoff_t max; /* starting useful block */ 4138 xfs_fileoff_t off; /* offset for this block */ 4139 xfs_extnum_t nextents; /* number of extent entries */ 4140 4141 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE || 4142 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS || 4143 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 4144 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 4145 *first_unused = 0; 4146 return 0; 4147 } 4148 ifp = XFS_IFORK_PTR(ip, whichfork); 4149 if (!(ifp->if_flags & XFS_IFEXTENTS) && 4150 (error = xfs_iread_extents(tp, ip, whichfork))) 4151 return error; 4152 lowest = *first_unused; 4153 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4154 base = &ifp->if_u1.if_extents[0]; 4155 for (lastaddr = 0, max = lowest, ep = base; 4156 ep < &base[nextents]; 4157 ep++) { 4158 off = xfs_bmbt_get_startoff(ep); 4159 /* 4160 * See if the hole before this extent will work. 4161 */ 4162 if (off >= lowest + len && off - max >= len) { 4163 *first_unused = max; 4164 return 0; 4165 } 4166 lastaddr = off + xfs_bmbt_get_blockcount(ep); 4167 max = XFS_FILEOFF_MAX(lastaddr, lowest); 4168 } 4169 *first_unused = max; 4170 return 0; 4171} 4172 4173/* 4174 * Returns the file-relative block number of the last block + 1 before 4175 * last_block (input value) in the file. 4176 * This is not based on i_size, it is based on the extent list. 4177 * Returns 0 for local files, as they do not have an extent list. 4178 */ 4179int /* error */ 4180xfs_bmap_last_before( 4181 xfs_trans_t *tp, /* transaction pointer */ 4182 xfs_inode_t *ip, /* incore inode */ 4183 xfs_fileoff_t *last_block, /* last block */ 4184 int whichfork) /* data or attr fork */ 4185{ 4186 xfs_fileoff_t bno; /* input file offset */ 4187 int eof; /* hit end of file */ 4188 xfs_bmbt_rec_t *ep; /* pointer to last extent */ 4189 int error; /* error return value */ 4190 xfs_bmbt_irec_t got; /* current extent value */ 4191 xfs_ifork_t *ifp; /* inode fork pointer */ 4192 xfs_extnum_t lastx; /* last extent used */ 4193 xfs_bmbt_irec_t prev; /* previous extent value */ 4194 4195 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 4196 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4197 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) 4198 return XFS_ERROR(EIO); 4199 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 4200 *last_block = 0; 4201 return 0; 4202 } 4203 ifp = XFS_IFORK_PTR(ip, whichfork); 4204 if (!(ifp->if_flags & XFS_IFEXTENTS) && 4205 (error = xfs_iread_extents(tp, ip, whichfork))) 4206 return error; 4207 bno = *last_block - 1; 4208 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 4209 &prev); 4210 if (eof || xfs_bmbt_get_startoff(ep) > bno) { 4211 if (prev.br_startoff == NULLFILEOFF) 4212 *last_block = 0; 4213 else 4214 *last_block = prev.br_startoff + prev.br_blockcount; 4215 } 4216 /* 4217 * Otherwise *last_block is already the right answer. 4218 */ 4219 return 0; 4220} 4221 4222/* 4223 * Returns the file-relative block number of the first block past eof in 4224 * the file. This is not based on i_size, it is based on the extent list. 4225 * Returns 0 for local files, as they do not have an extent list. 4226 */ 4227int /* error */ 4228xfs_bmap_last_offset( 4229 xfs_trans_t *tp, /* transaction pointer */ 4230 xfs_inode_t *ip, /* incore inode */ 4231 xfs_fileoff_t *last_block, /* last block */ 4232 int whichfork) /* data or attr fork */ 4233{ 4234 xfs_bmbt_rec_t *base; /* base of extent array */ 4235 xfs_bmbt_rec_t *ep; /* pointer to last extent */ 4236 int error; /* error return value */ 4237 xfs_ifork_t *ifp; /* inode fork pointer */ 4238 xfs_extnum_t nextents; /* number of extent entries */ 4239 4240 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 4241 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4242 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) 4243 return XFS_ERROR(EIO); 4244 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 4245 *last_block = 0; 4246 return 0; 4247 } 4248 ifp = XFS_IFORK_PTR(ip, whichfork); 4249 if (!(ifp->if_flags & XFS_IFEXTENTS) && 4250 (error = xfs_iread_extents(tp, ip, whichfork))) 4251 return error; 4252 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4253 if (!nextents) { 4254 *last_block = 0; 4255 return 0; 4256 } 4257 base = &ifp->if_u1.if_extents[0]; 4258 ASSERT(base != NULL); 4259 ep = &base[nextents - 1]; 4260 *last_block = xfs_bmbt_get_startoff(ep) + xfs_bmbt_get_blockcount(ep); 4261 return 0; 4262} 4263 4264/* 4265 * Returns whether the selected fork of the inode has exactly one 4266 * block or not. For the data fork we check this matches di_size, 4267 * implying the file's range is 0..bsize-1. 4268 */ 4269int /* 1=>1 block, 0=>otherwise */ 4270xfs_bmap_one_block( 4271 xfs_inode_t *ip, /* incore inode */ 4272 int whichfork) /* data or attr fork */ 4273{ 4274 xfs_bmbt_rec_t *ep; /* ptr to fork's extent */ 4275 xfs_ifork_t *ifp; /* inode fork pointer */ 4276 int rval; /* return value */ 4277 xfs_bmbt_irec_t s; /* internal version of extent */ 4278 4279#ifndef DEBUG 4280 if (whichfork == XFS_DATA_FORK) 4281 return ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize; 4282#endif /* !DEBUG */ 4283 if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) 4284 return 0; 4285 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 4286 return 0; 4287 ifp = XFS_IFORK_PTR(ip, whichfork); 4288 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 4289 ep = ifp->if_u1.if_extents; 4290 xfs_bmbt_get_all(ep, &s); 4291 rval = s.br_startoff == 0 && s.br_blockcount == 1; 4292 if (rval && whichfork == XFS_DATA_FORK) 4293 ASSERT(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); 4294 return rval; 4295} 4296 4297/* 4298 * Read in the extents to if_extents. 4299 * All inode fields are set up by caller, we just traverse the btree 4300 * and copy the records in. If the file system cannot contain unwritten 4301 * extents, the records are checked for no "state" flags. 4302 */ 4303int /* error */ 4304xfs_bmap_read_extents( 4305 xfs_trans_t *tp, /* transaction pointer */ 4306 xfs_inode_t *ip, /* incore inode */ 4307 int whichfork) /* data or attr fork */ 4308{ 4309 xfs_bmbt_block_t *block; /* current btree block */ 4310 xfs_fsblock_t bno; /* block # of "block" */ 4311 xfs_buf_t *bp; /* buffer for "block" */ 4312 int error; /* error return value */ 4313 xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ 4314#ifdef XFS_BMAP_TRACE 4315 static char fname[] = "xfs_bmap_read_extents"; 4316#endif 4317 xfs_extnum_t i, j; /* index into the extents list */ 4318 xfs_ifork_t *ifp; /* fork structure */ 4319 int level; /* btree level, for checking */ 4320 xfs_mount_t *mp; /* file system mount structure */ 4321 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 4322 /* REFERENCED */ 4323 xfs_extnum_t room; /* number of entries there's room for */ 4324 xfs_bmbt_rec_t *trp; /* target record pointer */ 4325 4326 bno = NULLFSBLOCK; 4327 mp = ip->i_mount; 4328 ifp = XFS_IFORK_PTR(ip, whichfork); 4329 exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE : 4330 XFS_EXTFMT_INODE(ip); 4331 block = ifp->if_broot; 4332 /* 4333 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 4334 */ 4335 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 4336 level = INT_GET(block->bb_level, ARCH_CONVERT); 4337 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); 4338 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); 4339 ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); 4340 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); 4341 bno = INT_GET(*pp, ARCH_CONVERT); 4342 /* 4343 * Go down the tree until leaf level is reached, following the first 4344 * pointer (leftmost) at each level. 4345 */ 4346 while (level-- > 0) { 4347 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 4348 XFS_BMAP_BTREE_REF))) 4349 return error; 4350 block = XFS_BUF_TO_BMBT_BLOCK(bp); 4351 XFS_WANT_CORRUPTED_GOTO( 4352 XFS_BMAP_SANITY_CHECK(mp, block, level), 4353 error0); 4354 if (level == 0) 4355 break; 4356 pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 4357 1, mp->m_bmap_dmxr[1]); 4358 XFS_WANT_CORRUPTED_GOTO( 4359 XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), 4360 error0); 4361 bno = INT_GET(*pp, ARCH_CONVERT); 4362 xfs_trans_brelse(tp, bp); 4363 } 4364 /* 4365 * Here with bp and block set to the leftmost leaf node in the tree. 4366 */ 4367 room = ifp->if_bytes / (uint)sizeof(*trp); 4368 trp = ifp->if_u1.if_extents; 4369 i = 0; 4370 /* 4371 * Loop over all leaf nodes. Copy information to the extent list. 4372 */ 4373 for (;;) { 4374 xfs_bmbt_rec_t *frp, *temp; 4375 xfs_fsblock_t nextbno; 4376 xfs_extnum_t num_recs; 4377 4378 4379 num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT); 4380 if (unlikely(i + num_recs > room)) { 4381 ASSERT(i + num_recs <= room); 4382 xfs_fs_cmn_err(CE_WARN, ip->i_mount, 4383 "corrupt dinode %Lu, (btree extents). Unmount and run xfs_repair.", 4384 (unsigned long long) ip->i_ino); 4385 XFS_ERROR_REPORT("xfs_bmap_read_extents(1)", 4386 XFS_ERRLEVEL_LOW, 4387 ip->i_mount); 4388 goto error0; 4389 } 4390 XFS_WANT_CORRUPTED_GOTO( 4391 XFS_BMAP_SANITY_CHECK(mp, block, 0), 4392 error0); 4393 /* 4394 * Read-ahead the next leaf block, if any. 4395 */ 4396 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 4397 if (nextbno != NULLFSBLOCK) 4398 xfs_btree_reada_bufl(mp, nextbno, 1); 4399 /* 4400 * Copy records into the extent list. 4401 */ 4402 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 4403 block, 1, mp->m_bmap_dmxr[0]); 4404 temp = trp; 4405 for (j = 0; j < num_recs; j++, frp++, trp++) { 4406 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); 4407 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); 4408 } 4409 if (exntf == XFS_EXTFMT_NOSTATE) { 4410 /* 4411 * Check all attribute bmap btree records and 4412 * any "older" data bmap btree records for a 4413 * set bit in the "extent flag" position. 4414 */ 4415 if (unlikely(xfs_check_nostate_extents(temp, num_recs))) { 4416 XFS_ERROR_REPORT("xfs_bmap_read_extents(2)", 4417 XFS_ERRLEVEL_LOW, 4418 ip->i_mount); 4419 goto error0; 4420 } 4421 } 4422 i += num_recs; 4423 xfs_trans_brelse(tp, bp); 4424 bno = nextbno; 4425 /* 4426 * If we've reached the end, stop. 4427 */ 4428 if (bno == NULLFSBLOCK) 4429 break; 4430 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 4431 XFS_BMAP_BTREE_REF))) 4432 return error; 4433 block = XFS_BUF_TO_BMBT_BLOCK(bp); 4434 } 4435 ASSERT(i == ifp->if_bytes / (uint)sizeof(*trp)); 4436 ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); 4437 xfs_bmap_trace_exlist(fname, ip, i, whichfork); 4438 return 0; 4439error0: 4440 xfs_trans_brelse(tp, bp); 4441 return XFS_ERROR(EFSCORRUPTED); 4442} 4443 4444#ifdef XFS_BMAP_TRACE 4445/* 4446 * Add bmap trace insert entries for all the contents of the extent list. 4447 */ 4448void 4449xfs_bmap_trace_exlist( 4450 char *fname, /* function name */ 4451 xfs_inode_t *ip, /* incore inode pointer */ 4452 xfs_extnum_t cnt, /* count of entries in the list */ 4453 int whichfork) /* data or attr fork */ 4454{ 4455 xfs_bmbt_rec_t *base; /* base of extent list */ 4456 xfs_bmbt_rec_t *ep; /* current entry in extent list */ 4457 xfs_extnum_t idx; /* extent list entry number */ 4458 xfs_ifork_t *ifp; /* inode fork pointer */ 4459 xfs_bmbt_irec_t s; /* extent list record */ 4460 4461 ifp = XFS_IFORK_PTR(ip, whichfork); 4462 ASSERT(cnt == ifp->if_bytes / (uint)sizeof(*base)); 4463 base = ifp->if_u1.if_extents; 4464 for (idx = 0, ep = base; idx < cnt; idx++, ep++) { 4465 xfs_bmbt_get_all(ep, &s); 4466 xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL, 4467 whichfork); 4468 } 4469} 4470#endif 4471 4472#ifdef DEBUG 4473/* 4474 * Validate that the bmbt_irecs being returned from bmapi are valid 4475 * given the callers original parameters. Specifically check the 4476 * ranges of the returned irecs to ensure that they only extent beyond 4477 * the given parameters if the XFS_BMAPI_ENTIRE flag was set. 4478 */ 4479STATIC void 4480xfs_bmap_validate_ret( 4481 xfs_fileoff_t bno, 4482 xfs_filblks_t len, 4483 int flags, 4484 xfs_bmbt_irec_t *mval, 4485 int nmap, 4486 int ret_nmap) 4487{ 4488 int i; /* index to map values */ 4489 4490 ASSERT(ret_nmap <= nmap); 4491 4492 for (i = 0; i < ret_nmap; i++) { 4493 ASSERT(mval[i].br_blockcount > 0); 4494 if (!(flags & XFS_BMAPI_ENTIRE)) { 4495 ASSERT(mval[i].br_startoff >= bno); 4496 ASSERT(mval[i].br_blockcount <= len); 4497 ASSERT(mval[i].br_startoff + mval[i].br_blockcount <= 4498 bno + len); 4499 } else { 4500 ASSERT(mval[i].br_startoff < bno + len); 4501 ASSERT(mval[i].br_startoff + mval[i].br_blockcount > 4502 bno); 4503 } 4504 ASSERT(i == 0 || 4505 mval[i - 1].br_startoff + mval[i - 1].br_blockcount == 4506 mval[i].br_startoff); 4507 if ((flags & XFS_BMAPI_WRITE) && !(flags & XFS_BMAPI_DELAY)) 4508 ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && 4509 mval[i].br_startblock != HOLESTARTBLOCK); 4510 ASSERT(mval[i].br_state == XFS_EXT_NORM || 4511 mval[i].br_state == XFS_EXT_UNWRITTEN); 4512 } 4513} 4514#endif /* DEBUG */ 4515 4516 4517/* 4518 * Map file blocks to filesystem blocks. 4519 * File range is given by the bno/len pair. 4520 * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) 4521 * into a hole or past eof. 4522 * Only allocates blocks from a single allocation group, 4523 * to avoid locking problems. 4524 * The returned value in "firstblock" from the first call in a transaction 4525 * must be remembered and presented to subsequent calls in "firstblock". 4526 * An upper bound for the number of blocks to be allocated is supplied to 4527 * the first call in "total"; if no allocation group has that many free 4528 * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). 4529 */ 4530int /* error */ 4531xfs_bmapi( 4532 xfs_trans_t *tp, /* transaction pointer */ 4533 xfs_inode_t *ip, /* incore inode */ 4534 xfs_fileoff_t bno, /* starting file offs. mapped */ 4535 xfs_filblks_t len, /* length to map in file */ 4536 int flags, /* XFS_BMAPI_... */ 4537 xfs_fsblock_t *firstblock, /* first allocated block 4538 controls a.g. for allocs */ 4539 xfs_extlen_t total, /* total blocks needed */ 4540 xfs_bmbt_irec_t *mval, /* output: map values */ 4541 int *nmap, /* i/o: mval size/count */ 4542 xfs_bmap_free_t *flist) /* i/o: list extents to free */ 4543{ 4544 xfs_fsblock_t abno; /* allocated block number */ 4545 xfs_extlen_t alen; /* allocated extent length */ 4546 xfs_fileoff_t aoff; /* allocated file offset */ 4547 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ 4548 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4549 xfs_fileoff_t end; /* end of mapped file region */ 4550 int eof; /* we've hit the end of extent list */ 4551 char contig; /* allocation must be one extent */ 4552 char delay; /* this request is for delayed alloc */ 4553 char exact; /* don't do all of wasdelayed extent */ 4554 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 4555 int error; /* error return */ 4556 xfs_bmbt_irec_t got; /* current extent list record */ 4557 xfs_ifork_t *ifp; /* inode fork pointer */ 4558 xfs_extlen_t indlen; /* indirect blocks length */ 4559 xfs_extnum_t lastx; /* last useful extent number */ 4560 int logflags; /* flags for transaction logging */ 4561 xfs_extlen_t minleft; /* min blocks left after allocation */ 4562 xfs_extlen_t minlen; /* min allocation size */ 4563 xfs_mount_t *mp; /* xfs mount structure */ 4564 int n; /* current extent index */ 4565 int nallocs; /* number of extents alloc\'d */ 4566 xfs_extnum_t nextents; /* number of extents in file */ 4567 xfs_fileoff_t obno; /* old block number (offset) */ 4568 xfs_bmbt_irec_t prev; /* previous extent list record */ 4569 int tmp_logflags; /* temp flags holder */ 4570 int whichfork; /* data or attr fork */ 4571 char inhole; /* current location is hole in file */ 4572 char stateless; /* ignore state flag set */ 4573 char trim; /* output trimmed to match range */ 4574 char userdata; /* allocating non-metadata */ 4575 char wasdelay; /* old extent was delayed */ 4576 char wr; /* this is a write request */ 4577 char rt; /* this is a realtime file */ 4578 char rsvd; /* OK to allocate reserved blocks */ 4579#ifdef DEBUG 4580 xfs_fileoff_t orig_bno; /* original block number value */ 4581 int orig_flags; /* original flags arg value */ 4582 xfs_filblks_t orig_len; /* original value of len arg */ 4583 xfs_bmbt_irec_t *orig_mval; /* original value of mval */ 4584 int orig_nmap; /* original value of *nmap */ 4585 4586 orig_bno = bno; 4587 orig_len = len; 4588 orig_flags = flags; 4589 orig_mval = mval; 4590 orig_nmap = *nmap; 4591#endif 4592 ASSERT(*nmap >= 1); 4593 ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE)); 4594 whichfork = (flags & XFS_BMAPI_ATTRFORK) ? 4595 XFS_ATTR_FORK : XFS_DATA_FORK; 4596 mp = ip->i_mount; 4597 if (unlikely(XFS_TEST_ERROR( 4598 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4599 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 4600 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL), 4601 mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { 4602 XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp); 4603 return XFS_ERROR(EFSCORRUPTED); 4604 } 4605 if (XFS_FORCED_SHUTDOWN(mp)) 4606 return XFS_ERROR(EIO); 4607 rt = XFS_IS_REALTIME_INODE(ip); 4608 ifp = XFS_IFORK_PTR(ip, whichfork); 4609 ASSERT(ifp->if_ext_max == 4610 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 4611 if ((wr = (flags & XFS_BMAPI_WRITE)) != 0) 4612 XFS_STATS_INC(xs_blk_mapw); 4613 else 4614 XFS_STATS_INC(xs_blk_mapr); 4615 delay = (flags & XFS_BMAPI_DELAY) != 0; 4616 trim = (flags & XFS_BMAPI_ENTIRE) == 0; 4617 userdata = (flags & XFS_BMAPI_METADATA) == 0; 4618 exact = (flags & XFS_BMAPI_EXACT) != 0; 4619 rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; 4620 contig = (flags & XFS_BMAPI_CONTIG) != 0; 4621 /* 4622 * stateless is used to combine extents which 4623 * differ only due to the state of the extents. 4624 * This technique is used from xfs_getbmap() 4625 * when the caller does not wish to see the 4626 * separation (which is the default). 4627 * 4628 * This technique is also used when writing a 4629 * buffer which has been partially written, 4630 * (usually by being flushed during a chunkread), 4631 * to ensure one write takes place. This also 4632 * prevents a change in the xfs inode extents at 4633 * this time, intentionally. This change occurs 4634 * on completion of the write operation, in 4635 * xfs_strat_comp(), where the xfs_bmapi() call 4636 * is transactioned, and the extents combined. 4637 */ 4638 stateless = (flags & XFS_BMAPI_IGSTATE) != 0; 4639 if (stateless && wr) /* if writing unwritten space, no */ 4640 wr = 0; /* allocations are allowed */ 4641 ASSERT(wr || !delay); 4642 logflags = 0; 4643 nallocs = 0; 4644 cur = NULL; 4645 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 4646 ASSERT(wr && tp); 4647 if ((error = xfs_bmap_local_to_extents(tp, ip, 4648 firstblock, total, &logflags, whichfork))) 4649 goto error0; 4650 } 4651 if (wr && *firstblock == NULLFSBLOCK) { 4652 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) 4653 minleft = INT_GET(ifp->if_broot->bb_level, ARCH_CONVERT) + 1; 4654 else 4655 minleft = 1; 4656 } else 4657 minleft = 0; 4658 if (!(ifp->if_flags & XFS_IFEXTENTS) && 4659 (error = xfs_iread_extents(tp, ip, whichfork))) 4660 goto error0; 4661 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 4662 &prev); 4663 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4664 n = 0; 4665 end = bno + len; 4666 obno = bno; 4667 bma.ip = NULL; 4668 while (bno < end && n < *nmap) { 4669 /* 4670 * Reading past eof, act as though there's a hole 4671 * up to end. 4672 */ 4673 if (eof && !wr) 4674 got.br_startoff = end; 4675 inhole = eof || got.br_startoff > bno; 4676 wasdelay = wr && !inhole && !delay && 4677 ISNULLSTARTBLOCK(got.br_startblock); 4678 /* 4679 * First, deal with the hole before the allocated space 4680 * that we found, if any. 4681 */ 4682 if (wr && (inhole || wasdelay)) { 4683 /* 4684 * For the wasdelay case, we could also just 4685 * allocate the stuff asked for in this bmap call 4686 * but that wouldn't be as good. 4687 */ 4688 if (wasdelay && !exact) { 4689 alen = (xfs_extlen_t)got.br_blockcount; 4690 aoff = got.br_startoff; 4691 if (lastx != NULLEXTNUM && lastx) { 4692 ep = &ifp->if_u1.if_extents[lastx - 1]; 4693 xfs_bmbt_get_all(ep, &prev); 4694 } 4695 } else if (wasdelay) { 4696 alen = (xfs_extlen_t) 4697 XFS_FILBLKS_MIN(len, 4698 (got.br_startoff + 4699 got.br_blockcount) - bno); 4700 aoff = bno; 4701 } else { 4702 alen = (xfs_extlen_t) 4703 XFS_FILBLKS_MIN(len, MAXEXTLEN); 4704 if (!eof) 4705 alen = (xfs_extlen_t) 4706 XFS_FILBLKS_MIN(alen, 4707 got.br_startoff - bno); 4708 aoff = bno; 4709 } 4710 minlen = contig ? alen : 1; 4711 if (delay) { 4712 xfs_extlen_t extsz = 0; 4713 4714 /* Figure out the extent size, adjust alen */ 4715 if (rt) { 4716 if (!(extsz = ip->i_d.di_extsize)) 4717 extsz = mp->m_sb.sb_rextsize; 4718 alen = roundup(alen, extsz); 4719 extsz = alen / mp->m_sb.sb_rextsize; 4720 } 4721 4722 /* 4723 * Make a transaction-less quota reservation for 4724 * delayed allocation blocks. This number gets 4725 * adjusted later. 4726 * We return EDQUOT if we haven't allocated 4727 * blks already inside this loop; 4728 */ 4729 if (XFS_TRANS_RESERVE_QUOTA_NBLKS( 4730 mp, NULL, ip, (long)alen, 0, 4731 rt ? XFS_QMOPT_RES_RTBLKS : 4732 XFS_QMOPT_RES_REGBLKS)) { 4733 if (n == 0) { 4734 *nmap = 0; 4735 ASSERT(cur == NULL); 4736 return XFS_ERROR(EDQUOT); 4737 } 4738 break; 4739 } 4740 4741 /* 4742 * Split changing sb for alen and indlen since 4743 * they could be coming from different places. 4744 */ 4745 indlen = (xfs_extlen_t) 4746 xfs_bmap_worst_indlen(ip, alen); 4747 ASSERT(indlen > 0); 4748 4749 if (rt) 4750 error = xfs_mod_incore_sb(mp, 4751 XFS_SBS_FREXTENTS, 4752 -(extsz), rsvd); 4753 else 4754 error = xfs_mod_incore_sb(mp, 4755 XFS_SBS_FDBLOCKS, 4756 -(alen), rsvd); 4757 if (!error) { 4758 error = xfs_mod_incore_sb(mp, 4759 XFS_SBS_FDBLOCKS, 4760 -(indlen), rsvd); 4761 if (error && rt) { 4762 xfs_mod_incore_sb(ip->i_mount, 4763 XFS_SBS_FREXTENTS, 4764 extsz, rsvd); 4765 } else if (error) { 4766 xfs_mod_incore_sb(ip->i_mount, 4767 XFS_SBS_FDBLOCKS, 4768 alen, rsvd); 4769 } 4770 } 4771 4772 if (error) { 4773 if (XFS_IS_QUOTA_ON(ip->i_mount)) 4774 /* unreserve the blocks now */ 4775 XFS_TRANS_UNRESERVE_QUOTA_NBLKS( 4776 mp, NULL, ip, 4777 (long)alen, 0, rt ? 4778 XFS_QMOPT_RES_RTBLKS : 4779 XFS_QMOPT_RES_REGBLKS); 4780 break; 4781 } 4782 4783 ip->i_delayed_blks += alen; 4784 abno = NULLSTARTBLOCK(indlen); 4785 } else { 4786 /* 4787 * If first time, allocate and fill in 4788 * once-only bma fields. 4789 */ 4790 if (bma.ip == NULL) { 4791 bma.tp = tp; 4792 bma.ip = ip; 4793 bma.prevp = &prev; 4794 bma.gotp = &got; 4795 bma.total = total; 4796 bma.userdata = 0; 4797 } 4798 /* Indicate if this is the first user data 4799 * in the file, or just any user data. 4800 */ 4801 if (userdata) { 4802 bma.userdata = (aoff == 0) ? 4803 XFS_ALLOC_INITIAL_USER_DATA : 4804 XFS_ALLOC_USERDATA; 4805 } 4806 /* 4807 * Fill in changeable bma fields. 4808 */ 4809 bma.eof = eof; 4810 bma.firstblock = *firstblock; 4811 bma.alen = alen; 4812 bma.off = aoff; 4813 bma.wasdel = wasdelay; 4814 bma.minlen = minlen; 4815 bma.low = flist->xbf_low; 4816 bma.minleft = minleft; 4817 /* 4818 * Only want to do the alignment at the 4819 * eof if it is userdata and allocation length 4820 * is larger than a stripe unit. 4821 */ 4822 if (mp->m_dalign && alen >= mp->m_dalign && 4823 userdata && whichfork == XFS_DATA_FORK) { 4824 if ((error = xfs_bmap_isaeof(ip, aoff, 4825 whichfork, &bma.aeof))) 4826 goto error0; 4827 } else 4828 bma.aeof = 0; 4829 /* 4830 * Call allocator. 4831 */ 4832 if ((error = xfs_bmap_alloc(&bma))) 4833 goto error0; 4834 /* 4835 * Copy out result fields. 4836 */ 4837 abno = bma.rval; 4838 if ((flist->xbf_low = bma.low)) 4839 minleft = 0; 4840 alen = bma.alen; 4841 aoff = bma.off; 4842 ASSERT(*firstblock == NULLFSBLOCK || 4843 XFS_FSB_TO_AGNO(mp, *firstblock) == 4844 XFS_FSB_TO_AGNO(mp, bma.firstblock) || 4845 (flist->xbf_low && 4846 XFS_FSB_TO_AGNO(mp, *firstblock) < 4847 XFS_FSB_TO_AGNO(mp, bma.firstblock))); 4848 *firstblock = bma.firstblock; 4849 if (cur) 4850 cur->bc_private.b.firstblock = 4851 *firstblock; 4852 if (abno == NULLFSBLOCK) 4853 break; 4854 if ((ifp->if_flags & XFS_IFBROOT) && !cur) { 4855 cur = xfs_btree_init_cursor(mp, 4856 tp, NULL, 0, XFS_BTNUM_BMAP, 4857 ip, whichfork); 4858 cur->bc_private.b.firstblock = 4859 *firstblock; 4860 cur->bc_private.b.flist = flist; 4861 } 4862 /* 4863 * Bump the number of extents we've allocated 4864 * in this call. 4865 */ 4866 nallocs++; 4867 } 4868 if (cur) 4869 cur->bc_private.b.flags = 4870 wasdelay ? XFS_BTCUR_BPRV_WASDEL : 0; 4871 got.br_startoff = aoff; 4872 got.br_startblock = abno; 4873 got.br_blockcount = alen; 4874 got.br_state = XFS_EXT_NORM; /* assume normal */ 4875 /* 4876 * Determine state of extent, and the filesystem. 4877 * A wasdelay extent has been initialized, so 4878 * shouldn't be flagged as unwritten. 4879 */ 4880 if (wr && XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { 4881 if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) 4882 got.br_state = XFS_EXT_UNWRITTEN; 4883 } 4884 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 4885 firstblock, flist, &tmp_logflags, whichfork, 4886 rsvd); 4887 logflags |= tmp_logflags; 4888 if (error) 4889 goto error0; 4890 lastx = ifp->if_lastex; 4891 ep = &ifp->if_u1.if_extents[lastx]; 4892 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4893 xfs_bmbt_get_all(ep, &got); 4894 ASSERT(got.br_startoff <= aoff); 4895 ASSERT(got.br_startoff + got.br_blockcount >= 4896 aoff + alen); 4897#ifdef DEBUG 4898 if (delay) { 4899 ASSERT(ISNULLSTARTBLOCK(got.br_startblock)); 4900 ASSERT(STARTBLOCKVAL(got.br_startblock) > 0); 4901 } 4902 ASSERT(got.br_state == XFS_EXT_NORM || 4903 got.br_state == XFS_EXT_UNWRITTEN); 4904#endif 4905 /* 4906 * Fall down into the found allocated space case. 4907 */ 4908 } else if (inhole) { 4909 /* 4910 * Reading in a hole. 4911 */ 4912 mval->br_startoff = bno; 4913 mval->br_startblock = HOLESTARTBLOCK; 4914 mval->br_blockcount = 4915 XFS_FILBLKS_MIN(len, got.br_startoff - bno); 4916 mval->br_state = XFS_EXT_NORM; 4917 bno += mval->br_blockcount; 4918 len -= mval->br_blockcount; 4919 mval++; 4920 n++; 4921 continue; 4922 } 4923 /* 4924 * Then deal with the allocated space we found. 4925 */ 4926 ASSERT(ep != NULL); 4927 if (trim && (got.br_startoff + got.br_blockcount > obno)) { 4928 if (obno > bno) 4929 bno = obno; 4930 ASSERT((bno >= obno) || (n == 0)); 4931 ASSERT(bno < end); 4932 mval->br_startoff = bno; 4933 if (ISNULLSTARTBLOCK(got.br_startblock)) { 4934 ASSERT(!wr || delay); 4935 mval->br_startblock = DELAYSTARTBLOCK; 4936 } else 4937 mval->br_startblock = 4938 got.br_startblock + 4939 (bno - got.br_startoff); 4940 /* 4941 * Return the minimum of what we got and what we 4942 * asked for for the length. We can use the len 4943 * variable here because it is modified below 4944 * and we could have been there before coming 4945 * here if the first part of the allocation 4946 * didn't overlap what was asked for. 4947 */ 4948 mval->br_blockcount = 4949 XFS_FILBLKS_MIN(end - bno, got.br_blockcount - 4950 (bno - got.br_startoff)); 4951 mval->br_state = got.br_state; 4952 ASSERT(mval->br_blockcount <= len); 4953 } else { 4954 *mval = got; 4955 if (ISNULLSTARTBLOCK(mval->br_startblock)) { 4956 ASSERT(!wr || delay); 4957 mval->br_startblock = DELAYSTARTBLOCK; 4958 } 4959 } 4960 4961 /* 4962 * Check if writing previously allocated but 4963 * unwritten extents. 4964 */ 4965 if (wr && mval->br_state == XFS_EXT_UNWRITTEN && 4966 ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) { 4967 /* 4968 * Modify (by adding) the state flag, if writing. 4969 */ 4970 ASSERT(mval->br_blockcount <= len); 4971 if ((ifp->if_flags & XFS_IFBROOT) && !cur) { 4972 cur = xfs_btree_init_cursor(mp, 4973 tp, NULL, 0, XFS_BTNUM_BMAP, 4974 ip, whichfork); 4975 cur->bc_private.b.firstblock = 4976 *firstblock; 4977 cur->bc_private.b.flist = flist; 4978 } 4979 mval->br_state = XFS_EXT_NORM; 4980 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 4981 firstblock, flist, &tmp_logflags, whichfork, 4982 rsvd); 4983 logflags |= tmp_logflags; 4984 if (error) 4985 goto error0; 4986 lastx = ifp->if_lastex; 4987 ep = &ifp->if_u1.if_extents[lastx]; 4988 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4989 xfs_bmbt_get_all(ep, &got); 4990 /* 4991 * We may have combined previously unwritten 4992 * space with written space, so generate 4993 * another request. 4994 */ 4995 if (mval->br_blockcount < len) 4996 continue; 4997 } 4998 4999 ASSERT(!trim || 5000 ((mval->br_startoff + mval->br_blockcount) <= end)); 5001 ASSERT(!trim || (mval->br_blockcount <= len) || 5002 (mval->br_startoff < obno)); 5003 bno = mval->br_startoff + mval->br_blockcount; 5004 len = end - bno; 5005 if (n > 0 && mval->br_startoff == mval[-1].br_startoff) { 5006 ASSERT(mval->br_startblock == mval[-1].br_startblock); 5007 ASSERT(mval->br_blockcount > mval[-1].br_blockcount); 5008 ASSERT(mval->br_state == mval[-1].br_state); 5009 mval[-1].br_blockcount = mval->br_blockcount; 5010 mval[-1].br_state = mval->br_state; 5011 } else if (n > 0 && mval->br_startblock != DELAYSTARTBLOCK && 5012 mval[-1].br_startblock != DELAYSTARTBLOCK && 5013 mval[-1].br_startblock != HOLESTARTBLOCK && 5014 mval->br_startblock == 5015 mval[-1].br_startblock + mval[-1].br_blockcount && 5016 (stateless || mval[-1].br_state == mval->br_state)) { 5017 ASSERT(mval->br_startoff == 5018 mval[-1].br_startoff + mval[-1].br_blockcount); 5019 mval[-1].br_blockcount += mval->br_blockcount; 5020 } else if (n > 0 && 5021 mval->br_startblock == DELAYSTARTBLOCK && 5022 mval[-1].br_startblock == DELAYSTARTBLOCK && 5023 mval->br_startoff == 5024 mval[-1].br_startoff + mval[-1].br_blockcount) { 5025 mval[-1].br_blockcount += mval->br_blockcount; 5026 mval[-1].br_state = mval->br_state; 5027 } else if (!((n == 0) && 5028 ((mval->br_startoff + mval->br_blockcount) <= 5029 obno))) { 5030 mval++; 5031 n++; 5032 } 5033 /* 5034 * If we're done, stop now. Stop when we've allocated 5035 * XFS_BMAP_MAX_NMAP extents no matter what. Otherwise 5036 * the transaction may get too big. 5037 */ 5038 if (bno >= end || n >= *nmap || nallocs >= *nmap) 5039 break; 5040 /* 5041 * Else go on to the next record. 5042 */ 5043 ep++; 5044 lastx++; 5045 if (lastx >= nextents) { 5046 eof = 1; 5047 prev = got; 5048 } else 5049 xfs_bmbt_get_all(ep, &got); 5050 } 5051 ifp->if_lastex = lastx; 5052 *nmap = n; 5053 /* 5054 * Transform from btree to extents, give it cur. 5055 */ 5056 if (tp && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && 5057 XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { 5058 ASSERT(wr && cur); 5059 error = xfs_bmap_btree_to_extents(tp, ip, cur, 5060 &tmp_logflags, whichfork); 5061 logflags |= tmp_logflags; 5062 if (error) 5063 goto error0; 5064 } 5065 ASSERT(ifp->if_ext_max == 5066 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5067 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 5068 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); 5069 error = 0; 5070 5071error0: 5072 /* 5073 * Log everything. Do this after conversion, there's no point in 5074 * logging the extent list if we've converted to btree format. 5075 */ 5076 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5077 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5078 logflags &= ~XFS_ILOG_FEXT(whichfork); 5079 else if ((logflags & XFS_ILOG_FBROOT(whichfork)) && 5080 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) 5081 logflags &= ~XFS_ILOG_FBROOT(whichfork); 5082 /* 5083 * Log whatever the flags say, even if error. Otherwise we might miss 5084 * detecting a case where the data is changed, there's an error, 5085 * and it's not logged so we don't shutdown when we should. 5086 */ 5087 if (logflags) { 5088 ASSERT(tp && wr); 5089 xfs_trans_log_inode(tp, ip, logflags); 5090 } 5091 if (cur) { 5092 if (!error) { 5093 ASSERT(*firstblock == NULLFSBLOCK || 5094 XFS_FSB_TO_AGNO(mp, *firstblock) == 5095 XFS_FSB_TO_AGNO(mp, 5096 cur->bc_private.b.firstblock) || 5097 (flist->xbf_low && 5098 XFS_FSB_TO_AGNO(mp, *firstblock) < 5099 XFS_FSB_TO_AGNO(mp, 5100 cur->bc_private.b.firstblock))); 5101 *firstblock = cur->bc_private.b.firstblock; 5102 } 5103 xfs_btree_del_cursor(cur, 5104 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 5105 } 5106 if (!error) 5107 xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, 5108 orig_nmap, *nmap); 5109 return error; 5110} 5111 5112/* 5113 * Map file blocks to filesystem blocks, simple version. 5114 * One block (extent) only, read-only. 5115 * For flags, only the XFS_BMAPI_ATTRFORK flag is examined. 5116 * For the other flag values, the effect is as if XFS_BMAPI_METADATA 5117 * was set and all the others were clear. 5118 */ 5119int /* error */ 5120xfs_bmapi_single( 5121 xfs_trans_t *tp, /* transaction pointer */ 5122 xfs_inode_t *ip, /* incore inode */ 5123 int whichfork, /* data or attr fork */ 5124 xfs_fsblock_t *fsb, /* output: mapped block */ 5125 xfs_fileoff_t bno) /* starting file offs. mapped */ 5126{ 5127 int eof; /* we've hit the end of extent list */ 5128 int error; /* error return */ 5129 xfs_bmbt_irec_t got; /* current extent list record */ 5130 xfs_ifork_t *ifp; /* inode fork pointer */ 5131 xfs_extnum_t lastx; /* last useful extent number */ 5132 xfs_bmbt_irec_t prev; /* previous extent list record */ 5133 5134 ifp = XFS_IFORK_PTR(ip, whichfork); 5135 if (unlikely( 5136 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 5137 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) { 5138 XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW, 5139 ip->i_mount); 5140 return XFS_ERROR(EFSCORRUPTED); 5141 } 5142 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 5143 return XFS_ERROR(EIO); 5144 XFS_STATS_INC(xs_blk_mapr); 5145 if (!(ifp->if_flags & XFS_IFEXTENTS) && 5146 (error = xfs_iread_extents(tp, ip, whichfork))) 5147 return error; 5148 (void)xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5149 &prev); 5150 /* 5151 * Reading past eof, act as though there's a hole 5152 * up to end. 5153 */ 5154 if (eof || got.br_startoff > bno) { 5155 *fsb = NULLFSBLOCK; 5156 return 0; 5157 } 5158 ASSERT(!ISNULLSTARTBLOCK(got.br_startblock)); 5159 ASSERT(bno < got.br_startoff + got.br_blockcount); 5160 *fsb = got.br_startblock + (bno - got.br_startoff); 5161 ifp->if_lastex = lastx; 5162 return 0; 5163} 5164 5165/* 5166 * Unmap (remove) blocks from a file. 5167 * If nexts is nonzero then the number of extents to remove is limited to 5168 * that value. If not all extents in the block range can be removed then 5169 * *done is set. 5170 */ 5171int /* error */ 5172xfs_bunmapi( 5173 xfs_trans_t *tp, /* transaction pointer */ 5174 struct xfs_inode *ip, /* incore inode */ 5175 xfs_fileoff_t bno, /* starting offset to unmap */ 5176 xfs_filblks_t len, /* length to unmap in file */ 5177 int flags, /* misc flags */ 5178 xfs_extnum_t nexts, /* number of extents max */ 5179 xfs_fsblock_t *firstblock, /* first allocated block 5180 controls a.g. for allocs */ 5181 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 5182 int *done) /* set if not done yet */ 5183{ 5184 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5185 xfs_bmbt_irec_t del; /* extent being deleted */ 5186 int eof; /* is deleting at eof */ 5187 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 5188 int error; /* error return value */ 5189 xfs_extnum_t extno; /* extent number in list */ 5190 xfs_bmbt_irec_t got; /* current extent list entry */ 5191 xfs_ifork_t *ifp; /* inode fork pointer */ 5192 int isrt; /* freeing in rt area */ 5193 xfs_extnum_t lastx; /* last extent index used */ 5194 int logflags; /* transaction logging flags */ 5195 xfs_extlen_t mod; /* rt extent offset */ 5196 xfs_mount_t *mp; /* mount structure */ 5197 xfs_extnum_t nextents; /* size of extent list */ 5198 xfs_bmbt_irec_t prev; /* previous extent list entry */ 5199 xfs_fileoff_t start; /* first file offset deleted */ 5200 int tmp_logflags; /* partial logging flags */ 5201 int wasdel; /* was a delayed alloc extent */ 5202 int whichfork; /* data or attribute fork */ 5203 int rsvd; /* OK to allocate reserved blocks */ 5204 xfs_fsblock_t sum; 5205 5206 xfs_bunmap_trace(ip, bno, len, flags, (inst_t *)__return_address); 5207 whichfork = (flags & XFS_BMAPI_ATTRFORK) ? 5208 XFS_ATTR_FORK : XFS_DATA_FORK; 5209 ifp = XFS_IFORK_PTR(ip, whichfork); 5210 if (unlikely( 5211 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 5212 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 5213 XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW, 5214 ip->i_mount); 5215 return XFS_ERROR(EFSCORRUPTED); 5216 } 5217 mp = ip->i_mount; 5218 if (XFS_FORCED_SHUTDOWN(mp)) 5219 return XFS_ERROR(EIO); 5220 rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; 5221 ASSERT(len > 0); 5222 ASSERT(nexts >= 0); 5223 ASSERT(ifp->if_ext_max == 5224 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5225 if (!(ifp->if_flags & XFS_IFEXTENTS) && 5226 (error = xfs_iread_extents(tp, ip, whichfork))) 5227 return error; 5228 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5229 if (nextents == 0) { 5230 *done = 1; 5231 return 0; 5232 } 5233 XFS_STATS_INC(xs_blk_unmap); 5234 isrt = (whichfork == XFS_DATA_FORK) && 5235 (ip->i_d.di_flags & XFS_DIFLAG_REALTIME); 5236 start = bno; 5237 bno = start + len - 1; 5238 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5239 &prev); 5240 /* 5241 * Check to see if the given block number is past the end of the 5242 * file, back up to the last block if so... 5243 */ 5244 if (eof) { 5245 ep = &ifp->if_u1.if_extents[--lastx]; 5246 xfs_bmbt_get_all(ep, &got); 5247 bno = got.br_startoff + got.br_blockcount - 1; 5248 } 5249 logflags = 0; 5250 if (ifp->if_flags & XFS_IFBROOT) { 5251 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); 5252 cur = xfs_btree_init_cursor(mp, tp, NULL, 0, XFS_BTNUM_BMAP, ip, 5253 whichfork); 5254 cur->bc_private.b.firstblock = *firstblock; 5255 cur->bc_private.b.flist = flist; 5256 cur->bc_private.b.flags = 0; 5257 } else 5258 cur = NULL; 5259 extno = 0; 5260 while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 && 5261 (nexts == 0 || extno < nexts)) { 5262 /* 5263 * Is the found extent after a hole in which bno lives? 5264 * Just back up to the previous extent, if so. 5265 */ 5266 if (got.br_startoff > bno) { 5267 if (--lastx < 0) 5268 break; 5269 ep--; 5270 xfs_bmbt_get_all(ep, &got); 5271 } 5272 /* 5273 * Is the last block of this extent before the range 5274 * we're supposed to delete? If so, we're done. 5275 */ 5276 bno = XFS_FILEOFF_MIN(bno, 5277 got.br_startoff + got.br_blockcount - 1); 5278 if (bno < start) 5279 break; 5280 /* 5281 * Then deal with the (possibly delayed) allocated space 5282 * we found. 5283 */ 5284 ASSERT(ep != NULL); 5285 del = got; 5286 wasdel = ISNULLSTARTBLOCK(del.br_startblock); 5287 if (got.br_startoff < start) { 5288 del.br_startoff = start; 5289 del.br_blockcount -= start - got.br_startoff; 5290 if (!wasdel) 5291 del.br_startblock += start - got.br_startoff; 5292 } 5293 if (del.br_startoff + del.br_blockcount > bno + 1) 5294 del.br_blockcount = bno + 1 - del.br_startoff; 5295 sum = del.br_startblock + del.br_blockcount; 5296 if (isrt && 5297 (mod = do_mod(sum, mp->m_sb.sb_rextsize))) { 5298 /* 5299 * Realtime extent not lined up at the end. 5300 * The extent could have been split into written 5301 * and unwritten pieces, or we could just be 5302 * unmapping part of it. But we can't really 5303 * get rid of part of a realtime extent. 5304 */ 5305 if (del.br_state == XFS_EXT_UNWRITTEN || 5306 !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { 5307 /* 5308 * This piece is unwritten, or we're not 5309 * using unwritten extents. Skip over it. 5310 */ 5311 ASSERT(bno >= mod); 5312 bno -= mod > del.br_blockcount ? 5313 del.br_blockcount : mod; 5314 if (bno < got.br_startoff) { 5315 if (--lastx >= 0) 5316 xfs_bmbt_get_all(--ep, &got); 5317 } 5318 continue; 5319 } 5320 /* 5321 * It's written, turn it unwritten. 5322 * This is better than zeroing it. 5323 */ 5324 ASSERT(del.br_state == XFS_EXT_NORM); 5325 ASSERT(xfs_trans_get_block_res(tp) > 0); 5326 /* 5327 * If this spans a realtime extent boundary, 5328 * chop it back to the start of the one we end at. 5329 */ 5330 if (del.br_blockcount > mod) { 5331 del.br_startoff += del.br_blockcount - mod; 5332 del.br_startblock += del.br_blockcount - mod; 5333 del.br_blockcount = mod; 5334 } 5335 del.br_state = XFS_EXT_UNWRITTEN; 5336 error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5337 firstblock, flist, &logflags, XFS_DATA_FORK, 0); 5338 if (error) 5339 goto error0; 5340 goto nodelete; 5341 } 5342 if (isrt && (mod = do_mod(del.br_startblock, mp->m_sb.sb_rextsize))) { 5343 /* 5344 * Realtime extent is lined up at the end but not 5345 * at the front. We'll get rid of full extents if 5346 * we can. 5347 */ 5348 mod = mp->m_sb.sb_rextsize - mod; 5349 if (del.br_blockcount > mod) { 5350 del.br_blockcount -= mod; 5351 del.br_startoff += mod; 5352 del.br_startblock += mod; 5353 } else if ((del.br_startoff == start && 5354 (del.br_state == XFS_EXT_UNWRITTEN || 5355 xfs_trans_get_block_res(tp) == 0)) || 5356 !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { 5357 /* 5358 * Can't make it unwritten. There isn't 5359 * a full extent here so just skip it. 5360 */ 5361 ASSERT(bno >= del.br_blockcount); 5362 bno -= del.br_blockcount; 5363 if (bno < got.br_startoff) { 5364 if (--lastx >= 0) 5365 xfs_bmbt_get_all(--ep, &got); 5366 } 5367 continue; 5368 } else if (del.br_state == XFS_EXT_UNWRITTEN) { 5369 /* 5370 * This one is already unwritten. 5371 * It must have a written left neighbor. 5372 * Unwrite the killed part of that one and 5373 * try again. 5374 */ 5375 ASSERT(lastx > 0); 5376 xfs_bmbt_get_all(ep - 1, &prev); 5377 ASSERT(prev.br_state == XFS_EXT_NORM); 5378 ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock)); 5379 ASSERT(del.br_startblock == 5380 prev.br_startblock + prev.br_blockcount); 5381 if (prev.br_startoff < start) { 5382 mod = start - prev.br_startoff; 5383 prev.br_blockcount -= mod; 5384 prev.br_startblock += mod; 5385 prev.br_startoff = start; 5386 } 5387 prev.br_state = XFS_EXT_UNWRITTEN; 5388 error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5389 &prev, firstblock, flist, &logflags, 5390 XFS_DATA_FORK, 0); 5391 if (error) 5392 goto error0; 5393 goto nodelete; 5394 } else { 5395 ASSERT(del.br_state == XFS_EXT_NORM); 5396 del.br_state = XFS_EXT_UNWRITTEN; 5397 error = xfs_bmap_add_extent(ip, lastx, &cur, 5398 &del, firstblock, flist, &logflags, 5399 XFS_DATA_FORK, 0); 5400 if (error) 5401 goto error0; 5402 goto nodelete; 5403 } 5404 } 5405 if (wasdel) { 5406 ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); 5407 /* Update realtim/data freespace, unreserve quota */ 5408 if (isrt) { 5409 xfs_filblks_t rtexts; 5410 5411 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); 5412 do_div(rtexts, mp->m_sb.sb_rextsize); 5413 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, 5414 (int)rtexts, rsvd); 5415 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, 5416 -((long)del.br_blockcount), 0, 5417 XFS_QMOPT_RES_RTBLKS); 5418 } else { 5419 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, 5420 (int)del.br_blockcount, rsvd); 5421 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, 5422 -((long)del.br_blockcount), 0, 5423 XFS_QMOPT_RES_REGBLKS); 5424 } 5425 ip->i_delayed_blks -= del.br_blockcount; 5426 if (cur) 5427 cur->bc_private.b.flags |= 5428 XFS_BTCUR_BPRV_WASDEL; 5429 } else if (cur) 5430 cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL; 5431 /* 5432 * If it's the case where the directory code is running 5433 * with no block reservation, and the deleted block is in 5434 * the middle of its extent, and the resulting insert 5435 * of an extent would cause transformation to btree format, 5436 * then reject it. The calling code will then swap 5437 * blocks around instead. 5438 * We have to do this now, rather than waiting for the 5439 * conversion to btree format, since the transaction 5440 * will be dirty. 5441 */ 5442 if (!wasdel && xfs_trans_get_block_res(tp) == 0 && 5443 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 5444 XFS_IFORK_NEXTENTS(ip, whichfork) >= ifp->if_ext_max && 5445 del.br_startoff > got.br_startoff && 5446 del.br_startoff + del.br_blockcount < 5447 got.br_startoff + got.br_blockcount) { 5448 error = XFS_ERROR(ENOSPC); 5449 goto error0; 5450 } 5451 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5452 &tmp_logflags, whichfork, rsvd); 5453 logflags |= tmp_logflags; 5454 if (error) 5455 goto error0; 5456 bno = del.br_startoff - 1; 5457nodelete: 5458 lastx = ifp->if_lastex; 5459 /* 5460 * If not done go on to the next (previous) record. 5461 * Reset ep in case the extents array was re-alloced. 5462 */ 5463 ep = &ifp->if_u1.if_extents[lastx]; 5464 if (bno != (xfs_fileoff_t)-1 && bno >= start) { 5465 if (lastx >= XFS_IFORK_NEXTENTS(ip, whichfork) || 5466 xfs_bmbt_get_startoff(ep) > bno) { 5467 lastx--; 5468 ep--; 5469 } 5470 if (lastx >= 0) 5471 xfs_bmbt_get_all(ep, &got); 5472 extno++; 5473 } 5474 } 5475 ifp->if_lastex = lastx; 5476 *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; 5477 ASSERT(ifp->if_ext_max == 5478 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5479 /* 5480 * Convert to a btree if necessary. 5481 */ 5482 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 5483 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) { 5484 ASSERT(cur == NULL); 5485 error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist, 5486 &cur, 0, &tmp_logflags, whichfork); 5487 logflags |= tmp_logflags; 5488 if (error) 5489 goto error0; 5490 } 5491 /* 5492 * transform from btree to extents, give it cur 5493 */ 5494 else if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && 5495 XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { 5496 ASSERT(cur != NULL); 5497 error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags, 5498 whichfork); 5499 logflags |= tmp_logflags; 5500 if (error) 5501 goto error0; 5502 } 5503 /* 5504 * transform from extents to local? 5505 */ 5506 ASSERT(ifp->if_ext_max == 5507 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5508 error = 0; 5509error0: 5510 /* 5511 * Log everything. Do this after conversion, there's no point in 5512 * logging the extent list if we've converted to btree format. 5513 */ 5514 if ((logflags & XFS_ILOG_FEXT(whichfork)) && 5515 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 5516 logflags &= ~XFS_ILOG_FEXT(whichfork); 5517 else if ((logflags & XFS_ILOG_FBROOT(whichfork)) && 5518 XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) 5519 logflags &= ~XFS_ILOG_FBROOT(whichfork); 5520 /* 5521 * Log inode even in the error case, if the transaction 5522 * is dirty we'll need to shut down the filesystem. 5523 */ 5524 if (logflags) 5525 xfs_trans_log_inode(tp, ip, logflags); 5526 if (cur) { 5527 if (!error) { 5528 *firstblock = cur->bc_private.b.firstblock; 5529 cur->bc_private.b.allocated = 0; 5530 } 5531 xfs_btree_del_cursor(cur, 5532 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 5533 } 5534 return error; 5535} 5536 5537/* 5538 * Fcntl interface to xfs_bmapi. 5539 */ 5540int /* error code */ 5541xfs_getbmap( 5542 bhv_desc_t *bdp, /* XFS behavior descriptor*/ 5543 struct getbmap *bmv, /* user bmap structure */ 5544 void __user *ap, /* pointer to user's array */ 5545 int interface) /* interface flags */ 5546{ 5547 __int64_t bmvend; /* last block requested */ 5548 int error; /* return value */ 5549 __int64_t fixlen; /* length for -1 case */ 5550 int i; /* extent number */ 5551 xfs_inode_t *ip; /* xfs incore inode pointer */ 5552 vnode_t *vp; /* corresponding vnode */ 5553 int lock; /* lock state */ 5554 xfs_bmbt_irec_t *map; /* buffer for user's data */ 5555 xfs_mount_t *mp; /* file system mount point */ 5556 int nex; /* # of user extents can do */ 5557 int nexleft; /* # of user extents left */ 5558 int subnex; /* # of bmapi's can do */ 5559 int nmap; /* number of map entries */ 5560 struct getbmap out; /* output structure */ 5561 int whichfork; /* data or attr fork */ 5562 int prealloced; /* this is a file with 5563 * preallocated data space */ 5564 int sh_unwritten; /* true, if unwritten */ 5565 /* extents listed separately */ 5566 int bmapi_flags; /* flags for xfs_bmapi */ 5567 __int32_t oflags; /* getbmapx bmv_oflags field */ 5568 5569 vp = BHV_TO_VNODE(bdp); 5570 ip = XFS_BHVTOI(bdp); 5571 mp = ip->i_mount; 5572 5573 whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK; 5574 sh_unwritten = (interface & BMV_IF_PREALLOC) != 0; 5575 5576 /* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not 5577 * generate a DMAPI read event. Otherwise, if the DM_EVENT_READ 5578 * bit is set for the file, generate a read event in order 5579 * that the DMAPI application may do its thing before we return 5580 * the extents. Usually this means restoring user file data to 5581 * regions of the file that look like holes. 5582 * 5583 * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify 5584 * BMV_IF_NO_DMAPI_READ so that read events are generated. 5585 * If this were not true, callers of ioctl( XFS_IOC_GETBMAP ) 5586 * could misinterpret holes in a DMAPI file as true holes, 5587 * when in fact they may represent offline user data. 5588 */ 5589 if ( (interface & BMV_IF_NO_DMAPI_READ) == 0 5590 && DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) 5591 && whichfork == XFS_DATA_FORK) { 5592 5593 error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL); 5594 if (error) 5595 return XFS_ERROR(error); 5596 } 5597 5598 if (whichfork == XFS_ATTR_FORK) { 5599 if (XFS_IFORK_Q(ip)) { 5600 if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS && 5601 ip->i_d.di_aformat != XFS_DINODE_FMT_BTREE && 5602 ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) 5603 return XFS_ERROR(EINVAL); 5604 } else if (unlikely( 5605 ip->i_d.di_aformat != 0 && 5606 ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS)) { 5607 XFS_ERROR_REPORT("xfs_getbmap", XFS_ERRLEVEL_LOW, 5608 ip->i_mount); 5609 return XFS_ERROR(EFSCORRUPTED); 5610 } 5611 } else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && 5612 ip->i_d.di_format != XFS_DINODE_FMT_BTREE && 5613 ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) 5614 return XFS_ERROR(EINVAL); 5615 if (whichfork == XFS_DATA_FORK) { 5616 if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) { 5617 prealloced = 1; 5618 fixlen = XFS_MAXIOFFSET(mp); 5619 } else { 5620 prealloced = 0; 5621 fixlen = ip->i_d.di_size; 5622 } 5623 } else { 5624 prealloced = 0; 5625 fixlen = 1LL << 32; 5626 } 5627 5628 if (bmv->bmv_length == -1) { 5629 fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen)); 5630 bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset), 5631 (__int64_t)0); 5632 } else if (bmv->bmv_length < 0) 5633 return XFS_ERROR(EINVAL); 5634 if (bmv->bmv_length == 0) { 5635 bmv->bmv_entries = 0; 5636 return 0; 5637 } 5638 nex = bmv->bmv_count - 1; 5639 if (nex <= 0) 5640 return XFS_ERROR(EINVAL); 5641 bmvend = bmv->bmv_offset + bmv->bmv_length; 5642 5643 xfs_ilock(ip, XFS_IOLOCK_SHARED); 5644 5645 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { 5646 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5647 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 5648 } 5649 5650 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); 5651 5652 lock = xfs_ilock_map_shared(ip); 5653 5654 /* 5655 * Don't let nex be bigger than the number of extents 5656 * we can have assuming alternating holes and real extents. 5657 */ 5658 if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1) 5659 nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1; 5660 5661 bmapi_flags = XFS_BMAPI_AFLAG(whichfork) | 5662 ((sh_unwritten) ? 0 : XFS_BMAPI_IGSTATE); 5663 5664 /* 5665 * Allocate enough space to handle "subnex" maps at a time. 5666 */ 5667 subnex = 16; 5668 map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP); 5669 5670 bmv->bmv_entries = 0; 5671 5672 if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0) { 5673 error = 0; 5674 goto unlock_and_return; 5675 } 5676 5677 nexleft = nex; 5678 5679 do { 5680 nmap = (nexleft > subnex) ? subnex : nexleft; 5681 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5682 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5683 bmapi_flags, NULL, 0, map, &nmap, NULL); 5684 if (error) 5685 goto unlock_and_return; 5686 ASSERT(nmap <= subnex); 5687 5688 for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) { 5689 nexleft--; 5690 oflags = (map[i].br_state == XFS_EXT_UNWRITTEN) ? 5691 BMV_OF_PREALLOC : 0; 5692 out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff); 5693 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); 5694 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); 5695 if (prealloced && 5696 map[i].br_startblock == HOLESTARTBLOCK && 5697 out.bmv_offset + out.bmv_length == bmvend) { 5698 /* 5699 * came to hole at end of file 5700 */ 5701 goto unlock_and_return; 5702 } else { 5703 out.bmv_block = 5704 (map[i].br_startblock == HOLESTARTBLOCK) ? 5705 -1 : 5706 XFS_FSB_TO_DB(ip, map[i].br_startblock); 5707 5708 /* return either getbmap/getbmapx structure. */ 5709 if (interface & BMV_IF_EXTENDED) { 5710 struct getbmapx outx; 5711 5712 GETBMAP_CONVERT(out,outx); 5713 outx.bmv_oflags = oflags; 5714 outx.bmv_unused1 = outx.bmv_unused2 = 0; 5715 if (copy_to_user(ap, &outx, 5716 sizeof(outx))) { 5717 error = XFS_ERROR(EFAULT); 5718 goto unlock_and_return; 5719 } 5720 } else { 5721 if (copy_to_user(ap, &out, 5722 sizeof(out))) { 5723 error = XFS_ERROR(EFAULT); 5724 goto unlock_and_return; 5725 } 5726 } 5727 bmv->bmv_offset = 5728 out.bmv_offset + out.bmv_length; 5729 bmv->bmv_length = MAX((__int64_t)0, 5730 (__int64_t)(bmvend - bmv->bmv_offset)); 5731 bmv->bmv_entries++; 5732 ap = (interface & BMV_IF_EXTENDED) ? 5733 (void __user *) 5734 ((struct getbmapx __user *)ap + 1) : 5735 (void __user *) 5736 ((struct getbmap __user *)ap + 1); 5737 } 5738 } 5739 } while (nmap && nexleft && bmv->bmv_length); 5740 5741unlock_and_return: 5742 xfs_iunlock_map_shared(ip, lock); 5743 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 5744 5745 kmem_free(map, subnex * sizeof(*map)); 5746 5747 return error; 5748} 5749 5750/* 5751 * Check the last inode extent to determine whether this allocation will result 5752 * in blocks being allocated at the end of the file. When we allocate new data 5753 * blocks at the end of the file which do not start at the previous data block, 5754 * we will try to align the new blocks at stripe unit boundaries. 5755 */ 5756STATIC int /* error */ 5757xfs_bmap_isaeof( 5758 xfs_inode_t *ip, /* incore inode pointer */ 5759 xfs_fileoff_t off, /* file offset in fsblocks */ 5760 int whichfork, /* data or attribute fork */ 5761 char *aeof) /* return value */ 5762{ 5763 int error; /* error return value */ 5764 xfs_ifork_t *ifp; /* inode fork pointer */ 5765 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5766 xfs_extnum_t nextents; /* size of extent list */ 5767 xfs_bmbt_irec_t s; /* expanded extent list entry */ 5768 5769 ASSERT(whichfork == XFS_DATA_FORK); 5770 ifp = XFS_IFORK_PTR(ip, whichfork); 5771 if (!(ifp->if_flags & XFS_IFEXTENTS) && 5772 (error = xfs_iread_extents(NULL, ip, whichfork))) 5773 return error; 5774 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5775 if (nextents == 0) { 5776 *aeof = 1; 5777 return 0; 5778 } 5779 /* 5780 * Go to the last extent 5781 */ 5782 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5783 xfs_bmbt_get_all(lastrec, &s); 5784 /* 5785 * Check we are allocating in the last extent (for delayed allocations) 5786 * or past the last extent for non-delayed allocations. 5787 */ 5788 *aeof = (off >= s.br_startoff && 5789 off < s.br_startoff + s.br_blockcount && 5790 ISNULLSTARTBLOCK(s.br_startblock)) || 5791 off >= s.br_startoff + s.br_blockcount; 5792 return 0; 5793} 5794 5795/* 5796 * Check if the endoff is outside the last extent. If so the caller will grow 5797 * the allocation to a stripe unit boundary. 5798 */ 5799int /* error */ 5800xfs_bmap_eof( 5801 xfs_inode_t *ip, /* incore inode pointer */ 5802 xfs_fileoff_t endoff, /* file offset in fsblocks */ 5803 int whichfork, /* data or attribute fork */ 5804 int *eof) /* result value */ 5805{ 5806 xfs_fsblock_t blockcount; /* extent block count */ 5807 int error; /* error return value */ 5808 xfs_ifork_t *ifp; /* inode fork pointer */ 5809 xfs_bmbt_rec_t *lastrec; /* extent list entry pointer */ 5810 xfs_extnum_t nextents; /* size of extent list */ 5811 xfs_fileoff_t startoff; /* extent starting file offset */ 5812 5813 ASSERT(whichfork == XFS_DATA_FORK); 5814 ifp = XFS_IFORK_PTR(ip, whichfork); 5815 if (!(ifp->if_flags & XFS_IFEXTENTS) && 5816 (error = xfs_iread_extents(NULL, ip, whichfork))) 5817 return error; 5818 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5819 if (nextents == 0) { 5820 *eof = 1; 5821 return 0; 5822 } 5823 /* 5824 * Go to the last extent 5825 */ 5826 lastrec = &ifp->if_u1.if_extents[nextents - 1]; 5827 startoff = xfs_bmbt_get_startoff(lastrec); 5828 blockcount = xfs_bmbt_get_blockcount(lastrec); 5829 *eof = endoff >= startoff + blockcount; 5830 return 0; 5831} 5832 5833#ifdef DEBUG 5834/* 5835 * Check that the extents list for the inode ip is in the right order. 5836 */ 5837STATIC void 5838xfs_bmap_check_extents( 5839 xfs_inode_t *ip, /* incore inode pointer */ 5840 int whichfork) /* data or attr fork */ 5841{ 5842 xfs_bmbt_rec_t *base; /* base of extents list */ 5843 xfs_bmbt_rec_t *ep; /* current extent entry */ 5844 xfs_ifork_t *ifp; /* inode fork pointer */ 5845 xfs_extnum_t nextents; /* number of extents in list */ 5846 5847 ifp = XFS_IFORK_PTR(ip, whichfork); 5848 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 5849 base = ifp->if_u1.if_extents; 5850 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 5851 for (ep = base; ep < &base[nextents - 1]; ep++) { 5852 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 5853 (void *)(ep + 1)); 5854 } 5855} 5856 5857STATIC 5858xfs_buf_t * 5859xfs_bmap_get_bp( 5860 xfs_btree_cur_t *cur, 5861 xfs_fsblock_t bno) 5862{ 5863 int i; 5864 xfs_buf_t *bp; 5865 5866 if (!cur) 5867 return(NULL); 5868 5869 bp = NULL; 5870 for(i = 0; i < XFS_BTREE_MAXLEVELS; i++) { 5871 bp = cur->bc_bufs[i]; 5872 if (!bp) break; 5873 if (XFS_BUF_ADDR(bp) == bno) 5874 break; /* Found it */ 5875 } 5876 if (i == XFS_BTREE_MAXLEVELS) 5877 bp = NULL; 5878 5879 if (!bp) { /* Chase down all the log items to see if the bp is there */ 5880 xfs_log_item_chunk_t *licp; 5881 xfs_trans_t *tp; 5882 5883 tp = cur->bc_tp; 5884 licp = &tp->t_items; 5885 while (!bp && licp != NULL) { 5886 if (XFS_LIC_ARE_ALL_FREE(licp)) { 5887 licp = licp->lic_next; 5888 continue; 5889 } 5890 for (i = 0; i < licp->lic_unused; i++) { 5891 xfs_log_item_desc_t *lidp; 5892 xfs_log_item_t *lip; 5893 xfs_buf_log_item_t *bip; 5894 xfs_buf_t *lbp; 5895 5896 if (XFS_LIC_ISFREE(licp, i)) { 5897 continue; 5898 } 5899 5900 lidp = XFS_LIC_SLOT(licp, i); 5901 lip = lidp->lid_item; 5902 if (lip->li_type != XFS_LI_BUF) 5903 continue; 5904 5905 bip = (xfs_buf_log_item_t *)lip; 5906 lbp = bip->bli_buf; 5907 5908 if (XFS_BUF_ADDR(lbp) == bno) { 5909 bp = lbp; 5910 break; /* Found it */ 5911 } 5912 } 5913 licp = licp->lic_next; 5914 } 5915 } 5916 return(bp); 5917} 5918 5919void 5920xfs_check_block( 5921 xfs_bmbt_block_t *block, 5922 xfs_mount_t *mp, 5923 int root, 5924 short sz) 5925{ 5926 int i, j, dmxr; 5927 xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */ 5928 xfs_bmbt_key_t *prevp, *keyp; 5929 5930 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 5931 5932 prevp = NULL; 5933 for( i = 1; i <= INT_GET(block->bb_numrecs, ARCH_CONVERT);i++) { 5934 dmxr = mp->m_bmap_dmxr[0]; 5935 5936 if (root) { 5937 keyp = XFS_BMAP_BROOT_KEY_ADDR(block, i, sz); 5938 } else { 5939 keyp = XFS_BTREE_KEY_ADDR(mp->m_sb.sb_blocksize, 5940 xfs_bmbt, block, i, dmxr); 5941 } 5942 5943 if (prevp) { 5944 xfs_btree_check_key(XFS_BTNUM_BMAP, prevp, keyp); 5945 } 5946 prevp = keyp; 5947 5948 /* 5949 * Compare the block numbers to see if there are dups. 5950 */ 5951 5952 if (root) { 5953 pp = XFS_BMAP_BROOT_PTR_ADDR(block, i, sz); 5954 } else { 5955 pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, 5956 xfs_bmbt, block, i, dmxr); 5957 } 5958 for (j = i+1; j <= INT_GET(block->bb_numrecs, ARCH_CONVERT); j++) { 5959 if (root) { 5960 thispa = XFS_BMAP_BROOT_PTR_ADDR(block, j, sz); 5961 } else { 5962 thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, 5963 xfs_bmbt, block, j, dmxr); 5964 } 5965 if (INT_GET(*thispa, ARCH_CONVERT) == 5966 INT_GET(*pp, ARCH_CONVERT)) { 5967 cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld", 5968 __FUNCTION__, j, i, 5969 INT_GET(*thispa, ARCH_CONVERT)); 5970 panic("%s: ptrs are equal in node\n", 5971 __FUNCTION__); 5972 } 5973 } 5974 } 5975} 5976 5977/* 5978 * Check that the extents for the inode ip are in the right order in all 5979 * btree leaves. 5980 */ 5981 5982STATIC void 5983xfs_bmap_check_leaf_extents( 5984 xfs_btree_cur_t *cur, /* btree cursor or null */ 5985 xfs_inode_t *ip, /* incore inode pointer */ 5986 int whichfork) /* data or attr fork */ 5987{ 5988 xfs_bmbt_block_t *block; /* current btree block */ 5989 xfs_fsblock_t bno; /* block # of "block" */ 5990 xfs_buf_t *bp; /* buffer for "block" */ 5991 int error; /* error return value */ 5992 xfs_extnum_t i=0; /* index into the extents list */ 5993 xfs_ifork_t *ifp; /* fork structure */ 5994 int level; /* btree level, for checking */ 5995 xfs_mount_t *mp; /* file system mount structure */ 5996 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 5997 xfs_bmbt_rec_t *ep, *lastp; /* extent pointers in block entry */ 5998 int bp_release = 0; 5999 6000 if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { 6001 return; 6002 } 6003 6004 bno = NULLFSBLOCK; 6005 mp = ip->i_mount; 6006 ifp = XFS_IFORK_PTR(ip, whichfork); 6007 block = ifp->if_broot; 6008 /* 6009 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 6010 */ 6011 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 6012 level = INT_GET(block->bb_level, ARCH_CONVERT); 6013 xfs_check_block(block, mp, 1, ifp->if_broot_bytes); 6014 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); 6015 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); 6016 ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); 6017 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); 6018 bno = INT_GET(*pp, ARCH_CONVERT); 6019 /* 6020 * Go down the tree until leaf level is reached, following the first 6021 * pointer (leftmost) at each level. 6022 */ 6023 while (level-- > 0) { 6024 /* See if buf is in cur first */ 6025 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno)); 6026 if (bp) { 6027 bp_release = 0; 6028 } else { 6029 bp_release = 1; 6030 } 6031 if (!bp && (error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, 6032 XFS_BMAP_BTREE_REF))) 6033 goto error_norelse; 6034 block = XFS_BUF_TO_BMBT_BLOCK(bp); 6035 XFS_WANT_CORRUPTED_GOTO( 6036 XFS_BMAP_SANITY_CHECK(mp, block, level), 6037 error0); 6038 if (level == 0) 6039 break; 6040 6041 /* 6042 * Check this block for basic sanity (increasing keys and 6043 * no duplicate blocks). 6044 */ 6045 6046 xfs_check_block(block, mp, 0, 0); 6047 pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 6048 1, mp->m_bmap_dmxr[1]); 6049 XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), error0); 6050 bno = INT_GET(*pp, ARCH_CONVERT); 6051 if (bp_release) { 6052 bp_release = 0; 6053 xfs_trans_brelse(NULL, bp); 6054 } 6055 } 6056 6057 /* 6058 * Here with bp and block set to the leftmost leaf node in the tree. 6059 */ 6060 i = 0; 6061 6062 /* 6063 * Loop over all leaf nodes checking that all extents are in the right order. 6064 */ 6065 lastp = NULL; 6066 for (;;) { 6067 xfs_bmbt_rec_t *frp; 6068 xfs_fsblock_t nextbno; 6069 xfs_extnum_t num_recs; 6070 6071 6072 num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT); 6073 6074 /* 6075 * Read-ahead the next leaf block, if any. 6076 */ 6077 6078 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 6079 6080 /* 6081 * Check all the extents to make sure they are OK. 6082 * If we had a previous block, the last entry should 6083 * conform with the first entry in this one. 6084 */ 6085 6086 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, 6087 block, 1, mp->m_bmap_dmxr[0]); 6088 6089 for (ep = frp;ep < frp + (num_recs - 1); ep++) { 6090 if (lastp) { 6091 xfs_btree_check_rec(XFS_BTNUM_BMAP, 6092 (void *)lastp, (void *)ep); 6093 } 6094 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep, 6095 (void *)(ep + 1)); 6096 } 6097 lastp = frp + num_recs - 1; /* For the next iteration */ 6098 6099 i += num_recs; 6100 if (bp_release) { 6101 bp_release = 0; 6102 xfs_trans_brelse(NULL, bp); 6103 } 6104 bno = nextbno; 6105 /* 6106 * If we've reached the end, stop. 6107 */ 6108 if (bno == NULLFSBLOCK) 6109 break; 6110 6111 bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno)); 6112 if (bp) { 6113 bp_release = 0; 6114 } else { 6115 bp_release = 1; 6116 } 6117 if (!bp && (error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, 6118 XFS_BMAP_BTREE_REF))) 6119 goto error_norelse; 6120 block = XFS_BUF_TO_BMBT_BLOCK(bp); 6121 } 6122 if (bp_release) { 6123 bp_release = 0; 6124 xfs_trans_brelse(NULL, bp); 6125 } 6126 return; 6127 6128error0: 6129 cmn_err(CE_WARN, "%s: at error0", __FUNCTION__); 6130 if (bp_release) 6131 xfs_trans_brelse(NULL, bp); 6132error_norelse: 6133 cmn_err(CE_WARN, "%s: BAD after btree leaves for %d extents", 6134 i, __FUNCTION__); 6135 panic("%s: CORRUPTED BTREE OR SOMETHING", __FUNCTION__); 6136 return; 6137} 6138#endif 6139 6140/* 6141 * Count fsblocks of the given fork. 6142 */ 6143int /* error */ 6144xfs_bmap_count_blocks( 6145 xfs_trans_t *tp, /* transaction pointer */ 6146 xfs_inode_t *ip, /* incore inode */ 6147 int whichfork, /* data or attr fork */ 6148 int *count) /* out: count of blocks */ 6149{ 6150 xfs_bmbt_block_t *block; /* current btree block */ 6151 xfs_fsblock_t bno; /* block # of "block" */ 6152 xfs_ifork_t *ifp; /* fork structure */ 6153 int level; /* btree level, for checking */ 6154 xfs_mount_t *mp; /* file system mount structure */ 6155 xfs_bmbt_ptr_t *pp; /* pointer to block address */ 6156 6157 bno = NULLFSBLOCK; 6158 mp = ip->i_mount; 6159 ifp = XFS_IFORK_PTR(ip, whichfork); 6160 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { 6161 if (unlikely(xfs_bmap_count_leaves(ifp->if_u1.if_extents, 6162 ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t), 6163 count) < 0)) { 6164 XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)", 6165 XFS_ERRLEVEL_LOW, mp); 6166 return XFS_ERROR(EFSCORRUPTED); 6167 } 6168 return 0; 6169 } 6170 6171 /* 6172 * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 6173 */ 6174 block = ifp->if_broot; 6175 ASSERT(INT_GET(block->bb_level, ARCH_CONVERT) > 0); 6176 level = INT_GET(block->bb_level, ARCH_CONVERT); 6177 pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); 6178 ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); 6179 ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); 6180 ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); 6181 bno = INT_GET(*pp, ARCH_CONVERT); 6182 6183 if (unlikely(xfs_bmap_count_tree(mp, tp, bno, level, count) < 0)) { 6184 XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW, 6185 mp); 6186 return XFS_ERROR(EFSCORRUPTED); 6187 } 6188 6189 return 0; 6190} 6191 6192/* 6193 * Recursively walks each level of a btree 6194 * to count total fsblocks is use. 6195 */ 6196int /* error */ 6197xfs_bmap_count_tree( 6198 xfs_mount_t *mp, /* file system mount point */ 6199 xfs_trans_t *tp, /* transaction pointer */ 6200 xfs_fsblock_t blockno, /* file system block number */ 6201 int levelin, /* level in btree */ 6202 int *count) /* Count of blocks */ 6203{ 6204 int error; 6205 xfs_buf_t *bp, *nbp; 6206 int level = levelin; 6207 xfs_bmbt_ptr_t *pp; 6208 xfs_fsblock_t bno = blockno; 6209 xfs_fsblock_t nextbno; 6210 xfs_bmbt_block_t *block, *nextblock; 6211 int numrecs; 6212 xfs_bmbt_rec_t *frp; 6213 6214 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF))) 6215 return error; 6216 *count += 1; 6217 block = XFS_BUF_TO_BMBT_BLOCK(bp); 6218 6219 if (--level) { 6220 /* Not at node above leafs, count this level of nodes */ 6221 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 6222 while (nextbno != NULLFSBLOCK) { 6223 if ((error = xfs_btree_read_bufl(mp, tp, nextbno, 6224 0, &nbp, XFS_BMAP_BTREE_REF))) 6225 return error; 6226 *count += 1; 6227 nextblock = XFS_BUF_TO_BMBT_BLOCK(nbp); 6228 nextbno = INT_GET(nextblock->bb_rightsib, ARCH_CONVERT); 6229 xfs_trans_brelse(tp, nbp); 6230 } 6231 6232 /* Dive to the next level */ 6233 pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, 6234 xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); 6235 bno = INT_GET(*pp, ARCH_CONVERT); 6236 if (unlikely((error = 6237 xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0)) { 6238 xfs_trans_brelse(tp, bp); 6239 XFS_ERROR_REPORT("xfs_bmap_count_tree(1)", 6240 XFS_ERRLEVEL_LOW, mp); 6241 return XFS_ERROR(EFSCORRUPTED); 6242 } 6243 xfs_trans_brelse(tp, bp); 6244 } else { 6245 /* count all level 1 nodes and their leaves */ 6246 for (;;) { 6247 nextbno = INT_GET(block->bb_rightsib, ARCH_CONVERT); 6248 numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT); 6249 frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, 6250 xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]); 6251 if (unlikely(xfs_bmap_count_leaves(frp, numrecs, count) < 0)) { 6252 xfs_trans_brelse(tp, bp); 6253 XFS_ERROR_REPORT("xfs_bmap_count_tree(2)", 6254 XFS_ERRLEVEL_LOW, mp); 6255 return XFS_ERROR(EFSCORRUPTED); 6256 } 6257 xfs_trans_brelse(tp, bp); 6258 if (nextbno == NULLFSBLOCK) 6259 break; 6260 bno = nextbno; 6261 if ((error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 6262 XFS_BMAP_BTREE_REF))) 6263 return error; 6264 *count += 1; 6265 block = XFS_BUF_TO_BMBT_BLOCK(bp); 6266 } 6267 } 6268 return 0; 6269} 6270 6271/* 6272 * Count leaf blocks given a pointer to an extent list. 6273 */ 6274int 6275xfs_bmap_count_leaves( 6276 xfs_bmbt_rec_t *frp, 6277 int numrecs, 6278 int *count) 6279{ 6280 int b; 6281 6282 for ( b = 1; b <= numrecs; b++, frp++) 6283 *count += xfs_bmbt_disk_get_blockcount(frp); 6284 return 0; 6285}