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