aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_block.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_block.c')
-rw-r--r--fs/xfs/xfs_dir2_block.c97
1 files changed, 1 insertions, 96 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 5e7fbd72cf52..5e8400064fa9 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -126,7 +126,7 @@ const struct xfs_buf_ops xfs_dir3_block_buf_ops = {
126 .verify_write = xfs_dir3_block_write_verify, 126 .verify_write = xfs_dir3_block_write_verify,
127}; 127};
128 128
129static int 129int
130xfs_dir3_block_read( 130xfs_dir3_block_read(
131 struct xfs_trans *tp, 131 struct xfs_trans *tp,
132 struct xfs_inode *dp, 132 struct xfs_inode *dp,
@@ -565,101 +565,6 @@ xfs_dir2_block_addname(
565} 565}
566 566
567/* 567/*
568 * Readdir for block directories.
569 */
570int /* error */
571xfs_dir2_block_getdents(
572 xfs_inode_t *dp, /* incore inode */
573 struct dir_context *ctx)
574{
575 xfs_dir2_data_hdr_t *hdr; /* block header */
576 struct xfs_buf *bp; /* buffer for block */
577 xfs_dir2_block_tail_t *btp; /* block tail */
578 xfs_dir2_data_entry_t *dep; /* block data entry */
579 xfs_dir2_data_unused_t *dup; /* block unused entry */
580 char *endptr; /* end of the data entries */
581 int error; /* error return value */
582 xfs_mount_t *mp; /* filesystem mount point */
583 char *ptr; /* current data entry */
584 int wantoff; /* starting block offset */
585 xfs_off_t cook;
586
587 mp = dp->i_mount;
588 /*
589 * If the block number in the offset is out of range, we're done.
590 */
591 if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
592 return 0;
593
594 error = xfs_dir3_block_read(NULL, dp, &bp);
595 if (error)
596 return error;
597
598 /*
599 * Extract the byte offset we start at from the seek pointer.
600 * We'll skip entries before this.
601 */
602 wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos);
603 hdr = bp->b_addr;
604 xfs_dir3_data_check(dp, bp);
605 /*
606 * Set up values for the loop.
607 */
608 btp = xfs_dir2_block_tail_p(mp, hdr);
609 ptr = (char *)xfs_dir3_data_entry_p(hdr);
610 endptr = (char *)xfs_dir2_block_leaf_p(btp);
611
612 /*
613 * Loop over the data portion of the block.
614 * Each object is a real entry (dep) or an unused one (dup).
615 */
616 while (ptr < endptr) {
617 dup = (xfs_dir2_data_unused_t *)ptr;
618 /*
619 * Unused, skip it.
620 */
621 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
622 ptr += be16_to_cpu(dup->length);
623 continue;
624 }
625
626 dep = (xfs_dir2_data_entry_t *)ptr;
627
628 /*
629 * Bump pointer for the next iteration.
630 */
631 ptr += xfs_dir2_data_entsize(dep->namelen);
632 /*
633 * The entry is before the desired starting point, skip it.
634 */
635 if ((char *)dep - (char *)hdr < wantoff)
636 continue;
637
638 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
639 (char *)dep - (char *)hdr);
640
641 ctx->pos = cook & 0x7fffffff;
642 /*
643 * If it didn't fit, set the final offset to here & return.
644 */
645 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
646 be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
647 xfs_trans_brelse(NULL, bp);
648 return 0;
649 }
650 }
651
652 /*
653 * Reached the end of the block.
654 * Set the offset to a non-existent block 1 and return.
655 */
656 ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
657 0x7fffffff;
658 xfs_trans_brelse(NULL, bp);
659 return 0;
660}
661
662/*
663 * Log leaf entries from the block. 568 * Log leaf entries from the block.
664 */ 569 */
665static void 570static void