aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_block.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2007-08-27 23:58:24 -0400
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-10-15 02:49:49 -0400
commit051e7cd44ab8f0f7c2958371485b4a1ff64a8d1b (patch)
tree23389d878944e0566effed4eb2de4c1ed5fed96e /fs/xfs/xfs_dir2_block.c
parent2bdf7cd0baa67608ada1517a281af359faf4c58c (diff)
[XFS] use filldir internally
Currently xfs has a rather complicated internal scheme to allow for different directory formats in IRIX. This patch rips all code related to this out and pushes useage of the Linux filldir callback into the lowlevel directory code. This does not make the code any less portable because filldir can be used to create dirents of all possible variations (including the IRIX ones as proved by the IRIX binary emulation code under arch/mips/). This patch get rid of an unessecary copy in the readdir path, about 400 lines of code and one of the last two users of the uio structure. This version is updated to deal with dmapi aswell which greatly simplifies the get_dirattrs code. The dmapi part has been tested using the get_dirattrs tools from the xfstest dmapi suite1 with various small and large directories. SGI-PV: 968563 SGI-Modid: xfs-linux-melb:xfs-kern:29478a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dir2_block.c')
-rw-r--r--fs/xfs/xfs_dir2_block.c63
1 files changed, 23 insertions, 40 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index e4df1aaae2a2..f6b919af7b82 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -432,12 +432,10 @@ xfs_dir2_block_addname(
432 */ 432 */
433int /* error */ 433int /* error */
434xfs_dir2_block_getdents( 434xfs_dir2_block_getdents(
435 xfs_trans_t *tp, /* transaction (NULL) */
436 xfs_inode_t *dp, /* incore inode */ 435 xfs_inode_t *dp, /* incore inode */
437 uio_t *uio, /* caller's buffer control */ 436 void *dirent,
438 int *eofp, /* eof reached? (out) */ 437 xfs_off_t *offset,
439 xfs_dirent_t *dbp, /* caller's buffer */ 438 filldir_t filldir)
440 xfs_dir2_put_t put) /* abi's formatting function */
441{ 439{
442 xfs_dir2_block_t *block; /* directory block structure */ 440 xfs_dir2_block_t *block; /* directory block structure */
443 xfs_dabuf_t *bp; /* buffer for block */ 441 xfs_dabuf_t *bp; /* buffer for block */
@@ -447,31 +445,32 @@ xfs_dir2_block_getdents(
447 char *endptr; /* end of the data entries */ 445 char *endptr; /* end of the data entries */
448 int error; /* error return value */ 446 int error; /* error return value */
449 xfs_mount_t *mp; /* filesystem mount point */ 447 xfs_mount_t *mp; /* filesystem mount point */
450 xfs_dir2_put_args_t p; /* arg package for put rtn */
451 char *ptr; /* current data entry */ 448 char *ptr; /* current data entry */
452 int wantoff; /* starting block offset */ 449 int wantoff; /* starting block offset */
450 xfs_ino_t ino;
451 xfs_off_t cook;
453 452
454 mp = dp->i_mount; 453 mp = dp->i_mount;
455 /* 454 /*
456 * If the block number in the offset is out of range, we're done. 455 * If the block number in the offset is out of range, we're done.
457 */ 456 */
458 if (xfs_dir2_dataptr_to_db(mp, uio->uio_offset) > mp->m_dirdatablk) { 457 if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) {
459 *eofp = 1;
460 return 0; 458 return 0;
461 } 459 }
462 /* 460 /*
463 * Can't read the block, give up, else get dabuf in bp. 461 * Can't read the block, give up, else get dabuf in bp.
464 */ 462 */
465 if ((error = 463 error = xfs_da_read_buf(NULL, dp, mp->m_dirdatablk, -1,
466 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 464 &bp, XFS_DATA_FORK);
465 if (error)
467 return error; 466 return error;
468 } 467
469 ASSERT(bp != NULL); 468 ASSERT(bp != NULL);
470 /* 469 /*
471 * Extract the byte offset we start at from the seek pointer. 470 * Extract the byte offset we start at from the seek pointer.
472 * We'll skip entries before this. 471 * We'll skip entries before this.
473 */ 472 */
474 wantoff = xfs_dir2_dataptr_to_off(mp, uio->uio_offset); 473 wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
475 block = bp->data; 474 block = bp->data;
476 xfs_dir2_data_check(dp, bp); 475 xfs_dir2_data_check(dp, bp);
477 /* 476 /*
@@ -480,9 +479,7 @@ xfs_dir2_block_getdents(
480 btp = xfs_dir2_block_tail_p(mp, block); 479 btp = xfs_dir2_block_tail_p(mp, block);
481 ptr = (char *)block->u; 480 ptr = (char *)block->u;
482 endptr = (char *)xfs_dir2_block_leaf_p(btp); 481 endptr = (char *)xfs_dir2_block_leaf_p(btp);
483 p.dbp = dbp; 482
484 p.put = put;
485 p.uio = uio;
486 /* 483 /*
487 * Loop over the data portion of the block. 484 * Loop over the data portion of the block.
488 * Each object is a real entry (dep) or an unused one (dup). 485 * Each object is a real entry (dep) or an unused one (dup).
@@ -508,33 +505,24 @@ xfs_dir2_block_getdents(
508 */ 505 */
509 if ((char *)dep - (char *)block < wantoff) 506 if ((char *)dep - (char *)block < wantoff)
510 continue; 507 continue;
511 /*
512 * Set up argument structure for put routine.
513 */
514 p.namelen = dep->namelen;
515 508
516 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 509 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
517 ptr - (char *)block); 510 ptr - (char *)block);
518 p.ino = be64_to_cpu(dep->inumber); 511 ino = be64_to_cpu(dep->inumber);
519#if XFS_BIG_INUMS 512#if XFS_BIG_INUMS
520 p.ino += mp->m_inoadd; 513 ino += mp->m_inoadd;
521#endif 514#endif
522 p.name = (char *)dep->name;
523
524 /*
525 * Put the entry in the caller's buffer.
526 */
527 error = p.put(&p);
528 515
529 /* 516 /*
530 * If it didn't fit, set the final offset to here & return. 517 * If it didn't fit, set the final offset to here & return.
531 */ 518 */
532 if (!p.done) { 519 if (filldir(dirent, dep->name, dep->namelen, cook,
533 uio->uio_offset = 520 ino, DT_UNKNOWN)) {
534 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 521 *offset = xfs_dir2_db_off_to_dataptr(mp,
522 mp->m_dirdatablk,
535 (char *)dep - (char *)block); 523 (char *)dep - (char *)block);
536 xfs_da_brelse(tp, bp); 524 xfs_da_brelse(NULL, bp);
537 return error; 525 return 0;
538 } 526 }
539 } 527 }
540 528
@@ -542,13 +530,8 @@ xfs_dir2_block_getdents(
542 * Reached the end of the block. 530 * Reached the end of the block.
543 * Set the offset to a non-existent block 1 and return. 531 * Set the offset to a non-existent block 1 and return.
544 */ 532 */
545 *eofp = 1; 533 *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
546 534 xfs_da_brelse(NULL, bp);
547 uio->uio_offset =
548 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
549
550 xfs_da_brelse(tp, bp);
551
552 return 0; 535 return 0;
553} 536}
554 537