1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_log_format.h" 11 #include "xfs_trans_resv.h" 12 #include "xfs_mount.h" 13 #include "xfs_inode.h" 14 #include "xfs_trans.h" 15 #include "xfs_bmap.h" 16 #include "xfs_dir2.h" 17 #include "xfs_dir2_priv.h" 18 #include "xfs_errortag.h" 19 #include "xfs_error.h" 20 #include "xfs_trace.h" 21 #include "xfs_health.h" 22 23 const struct xfs_name xfs_name_dotdot = { 24 .name = (const unsigned char *)"..", 25 .len = 2, 26 .type = XFS_DIR3_FT_DIR, 27 }; 28 29 const struct xfs_name xfs_name_dot = { 30 .name = (const unsigned char *)".", 31 .len = 1, 32 .type = XFS_DIR3_FT_DIR, 33 }; 34 35 /* 36 * Convert inode mode to directory entry filetype 37 */ 38 unsigned char 39 xfs_mode_to_ftype( 40 int mode) 41 { 42 switch (mode & S_IFMT) { 43 case S_IFREG: 44 return XFS_DIR3_FT_REG_FILE; 45 case S_IFDIR: 46 return XFS_DIR3_FT_DIR; 47 case S_IFCHR: 48 return XFS_DIR3_FT_CHRDEV; 49 case S_IFBLK: 50 return XFS_DIR3_FT_BLKDEV; 51 case S_IFIFO: 52 return XFS_DIR3_FT_FIFO; 53 case S_IFSOCK: 54 return XFS_DIR3_FT_SOCK; 55 case S_IFLNK: 56 return XFS_DIR3_FT_SYMLINK; 57 default: 58 return XFS_DIR3_FT_UNKNOWN; 59 } 60 } 61 62 /* 63 * ASCII case-insensitive (ie. A-Z) support for directories that was 64 * used in IRIX. 65 */ 66 xfs_dahash_t 67 xfs_ascii_ci_hashname( 68 const struct xfs_name *name) 69 { 70 xfs_dahash_t hash; 71 int i; 72 73 for (i = 0, hash = 0; i < name->len; i++) 74 hash = xfs_ascii_ci_xfrm(name->name[i]) ^ rol32(hash, 7); 75 76 return hash; 77 } 78 79 enum xfs_dacmp 80 xfs_ascii_ci_compname( 81 struct xfs_da_args *args, 82 const unsigned char *name, 83 int len) 84 { 85 enum xfs_dacmp result; 86 int i; 87 88 if (args->namelen != len) 89 return XFS_CMP_DIFFERENT; 90 91 result = XFS_CMP_EXACT; 92 for (i = 0; i < len; i++) { 93 if (args->name[i] == name[i]) 94 continue; 95 if (xfs_ascii_ci_xfrm(args->name[i]) != 96 xfs_ascii_ci_xfrm(name[i])) 97 return XFS_CMP_DIFFERENT; 98 result = XFS_CMP_CASE; 99 } 100 101 return result; 102 } 103 104 int 105 xfs_da_mount( 106 struct xfs_mount *mp) 107 { 108 struct xfs_da_geometry *dageo; 109 110 111 ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT); 112 ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE); 113 114 mp->m_dir_geo = kzalloc(sizeof(struct xfs_da_geometry), 115 GFP_KERNEL | __GFP_RETRY_MAYFAIL); 116 mp->m_attr_geo = kzalloc(sizeof(struct xfs_da_geometry), 117 GFP_KERNEL | __GFP_RETRY_MAYFAIL); 118 if (!mp->m_dir_geo || !mp->m_attr_geo) { 119 kfree(mp->m_dir_geo); 120 kfree(mp->m_attr_geo); 121 return -ENOMEM; 122 } 123 124 /* set up directory geometry */ 125 dageo = mp->m_dir_geo; 126 dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog; 127 dageo->fsblog = mp->m_sb.sb_blocklog; 128 dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb); 129 dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog; 130 if (xfs_has_crc(mp)) { 131 dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr); 132 dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr); 133 dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr); 134 dageo->data_entry_offset = 135 sizeof(struct xfs_dir3_data_hdr); 136 } else { 137 dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr); 138 dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr); 139 dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr); 140 dageo->data_entry_offset = 141 sizeof(struct xfs_dir2_data_hdr); 142 } 143 dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) / 144 sizeof(struct xfs_dir2_leaf_entry); 145 dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) / 146 sizeof(xfs_dir2_data_off_t); 147 148 dageo->data_first_offset = dageo->data_entry_offset + 149 xfs_dir2_data_entsize(mp, 1) + 150 xfs_dir2_data_entsize(mp, 2); 151 152 /* 153 * Now we've set up the block conversion variables, we can calculate the 154 * segment block constants using the geometry structure. 155 */ 156 dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET); 157 dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET); 158 dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET); 159 dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) / 160 (uint)sizeof(xfs_da_node_entry_t); 161 dageo->max_extents = (XFS_DIR2_MAX_SPACES * XFS_DIR2_SPACE_SIZE) >> 162 mp->m_sb.sb_blocklog; 163 dageo->magicpct = (dageo->blksize * 37) / 100; 164 165 /* set up attribute geometry - single fsb only */ 166 dageo = mp->m_attr_geo; 167 dageo->blklog = mp->m_sb.sb_blocklog; 168 dageo->fsblog = mp->m_sb.sb_blocklog; 169 dageo->blksize = 1 << dageo->blklog; 170 dageo->fsbcount = 1; 171 dageo->node_hdr_size = mp->m_dir_geo->node_hdr_size; 172 dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) / 173 (uint)sizeof(xfs_da_node_entry_t); 174 175 if (xfs_has_large_extent_counts(mp)) 176 dageo->max_extents = XFS_MAX_EXTCNT_ATTR_FORK_LARGE; 177 else 178 dageo->max_extents = XFS_MAX_EXTCNT_ATTR_FORK_SMALL; 179 180 dageo->magicpct = (dageo->blksize * 37) / 100; 181 return 0; 182 } 183 184 void 185 xfs_da_unmount( 186 struct xfs_mount *mp) 187 { 188 kfree(mp->m_dir_geo); 189 kfree(mp->m_attr_geo); 190 } 191 192 /* 193 * Return 1 if directory contains only "." and "..". 194 */ 195 int 196 xfs_dir_isempty( 197 xfs_inode_t *dp) 198 { 199 xfs_dir2_sf_hdr_t *sfp; 200 201 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 202 if (dp->i_disk_size == 0) /* might happen during shutdown. */ 203 return 1; 204 if (dp->i_disk_size > xfs_inode_data_fork_size(dp)) 205 return 0; 206 sfp = dp->i_df.if_data; 207 return !sfp->count; 208 } 209 210 /* 211 * Validate a given inode number. 212 */ 213 int 214 xfs_dir_ino_validate( 215 xfs_mount_t *mp, 216 xfs_ino_t ino) 217 { 218 bool ino_ok = xfs_verify_dir_ino(mp, ino); 219 220 if (XFS_IS_CORRUPT(mp, !ino_ok) || 221 XFS_TEST_ERROR(false, mp, XFS_ERRTAG_DIR_INO_VALIDATE)) { 222 xfs_warn(mp, "Invalid inode number 0x%Lx", 223 (unsigned long long) ino); 224 return -EFSCORRUPTED; 225 } 226 return 0; 227 } 228 229 /* 230 * Initialize a directory with its "." and ".." entries. 231 */ 232 int 233 xfs_dir_init( 234 xfs_trans_t *tp, 235 xfs_inode_t *dp, 236 xfs_inode_t *pdp) 237 { 238 struct xfs_da_args *args; 239 int error; 240 241 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 242 error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino); 243 if (error) 244 return error; 245 246 args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); 247 if (!args) 248 return -ENOMEM; 249 250 args->geo = dp->i_mount->m_dir_geo; 251 args->dp = dp; 252 args->trans = tp; 253 args->owner = dp->i_ino; 254 error = xfs_dir2_sf_create(args, pdp->i_ino); 255 kfree(args); 256 return error; 257 } 258 259 enum xfs_dir2_fmt 260 xfs_dir2_format( 261 struct xfs_da_args *args, 262 int *error) 263 { 264 struct xfs_inode *dp = args->dp; 265 struct xfs_mount *mp = dp->i_mount; 266 struct xfs_da_geometry *geo = mp->m_dir_geo; 267 xfs_fileoff_t eof; 268 269 xfs_assert_ilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL); 270 271 *error = 0; 272 if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) 273 return XFS_DIR2_FMT_SF; 274 275 *error = xfs_bmap_last_offset(dp, &eof, XFS_DATA_FORK); 276 if (*error) 277 return XFS_DIR2_FMT_ERROR; 278 279 if (eof == XFS_B_TO_FSB(mp, geo->blksize)) { 280 if (XFS_IS_CORRUPT(mp, dp->i_disk_size != geo->blksize)) { 281 xfs_da_mark_sick(args); 282 *error = -EFSCORRUPTED; 283 return XFS_DIR2_FMT_ERROR; 284 } 285 return XFS_DIR2_FMT_BLOCK; 286 } 287 if (eof == geo->leafblk + geo->fsbcount) 288 return XFS_DIR2_FMT_LEAF; 289 return XFS_DIR2_FMT_NODE; 290 } 291 292 int 293 xfs_dir_createname_args( 294 struct xfs_da_args *args) 295 { 296 int error; 297 298 if (!args->inumber) 299 args->op_flags |= XFS_DA_OP_JUSTCHECK; 300 301 switch (xfs_dir2_format(args, &error)) { 302 case XFS_DIR2_FMT_SF: 303 return xfs_dir2_sf_addname(args); 304 case XFS_DIR2_FMT_BLOCK: 305 return xfs_dir2_block_addname(args); 306 case XFS_DIR2_FMT_LEAF: 307 return xfs_dir2_leaf_addname(args); 308 case XFS_DIR2_FMT_NODE: 309 return xfs_dir2_node_addname(args); 310 default: 311 return error; 312 } 313 } 314 315 /* 316 * Enter a name in a directory, or check for available space. 317 * If inum is 0, only the available space test is performed. 318 */ 319 int 320 xfs_dir_createname( 321 struct xfs_trans *tp, 322 struct xfs_inode *dp, 323 const struct xfs_name *name, 324 xfs_ino_t inum, /* new entry inode number */ 325 xfs_extlen_t total) /* bmap's total block count */ 326 { 327 struct xfs_da_args *args; 328 int rval; 329 330 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 331 332 if (inum) { 333 rval = xfs_dir_ino_validate(tp->t_mountp, inum); 334 if (rval) 335 return rval; 336 XFS_STATS_INC(dp->i_mount, xs_dir_create); 337 } 338 339 args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); 340 if (!args) 341 return -ENOMEM; 342 343 args->geo = dp->i_mount->m_dir_geo; 344 args->name = name->name; 345 args->namelen = name->len; 346 args->filetype = name->type; 347 args->hashval = xfs_dir2_hashname(dp->i_mount, name); 348 args->inumber = inum; 349 args->dp = dp; 350 args->total = total; 351 args->whichfork = XFS_DATA_FORK; 352 args->trans = tp; 353 args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; 354 args->owner = dp->i_ino; 355 356 rval = xfs_dir_createname_args(args); 357 kfree(args); 358 return rval; 359 } 360 361 /* 362 * If doing a CI lookup and case-insensitive match, dup actual name into 363 * args.value. Return EEXIST for success (ie. name found) or an error. 364 */ 365 int 366 xfs_dir_cilookup_result( 367 struct xfs_da_args *args, 368 const unsigned char *name, 369 int len) 370 { 371 if (args->cmpresult == XFS_CMP_DIFFERENT) 372 return -ENOENT; 373 if (args->cmpresult != XFS_CMP_CASE || 374 !(args->op_flags & XFS_DA_OP_CILOOKUP)) 375 return -EEXIST; 376 377 args->value = kmalloc(len, 378 GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_RETRY_MAYFAIL); 379 if (!args->value) 380 return -ENOMEM; 381 382 memcpy(args->value, name, len); 383 args->valuelen = len; 384 return -EEXIST; 385 } 386 387 int 388 xfs_dir_lookup_args( 389 struct xfs_da_args *args) 390 { 391 int error; 392 393 switch (xfs_dir2_format(args, &error)) { 394 case XFS_DIR2_FMT_SF: 395 error = xfs_dir2_sf_lookup(args); 396 break; 397 case XFS_DIR2_FMT_BLOCK: 398 error = xfs_dir2_block_lookup(args); 399 break; 400 case XFS_DIR2_FMT_LEAF: 401 error = xfs_dir2_leaf_lookup(args); 402 break; 403 case XFS_DIR2_FMT_NODE: 404 error = xfs_dir2_node_lookup(args); 405 break; 406 default: 407 break; 408 } 409 410 if (error != -EEXIST) 411 return error; 412 return 0; 413 } 414 415 /* 416 * Lookup a name in a directory, give back the inode number. 417 * If ci_name is not NULL, returns the actual name in ci_name if it differs 418 * to name, or ci_name->name is set to NULL for an exact match. 419 */ 420 421 int 422 xfs_dir_lookup( 423 struct xfs_trans *tp, 424 struct xfs_inode *dp, 425 const struct xfs_name *name, 426 xfs_ino_t *inum, /* out: inode number */ 427 struct xfs_name *ci_name) /* out: actual name if CI match */ 428 { 429 struct xfs_da_args *args; 430 int rval; 431 int lock_mode; 432 433 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 434 XFS_STATS_INC(dp->i_mount, xs_dir_lookup); 435 436 args = kzalloc(sizeof(*args), 437 GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); 438 args->geo = dp->i_mount->m_dir_geo; 439 args->name = name->name; 440 args->namelen = name->len; 441 args->filetype = name->type; 442 args->hashval = xfs_dir2_hashname(dp->i_mount, name); 443 args->dp = dp; 444 args->whichfork = XFS_DATA_FORK; 445 args->trans = tp; 446 args->op_flags = XFS_DA_OP_OKNOENT; 447 args->owner = dp->i_ino; 448 if (ci_name) 449 args->op_flags |= XFS_DA_OP_CILOOKUP; 450 451 lock_mode = xfs_ilock_data_map_shared(dp); 452 rval = xfs_dir_lookup_args(args); 453 if (!rval) { 454 *inum = args->inumber; 455 if (ci_name) { 456 ci_name->name = args->value; 457 ci_name->len = args->valuelen; 458 } 459 } 460 xfs_iunlock(dp, lock_mode); 461 kfree(args); 462 return rval; 463 } 464 465 int 466 xfs_dir_removename_args( 467 struct xfs_da_args *args) 468 { 469 int error; 470 471 switch (xfs_dir2_format(args, &error)) { 472 case XFS_DIR2_FMT_SF: 473 return xfs_dir2_sf_removename(args); 474 case XFS_DIR2_FMT_BLOCK: 475 return xfs_dir2_block_removename(args); 476 case XFS_DIR2_FMT_LEAF: 477 return xfs_dir2_leaf_removename(args); 478 case XFS_DIR2_FMT_NODE: 479 return xfs_dir2_node_removename(args); 480 default: 481 return error; 482 } 483 } 484 485 /* 486 * Remove an entry from a directory. 487 */ 488 int 489 xfs_dir_removename( 490 struct xfs_trans *tp, 491 struct xfs_inode *dp, 492 const struct xfs_name *name, 493 xfs_ino_t ino, 494 xfs_extlen_t total) /* bmap's total block count */ 495 { 496 struct xfs_da_args *args; 497 int rval; 498 499 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 500 XFS_STATS_INC(dp->i_mount, xs_dir_remove); 501 502 args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); 503 if (!args) 504 return -ENOMEM; 505 506 args->geo = dp->i_mount->m_dir_geo; 507 args->name = name->name; 508 args->namelen = name->len; 509 args->filetype = name->type; 510 args->hashval = xfs_dir2_hashname(dp->i_mount, name); 511 args->inumber = ino; 512 args->dp = dp; 513 args->total = total; 514 args->whichfork = XFS_DATA_FORK; 515 args->trans = tp; 516 args->owner = dp->i_ino; 517 rval = xfs_dir_removename_args(args); 518 kfree(args); 519 return rval; 520 } 521 522 int 523 xfs_dir_replace_args( 524 struct xfs_da_args *args) 525 { 526 int error; 527 528 switch (xfs_dir2_format(args, &error)) { 529 case XFS_DIR2_FMT_SF: 530 return xfs_dir2_sf_replace(args); 531 case XFS_DIR2_FMT_BLOCK: 532 return xfs_dir2_block_replace(args); 533 case XFS_DIR2_FMT_LEAF: 534 return xfs_dir2_leaf_replace(args); 535 case XFS_DIR2_FMT_NODE: 536 return xfs_dir2_node_replace(args); 537 default: 538 return error; 539 } 540 } 541 542 /* 543 * Replace the inode number of a directory entry. 544 */ 545 int 546 xfs_dir_replace( 547 struct xfs_trans *tp, 548 struct xfs_inode *dp, 549 const struct xfs_name *name, /* name of entry to replace */ 550 xfs_ino_t inum, /* new inode number */ 551 xfs_extlen_t total) /* bmap's total block count */ 552 { 553 struct xfs_da_args *args; 554 int rval; 555 556 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 557 558 rval = xfs_dir_ino_validate(tp->t_mountp, inum); 559 if (rval) 560 return rval; 561 562 args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); 563 if (!args) 564 return -ENOMEM; 565 566 args->geo = dp->i_mount->m_dir_geo; 567 args->name = name->name; 568 args->namelen = name->len; 569 args->filetype = name->type; 570 args->hashval = xfs_dir2_hashname(dp->i_mount, name); 571 args->inumber = inum; 572 args->dp = dp; 573 args->total = total; 574 args->whichfork = XFS_DATA_FORK; 575 args->trans = tp; 576 args->owner = dp->i_ino; 577 rval = xfs_dir_replace_args(args); 578 kfree(args); 579 return rval; 580 } 581 582 /* 583 * See if this entry can be added to the directory without allocating space. 584 */ 585 int 586 xfs_dir_canenter( 587 xfs_trans_t *tp, 588 xfs_inode_t *dp, 589 struct xfs_name *name) /* name of entry to add */ 590 { 591 return xfs_dir_createname(tp, dp, name, 0, 0); 592 } 593 594 /* 595 * Utility routines. 596 */ 597 598 /* 599 * Add a block to the directory. 600 * 601 * This routine is for data and free blocks, not leaf/node blocks which are 602 * handled by xfs_da_grow_inode. 603 */ 604 int 605 xfs_dir2_grow_inode( 606 struct xfs_da_args *args, 607 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ 608 xfs_dir2_db_t *dbp) /* out: block number added */ 609 { 610 struct xfs_inode *dp = args->dp; 611 struct xfs_mount *mp = dp->i_mount; 612 xfs_fileoff_t bno; /* directory offset of new block */ 613 int count; /* count of filesystem blocks */ 614 int error; 615 616 trace_xfs_dir2_grow_inode(args, space); 617 618 /* 619 * Set lowest possible block in the space requested. 620 */ 621 bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE); 622 count = args->geo->fsbcount; 623 624 error = xfs_da_grow_inode_int(args, &bno, count); 625 if (error) 626 return error; 627 628 *dbp = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)bno); 629 630 /* 631 * Update file's size if this is the data space and it grew. 632 */ 633 if (space == XFS_DIR2_DATA_SPACE) { 634 xfs_fsize_t size; /* directory file (data) size */ 635 636 size = XFS_FSB_TO_B(mp, bno + count); 637 if (size > dp->i_disk_size) { 638 dp->i_disk_size = size; 639 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); 640 } 641 } 642 return 0; 643 } 644 645 /* 646 * Remove the given block from the directory. 647 * This routine is used for data and free blocks, leaf/node are done 648 * by xfs_da_shrink_inode. 649 */ 650 int 651 xfs_dir2_shrink_inode( 652 struct xfs_da_args *args, 653 xfs_dir2_db_t db, 654 struct xfs_buf *bp) 655 { 656 xfs_fileoff_t bno; /* directory file offset */ 657 xfs_dablk_t da; /* directory file offset */ 658 int done; /* bunmap is finished */ 659 struct xfs_inode *dp; 660 int error; 661 struct xfs_mount *mp; 662 struct xfs_trans *tp; 663 664 trace_xfs_dir2_shrink_inode(args, db); 665 666 dp = args->dp; 667 mp = dp->i_mount; 668 tp = args->trans; 669 da = xfs_dir2_db_to_da(args->geo, db); 670 671 /* Unmap the fsblock(s). */ 672 error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, &done); 673 if (error) { 674 /* 675 * ENOSPC actually can happen if we're in a removename with no 676 * space reservation, and the resulting block removal would 677 * cause a bmap btree split or conversion from extents to btree. 678 * This can only happen for un-fragmented directory blocks, 679 * since you need to be punching out the middle of an extent. 680 * In this case we need to leave the block in the file, and not 681 * binval it. So the block has to be in a consistent empty 682 * state and appropriately logged. We don't free up the buffer, 683 * the caller can tell it hasn't happened since it got an error 684 * back. 685 */ 686 return error; 687 } 688 ASSERT(done); 689 /* 690 * Invalidate the buffer from the transaction. 691 */ 692 xfs_trans_binval(tp, bp); 693 /* 694 * If it's not a data block, we're done. 695 */ 696 if (db >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET)) 697 return 0; 698 /* 699 * If the block isn't the last one in the directory, we're done. 700 */ 701 if (dp->i_disk_size > xfs_dir2_db_off_to_byte(args->geo, db + 1, 0)) 702 return 0; 703 bno = da; 704 if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) { 705 /* 706 * This can't really happen unless there's kernel corruption. 707 */ 708 return error; 709 } 710 if (db == args->geo->datablk) 711 ASSERT(bno == 0); 712 else 713 ASSERT(bno > 0); 714 /* 715 * Set the size to the new last block. 716 */ 717 dp->i_disk_size = XFS_FSB_TO_B(mp, bno); 718 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 719 return 0; 720 } 721 722 /* Returns true if the directory entry name is valid. */ 723 bool 724 xfs_dir2_namecheck( 725 const void *name, 726 size_t length) 727 { 728 /* 729 * MAXNAMELEN includes the trailing null, but (name/length) leave it 730 * out, so use >= for the length check. 731 */ 732 if (length >= MAXNAMELEN) 733 return false; 734 735 /* There shouldn't be any slashes or nulls here */ 736 return !memchr(name, '/', length) && !memchr(name, 0, length); 737 } 738 739 xfs_dahash_t 740 xfs_dir2_hashname( 741 struct xfs_mount *mp, 742 const struct xfs_name *name) 743 { 744 if (unlikely(xfs_has_asciici(mp))) 745 return xfs_ascii_ci_hashname(name); 746 return xfs_da_hashname(name->name, name->len); 747 } 748 749 enum xfs_dacmp 750 xfs_dir2_compname( 751 struct xfs_da_args *args, 752 const unsigned char *name, 753 int len) 754 { 755 if (unlikely(xfs_has_asciici(args->dp->i_mount))) 756 return xfs_ascii_ci_compname(args, name, len); 757 return xfs_da_compname(args, name, len); 758 } 759