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