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 | ||
