diff options
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 76 |
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 | */ |
750 | int /* error */ | 750 | int /* error */ |
751 | xfs_dir2_leaf_getdents( | 751 | xfs_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 | ||