aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_readdir.c')
-rw-r--r--fs/xfs/xfs_dir2_readdir.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 642d55d10075..2fbf643fa10a 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -406,6 +406,7 @@ xfs_dir2_leaf_readbuf(
406 406
407 /* 407 /*
408 * Do we need more readahead? 408 * Do we need more readahead?
409 * Each loop tries to process 1 full dir blk; last may be partial.
409 */ 410 */
410 blk_start_plug(&plug); 411 blk_start_plug(&plug);
411 for (mip->ra_index = mip->ra_offset = i = 0; 412 for (mip->ra_index = mip->ra_offset = i = 0;
@@ -416,7 +417,8 @@ xfs_dir2_leaf_readbuf(
416 * Read-ahead a contiguous directory block. 417 * Read-ahead a contiguous directory block.
417 */ 418 */
418 if (i > mip->ra_current && 419 if (i > mip->ra_current &&
419 map[mip->ra_index].br_blockcount >= geo->fsbcount) { 420 (map[mip->ra_index].br_blockcount - mip->ra_offset) >=
421 geo->fsbcount) {
420 xfs_dir3_data_readahead(dp, 422 xfs_dir3_data_readahead(dp,
421 map[mip->ra_index].br_startoff + mip->ra_offset, 423 map[mip->ra_index].br_startoff + mip->ra_offset,
422 XFS_FSB_TO_DADDR(dp->i_mount, 424 XFS_FSB_TO_DADDR(dp->i_mount,
@@ -437,14 +439,19 @@ xfs_dir2_leaf_readbuf(
437 } 439 }
438 440
439 /* 441 /*
440 * Advance offset through the mapping table. 442 * Advance offset through the mapping table, processing a full
443 * dir block even if it is fragmented into several extents.
444 * But stop if we have consumed all valid mappings, even if
445 * it's not yet a full directory block.
441 */ 446 */
442 for (j = 0; j < geo->fsbcount; j += length ) { 447 for (j = 0;
448 j < geo->fsbcount && mip->ra_index < mip->map_valid;
449 j += length ) {
443 /* 450 /*
444 * The rest of this extent but not more than a dir 451 * The rest of this extent but not more than a dir
445 * block. 452 * block.
446 */ 453 */
447 length = min_t(int, geo->fsbcount, 454 length = min_t(int, geo->fsbcount - j,
448 map[mip->ra_index].br_blockcount - 455 map[mip->ra_index].br_blockcount -
449 mip->ra_offset); 456 mip->ra_offset);
450 mip->ra_offset += length; 457 mip->ra_offset += length;