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 return -EFSCORRUPTED; 123 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, 124 xfs_dir3_get_dtype(mp, filetype))) 125 return 0; 126 sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 127 } 128 129 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & 130 0x7fffffff; 131 return 0; 132 } 133 134 /* 135 * Readdir for block directories. 136 */ 137 STATIC int 138 xfs_dir2_block_getdents( 139 struct xfs_da_args *args, 140 struct dir_context *ctx, 141 unsigned int *lock_mode) 142 { 143 struct xfs_inode *dp = args->dp; /* incore directory inode */ 144 struct xfs_buf *bp; /* buffer for block */ 145 int error; /* error return value */ 146 int wantoff; /* starting block offset */ 147 xfs_off_t cook; 148 struct xfs_da_geometry *geo = args->geo; 149 unsigned int offset, next_offset; 150 unsigned int end; 151 152 /* 153 * If the block number in the offset is out of range, we're done. 154 */ 155 if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk) 156 return 0; 157 158 error = xfs_dir3_block_read(args->trans, dp, &bp); 159 if (error) 160 return error; 161 162 xfs_iunlock(dp, *lock_mode); 163 *lock_mode = 0; 164 165 /* 166 * Extract the byte offset we start at from the seek pointer. 167 * We'll skip entries before this. 168 */ 169 wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos); 170 xfs_dir3_data_check(dp, bp); 171 172 /* 173 * Loop over the data portion of the block. 174 * Each object is a real entry (dep) or an unused one (dup). 175 */ 176 end = xfs_dir3_data_end_offset(geo, bp->b_addr); 177 for (offset = geo->data_entry_offset; 178 offset < end; 179 offset = next_offset) { 180 struct xfs_dir2_data_unused *dup = bp->b_addr + offset; 181 struct xfs_dir2_data_entry *dep = bp->b_addr + offset; 182 uint8_t filetype; 183 184 /* 185 * Unused, skip it. 186 */ 187 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 188 next_offset = offset + be16_to_cpu(dup->length); 189 continue; 190 } 191 192 /* 193 * Bump pointer for the next iteration. 194 */ 195 next_offset = offset + 196 xfs_dir2_data_entsize(dp->i_mount, dep->namelen); 197 198 /* 199 * The entry is before the desired starting point, skip it. 200 */ 201 if (offset < wantoff) 202 continue; 203 204 cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset); 205 206 ctx->pos = cook & 0x7fffffff; 207 filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); 208 /* 209 * If it didn't fit, set the final offset to here & return. 210 */ 211 if (XFS_IS_CORRUPT(dp->i_mount, 212 !xfs_dir2_namecheck(dep->name, 213 dep->namelen))) { 214 error = -EFSCORRUPTED; 215 goto out_rele; 216 } 217 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 218 be64_to_cpu(dep->inumber), 219 xfs_dir3_get_dtype(dp->i_mount, filetype))) 220 goto out_rele; 221 } 222 223 /* 224 * Reached the end of the block. 225 * Set the offset to a non-existent block 1 and return. 226 */ 227 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & 228 0x7fffffff; 229 out_rele: 230 xfs_trans_brelse(args->trans, bp); 231 return error; 232 } 233 234 /* 235 * Read a directory block and initiate readahead for blocks beyond that. 236 * We maintain a sliding readahead window of the remaining space in the 237 * buffer rounded up to the nearest block. 238 */ 239 STATIC int 240 xfs_dir2_leaf_readbuf( 241 struct xfs_da_args *args, 242 size_t bufsize, 243 xfs_dir2_off_t *cur_off, 244 xfs_dablk_t *ra_blk, 245 struct xfs_buf **bpp) 246 { 247 struct xfs_inode *dp = args->dp; 248 struct xfs_buf *bp = NULL; 249 struct xfs_da_geometry *geo = args->geo; 250 struct xfs_ifork *ifp = xfs_ifork_ptr(dp, XFS_DATA_FORK); 251 struct xfs_bmbt_irec map; 252 struct blk_plug plug; 253 xfs_dir2_off_t new_off; 254 xfs_dablk_t next_ra; 255 xfs_dablk_t map_off; 256 xfs_dablk_t last_da; 257 struct xfs_iext_cursor icur; 258 int ra_want; 259 int error = 0; 260 261 error = xfs_iread_extents(args->trans, dp, XFS_DATA_FORK); 262 if (error) 263 goto out; 264 265 /* 266 * Look for mapped directory blocks at or above the current offset. 267 * Truncate down to the nearest directory block to start the scanning 268 * operation. 269 */ 270 last_da = xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET); 271 map_off = xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, *cur_off)); 272 if (!xfs_iext_lookup_extent(dp, ifp, map_off, &icur, &map)) 273 goto out; 274 if (map.br_startoff >= last_da) 275 goto out; 276 xfs_trim_extent(&map, map_off, last_da - map_off); 277 278 /* Read the directory block of that first mapping. */ 279 new_off = xfs_dir2_da_to_byte(geo, map.br_startoff); 280 if (new_off > *cur_off) 281 *cur_off = new_off; 282 error = xfs_dir3_data_read(args->trans, dp, map.br_startoff, 0, &bp); 283 if (error) 284 goto out; 285 286 /* 287 * Start readahead for the next bufsize's worth of dir data blocks. 288 * We may have already issued readahead for some of that range; 289 * ra_blk tracks the last block we tried to read(ahead). 290 */ 291 ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)); 292 if (*ra_blk >= last_da) 293 goto out; 294 else if (*ra_blk == 0) 295 *ra_blk = map.br_startoff; 296 next_ra = map.br_startoff + geo->fsbcount; 297 if (next_ra >= last_da) 298 goto out_no_ra; 299 if (map.br_blockcount < geo->fsbcount && 300 !xfs_iext_next_extent(ifp, &icur, &map)) 301 goto out_no_ra; 302 if (map.br_startoff >= last_da) 303 goto out_no_ra; 304 xfs_trim_extent(&map, next_ra, last_da - next_ra); 305 306 /* Start ra for each dir (not fs) block that has a mapping. */ 307 blk_start_plug(&plug); 308 while (ra_want > 0) { 309 next_ra = roundup((xfs_dablk_t)map.br_startoff, geo->fsbcount); 310 while (ra_want > 0 && 311 next_ra < map.br_startoff + map.br_blockcount) { 312 if (next_ra >= last_da) { 313 *ra_blk = last_da; 314 break; 315 } 316 if (next_ra > *ra_blk) { 317 xfs_dir3_data_readahead(dp, next_ra, 318 XFS_DABUF_MAP_HOLE_OK); 319 *ra_blk = next_ra; 320 } 321 ra_want -= geo->fsbcount; 322 next_ra += geo->fsbcount; 323 } 324 if (!xfs_iext_next_extent(ifp, &icur, &map)) { 325 *ra_blk = last_da; 326 break; 327 } 328 } 329 blk_finish_plug(&plug); 330 331 out: 332 *bpp = bp; 333 return error; 334 out_no_ra: 335 *ra_blk = last_da; 336 goto out; 337 } 338 339 /* 340 * Getdents (readdir) for leaf and node directories. 341 * This reads the data blocks only, so is the same for both forms. 342 */ 343 STATIC int 344 xfs_dir2_leaf_getdents( 345 struct xfs_da_args *args, 346 struct dir_context *ctx, 347 size_t bufsize, 348 unsigned int *lock_mode) 349 { 350 struct xfs_inode *dp = args->dp; 351 struct xfs_mount *mp = dp->i_mount; 352 struct xfs_buf *bp = NULL; /* data block buffer */ 353 xfs_dir2_data_entry_t *dep; /* data entry */ 354 xfs_dir2_data_unused_t *dup; /* unused entry */ 355 struct xfs_da_geometry *geo = args->geo; 356 xfs_dablk_t rablk = 0; /* current readahead block */ 357 xfs_dir2_off_t curoff; /* current overall offset */ 358 int length; /* temporary length value */ 359 int byteoff; /* offset in current block */ 360 unsigned int offset = 0; 361 int error = 0; /* error return value */ 362 363 /* 364 * If the offset is at or past the largest allowed value, 365 * give up right away. 366 */ 367 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR) 368 return 0; 369 370 /* 371 * Inside the loop we keep the main offset value as a byte offset 372 * in the directory file. 373 */ 374 curoff = xfs_dir2_dataptr_to_byte(ctx->pos); 375 376 /* 377 * Loop over directory entries until we reach the end offset. 378 * Get more blocks and readahead as necessary. 379 */ 380 while (curoff < XFS_DIR2_LEAF_OFFSET) { 381 uint8_t filetype; 382 383 /* 384 * If we have no buffer, or we're off the end of the 385 * current buffer, need to get another one. 386 */ 387 if (!bp || offset >= geo->blksize) { 388 if (bp) { 389 xfs_trans_brelse(args->trans, bp); 390 bp = NULL; 391 } 392 393 if (*lock_mode == 0) 394 *lock_mode = xfs_ilock_data_map_shared(dp); 395 error = xfs_dir2_leaf_readbuf(args, bufsize, &curoff, 396 &rablk, &bp); 397 if (error || !bp) 398 break; 399 400 xfs_iunlock(dp, *lock_mode); 401 *lock_mode = 0; 402 403 xfs_dir3_data_check(dp, bp); 404 /* 405 * Find our position in the block. 406 */ 407 offset = geo->data_entry_offset; 408 byteoff = xfs_dir2_byte_to_off(geo, curoff); 409 /* 410 * Skip past the header. 411 */ 412 if (byteoff == 0) 413 curoff += geo->data_entry_offset; 414 /* 415 * Skip past entries until we reach our offset. 416 */ 417 else { 418 while (offset < byteoff) { 419 dup = bp->b_addr + offset; 420 421 if (be16_to_cpu(dup->freetag) 422 == XFS_DIR2_DATA_FREE_TAG) { 423 424 length = be16_to_cpu(dup->length); 425 offset += length; 426 continue; 427 } 428 dep = bp->b_addr + offset; 429 length = xfs_dir2_data_entsize(mp, 430 dep->namelen); 431 offset += length; 432 } 433 /* 434 * Now set our real offset. 435 */ 436 curoff = 437 xfs_dir2_db_off_to_byte(geo, 438 xfs_dir2_byte_to_db(geo, curoff), 439 offset); 440 if (offset >= geo->blksize) 441 continue; 442 } 443 } 444 445 /* 446 * We have a pointer to an entry. Is it a live one? 447 */ 448 dup = bp->b_addr + offset; 449 450 /* 451 * No, it's unused, skip over it. 452 */ 453 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 454 length = be16_to_cpu(dup->length); 455 offset += length; 456 curoff += length; 457 continue; 458 } 459 460 dep = bp->b_addr + offset; 461 length = xfs_dir2_data_entsize(mp, dep->namelen); 462 filetype = xfs_dir2_data_get_ftype(mp, dep); 463 464 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; 465 if (XFS_IS_CORRUPT(dp->i_mount, 466 !xfs_dir2_namecheck(dep->name, 467 dep->namelen))) { 468 error = -EFSCORRUPTED; 469 break; 470 } 471 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 472 be64_to_cpu(dep->inumber), 473 xfs_dir3_get_dtype(dp->i_mount, filetype))) 474 break; 475 476 /* 477 * Advance to next entry in the block. 478 */ 479 offset += length; 480 curoff += length; 481 /* bufsize may have just been a guess; don't go negative */ 482 bufsize = bufsize > length ? bufsize - length : 0; 483 } 484 485 /* 486 * All done. Set output offset value to current offset. 487 */ 488 if (curoff > xfs_dir2_dataptr_to_byte(XFS_DIR2_MAX_DATAPTR)) 489 ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff; 490 else 491 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; 492 if (bp) 493 xfs_trans_brelse(args->trans, bp); 494 return error; 495 } 496 497 /* 498 * Read a directory. 499 * 500 * If supplied, the transaction collects locked dir buffers to avoid 501 * nested buffer deadlocks. This function does not dirty the 502 * transaction. The caller must hold the IOLOCK (shared or exclusive) 503 * before calling this function. 504 */ 505 int 506 xfs_readdir( 507 struct xfs_trans *tp, 508 struct xfs_inode *dp, 509 struct dir_context *ctx, 510 size_t bufsize) 511 { 512 struct xfs_da_args args = { NULL }; 513 unsigned int lock_mode; 514 bool isblock; 515 int error; 516 517 trace_xfs_readdir(dp); 518 519 if (xfs_is_shutdown(dp->i_mount)) 520 return -EIO; 521 if (xfs_ifork_zapped(dp, XFS_DATA_FORK)) 522 return -EIO; 523 524 ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); 525 ASSERT(xfs_isilocked(dp, XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); 526 XFS_STATS_INC(dp->i_mount, xs_dir_getdents); 527 528 args.dp = dp; 529 args.geo = dp->i_mount->m_dir_geo; 530 args.trans = tp; 531 532 if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) 533 return xfs_dir2_sf_getdents(&args, ctx); 534 535 lock_mode = xfs_ilock_data_map_shared(dp); 536 error = xfs_dir2_isblock(&args, &isblock); 537 if (error) 538 goto out_unlock; 539 540 if (isblock) { 541 error = xfs_dir2_block_getdents(&args, ctx, &lock_mode); 542 goto out_unlock; 543 } 544 545 error = xfs_dir2_leaf_getdents(&args, ctx, bufsize, &lock_mode); 546 547 out_unlock: 548 if (lock_mode) 549 xfs_iunlock(dp, lock_mode); 550 return error; 551 } 552