1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * Copyright (c) 2013 Red Hat, Inc. 5 * All Rights Reserved. 6 */ 7 #include "xfs.h" 8 #include "xfs_fs.h" 9 #include "xfs_shared.h" 10 #include "xfs_format.h" 11 #include "xfs_log_format.h" 12 #include "xfs_trans_resv.h" 13 #include "xfs_mount.h" 14 #include "xfs_inode.h" 15 #include "xfs_dir2.h" 16 #include "xfs_dir2_priv.h" 17 #include "xfs_trace.h" 18 #include "xfs_bmap.h" 19 #include "xfs_trans.h" 20 #include "xfs_error.h" 21 #include "xfs_health.h" 22 23 /* 24 * Directory file type support functions 25 */ 26 static unsigned char xfs_dir3_filetype_table[] = { 27 DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, 28 DT_FIFO, DT_SOCK, DT_LNK, DT_WHT, 29 }; 30 31 unsigned char 32 xfs_dir3_get_dtype( 33 struct xfs_mount *mp, 34 uint8_t filetype) 35 { 36 if (!xfs_has_ftype(mp)) 37 return DT_UNKNOWN; 38 39 if (filetype >= XFS_DIR3_FT_MAX) 40 return DT_UNKNOWN; 41 42 return xfs_dir3_filetype_table[filetype]; 43 } 44 45 STATIC int 46 xfs_dir2_sf_getdents( 47 struct xfs_da_args *args, 48 struct dir_context *ctx) 49 { 50 int i; /* shortform entry number */ 51 struct xfs_inode *dp = args->dp; /* incore directory inode */ 52 struct xfs_mount *mp = dp->i_mount; 53 xfs_dir2_dataptr_t off; /* current entry's offset */ 54 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 55 struct xfs_dir2_sf_hdr *sfp = dp->i_df.if_data; 56 xfs_dir2_dataptr_t dot_offset; 57 xfs_dir2_dataptr_t dotdot_offset; 58 xfs_ino_t ino; 59 struct xfs_da_geometry *geo = args->geo; 60 61 ASSERT(dp->i_df.if_format == XFS_DINODE_FMT_LOCAL); 62 ASSERT(dp->i_df.if_bytes == dp->i_disk_size); 63 ASSERT(sfp != NULL); 64 65 /* 66 * If the block number in the offset is out of range, we're done. 67 */ 68 if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk) 69 return 0; 70 71 /* 72 * Precalculate offsets for "." and ".." as we will always need them. 73 * This relies on the fact that directories always start with the 74 * entries for "." and "..". 75 */ 76 dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, 77 geo->data_entry_offset); 78 dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, 79 geo->data_entry_offset + 80 xfs_dir2_data_entsize(mp, sizeof(".") - 1)); 81 82 /* 83 * Put . entry unless we're starting past it. 84 */ 85 if (ctx->pos <= dot_offset) { 86 ctx->pos = dot_offset & 0x7fffffff; 87 if (!dir_emit(ctx, ".", 1, dp->i_ino, DT_DIR)) 88 return 0; 89 } 90 91 /* 92 * Put .. entry unless we're starting past it. 93 */ 94 if (ctx->pos <= dotdot_offset) { 95 ino = xfs_dir2_sf_get_parent_ino(sfp); 96 ctx->pos = dotdot_offset & 0x7fffffff; 97 if (!dir_emit(ctx, "..", 2, ino, DT_DIR)) 98 return 0; 99 } 100 101 /* 102 * Loop while there are more entries and put'ing works. 103 */ 104 sfep = xfs_dir2_sf_firstentry(sfp); 105 for (i = 0; i < sfp->count; i++) { 106 uint8_t filetype; 107 108 off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, 109 xfs_dir2_sf_get_offset(sfep)); 110 111 if (ctx->pos > off) { 112 sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 113 continue; 114 } 115 116 ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); 117 filetype = xfs_dir2_sf_get_ftype(mp, sfep); 118 ctx->pos = off & 0x7fffffff; 119 if (XFS_IS_CORRUPT(dp->i_mount, 120 !xfs_dir2_namecheck(sfep->name, 121 sfep->namelen))) { 122 xfs_dirattr_mark_sick(dp, XFS_DATA_FORK); 123 return -EFSCORRUPTED; 124 } 125 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, 126 xfs_dir3_get_dtype(mp, filetype))) 127 return 0; 128 sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 129 } 130 131 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & 132 0x7fffffff; 133 return 0; 134 } 135 136 /* 137 * Readdir for block directories. 138 */ 139 STATIC int 140 xfs_dir2_block_getdents( 141 struct xfs_da_args *args, 142 struct dir_context *ctx, 143 unsigned int *lock_mode) 144 { 145 struct xfs_inode *dp = args->dp; /* incore directory inode */ 146 struct xfs_buf *bp; /* buffer for block */ 147 int error; /* error return value */ 148 int wantoff; /* starting block offset */ 149 xfs_off_t cook; 150 struct xfs_da_geometry *geo = args->geo; 151 unsigned int offset, next_offset; 152 unsigned int end; 153 154 /* 155 * If the block number in the offset is out of range, we're done. 156 */ 157 if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk) 158 return 0; 159 160 error = xfs_dir3_block_read(args->trans, dp, &bp); 161 if (error) 162 return error; 163 164 xfs_iunlock(dp, *lock_mode); 165 *lock_mode = 0; 166 167 /* 168 * Extract the byte offset we start at from the seek pointer. 169 * We'll skip entries before this. 170 */ 171 wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos); 172 xfs_dir3_data_check(dp, bp); 173 174 /* 175 * Loop over the data portion of the block. 176 * Each object is a real entry (dep) or an unused one (dup). 177 */ 178 end = xfs_dir3_data_end_offset(geo, bp->b_addr); 179 for (offset = geo->data_entry_offset; 180 offset < end; 181 offset = next_offset) { 182 struct xfs_dir2_data_unused *dup = bp->b_addr + offset; 183 struct xfs_dir2_data_entry *dep = bp->b_addr + offset; 184 uint8_t filetype; 185 186 /* 187 * Unused, skip it. 188 */ 189 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 190 next_offset = offset + be16_to_cpu(dup->length); 191 continue; 192 } 193 194 /* 195 * Bump pointer for the next iteration. 196 */ 197 next_offset = offset + 198 xfs_dir2_data_entsize(dp->i_mount, dep->namelen); 199 200 /* 201 * The entry is before the desired starting point, skip it. 202 */ 203 if (offset < wantoff) 204 continue; 205 206 cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset); 207 208 ctx->pos = cook & 0x7fffffff; 209 filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); 210 /* 211 * If it didn't fit, set the final offset to here & return. 212 */ 213 if (XFS_IS_CORRUPT(dp->i_mount, 214 !xfs_dir2_namecheck(dep->name, 215 dep->namelen))) { 216 xfs_dirattr_mark_sick(dp, XFS_DATA_FORK); 217 error = -EFSCORRUPTED; 218 goto out_rele; 219 } 220 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 221 be64_to_cpu(dep->inumber), 222 xfs_dir3_get_dtype(dp->i_mount, filetype))) 223 goto out_rele; 224 } 225 226 /* 227 * Reached the end of the block. 228 * Set the offset to a non-existent block 1 and return. 229 */ 230 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & 231 0x7fffffff; 232 out_rele: 233 xfs_trans_brelse(args->trans, bp); 234 return error; 235 } 236 237 /* 238 * Read a directory block and initiate readahead for blocks beyond that. 239 * We maintain a sliding readahead window of the remaining space in the 240 * buffer rounded up to the nearest block. 241 */ 242 STATIC int 243 xfs_dir2_leaf_readbuf( 244 struct xfs_da_args *args, 245 size_t bufsize, 246 xfs_dir2_off_t *cur_off, 247 xfs_dablk_t *ra_blk, 248 struct xfs_buf **bpp) 249 { 250 struct xfs_inode *dp = args->dp; 251 struct xfs_buf *bp = NULL; 252 struct xfs_da_geometry *geo = args->geo; 253 struct xfs_ifork *ifp = xfs_ifork_ptr(dp, XFS_DATA_FORK); 254 struct xfs_bmbt_irec map; 255 struct blk_plug plug; 256 xfs_dir2_off_t new_off; 257 xfs_dablk_t next_ra; 258 xfs_dablk_t map_off; 259 xfs_dablk_t last_da; 260 struct xfs_iext_cursor icur; 261 int ra_want; 262 int error = 0; 263 264 error = xfs_iread_extents(args->trans, dp, XFS_DATA_FORK); 265 if (error) 266 goto out; 267 268 /* 269 * Look for mapped directory blocks at or above the current offset. 270 * Truncate down to the nearest directory block to start the scanning 271 * operation. 272 */ 273 last_da = xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET); 274 map_off = xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, *cur_off)); 275 if (!xfs_iext_lookup_extent(dp, ifp, map_off, &icur, &map)) 276 goto out; 277 if (map.br_startoff >= last_da) 278 goto out; 279 xfs_trim_extent(&map, map_off, last_da - map_off); 280 281 /* Read the directory block of that first mapping. */ 282 new_off = xfs_dir2_da_to_byte(geo, map.br_startoff); 283 if (new_off > *cur_off) 284 *cur_off = new_off; 285 error = xfs_dir3_data_read(args->trans, dp, map.br_startoff, 0, &bp); 286 if (error) 287 goto out; 288 289 /* 290 * Start readahead for the next bufsize's worth of dir data blocks. 291 * We may have already issued readahead for some of that range; 292 * ra_blk tracks the last block we tried to read(ahead). 293 */ 294 ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)); 295 if (*ra_blk >= last_da) 296 goto out; 297 else if (*ra_blk == 0) 298 *ra_blk = map.br_startoff; 299 next_ra = map.br_startoff + geo->fsbcount; 300 if (next_ra >= last_da) 301 goto out_no_ra; 302 if (map.br_blockcount < geo->fsbcount && 303 !xfs_iext_next_extent(ifp, &icur, &map)) 304 goto out_no_ra; 305 if (map.br_startoff >= last_da) 306 goto out_no_ra; 307 xfs_trim_extent(&map, next_ra, last_da - next_ra); 308 309 /* Start ra for each dir (not fs) block that has a mapping. */ 310 blk_start_plug(&plug); 311 while (ra_want > 0) { 312 next_ra = roundup((xfs_dablk_t)map.br_startoff, geo->fsbcount); 313 while (ra_want > 0 && 314 next_ra < map.br_startoff + map.br_blockcount) { 315 if (next_ra >= last_da) { 316 *ra_blk = last_da; 317 break; 318 } 319 if (next_ra > *ra_blk) { 320 xfs_dir3_data_readahead(dp, next_ra, 321 XFS_DABUF_MAP_HOLE_OK); 322 *ra_blk = next_ra; 323 } 324 ra_want -= geo->fsbcount; 325 next_ra += geo->fsbcount; 326 } 327 if (!xfs_iext_next_extent(ifp, &icur, &map)) { 328 *ra_blk = last_da; 329 break; 330 } 331 } 332 blk_finish_plug(&plug); 333 334 out: 335 *bpp = bp; 336 return error; 337 out_no_ra: 338 *ra_blk = last_da; 339 goto out; 340 } 341 342 /* 343 * Getdents (readdir) for leaf and node directories. 344 * This reads the data blocks only, so is the same for both forms. 345 */ 346 STATIC int 347 xfs_dir2_leaf_getdents( 348 struct xfs_da_args *args, 349 struct dir_context *ctx, 350 size_t bufsize, 351 unsigned int *lock_mode) 352 { 353 struct xfs_inode *dp = args->dp; 354 struct xfs_mount *mp = dp->i_mount; 355 struct xfs_buf *bp = NULL; /* data block buffer */ 356 xfs_dir2_data_entry_t *dep; /* data entry */ 357 xfs_dir2_data_unused_t *dup; /* unused entry */ 358 struct xfs_da_geometry *geo = args->geo; 359 xfs_dablk_t rablk = 0; /* current readahead block */ 360 xfs_dir2_off_t curoff; /* current overall offset */ 361 int length; /* temporary length value */ 362 int byteoff; /* offset in current block */ 363 unsigned int offset = 0; 364 int error = 0; /* error return value */ 365 366 /* 367 * If the offset is at or past the largest allowed value, 368 * give up right away. 369 */ 370 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR) 371 return 0; 372 373 /* 374 * Inside the loop we keep the main offset value as a byte offset 375 * in the directory file. 376 */ 377 curoff = xfs_dir2_dataptr_to_byte(ctx->pos); 378 379 /* 380 * Loop over directory entries until we reach the end offset. 381 * Get more blocks and readahead as necessary. 382 */ 383 while (curoff < XFS_DIR2_LEAF_OFFSET) { 384 uint8_t filetype; 385 386 /* 387 * If we have no buffer, or we're off the end of the 388 * current buffer, need to get another one. 389 */ 390 if (!bp || offset >= geo->blksize) { 391 if (bp) { 392 xfs_trans_brelse(args->trans, bp); 393 bp = NULL; 394 } 395 396 if (*lock_mode == 0) 397 *lock_mode = xfs_ilock_data_map_shared(dp); 398 error = xfs_dir2_leaf_readbuf(args, bufsize, &curoff, 399 &rablk, &bp); 400 if (error || !bp) 401 break; 402 403 xfs_iunlock(dp, *lock_mode); 404 *lock_mode = 0; 405 406 xfs_dir3_data_check(dp, bp); 407 /* 408 * Find our position in the block. 409 */ 410 offset = geo->data_entry_offset; 411 byteoff = xfs_dir2_byte_to_off(geo, curoff); 412 /* 413 * Skip past the header. 414 */ 415 if (byteoff == 0) 416 curoff += geo->data_entry_offset; 417 /* 418 * Skip past entries until we reach our offset. 419 */ 420 else { 421 while (offset < byteoff) { 422 dup = bp->b_addr + offset; 423 424 if (be16_to_cpu(dup->freetag) 425 == XFS_DIR2_DATA_FREE_TAG) { 426 427 length = be16_to_cpu(dup->length); 428 offset += length; 429 continue; 430 } 431 dep = bp->b_addr + offset; 432 length = xfs_dir2_data_entsize(mp, 433 dep->namelen); 434 offset += length; 435 } 436 /* 437 * Now set our real offset. 438 */ 439 curoff = 440 xfs_dir2_db_off_to_byte(geo, 441 xfs_dir2_byte_to_db(geo, curoff), 442 offset); 443 if (offset >= geo->blksize) 444 continue; 445 } 446 } 447 448 /* 449 * We have a pointer to an entry. Is it a live one? 450 */ 451 dup = bp->b_addr + offset; 452 453 /* 454 * No, it's unused, skip over it. 455 */ 456 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 457 length = be16_to_cpu(dup->length); 458 offset += length; 459 curoff += length; 460 continue; 461 } 462 463 dep = bp->b_addr + offset; 464 length = xfs_dir2_data_entsize(mp, dep->namelen); 465 filetype = xfs_dir2_data_get_ftype(mp, dep); 466 467 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; 468 if (XFS_IS_CORRUPT(dp->i_mount, 469 !xfs_dir2_namecheck(dep->name, 470 dep->namelen))) { 471 xfs_dirattr_mark_sick(dp, XFS_DATA_FORK); 472 error = -EFSCORRUPTED; 473 break; 474 } 475 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 476 be64_to_cpu(dep->inumber), 477 xfs_dir3_get_dtype(dp->i_mount, filetype))) 478 break; 479 480 /* 481 * Advance to next entry in the block. 482 */ 483 offset += length; 484 curoff += length; 485 /* bufsize may have just been a guess; don't go negative */ 486 bufsize = bufsize > length ? bufsize - length : 0; 487 } 488 489 /* 490 * All done. Set output offset value to current offset. 491 */ 492 if (curoff > xfs_dir2_dataptr_to_byte(XFS_DIR2_MAX_DATAPTR)) 493 ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff; 494 else 495 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; 496 if (bp) 497 xfs_trans_brelse(args->trans, bp); 498 return error; 499 } 500 501 /* 502 * Read a directory. 503 * 504 * If supplied, the transaction collects locked dir buffers to avoid 505 * nested buffer deadlocks. This function does not dirty the 506 * transaction. The caller must hold the IOLOCK (shared or exclusive) 507 * before calling this function. 508 */ 509 int 510 xfs_readdir( 511 struct xfs_trans *tp, 512 struct xfs_inode *dp, 513 struct dir_context *ctx, 514 size_t bufsize) 515 { 516 struct xfs_da_args args = { NULL }; 517 unsigned int lock_mode; 518 bool isblock; 519 int error; 520 521 trace_xfs_readdir(dp); 522 523 if (xfs_is_shutdown(dp->i_mount)) 524 return -EIO; 525 if (xfs_ifork_zapped(dp, XFS_DATA_FORK)) 526 return -EIO; 527 528 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 529 xfs_assert_ilocked(dp, XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL); 530 XFS_STATS_INC(dp->i_mount, xs_dir_getdents); 531 532 args.dp = dp; 533 args.geo = dp->i_mount->m_dir_geo; 534 args.trans = tp; 535 536 if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) 537 return xfs_dir2_sf_getdents(&args, ctx); 538 539 lock_mode = xfs_ilock_data_map_shared(dp); 540 error = xfs_dir2_isblock(&args, &isblock); 541 if (error) 542 goto out_unlock; 543 544 if (isblock) { 545 error = xfs_dir2_block_getdents(&args, ctx, &lock_mode); 546 goto out_unlock; 547 } 548 549 error = xfs_dir2_leaf_getdents(&args, ctx, bufsize, &lock_mode); 550 551 out_unlock: 552 if (lock_mode) 553 xfs_iunlock(dp, lock_mode); 554 return error; 555 } 556