diff options
-rw-r--r-- | fs/xfs/xfs_dir2.c | 50 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_readdir.c | 85 |
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 | */ |
650 | int | 650 | int |
651 | xfs_dir2_isblock( | 651 | xfs_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 | */ |
671 | int | 669 | int |
672 | xfs_dir2_isleaf( | 670 | xfs_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 | */ |
149 | extern int xfs_dir2_isblock(struct xfs_inode *dp, int *r); | 149 | extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r); |
150 | extern int xfs_dir2_isleaf(struct xfs_inode *dp, int *r); | 150 | extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r); |
151 | extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, | 151 | extern 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 | ||
77 | STATIC int | 77 | STATIC int |
78 | xfs_dir2_sf_getdents( | 78 | xfs_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 | */ |
179 | STATIC int | 176 | STATIC int |
180 | xfs_dir2_block_getdents( | 177 | xfs_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 | ||
291 | STATIC int | 286 | STATIC int |
292 | xfs_dir2_leaf_readbuf( | 287 | xfs_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 | */ |
494 | STATIC int | 488 | STATIC int |
495 | xfs_dir2_leaf_getdents( | 489 | xfs_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 | */ |
675 | int | 666 | int |
676 | xfs_readdir( | 667 | xfs_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; |