aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r--fs/xfs/xfs_dir2_leaf.c76
1 files changed, 30 insertions, 46 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 1b73c9ad646a..e7c12fa1303e 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -749,12 +749,11 @@ xfs_dir2_leaf_compact_x1(
749 */ 749 */
750int /* error */ 750int /* error */
751xfs_dir2_leaf_getdents( 751xfs_dir2_leaf_getdents(
752 xfs_trans_t *tp, /* transaction pointer */
753 xfs_inode_t *dp, /* incore directory inode */ 752 xfs_inode_t *dp, /* incore directory inode */
754 uio_t *uio, /* I/O control & vectors */ 753 void *dirent,
755 int *eofp, /* out: reached end of dir */ 754 size_t bufsize,
756 xfs_dirent_t *dbp, /* caller's buffer */ 755 xfs_off_t *offset,
757 xfs_dir2_put_t put) /* ABI formatting routine */ 756 filldir_t filldir)
758{ 757{
759 xfs_dabuf_t *bp; /* data block buffer */ 758 xfs_dabuf_t *bp; /* data block buffer */
760 int byteoff; /* offset in current block */ 759 int byteoff; /* offset in current block */
@@ -763,7 +762,6 @@ xfs_dir2_leaf_getdents(
763 xfs_dir2_data_t *data; /* data block structure */ 762 xfs_dir2_data_t *data; /* data block structure */
764 xfs_dir2_data_entry_t *dep; /* data entry */ 763 xfs_dir2_data_entry_t *dep; /* data entry */
765 xfs_dir2_data_unused_t *dup; /* unused entry */ 764 xfs_dir2_data_unused_t *dup; /* unused entry */
766 int eof; /* reached end of directory */
767 int error = 0; /* error return value */ 765 int error = 0; /* error return value */
768 int i; /* temporary loop index */ 766 int i; /* temporary loop index */
769 int j; /* temporary loop index */ 767 int j; /* temporary loop index */
@@ -776,46 +774,38 @@ xfs_dir2_leaf_getdents(
776 xfs_mount_t *mp; /* filesystem mount point */ 774 xfs_mount_t *mp; /* filesystem mount point */
777 xfs_dir2_off_t newoff; /* new curoff after new blk */ 775 xfs_dir2_off_t newoff; /* new curoff after new blk */
778 int nmap; /* mappings to ask xfs_bmapi */ 776 int nmap; /* mappings to ask xfs_bmapi */
779 xfs_dir2_put_args_t *p; /* formatting arg bundle */
780 char *ptr = NULL; /* pointer to current data */ 777 char *ptr = NULL; /* pointer to current data */
781 int ra_current; /* number of read-ahead blks */ 778 int ra_current; /* number of read-ahead blks */
782 int ra_index; /* *map index for read-ahead */ 779 int ra_index; /* *map index for read-ahead */
783 int ra_offset; /* map entry offset for ra */ 780 int ra_offset; /* map entry offset for ra */
784 int ra_want; /* readahead count wanted */ 781 int ra_want; /* readahead count wanted */
782 xfs_ino_t ino;
785 783
786 /* 784 /*
787 * If the offset is at or past the largest allowed value, 785 * If the offset is at or past the largest allowed value,
788 * give up right away, return eof. 786 * give up right away.
789 */ 787 */
790 if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) { 788 if (*offset >= XFS_DIR2_MAX_DATAPTR)
791 *eofp = 1;
792 return 0; 789 return 0;
793 } 790
794 mp = dp->i_mount; 791 mp = dp->i_mount;
795 /* 792
796 * Setup formatting arguments.
797 */
798 p = kmem_alloc(sizeof(*p), KM_SLEEP);
799 p->dbp = dbp;
800 p->put = put;
801 p->uio = uio;
802 /* 793 /*
803 * Set up to bmap a number of blocks based on the caller's 794 * Set up to bmap a number of blocks based on the caller's
804 * buffer size, the directory block size, and the filesystem 795 * buffer size, the directory block size, and the filesystem
805 * block size. 796 * block size.
806 */ 797 */
807 map_size = 798 map_size = howmany(bufsize + mp->m_dirblksize, mp->m_sb.sb_blocksize);
808 howmany(uio->uio_resid + mp->m_dirblksize,
809 mp->m_sb.sb_blocksize);
810 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); 799 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP);
811 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; 800 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0;
812 bp = NULL; 801 bp = NULL;
813 eof = 1; 802
814 /* 803 /*
815 * Inside the loop we keep the main offset value as a byte offset 804 * Inside the loop we keep the main offset value as a byte offset
816 * in the directory file. 805 * in the directory file.
817 */ 806 */
818 curoff = xfs_dir2_dataptr_to_byte(mp, uio->uio_offset); 807 curoff = xfs_dir2_dataptr_to_byte(mp, *offset);
808
819 /* 809 /*
820 * Force this conversion through db so we truncate the offset 810 * Force this conversion through db so we truncate the offset
821 * down to get the start of the data block. 811 * down to get the start of the data block.
@@ -836,7 +826,7 @@ xfs_dir2_leaf_getdents(
836 * take it out of the mapping. 826 * take it out of the mapping.
837 */ 827 */
838 if (bp) { 828 if (bp) {
839 xfs_da_brelse(tp, bp); 829 xfs_da_brelse(NULL, bp);
840 bp = NULL; 830 bp = NULL;
841 map_blocks -= mp->m_dirblkfsbs; 831 map_blocks -= mp->m_dirblkfsbs;
842 /* 832 /*
@@ -862,8 +852,9 @@ xfs_dir2_leaf_getdents(
862 /* 852 /*
863 * Recalculate the readahead blocks wanted. 853 * Recalculate the readahead blocks wanted.
864 */ 854 */
865 ra_want = howmany(uio->uio_resid + mp->m_dirblksize, 855 ra_want = howmany(bufsize + mp->m_dirblksize,
866 mp->m_sb.sb_blocksize) - 1; 856 mp->m_sb.sb_blocksize) - 1;
857
867 /* 858 /*
868 * If we don't have as many as we want, and we haven't 859 * If we don't have as many as we want, and we haven't
869 * run out of data blocks, get some more mappings. 860 * run out of data blocks, get some more mappings.
@@ -876,7 +867,7 @@ xfs_dir2_leaf_getdents(
876 * we already have in the table. 867 * we already have in the table.
877 */ 868 */
878 nmap = map_size - map_valid; 869 nmap = map_size - map_valid;
879 error = xfs_bmapi(tp, dp, 870 error = xfs_bmapi(NULL, dp,
880 map_off, 871 map_off,
881 xfs_dir2_byte_to_da(mp, 872 xfs_dir2_byte_to_da(mp,
882 XFS_DIR2_LEAF_OFFSET) - map_off, 873 XFS_DIR2_LEAF_OFFSET) - map_off,
@@ -939,7 +930,7 @@ xfs_dir2_leaf_getdents(
939 * mapping. 930 * mapping.
940 */ 931 */
941 curdb = xfs_dir2_da_to_db(mp, map->br_startoff); 932 curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
942 error = xfs_da_read_buf(tp, dp, map->br_startoff, 933 error = xfs_da_read_buf(NULL, dp, map->br_startoff,
943 map->br_blockcount >= mp->m_dirblkfsbs ? 934 map->br_blockcount >= mp->m_dirblkfsbs ?
944 XFS_FSB_TO_DADDR(mp, map->br_startblock) : 935 XFS_FSB_TO_DADDR(mp, map->br_startblock) :
945 -1, 936 -1,
@@ -982,7 +973,7 @@ xfs_dir2_leaf_getdents(
982 * is a very rare case. 973 * is a very rare case.
983 */ 974 */
984 else if (i > ra_current) { 975 else if (i > ra_current) {
985 (void)xfs_da_reada_buf(tp, dp, 976 (void)xfs_da_reada_buf(NULL, dp,
986 map[ra_index].br_startoff + 977 map[ra_index].br_startoff +
987 ra_offset, XFS_DATA_FORK); 978 ra_offset, XFS_DATA_FORK);
988 ra_current = i; 979 ra_current = i;
@@ -1089,46 +1080,39 @@ xfs_dir2_leaf_getdents(
1089 */ 1080 */
1090 dep = (xfs_dir2_data_entry_t *)ptr; 1081 dep = (xfs_dir2_data_entry_t *)ptr;
1091 1082
1092 p->namelen = dep->namelen; 1083 length = xfs_dir2_data_entsize(dep->namelen);
1093
1094 length = xfs_dir2_data_entsize(p->namelen);
1095
1096 p->cook = xfs_dir2_byte_to_dataptr(mp, curoff + length);
1097 1084
1098 p->ino = be64_to_cpu(dep->inumber); 1085 ino = be64_to_cpu(dep->inumber);
1099#if XFS_BIG_INUMS 1086#if XFS_BIG_INUMS
1100 p->ino += mp->m_inoadd; 1087 ino += mp->m_inoadd;
1101#endif 1088#endif
1102 p->name = (char *)dep->name;
1103
1104 error = p->put(p);
1105 1089
1106 /* 1090 /*
1107 * Won't fit. Return to caller. 1091 * Won't fit. Return to caller.
1108 */ 1092 */
1109 if (!p->done) { 1093 if (filldir(dirent, dep->name, dep->namelen,
1110 eof = 0; 1094 xfs_dir2_byte_to_dataptr(mp, curoff + length),
1095 ino, DT_UNKNOWN))
1111 break; 1096 break;
1112 } 1097
1113 /* 1098 /*
1114 * Advance to next entry in the block. 1099 * Advance to next entry in the block.
1115 */ 1100 */
1116 ptr += length; 1101 ptr += length;
1117 curoff += length; 1102 curoff += length;
1103 bufsize -= length;
1118 } 1104 }
1119 1105
1120 /* 1106 /*
1121 * All done. Set output offset value to current offset. 1107 * All done. Set output offset value to current offset.
1122 */ 1108 */
1123 *eofp = eof;
1124 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) 1109 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
1125 uio->uio_offset = XFS_DIR2_MAX_DATAPTR; 1110 *offset = XFS_DIR2_MAX_DATAPTR;
1126 else 1111 else
1127 uio->uio_offset = xfs_dir2_byte_to_dataptr(mp, curoff); 1112 *offset = xfs_dir2_byte_to_dataptr(mp, curoff);
1128 kmem_free(map, map_size * sizeof(*map)); 1113 kmem_free(map, map_size * sizeof(*map));
1129 kmem_free(p, sizeof(*p));
1130 if (bp) 1114 if (bp)
1131 xfs_da_brelse(tp, bp); 1115 xfs_da_brelse(NULL, bp);
1132 return error; 1116 return error;
1133} 1117}
1134 1118