aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_dir2.c50
-rw-r--r--fs/xfs/xfs_dir2.h4
-rw-r--r--fs/xfs/xfs_dir2_readdir.c85
3 files changed, 65 insertions, 74 deletions
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 97f1802a9018..07aa3907d237 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -282,7 +282,7 @@ xfs_dir_createname(
282 goto out_free; 282 goto out_free;
283 } 283 }
284 284
285 rval = xfs_dir2_isblock(dp, &v); 285 rval = xfs_dir2_isblock(args, &v);
286 if (rval) 286 if (rval)
287 goto out_free; 287 goto out_free;
288 if (v) { 288 if (v) {
@@ -290,7 +290,7 @@ xfs_dir_createname(
290 goto out_free; 290 goto out_free;
291 } 291 }
292 292
293 rval = xfs_dir2_isleaf(dp, &v); 293 rval = xfs_dir2_isleaf(args, &v);
294 if (rval) 294 if (rval)
295 goto out_free; 295 goto out_free;
296 if (v) 296 if (v)
@@ -375,7 +375,7 @@ xfs_dir_lookup(
375 goto out_check_rval; 375 goto out_check_rval;
376 } 376 }
377 377
378 rval = xfs_dir2_isblock(dp, &v); 378 rval = xfs_dir2_isblock(args, &v);
379 if (rval) 379 if (rval)
380 goto out_free; 380 goto out_free;
381 if (v) { 381 if (v) {
@@ -383,7 +383,7 @@ xfs_dir_lookup(
383 goto out_check_rval; 383 goto out_check_rval;
384 } 384 }
385 385
386 rval = xfs_dir2_isleaf(dp, &v); 386 rval = xfs_dir2_isleaf(args, &v);
387 if (rval) 387 if (rval)
388 goto out_free; 388 goto out_free;
389 if (v) 389 if (v)
@@ -448,7 +448,7 @@ xfs_dir_removename(
448 goto out_free; 448 goto out_free;
449 } 449 }
450 450
451 rval = xfs_dir2_isblock(dp, &v); 451 rval = xfs_dir2_isblock(args, &v);
452 if (rval) 452 if (rval)
453 goto out_free; 453 goto out_free;
454 if (v) { 454 if (v) {
@@ -456,7 +456,7 @@ xfs_dir_removename(
456 goto out_free; 456 goto out_free;
457 } 457 }
458 458
459 rval = xfs_dir2_isleaf(dp, &v); 459 rval = xfs_dir2_isleaf(args, &v);
460 if (rval) 460 if (rval)
461 goto out_free; 461 goto out_free;
462 if (v) 462 if (v)
@@ -513,7 +513,7 @@ xfs_dir_replace(
513 goto out_free; 513 goto out_free;
514 } 514 }
515 515
516 rval = xfs_dir2_isblock(dp, &v); 516 rval = xfs_dir2_isblock(args, &v);
517 if (rval) 517 if (rval)
518 goto out_free; 518 goto out_free;
519 if (v) { 519 if (v) {
@@ -521,7 +521,7 @@ xfs_dir_replace(
521 goto out_free; 521 goto out_free;
522 } 522 }
523 523
524 rval = xfs_dir2_isleaf(dp, &v); 524 rval = xfs_dir2_isleaf(args, &v);
525 if (rval) 525 if (rval)
526 goto out_free; 526 goto out_free;
527 if (v) 527 if (v)
@@ -573,7 +573,7 @@ xfs_dir_canenter(
573 goto out_free; 573 goto out_free;
574 } 574 }
575 575
576 rval = xfs_dir2_isblock(dp, &v); 576 rval = xfs_dir2_isblock(args, &v);
577 if (rval) 577 if (rval)
578 goto out_free; 578 goto out_free;
579 if (v) { 579 if (v) {
@@ -581,7 +581,7 @@ xfs_dir_canenter(
581 goto out_free; 581 goto out_free;
582 } 582 }
583 583
584 rval = xfs_dir2_isleaf(dp, &v); 584 rval = xfs_dir2_isleaf(args, &v);
585 if (rval) 585 if (rval)
586 goto out_free; 586 goto out_free;
587 if (v) 587 if (v)
@@ -649,18 +649,16 @@ xfs_dir2_grow_inode(
649 */ 649 */
650int 650int
651xfs_dir2_isblock( 651xfs_dir2_isblock(
652 xfs_inode_t *dp, 652 struct xfs_da_args *args,
653 int *vp) /* out: 1 is block, 0 is not block */ 653 int *vp) /* out: 1 is block, 0 is not block */
654{ 654{
655 xfs_fileoff_t last; /* last file offset */ 655 xfs_fileoff_t last; /* last file offset */
656 xfs_mount_t *mp; 656 int rval;
657 int rval;
658 657
659 mp = dp->i_mount; 658 if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
660 if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
661 return rval; 659 return rval;
662 rval = XFS_FSB_TO_B(mp, last) == mp->m_dir_geo->blksize; 660 rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
663 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dir_geo->blksize); 661 ASSERT(rval == 0 || args->dp->i_d.di_size == args->geo->blksize);
664 *vp = rval; 662 *vp = rval;
665 return 0; 663 return 0;
666} 664}
@@ -670,17 +668,15 @@ xfs_dir2_isblock(
670 */ 668 */
671int 669int
672xfs_dir2_isleaf( 670xfs_dir2_isleaf(
673 xfs_inode_t *dp, 671 struct xfs_da_args *args,
674 int *vp) /* out: 1 is leaf, 0 is not leaf */ 672 int *vp) /* out: 1 is block, 0 is not block */
675{ 673{
676 xfs_fileoff_t last; /* last file offset */ 674 xfs_fileoff_t last; /* last file offset */
677 xfs_mount_t *mp; 675 int rval;
678 int rval;
679 676
680 mp = dp->i_mount; 677 if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
681 if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
682 return rval; 678 return rval;
683 *vp = last == mp->m_dir_geo->leafblk + (1 << mp->m_sb.sb_dirblklog); 679 *vp = last == args->geo->leafblk + args->geo->fsbcount;
684 return 0; 680 return 0;
685} 681}
686 682
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 9b709ae3ba1e..1292e780e5b7 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -146,8 +146,8 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
146/* 146/*
147 * Interface routines used by userspace utilities 147 * Interface routines used by userspace utilities
148 */ 148 */
149extern int xfs_dir2_isblock(struct xfs_inode *dp, int *r); 149extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r);
150extern int xfs_dir2_isleaf(struct xfs_inode *dp, int *r); 150extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
151extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, 151extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
152 struct xfs_buf *bp); 152 struct xfs_buf *bp);
153 153
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index fa393d5c2a14..ca1f43cd3939 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -76,28 +76,25 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
76 76
77STATIC int 77STATIC int
78xfs_dir2_sf_getdents( 78xfs_dir2_sf_getdents(
79 xfs_inode_t *dp, /* incore directory inode */ 79 struct xfs_da_args *args,
80 struct dir_context *ctx) 80 struct dir_context *ctx)
81{ 81{
82 int i; /* shortform entry number */ 82 int i; /* shortform entry number */
83 xfs_mount_t *mp; /* filesystem mount point */ 83 struct xfs_inode *dp = args->dp; /* incore directory inode */
84 xfs_dir2_dataptr_t off; /* current entry's offset */ 84 xfs_dir2_dataptr_t off; /* current entry's offset */
85 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 85 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
86 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ 86 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
87 xfs_dir2_dataptr_t dot_offset; 87 xfs_dir2_dataptr_t dot_offset;
88 xfs_dir2_dataptr_t dotdot_offset; 88 xfs_dir2_dataptr_t dotdot_offset;
89 xfs_ino_t ino; 89 xfs_ino_t ino;
90 struct xfs_da_geometry *geo; 90 struct xfs_da_geometry *geo = args->geo;
91
92 mp = dp->i_mount;
93 geo = mp->m_dir_geo;
94 91
95 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 92 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
96 /* 93 /*
97 * Give up if the directory is way too short. 94 * Give up if the directory is way too short.
98 */ 95 */
99 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 96 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
100 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 97 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
101 return XFS_ERROR(EIO); 98 return XFS_ERROR(EIO);
102 } 99 }
103 100
@@ -163,13 +160,13 @@ xfs_dir2_sf_getdents(
163 filetype = dp->d_ops->sf_get_ftype(sfep); 160 filetype = dp->d_ops->sf_get_ftype(sfep);
164 ctx->pos = off & 0x7fffffff; 161 ctx->pos = off & 0x7fffffff;
165 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, 162 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
166 xfs_dir3_get_dtype(mp, filetype))) 163 xfs_dir3_get_dtype(dp->i_mount, filetype)))
167 return 0; 164 return 0;
168 sfep = dp->d_ops->sf_nextentry(sfp, sfep); 165 sfep = dp->d_ops->sf_nextentry(sfp, sfep);
169 } 166 }
170 167
171 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & 168 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
172 0x7fffffff; 169 0x7fffffff;
173 return 0; 170 return 0;
174} 171}
175 172
@@ -178,9 +175,10 @@ xfs_dir2_sf_getdents(
178 */ 175 */
179STATIC int 176STATIC int
180xfs_dir2_block_getdents( 177xfs_dir2_block_getdents(
181 xfs_inode_t *dp, /* incore inode */ 178 struct xfs_da_args *args,
182 struct dir_context *ctx) 179 struct dir_context *ctx)
183{ 180{
181 struct xfs_inode *dp = args->dp; /* incore directory inode */
184 xfs_dir2_data_hdr_t *hdr; /* block header */ 182 xfs_dir2_data_hdr_t *hdr; /* block header */
185 struct xfs_buf *bp; /* buffer for block */ 183 struct xfs_buf *bp; /* buffer for block */
186 xfs_dir2_block_tail_t *btp; /* block tail */ 184 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -188,14 +186,11 @@ xfs_dir2_block_getdents(
188 xfs_dir2_data_unused_t *dup; /* block unused entry */ 186 xfs_dir2_data_unused_t *dup; /* block unused entry */
189 char *endptr; /* end of the data entries */ 187 char *endptr; /* end of the data entries */
190 int error; /* error return value */ 188 int error; /* error return value */
191 xfs_mount_t *mp; /* filesystem mount point */
192 char *ptr; /* current data entry */ 189 char *ptr; /* current data entry */
193 int wantoff; /* starting block offset */ 190 int wantoff; /* starting block offset */
194 xfs_off_t cook; 191 xfs_off_t cook;
195 struct xfs_da_geometry *geo; 192 struct xfs_da_geometry *geo = args->geo;
196 193
197 mp = dp->i_mount;
198 geo = mp->m_dir_geo;
199 /* 194 /*
200 * If the block number in the offset is out of range, we're done. 195 * If the block number in the offset is out of range, we're done.
201 */ 196 */
@@ -258,7 +253,7 @@ xfs_dir2_block_getdents(
258 */ 253 */
259 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 254 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
260 be64_to_cpu(dep->inumber), 255 be64_to_cpu(dep->inumber),
261 xfs_dir3_get_dtype(mp, filetype))) { 256 xfs_dir3_get_dtype(dp->i_mount, filetype))) {
262 xfs_trans_brelse(NULL, bp); 257 xfs_trans_brelse(NULL, bp);
263 return 0; 258 return 0;
264 } 259 }
@@ -269,7 +264,7 @@ xfs_dir2_block_getdents(
269 * Set the offset to a non-existent block 1 and return. 264 * Set the offset to a non-existent block 1 and return.
270 */ 265 */
271 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & 266 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
272 0x7fffffff; 267 0x7fffffff;
273 xfs_trans_brelse(NULL, bp); 268 xfs_trans_brelse(NULL, bp);
274 return 0; 269 return 0;
275} 270}
@@ -290,13 +285,13 @@ struct xfs_dir2_leaf_map_info {
290 285
291STATIC int 286STATIC int
292xfs_dir2_leaf_readbuf( 287xfs_dir2_leaf_readbuf(
293 struct xfs_inode *dp, 288 struct xfs_da_args *args,
294 size_t bufsize, 289 size_t bufsize,
295 struct xfs_dir2_leaf_map_info *mip, 290 struct xfs_dir2_leaf_map_info *mip,
296 xfs_dir2_off_t *curoff, 291 xfs_dir2_off_t *curoff,
297 struct xfs_buf **bpp) 292 struct xfs_buf **bpp)
298{ 293{
299 struct xfs_mount *mp = dp->i_mount; 294 struct xfs_inode *dp = args->dp;
300 struct xfs_buf *bp = *bpp; 295 struct xfs_buf *bp = *bpp;
301 struct xfs_bmbt_irec *map = mip->map; 296 struct xfs_bmbt_irec *map = mip->map;
302 struct blk_plug plug; 297 struct blk_plug plug;
@@ -304,7 +299,7 @@ xfs_dir2_leaf_readbuf(
304 int length; 299 int length;
305 int i; 300 int i;
306 int j; 301 int j;
307 struct xfs_da_geometry *geo = mp->m_dir_geo; 302 struct xfs_da_geometry *geo = args->geo;
308 303
309 /* 304 /*
310 * If we have a buffer, we need to release it and 305 * If we have a buffer, we need to release it and
@@ -338,8 +333,7 @@ xfs_dir2_leaf_readbuf(
338 /* 333 /*
339 * Recalculate the readahead blocks wanted. 334 * Recalculate the readahead blocks wanted.
340 */ 335 */
341 mip->ra_want = howmany(bufsize + geo->blksize, 336 mip->ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)) - 1;
342 mp->m_sb.sb_blocksize) - 1;
343 ASSERT(mip->ra_want >= 0); 337 ASSERT(mip->ra_want >= 0);
344 338
345 /* 339 /*
@@ -411,8 +405,8 @@ xfs_dir2_leaf_readbuf(
411 mip->curdb = xfs_dir2_da_to_db(geo, map->br_startoff); 405 mip->curdb = xfs_dir2_da_to_db(geo, map->br_startoff);
412 error = xfs_dir3_data_read(NULL, dp, map->br_startoff, 406 error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
413 map->br_blockcount >= geo->fsbcount ? 407 map->br_blockcount >= geo->fsbcount ?
414 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp); 408 XFS_FSB_TO_DADDR(dp->i_mount, map->br_startblock) :
415 409 -1, &bp);
416 /* 410 /*
417 * Should just skip over the data block instead of giving up. 411 * Should just skip over the data block instead of giving up.
418 */ 412 */
@@ -441,7 +435,7 @@ xfs_dir2_leaf_readbuf(
441 map[mip->ra_index].br_blockcount >= geo->fsbcount) { 435 map[mip->ra_index].br_blockcount >= geo->fsbcount) {
442 xfs_dir3_data_readahead(dp, 436 xfs_dir3_data_readahead(dp,
443 map[mip->ra_index].br_startoff + mip->ra_offset, 437 map[mip->ra_index].br_startoff + mip->ra_offset,
444 XFS_FSB_TO_DADDR(mp, 438 XFS_FSB_TO_DADDR(dp->i_mount,
445 map[mip->ra_index].br_startblock + 439 map[mip->ra_index].br_startblock +
446 mip->ra_offset)); 440 mip->ra_offset));
447 mip->ra_current = i; 441 mip->ra_current = i;
@@ -493,23 +487,23 @@ out:
493 */ 487 */
494STATIC int 488STATIC int
495xfs_dir2_leaf_getdents( 489xfs_dir2_leaf_getdents(
496 xfs_inode_t *dp, /* incore directory inode */ 490 struct xfs_da_args *args,
497 struct dir_context *ctx, 491 struct dir_context *ctx,
498 size_t bufsize) 492 size_t bufsize)
499{ 493{
494 struct xfs_inode *dp = args->dp;
500 struct xfs_buf *bp = NULL; /* data block buffer */ 495 struct xfs_buf *bp = NULL; /* data block buffer */
501 xfs_dir2_data_hdr_t *hdr; /* data block header */ 496 xfs_dir2_data_hdr_t *hdr; /* data block header */
502 xfs_dir2_data_entry_t *dep; /* data entry */ 497 xfs_dir2_data_entry_t *dep; /* data entry */
503 xfs_dir2_data_unused_t *dup; /* unused entry */ 498 xfs_dir2_data_unused_t *dup; /* unused entry */
504 int error = 0; /* error return value */ 499 int error = 0; /* error return value */
505 int length; /* temporary length value */ 500 int length; /* temporary length value */
506 xfs_mount_t *mp; /* filesystem mount point */
507 int byteoff; /* offset in current block */ 501 int byteoff; /* offset in current block */
508 xfs_dir2_off_t curoff; /* current overall offset */ 502 xfs_dir2_off_t curoff; /* current overall offset */
509 xfs_dir2_off_t newoff; /* new curoff after new blk */ 503 xfs_dir2_off_t newoff; /* new curoff after new blk */
510 char *ptr = NULL; /* pointer to current data */ 504 char *ptr = NULL; /* pointer to current data */
511 struct xfs_dir2_leaf_map_info *map_info; 505 struct xfs_dir2_leaf_map_info *map_info;
512 struct xfs_da_geometry *geo; 506 struct xfs_da_geometry *geo = args->geo;
513 507
514 /* 508 /*
515 * If the offset is at or past the largest allowed value, 509 * If the offset is at or past the largest allowed value,
@@ -518,15 +512,12 @@ xfs_dir2_leaf_getdents(
518 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR) 512 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
519 return 0; 513 return 0;
520 514
521 mp = dp->i_mount;
522 geo = mp->m_dir_geo;
523
524 /* 515 /*
525 * Set up to bmap a number of blocks based on the caller's 516 * Set up to bmap a number of blocks based on the caller's
526 * buffer size, the directory block size, and the filesystem 517 * buffer size, the directory block size, and the filesystem
527 * block size. 518 * block size.
528 */ 519 */
529 length = howmany(bufsize + geo->blksize, mp->m_sb.sb_blocksize); 520 length = howmany(bufsize + geo->blksize, (1 << geo->fsblog));
530 map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) + 521 map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
531 (length * sizeof(struct xfs_bmbt_irec)), 522 (length * sizeof(struct xfs_bmbt_irec)),
532 KM_SLEEP | KM_NOFS); 523 KM_SLEEP | KM_NOFS);
@@ -558,7 +549,7 @@ xfs_dir2_leaf_getdents(
558 */ 549 */
559 if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) { 550 if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
560 551
561 error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info, 552 error = xfs_dir2_leaf_readbuf(args, bufsize, map_info,
562 &curoff, &bp); 553 &curoff, &bp);
563 if (error || !map_info->map_valid) 554 if (error || !map_info->map_valid)
564 break; 555 break;
@@ -566,7 +557,7 @@ xfs_dir2_leaf_getdents(
566 /* 557 /*
567 * Having done a read, we need to set a new offset. 558 * Having done a read, we need to set a new offset.
568 */ 559 */
569 newoff = xfs_dir2_db_off_to_byte(mp->m_dir_geo, 560 newoff = xfs_dir2_db_off_to_byte(geo,
570 map_info->curdb, 0); 561 map_info->curdb, 0);
571 /* 562 /*
572 * Start of the current block. 563 * Start of the current block.
@@ -585,7 +576,7 @@ xfs_dir2_leaf_getdents(
585 * Find our position in the block. 576 * Find our position in the block.
586 */ 577 */
587 ptr = (char *)dp->d_ops->data_entry_p(hdr); 578 ptr = (char *)dp->d_ops->data_entry_p(hdr);
588 byteoff = xfs_dir2_byte_to_off(mp->m_dir_geo, curoff); 579 byteoff = xfs_dir2_byte_to_off(geo, curoff);
589 /* 580 /*
590 * Skip past the header. 581 * Skip past the header.
591 */ 582 */
@@ -644,7 +635,7 @@ xfs_dir2_leaf_getdents(
644 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; 635 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
645 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 636 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
646 be64_to_cpu(dep->inumber), 637 be64_to_cpu(dep->inumber),
647 xfs_dir3_get_dtype(mp, filetype))) 638 xfs_dir3_get_dtype(dp->i_mount, filetype)))
648 break; 639 break;
649 640
650 /* 641 /*
@@ -674,13 +665,14 @@ xfs_dir2_leaf_getdents(
674 */ 665 */
675int 666int
676xfs_readdir( 667xfs_readdir(
677 xfs_inode_t *dp, 668 struct xfs_inode *dp,
678 struct dir_context *ctx, 669 struct dir_context *ctx,
679 size_t bufsize) 670 size_t bufsize)
680{ 671{
681 int rval; /* return value */ 672 struct xfs_da_args args = {0};
682 int v; /* type-checking value */ 673 int rval;
683 uint lock_mode; 674 int v;
675 uint lock_mode;
684 676
685 trace_xfs_readdir(dp); 677 trace_xfs_readdir(dp);
686 678
@@ -690,15 +682,18 @@ xfs_readdir(
690 ASSERT(S_ISDIR(dp->i_d.di_mode)); 682 ASSERT(S_ISDIR(dp->i_d.di_mode));
691 XFS_STATS_INC(xs_dir_getdents); 683 XFS_STATS_INC(xs_dir_getdents);
692 684
685 args.dp = dp;
686 args.geo = dp->i_mount->m_dir_geo;
687
693 lock_mode = xfs_ilock_data_map_shared(dp); 688 lock_mode = xfs_ilock_data_map_shared(dp);
694 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 689 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
695 rval = xfs_dir2_sf_getdents(dp, ctx); 690 rval = xfs_dir2_sf_getdents(&args, ctx);
696 else if ((rval = xfs_dir2_isblock(dp, &v))) 691 else if ((rval = xfs_dir2_isblock(&args, &v)))
697 ; 692 ;
698 else if (v) 693 else if (v)
699 rval = xfs_dir2_block_getdents(dp, ctx); 694 rval = xfs_dir2_block_getdents(&args, ctx);
700 else 695 else
701 rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize); 696 rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize);
702 xfs_iunlock(dp, lock_mode); 697 xfs_iunlock(dp, lock_mode);
703 698
704 return rval; 699 return rval;