1/* 2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18#include "xfs.h" 19#include "xfs_fs.h" 20#include "xfs_types.h" 21#include "xfs_log.h" 22#include "xfs_inum.h" 23#include "xfs_trans.h" 24#include "xfs_sb.h" 25#include "xfs_ag.h" 26#include "xfs_dir2.h" 27#include "xfs_mount.h" 28#include "xfs_da_btree.h" 29#include "xfs_bmap_btree.h" 30#include "xfs_dir2_sf.h" 31#include "xfs_dinode.h" 32#include "xfs_inode.h" 33#include "xfs_inode_item.h" 34#include "xfs_dir2_data.h" 35#include "xfs_dir2_leaf.h" 36#include "xfs_dir2_block.h" 37#include "xfs_error.h" 38#include "xfs_trace.h" 39 40/* 41 * Local function prototypes. 42 */ 43static void xfs_dir2_block_log_leaf(xfs_trans_t *tp, xfs_dabuf_t *bp, int first, 44 int last); 45static void xfs_dir2_block_log_tail(xfs_trans_t *tp, xfs_dabuf_t *bp); 46static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, 47 int *entno); 48static int xfs_dir2_block_sort(const void *a, const void *b); 49 50static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; 51 52/* 53 * One-time startup routine called from xfs_init(). 54 */ 55void 56xfs_dir_startup(void) 57{ 58 xfs_dir_hash_dot = xfs_da_hashname((unsigned char *)".", 1); 59 xfs_dir_hash_dotdot = xfs_da_hashname((unsigned char *)"..", 2); 60} 61 62/* 63 * Add an entry to a block directory. 64 */ 65int /* error */ 66xfs_dir2_block_addname( 67 xfs_da_args_t *args) /* directory op arguments */ 68{ 69 xfs_dir2_data_free_t *bf; /* bestfree table in block */ 70 xfs_dir2_block_t *block; /* directory block structure */ 71 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 72 xfs_dabuf_t *bp; /* buffer for block */ 73 xfs_dir2_block_tail_t *btp; /* block tail */ 74 int compact; /* need to compact leaf ents */ 75 xfs_dir2_data_entry_t *dep; /* block data entry */ 76 xfs_inode_t *dp; /* directory inode */ 77 xfs_dir2_data_unused_t *dup; /* block unused entry */ 78 int error; /* error return value */ 79 xfs_dir2_data_unused_t *enddup=NULL; /* unused at end of data */ 80 xfs_dahash_t hash; /* hash value of found entry */ 81 int high; /* high index for binary srch */ 82 int highstale; /* high stale index */ 83 int lfloghigh=0; /* last final leaf to log */ 84 int lfloglow=0; /* first final leaf to log */ 85 int len; /* length of the new entry */ 86 int low; /* low index for binary srch */ 87 int lowstale; /* low stale index */ 88 int mid=0; /* midpoint for binary srch */ 89 xfs_mount_t *mp; /* filesystem mount point */ 90 int needlog; /* need to log header */ 91 int needscan; /* need to rescan freespace */ 92 __be16 *tagp; /* pointer to tag value */ 93 xfs_trans_t *tp; /* transaction structure */ 94 95 trace_xfs_dir2_block_addname(args); 96 97 dp = args->dp; 98 tp = args->trans; 99 mp = dp->i_mount; 100 /* 101 * Read the (one and only) directory block into dabuf bp. 102 */ 103 if ((error = 104 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 105 return error; 106 } 107 ASSERT(bp != NULL); 108 block = bp->data; 109 /* 110 * Check the magic number, corrupted if wrong. 111 */ 112 if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) { 113 XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", 114 XFS_ERRLEVEL_LOW, mp, block); 115 xfs_da_brelse(tp, bp); 116 return XFS_ERROR(EFSCORRUPTED); 117 } 118 len = xfs_dir2_data_entsize(args->namelen); 119 /* 120 * Set up pointers to parts of the block. 121 */ 122 bf = block->hdr.bestfree; 123 btp = xfs_dir2_block_tail_p(mp, block); 124 blp = xfs_dir2_block_leaf_p(btp); 125 /* 126 * No stale entries? Need space for entry and new leaf. 127 */ 128 if (!btp->stale) { 129 /* 130 * Tag just before the first leaf entry. 131 */ 132 tagp = (__be16 *)blp - 1; 133 /* 134 * Data object just before the first leaf entry. 135 */ 136 enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); 137 /* 138 * If it's not free then can't do this add without cleaning up: 139 * the space before the first leaf entry needs to be free so it 140 * can be expanded to hold the pointer to the new entry. 141 */ 142 if (be16_to_cpu(enddup->freetag) != XFS_DIR2_DATA_FREE_TAG) 143 dup = enddup = NULL; 144 /* 145 * Check out the biggest freespace and see if it's the same one. 146 */ 147 else { 148 dup = (xfs_dir2_data_unused_t *) 149 ((char *)block + be16_to_cpu(bf[0].offset)); 150 if (dup == enddup) { 151 /* 152 * It is the biggest freespace, is it too small 153 * to hold the new leaf too? 154 */ 155 if (be16_to_cpu(dup->length) < len + (uint)sizeof(*blp)) { 156 /* 157 * Yes, we use the second-largest 158 * entry instead if it works. 159 */ 160 if (be16_to_cpu(bf[1].length) >= len) 161 dup = (xfs_dir2_data_unused_t *) 162 ((char *)block + 163 be16_to_cpu(bf[1].offset)); 164 else 165 dup = NULL; 166 } 167 } else { 168 /* 169 * Not the same free entry, 170 * just check its length. 171 */ 172 if (be16_to_cpu(dup->length) < len) { 173 dup = NULL; 174 } 175 } 176 } 177 compact = 0; 178 } 179 /* 180 * If there are stale entries we'll use one for the leaf. 181 * Is the biggest entry enough to avoid compaction? 182 */ 183 else if (be16_to_cpu(bf[0].length) >= len) { 184 dup = (xfs_dir2_data_unused_t *) 185 ((char *)block + be16_to_cpu(bf[0].offset)); 186 compact = 0; 187 } 188 /* 189 * Will need to compact to make this work. 190 */ 191 else { 192 /* 193 * Tag just before the first leaf entry. 194 */ 195 tagp = (__be16 *)blp - 1; 196 /* 197 * Data object just before the first leaf entry. 198 */ 199 dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); 200 /* 201 * If it's not free then the data will go where the 202 * leaf data starts now, if it works at all. 203 */ 204 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 205 if (be16_to_cpu(dup->length) + (be32_to_cpu(btp->stale) - 1) * 206 (uint)sizeof(*blp) < len) 207 dup = NULL; 208 } else if ((be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len) 209 dup = NULL; 210 else 211 dup = (xfs_dir2_data_unused_t *)blp; 212 compact = 1; 213 } 214 /* 215 * If this isn't a real add, we're done with the buffer. 216 */ 217 if (args->op_flags & XFS_DA_OP_JUSTCHECK) 218 xfs_da_brelse(tp, bp); 219 /* 220 * If we don't have space for the new entry & leaf ... 221 */ 222 if (!dup) { 223 /* 224 * Not trying to actually do anything, or don't have 225 * a space reservation: return no-space. 226 */ 227 if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) 228 return XFS_ERROR(ENOSPC); 229 /* 230 * Convert to the next larger format. 231 * Then add the new entry in that format. 232 */ 233 error = xfs_dir2_block_to_leaf(args, bp); 234 xfs_da_buf_done(bp); 235 if (error) 236 return error; 237 return xfs_dir2_leaf_addname(args); 238 } 239 /* 240 * Just checking, and it would work, so say so. 241 */ 242 if (args->op_flags & XFS_DA_OP_JUSTCHECK) 243 return 0; 244 needlog = needscan = 0; 245 if (compact) { 246 int fromidx; /* source leaf index */ 247 int toidx; /* target leaf index */ 248 249 for (fromidx = toidx = be32_to_cpu(btp->count) - 1, 250 highstale = lfloghigh = -1; 251 fromidx >= 0; 252 fromidx--) { 253 if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) { 254 if (highstale == -1) 255 highstale = toidx; 256 else { 257 if (lfloghigh == -1) 258 lfloghigh = toidx; 259 continue; 260 } 261 } 262 if (fromidx < toidx) 263 blp[toidx] = blp[fromidx]; 264 toidx--; 265 } 266 lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); 267 lfloghigh -= be32_to_cpu(btp->stale) - 1; 268 be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); 269 xfs_dir2_data_make_free(tp, bp, 270 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), 271 (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), 272 &needlog, &needscan); 273 blp += be32_to_cpu(btp->stale) - 1; 274 btp->stale = cpu_to_be32(1); 275 /* 276 * If we now need to rebuild the bestfree map, do so. 277 * This needs to happen before the next call to use_free. 278 */ 279 if (needscan) { 280 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 281 needscan = 0; 282 } 283 } 284 /* 285 * Set leaf logging boundaries to impossible state. 286 * For the no-stale case they're set explicitly. 287 */ 288 else if (btp->stale) { 289 lfloglow = be32_to_cpu(btp->count); 290 lfloghigh = -1; 291 } 292 /* 293 * Find the slot that's first lower than our hash value, -1 if none. 294 */ 295 for (low = 0, high = be32_to_cpu(btp->count) - 1; low <= high; ) { 296 mid = (low + high) >> 1; 297 if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval) 298 break; 299 if (hash < args->hashval) 300 low = mid + 1; 301 else 302 high = mid - 1; 303 } 304 while (mid >= 0 && be32_to_cpu(blp[mid].hashval) >= args->hashval) { 305 mid--; 306 } 307 /* 308 * No stale entries, will use enddup space to hold new leaf. 309 */ 310 if (!btp->stale) { 311 /* 312 * Mark the space needed for the new leaf entry, now in use. 313 */ 314 xfs_dir2_data_use_free(tp, bp, enddup, 315 (xfs_dir2_data_aoff_t) 316 ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) - 317 sizeof(*blp)), 318 (xfs_dir2_data_aoff_t)sizeof(*blp), 319 &needlog, &needscan); 320 /* 321 * Update the tail (entry count). 322 */ 323 be32_add_cpu(&btp->count, 1); 324 /* 325 * If we now need to rebuild the bestfree map, do so. 326 * This needs to happen before the next call to use_free. 327 */ 328 if (needscan) { 329 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, 330 &needlog); 331 needscan = 0; 332 } 333 /* 334 * Adjust pointer to the first leaf entry, we're about to move 335 * the table up one to open up space for the new leaf entry. 336 * Then adjust our index to match. 337 */ 338 blp--; 339 mid++; 340 if (mid) 341 memmove(blp, &blp[1], mid * sizeof(*blp)); 342 lfloglow = 0; 343 lfloghigh = mid; 344 } 345 /* 346 * Use a stale leaf for our new entry. 347 */ 348 else { 349 for (lowstale = mid; 350 lowstale >= 0 && 351 be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR; 352 lowstale--) 353 continue; 354 for (highstale = mid + 1; 355 highstale < be32_to_cpu(btp->count) && 356 be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR && 357 (lowstale < 0 || mid - lowstale > highstale - mid); 358 highstale++) 359 continue; 360 /* 361 * Move entries toward the low-numbered stale entry. 362 */ 363 if (lowstale >= 0 && 364 (highstale == be32_to_cpu(btp->count) || 365 mid - lowstale <= highstale - mid)) { 366 if (mid - lowstale) 367 memmove(&blp[lowstale], &blp[lowstale + 1], 368 (mid - lowstale) * sizeof(*blp)); 369 lfloglow = MIN(lowstale, lfloglow); 370 lfloghigh = MAX(mid, lfloghigh); 371 } 372 /* 373 * Move entries toward the high-numbered stale entry. 374 */ 375 else { 376 ASSERT(highstale < be32_to_cpu(btp->count)); 377 mid++; 378 if (highstale - mid) 379 memmove(&blp[mid + 1], &blp[mid], 380 (highstale - mid) * sizeof(*blp)); 381 lfloglow = MIN(mid, lfloglow); 382 lfloghigh = MAX(highstale, lfloghigh); 383 } 384 be32_add_cpu(&btp->stale, -1); 385 } 386 /* 387 * Point to the new data entry. 388 */ 389 dep = (xfs_dir2_data_entry_t *)dup; 390 /* 391 * Fill in the leaf entry. 392 */ 393 blp[mid].hashval = cpu_to_be32(args->hashval); 394 blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 395 (char *)dep - (char *)block)); 396 xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); 397 /* 398 * Mark space for the data entry used. 399 */ 400 xfs_dir2_data_use_free(tp, bp, dup, 401 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), 402 (xfs_dir2_data_aoff_t)len, &needlog, &needscan); 403 /* 404 * Create the new data entry. 405 */ 406 dep->inumber = cpu_to_be64(args->inumber); 407 dep->namelen = args->namelen; 408 memcpy(dep->name, args->name, args->namelen); 409 tagp = xfs_dir2_data_entry_tag_p(dep); 410 *tagp = cpu_to_be16((char *)dep - (char *)block); 411 /* 412 * Clean up the bestfree array and log the header, tail, and entry. 413 */ 414 if (needscan) 415 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 416 if (needlog) 417 xfs_dir2_data_log_header(tp, bp); 418 xfs_dir2_block_log_tail(tp, bp); 419 xfs_dir2_data_log_entry(tp, bp, dep); 420 xfs_dir2_data_check(dp, bp); 421 xfs_da_buf_done(bp); 422 return 0; 423} 424 425/* 426 * Readdir for block directories. 427 */ 428int /* error */ 429xfs_dir2_block_getdents( 430 xfs_inode_t *dp, /* incore inode */ 431 void *dirent, 432 xfs_off_t *offset, 433 filldir_t filldir) 434{ 435 xfs_dir2_block_t *block; /* directory block structure */ 436 xfs_dabuf_t *bp; /* buffer for block */ 437 xfs_dir2_block_tail_t *btp; /* block tail */ 438 xfs_dir2_data_entry_t *dep; /* block data entry */ 439 xfs_dir2_data_unused_t *dup; /* block unused entry */ 440 char *endptr; /* end of the data entries */ 441 int error; /* error return value */ 442 xfs_mount_t *mp; /* filesystem mount point */ 443 char *ptr; /* current data entry */ 444 int wantoff; /* starting block offset */ 445 xfs_off_t cook; 446 447 mp = dp->i_mount; 448 /* 449 * If the block number in the offset is out of range, we're done. 450 */ 451 if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) { 452 return 0; 453 } 454 /* 455 * Can't read the block, give up, else get dabuf in bp. 456 */ 457 error = xfs_da_read_buf(NULL, dp, mp->m_dirdatablk, -1, 458 &bp, XFS_DATA_FORK); 459 if (error) 460 return error; 461 462 ASSERT(bp != NULL); 463 /* 464 * Extract the byte offset we start at from the seek pointer. 465 * We'll skip entries before this. 466 */ 467 wantoff = xfs_dir2_dataptr_to_off(mp, *offset); 468 block = bp->data; 469 xfs_dir2_data_check(dp, bp); 470 /* 471 * Set up values for the loop. 472 */ 473 btp = xfs_dir2_block_tail_p(mp, block); 474 ptr = (char *)block->u; 475 endptr = (char *)xfs_dir2_block_leaf_p(btp); 476 477 /* 478 * Loop over the data portion of the block. 479 * Each object is a real entry (dep) or an unused one (dup). 480 */ 481 while (ptr < endptr) { 482 dup = (xfs_dir2_data_unused_t *)ptr; 483 /* 484 * Unused, skip it. 485 */ 486 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 487 ptr += be16_to_cpu(dup->length); 488 continue; 489 } 490 491 dep = (xfs_dir2_data_entry_t *)ptr; 492 493 /* 494 * Bump pointer for the next iteration. 495 */ 496 ptr += xfs_dir2_data_entsize(dep->namelen); 497 /* 498 * The entry is before the desired starting point, skip it. 499 */ 500 if ((char *)dep - (char *)block < wantoff) 501 continue; 502 503 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 504 (char *)dep - (char *)block); 505 506 /* 507 * If it didn't fit, set the final offset to here & return. 508 */ 509 if (filldir(dirent, (char *)dep->name, dep->namelen, 510 cook & 0x7fffffff, be64_to_cpu(dep->inumber), 511 DT_UNKNOWN)) { 512 *offset = cook & 0x7fffffff; 513 xfs_da_brelse(NULL, bp); 514 return 0; 515 } 516 } 517 518 /* 519 * Reached the end of the block. 520 * Set the offset to a non-existent block 1 and return. 521 */ 522 *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & 523 0x7fffffff; 524 xfs_da_brelse(NULL, bp); 525 return 0; 526} 527 528/* 529 * Log leaf entries from the block. 530 */ 531static void 532xfs_dir2_block_log_leaf( 533 xfs_trans_t *tp, /* transaction structure */ 534 xfs_dabuf_t *bp, /* block buffer */ 535 int first, /* index of first logged leaf */ 536 int last) /* index of last logged leaf */ 537{ 538 xfs_dir2_block_t *block; /* directory block structure */ 539 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 540 xfs_dir2_block_tail_t *btp; /* block tail */ 541 xfs_mount_t *mp; /* filesystem mount point */ 542 543 mp = tp->t_mountp; 544 block = bp->data; 545 btp = xfs_dir2_block_tail_p(mp, block); 546 blp = xfs_dir2_block_leaf_p(btp); 547 xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), 548 (uint)((char *)&blp[last + 1] - (char *)block - 1)); 549} 550 551/* 552 * Log the block tail. 553 */ 554static void 555xfs_dir2_block_log_tail( 556 xfs_trans_t *tp, /* transaction structure */ 557 xfs_dabuf_t *bp) /* block buffer */ 558{ 559 xfs_dir2_block_t *block; /* directory block structure */ 560 xfs_dir2_block_tail_t *btp; /* block tail */ 561 xfs_mount_t *mp; /* filesystem mount point */ 562 563 mp = tp->t_mountp; 564 block = bp->data; 565 btp = xfs_dir2_block_tail_p(mp, block); 566 xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), 567 (uint)((char *)(btp + 1) - (char *)block - 1)); 568} 569 570/* 571 * Look up an entry in the block. This is the external routine, 572 * xfs_dir2_block_lookup_int does the real work. 573 */ 574int /* error */ 575xfs_dir2_block_lookup( 576 xfs_da_args_t *args) /* dir lookup arguments */ 577{ 578 xfs_dir2_block_t *block; /* block structure */ 579 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 580 xfs_dabuf_t *bp; /* block buffer */ 581 xfs_dir2_block_tail_t *btp; /* block tail */ 582 xfs_dir2_data_entry_t *dep; /* block data entry */ 583 xfs_inode_t *dp; /* incore inode */ 584 int ent; /* entry index */ 585 int error; /* error return value */ 586 xfs_mount_t *mp; /* filesystem mount point */ 587 588 trace_xfs_dir2_block_lookup(args); 589 590 /* 591 * Get the buffer, look up the entry. 592 * If not found (ENOENT) then return, have no buffer. 593 */ 594 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) 595 return error; 596 dp = args->dp; 597 mp = dp->i_mount; 598 block = bp->data; 599 xfs_dir2_data_check(dp, bp); 600 btp = xfs_dir2_block_tail_p(mp, block); 601 blp = xfs_dir2_block_leaf_p(btp); 602 /* 603 * Get the offset from the leaf entry, to point to the data. 604 */ 605 dep = (xfs_dir2_data_entry_t *)((char *)block + 606 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 607 /* 608 * Fill in inode number, CI name if appropriate, release the block. 609 */ 610 args->inumber = be64_to_cpu(dep->inumber); 611 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); 612 xfs_da_brelse(args->trans, bp); 613 return XFS_ERROR(error); 614} 615 616/* 617 * Internal block lookup routine. 618 */ 619static int /* error */ 620xfs_dir2_block_lookup_int( 621 xfs_da_args_t *args, /* dir lookup arguments */ 622 xfs_dabuf_t **bpp, /* returned block buffer */ 623 int *entno) /* returned entry number */ 624{ 625 xfs_dir2_dataptr_t addr; /* data entry address */ 626 xfs_dir2_block_t *block; /* block structure */ 627 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 628 xfs_dabuf_t *bp; /* block buffer */ 629 xfs_dir2_block_tail_t *btp; /* block tail */ 630 xfs_dir2_data_entry_t *dep; /* block data entry */ 631 xfs_inode_t *dp; /* incore inode */ 632 int error; /* error return value */ 633 xfs_dahash_t hash; /* found hash value */ 634 int high; /* binary search high index */ 635 int low; /* binary search low index */ 636 int mid; /* binary search current idx */ 637 xfs_mount_t *mp; /* filesystem mount point */ 638 xfs_trans_t *tp; /* transaction pointer */ 639 enum xfs_dacmp cmp; /* comparison result */ 640 641 dp = args->dp; 642 tp = args->trans; 643 mp = dp->i_mount; 644 /* 645 * Read the buffer, return error if we can't get it. 646 */ 647 if ((error = 648 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 649 return error; 650 } 651 ASSERT(bp != NULL); 652 block = bp->data; 653 xfs_dir2_data_check(dp, bp); 654 btp = xfs_dir2_block_tail_p(mp, block); 655 blp = xfs_dir2_block_leaf_p(btp); 656 /* 657 * Loop doing a binary search for our hash value. 658 * Find our entry, ENOENT if it's not there. 659 */ 660 for (low = 0, high = be32_to_cpu(btp->count) - 1; ; ) { 661 ASSERT(low <= high); 662 mid = (low + high) >> 1; 663 if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval) 664 break; 665 if (hash < args->hashval) 666 low = mid + 1; 667 else 668 high = mid - 1; 669 if (low > high) { 670 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); 671 xfs_da_brelse(tp, bp); 672 return XFS_ERROR(ENOENT); 673 } 674 } 675 /* 676 * Back up to the first one with the right hash value. 677 */ 678 while (mid > 0 && be32_to_cpu(blp[mid - 1].hashval) == args->hashval) { 679 mid--; 680 } 681 /* 682 * Now loop forward through all the entries with the 683 * right hash value looking for our name. 684 */ 685 do { 686 if ((addr = be32_to_cpu(blp[mid].address)) == XFS_DIR2_NULL_DATAPTR) 687 continue; 688 /* 689 * Get pointer to the entry from the leaf. 690 */ 691 dep = (xfs_dir2_data_entry_t *) 692 ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); 693 /* 694 * Compare name and if it's an exact match, return the index 695 * and buffer. If it's the first case-insensitive match, store 696 * the index and buffer and continue looking for an exact match. 697 */ 698 cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); 699 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 700 args->cmpresult = cmp; 701 *bpp = bp; 702 *entno = mid; 703 if (cmp == XFS_CMP_EXACT) 704 return 0; 705 } 706 } while (++mid < be32_to_cpu(btp->count) && 707 be32_to_cpu(blp[mid].hashval) == hash); 708 709 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); 710 /* 711 * Here, we can only be doing a lookup (not a rename or replace). 712 * If a case-insensitive match was found earlier, return success. 713 */ 714 if (args->cmpresult == XFS_CMP_CASE) 715 return 0; 716 /* 717 * No match, release the buffer and return ENOENT. 718 */ 719 xfs_da_brelse(tp, bp); 720 return XFS_ERROR(ENOENT); 721} 722 723/* 724 * Remove an entry from a block format directory. 725 * If that makes the block small enough to fit in shortform, transform it. 726 */ 727int /* error */ 728xfs_dir2_block_removename( 729 xfs_da_args_t *args) /* directory operation args */ 730{ 731 xfs_dir2_block_t *block; /* block structure */ 732 xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ 733 xfs_dabuf_t *bp; /* block buffer */ 734 xfs_dir2_block_tail_t *btp; /* block tail */ 735 xfs_dir2_data_entry_t *dep; /* block data entry */ 736 xfs_inode_t *dp; /* incore inode */ 737 int ent; /* block leaf entry index */ 738 int error; /* error return value */ 739 xfs_mount_t *mp; /* filesystem mount point */ 740 int needlog; /* need to log block header */ 741 int needscan; /* need to fixup bestfree */ 742 xfs_dir2_sf_hdr_t sfh; /* shortform header */ 743 int size; /* shortform size */ 744 xfs_trans_t *tp; /* transaction pointer */ 745 746 trace_xfs_dir2_block_removename(args); 747 748 /* 749 * Look up the entry in the block. Gets the buffer and entry index. 750 * It will always be there, the vnodeops level does a lookup first. 751 */ 752 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) { 753 return error; 754 } 755 dp = args->dp; 756 tp = args->trans; 757 mp = dp->i_mount; 758 block = bp->data; 759 btp = xfs_dir2_block_tail_p(mp, block); 760 blp = xfs_dir2_block_leaf_p(btp); 761 /* 762 * Point to the data entry using the leaf entry. 763 */ 764 dep = (xfs_dir2_data_entry_t *) 765 ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 766 /* 767 * Mark the data entry's space free. 768 */ 769 needlog = needscan = 0; 770 xfs_dir2_data_make_free(tp, bp, 771 (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), 772 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); 773 /* 774 * Fix up the block tail. 775 */ 776 be32_add_cpu(&btp->stale, 1); 777 xfs_dir2_block_log_tail(tp, bp); 778 /* 779 * Remove the leaf entry by marking it stale. 780 */ 781 blp[ent].address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 782 xfs_dir2_block_log_leaf(tp, bp, ent, ent); 783 /* 784 * Fix up bestfree, log the header if necessary. 785 */ 786 if (needscan) 787 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 788 if (needlog) 789 xfs_dir2_data_log_header(tp, bp); 790 xfs_dir2_data_check(dp, bp); 791 /* 792 * See if the size as a shortform is good enough. 793 */ 794 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > 795 XFS_IFORK_DSIZE(dp)) { 796 xfs_da_buf_done(bp); 797 return 0; 798 } 799 /* 800 * If it works, do the conversion. 801 */ 802 return xfs_dir2_block_to_sf(args, bp, size, &sfh); 803} 804 805/* 806 * Replace an entry in a V2 block directory. 807 * Change the inode number to the new value. 808 */ 809int /* error */ 810xfs_dir2_block_replace( 811 xfs_da_args_t *args) /* directory operation args */ 812{ 813 xfs_dir2_block_t *block; /* block structure */ 814 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 815 xfs_dabuf_t *bp; /* block buffer */ 816 xfs_dir2_block_tail_t *btp; /* block tail */ 817 xfs_dir2_data_entry_t *dep; /* block data entry */ 818 xfs_inode_t *dp; /* incore inode */ 819 int ent; /* leaf entry index */ 820 int error; /* error return value */ 821 xfs_mount_t *mp; /* filesystem mount point */ 822 823 trace_xfs_dir2_block_replace(args); 824 825 /* 826 * Lookup the entry in the directory. Get buffer and entry index. 827 * This will always succeed since the caller has already done a lookup. 828 */ 829 if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent))) { 830 return error; 831 } 832 dp = args->dp; 833 mp = dp->i_mount; 834 block = bp->data; 835 btp = xfs_dir2_block_tail_p(mp, block); 836 blp = xfs_dir2_block_leaf_p(btp); 837 /* 838 * Point to the data entry we need to change. 839 */ 840 dep = (xfs_dir2_data_entry_t *) 841 ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 842 ASSERT(be64_to_cpu(dep->inumber) != args->inumber); 843 /* 844 * Change the inode number to the new value. 845 */ 846 dep->inumber = cpu_to_be64(args->inumber); 847 xfs_dir2_data_log_entry(args->trans, bp, dep); 848 xfs_dir2_data_check(dp, bp); 849 xfs_da_buf_done(bp); 850 return 0; 851} 852 853/* 854 * Qsort comparison routine for the block leaf entries. 855 */ 856static int /* sort order */ 857xfs_dir2_block_sort( 858 const void *a, /* first leaf entry */ 859 const void *b) /* second leaf entry */ 860{ 861 const xfs_dir2_leaf_entry_t *la; /* first leaf entry */ 862 const xfs_dir2_leaf_entry_t *lb; /* second leaf entry */ 863 864 la = a; 865 lb = b; 866 return be32_to_cpu(la->hashval) < be32_to_cpu(lb->hashval) ? -1 : 867 (be32_to_cpu(la->hashval) > be32_to_cpu(lb->hashval) ? 1 : 0); 868} 869 870/* 871 * Convert a V2 leaf directory to a V2 block directory if possible. 872 */ 873int /* error */ 874xfs_dir2_leaf_to_block( 875 xfs_da_args_t *args, /* operation arguments */ 876 xfs_dabuf_t *lbp, /* leaf buffer */ 877 xfs_dabuf_t *dbp) /* data buffer */ 878{ 879 __be16 *bestsp; /* leaf bests table */ 880 xfs_dir2_block_t *block; /* block structure */ 881 xfs_dir2_block_tail_t *btp; /* block tail */ 882 xfs_inode_t *dp; /* incore directory inode */ 883 xfs_dir2_data_unused_t *dup; /* unused data entry */ 884 int error; /* error return value */ 885 int from; /* leaf from index */ 886 xfs_dir2_leaf_t *leaf; /* leaf structure */ 887 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 888 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 889 xfs_mount_t *mp; /* file system mount point */ 890 int needlog; /* need to log data header */ 891 int needscan; /* need to scan for bestfree */ 892 xfs_dir2_sf_hdr_t sfh; /* shortform header */ 893 int size; /* bytes used */ 894 __be16 *tagp; /* end of entry (tag) */ 895 int to; /* block/leaf to index */ 896 xfs_trans_t *tp; /* transaction pointer */ 897 898 trace_xfs_dir2_leaf_to_block(args); 899 900 dp = args->dp; 901 tp = args->trans; 902 mp = dp->i_mount; 903 leaf = lbp->data; 904 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 905 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 906 /* 907 * If there are data blocks other than the first one, take this 908 * opportunity to remove trailing empty data blocks that may have 909 * been left behind during no-space-reservation operations. 910 * These will show up in the leaf bests table. 911 */ 912 while (dp->i_d.di_size > mp->m_dirblksize) { 913 bestsp = xfs_dir2_leaf_bests_p(ltp); 914 if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == 915 mp->m_dirblksize - (uint)sizeof(block->hdr)) { 916 if ((error = 917 xfs_dir2_leaf_trim_data(args, lbp, 918 (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) 919 goto out; 920 } else { 921 error = 0; 922 goto out; 923 } 924 } 925 /* 926 * Read the data block if we don't already have it, give up if it fails. 927 */ 928 if (dbp == NULL && 929 (error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp, 930 XFS_DATA_FORK))) { 931 goto out; 932 } 933 block = dbp->data; 934 ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC); 935 /* 936 * Size of the "leaf" area in the block. 937 */ 938 size = (uint)sizeof(block->tail) + 939 (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 940 /* 941 * Look at the last data entry. 942 */ 943 tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1; 944 dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); 945 /* 946 * If it's not free or is too short we can't do it. 947 */ 948 if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG || 949 be16_to_cpu(dup->length) < size) { 950 error = 0; 951 goto out; 952 } 953 /* 954 * Start converting it to block form. 955 */ 956 block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); 957 needlog = 1; 958 needscan = 0; 959 /* 960 * Use up the space at the end of the block (blp/btp). 961 */ 962 xfs_dir2_data_use_free(tp, dbp, dup, mp->m_dirblksize - size, size, 963 &needlog, &needscan); 964 /* 965 * Initialize the block tail. 966 */ 967 btp = xfs_dir2_block_tail_p(mp, block); 968 btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 969 btp->stale = 0; 970 xfs_dir2_block_log_tail(tp, dbp); 971 /* 972 * Initialize the block leaf area. We compact out stale entries. 973 */ 974 lep = xfs_dir2_block_leaf_p(btp); 975 for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { 976 if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) 977 continue; 978 lep[to++] = leaf->ents[from]; 979 } 980 ASSERT(to == be32_to_cpu(btp->count)); 981 xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); 982 /* 983 * Scan the bestfree if we need it and log the data block header. 984 */ 985 if (needscan) 986 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 987 if (needlog) 988 xfs_dir2_data_log_header(tp, dbp); 989 /* 990 * Pitch the old leaf block. 991 */ 992 error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); 993 lbp = NULL; 994 if (error) { 995 goto out; 996 } 997 /* 998 * Now see if the resulting block can be shrunken to shortform. 999 */ 1000 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > 1001 XFS_IFORK_DSIZE(dp)) { 1002 error = 0; 1003 goto out; 1004 } 1005 return xfs_dir2_block_to_sf(args, dbp, size, &sfh); 1006out: 1007 if (lbp) 1008 xfs_da_buf_done(lbp); 1009 if (dbp) 1010 xfs_da_buf_done(dbp); 1011 return error; 1012} 1013 1014/* 1015 * Convert the shortform directory to block form. 1016 */ 1017int /* error */ 1018xfs_dir2_sf_to_block( 1019 xfs_da_args_t *args) /* operation arguments */ 1020{ 1021 xfs_dir2_db_t blkno; /* dir-relative block # (0) */ 1022 xfs_dir2_block_t *block; /* block structure */ 1023 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 1024 xfs_dabuf_t *bp; /* block buffer */ 1025 xfs_dir2_block_tail_t *btp; /* block tail pointer */ 1026 char *buf; /* sf buffer */ 1027 int buf_len; 1028 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 1029 xfs_inode_t *dp; /* incore directory inode */ 1030 int dummy; /* trash */ 1031 xfs_dir2_data_unused_t *dup; /* unused entry pointer */ 1032 int endoffset; /* end of data objects */ 1033 int error; /* error return value */ 1034 int i; /* index */ 1035 xfs_mount_t *mp; /* filesystem mount point */ 1036 int needlog; /* need to log block header */ 1037 int needscan; /* need to scan block freespc */ 1038 int newoffset; /* offset from current entry */ 1039 int offset; /* target block offset */ 1040 xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ 1041 xfs_dir2_sf_t *sfp; /* shortform structure */ 1042 __be16 *tagp; /* end of data entry */ 1043 xfs_trans_t *tp; /* transaction pointer */ 1044 struct xfs_name name; 1045 1046 trace_xfs_dir2_sf_to_block(args); 1047 1048 dp = args->dp; 1049 tp = args->trans; 1050 mp = dp->i_mount; 1051 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 1052 /* 1053 * Bomb out if the shortform directory is way too short. 1054 */ 1055 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 1056 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 1057 return XFS_ERROR(EIO); 1058 } 1059 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 1060 ASSERT(dp->i_df.if_u1.if_data != NULL); 1061 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1062 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); 1063 /* 1064 * Copy the directory into the stack buffer. 1065 * Then pitch the incore inode data so we can make extents. 1066 */ 1067 1068 buf_len = dp->i_df.if_bytes; 1069 buf = kmem_alloc(buf_len, KM_SLEEP); 1070 1071 memcpy(buf, sfp, buf_len); 1072 xfs_idata_realloc(dp, -buf_len, XFS_DATA_FORK); 1073 dp->i_d.di_size = 0; 1074 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 1075 /* 1076 * Reset pointer - old sfp is gone. 1077 */ 1078 sfp = (xfs_dir2_sf_t *)buf; 1079 /* 1080 * Add block 0 to the inode. 1081 */ 1082 error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno); 1083 if (error) { 1084 kmem_free(buf); 1085 return error; 1086 } 1087 /* 1088 * Initialize the data block. 1089 */ 1090 error = xfs_dir2_data_init(args, blkno, &bp); 1091 if (error) { 1092 kmem_free(buf); 1093 return error; 1094 } 1095 block = bp->data; 1096 block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); 1097 /* 1098 * Compute size of block "tail" area. 1099 */ 1100 i = (uint)sizeof(*btp) + 1101 (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); 1102 /* 1103 * The whole thing is initialized to free by the init routine. 1104 * Say we're using the leaf and tail area. 1105 */ 1106 dup = (xfs_dir2_data_unused_t *)block->u; 1107 needlog = needscan = 0; 1108 xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog, 1109 &needscan); 1110 ASSERT(needscan == 0); 1111 /* 1112 * Fill in the tail. 1113 */ 1114 btp = xfs_dir2_block_tail_p(mp, block); 1115 btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ 1116 btp->stale = 0; 1117 blp = xfs_dir2_block_leaf_p(btp); 1118 endoffset = (uint)((char *)blp - (char *)block); 1119 /* 1120 * Remove the freespace, we'll manage it. 1121 */ 1122 xfs_dir2_data_use_free(tp, bp, dup, 1123 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), 1124 be16_to_cpu(dup->length), &needlog, &needscan); 1125 /* 1126 * Create entry for . 1127 */ 1128 dep = (xfs_dir2_data_entry_t *) 1129 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); 1130 dep->inumber = cpu_to_be64(dp->i_ino); 1131 dep->namelen = 1; 1132 dep->name[0] = '.'; 1133 tagp = xfs_dir2_data_entry_tag_p(dep); 1134 *tagp = cpu_to_be16((char *)dep - (char *)block); 1135 xfs_dir2_data_log_entry(tp, bp, dep); 1136 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); 1137 blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1138 (char *)dep - (char *)block)); 1139 /* 1140 * Create entry for .. 1141 */ 1142 dep = (xfs_dir2_data_entry_t *) 1143 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); 1144 dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); 1145 dep->namelen = 2; 1146 dep->name[0] = dep->name[1] = '.'; 1147 tagp = xfs_dir2_data_entry_tag_p(dep); 1148 *tagp = cpu_to_be16((char *)dep - (char *)block); 1149 xfs_dir2_data_log_entry(tp, bp, dep); 1150 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); 1151 blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1152 (char *)dep - (char *)block)); 1153 offset = XFS_DIR2_DATA_FIRST_OFFSET; 1154 /* 1155 * Loop over existing entries, stuff them in. 1156 */ 1157 if ((i = 0) == sfp->hdr.count) 1158 sfep = NULL; 1159 else 1160 sfep = xfs_dir2_sf_firstentry(sfp); 1161 /* 1162 * Need to preserve the existing offset values in the sf directory. 1163 * Insert holes (unused entries) where necessary. 1164 */ 1165 while (offset < endoffset) { 1166 /* 1167 * sfep is null when we reach the end of the list. 1168 */ 1169 if (sfep == NULL) 1170 newoffset = endoffset; 1171 else 1172 newoffset = xfs_dir2_sf_get_offset(sfep); 1173 /* 1174 * There should be a hole here, make one. 1175 */ 1176 if (offset < newoffset) { 1177 dup = (xfs_dir2_data_unused_t *) 1178 ((char *)block + offset); 1179 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 1180 dup->length = cpu_to_be16(newoffset - offset); 1181 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( 1182 ((char *)dup - (char *)block)); 1183 xfs_dir2_data_log_unused(tp, bp, dup); 1184 (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, 1185 dup, &dummy); 1186 offset += be16_to_cpu(dup->length); 1187 continue; 1188 } 1189 /* 1190 * Copy a real entry. 1191 */ 1192 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); 1193 dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, 1194 xfs_dir2_sf_inumberp(sfep))); 1195 dep->namelen = sfep->namelen; 1196 memcpy(dep->name, sfep->name, dep->namelen); 1197 tagp = xfs_dir2_data_entry_tag_p(dep); 1198 *tagp = cpu_to_be16((char *)dep - (char *)block); 1199 xfs_dir2_data_log_entry(tp, bp, dep); 1200 name.name = sfep->name; 1201 name.len = sfep->namelen; 1202 blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> 1203 hashname(&name)); 1204 blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1205 (char *)dep - (char *)block)); 1206 offset = (int)((char *)(tagp + 1) - (char *)block); 1207 if (++i == sfp->hdr.count) 1208 sfep = NULL; 1209 else 1210 sfep = xfs_dir2_sf_nextentry(sfp, sfep); 1211 } 1212 /* Done with the temporary buffer */ 1213 kmem_free(buf); 1214 /* 1215 * Sort the leaf entries by hash value. 1216 */ 1217 xfs_sort(blp, be32_to_cpu(btp->count), sizeof(*blp), xfs_dir2_block_sort); 1218 /* 1219 * Log the leaf entry area and tail. 1220 * Already logged the header in data_init, ignore needlog. 1221 */ 1222 ASSERT(needscan == 0); 1223 xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1); 1224 xfs_dir2_block_log_tail(tp, bp); 1225 xfs_dir2_data_check(dp, bp); 1226 xfs_da_buf_done(bp); 1227 return 0; 1228} 1229