xfs: cleanup xfs_dir2_block_getdents
Use an offset as the main means for iteration, and only do pointer arithmetics to find the data/unused entries. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
parent
ee641d5af5
commit
263dde869b
@ -142,17 +142,14 @@ xfs_dir2_block_getdents(
|
|||||||
struct dir_context *ctx)
|
struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
struct xfs_inode *dp = args->dp; /* incore directory inode */
|
struct xfs_inode *dp = args->dp; /* incore directory inode */
|
||||||
xfs_dir2_data_hdr_t *hdr; /* block header */
|
|
||||||
struct xfs_buf *bp; /* buffer for block */
|
struct xfs_buf *bp; /* buffer for block */
|
||||||
xfs_dir2_data_entry_t *dep; /* block data entry */
|
|
||||||
xfs_dir2_data_unused_t *dup; /* block unused entry */
|
|
||||||
char *endptr; /* end of the data entries */
|
|
||||||
int error; /* error return value */
|
int error; /* error return value */
|
||||||
char *ptr; /* current data entry */
|
|
||||||
int wantoff; /* starting block offset */
|
int wantoff; /* starting block offset */
|
||||||
xfs_off_t cook;
|
xfs_off_t cook;
|
||||||
struct xfs_da_geometry *geo = args->geo;
|
struct xfs_da_geometry *geo = args->geo;
|
||||||
int lock_mode;
|
int lock_mode;
|
||||||
|
unsigned int offset;
|
||||||
|
unsigned int end;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the block number in the offset is out of range, we're done.
|
* If the block number in the offset is out of range, we're done.
|
||||||
@ -171,44 +168,39 @@ xfs_dir2_block_getdents(
|
|||||||
* We'll skip entries before this.
|
* We'll skip entries before this.
|
||||||
*/
|
*/
|
||||||
wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
|
wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
|
||||||
hdr = bp->b_addr;
|
|
||||||
xfs_dir3_data_check(dp, bp);
|
xfs_dir3_data_check(dp, bp);
|
||||||
/*
|
|
||||||
* Set up values for the loop.
|
|
||||||
*/
|
|
||||||
ptr = (char *)dp->d_ops->data_entry_p(hdr);
|
|
||||||
endptr = xfs_dir3_data_endp(geo, hdr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop over the data portion of the block.
|
* Loop over the data portion of the block.
|
||||||
* Each object is a real entry (dep) or an unused one (dup).
|
* Each object is a real entry (dep) or an unused one (dup).
|
||||||
*/
|
*/
|
||||||
while (ptr < endptr) {
|
offset = dp->d_ops->data_entry_offset;
|
||||||
|
end = xfs_dir3_data_endp(geo, bp->b_addr) - bp->b_addr;
|
||||||
|
while (offset < end) {
|
||||||
|
struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
|
||||||
|
struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
|
||||||
uint8_t filetype;
|
uint8_t filetype;
|
||||||
|
|
||||||
dup = (xfs_dir2_data_unused_t *)ptr;
|
|
||||||
/*
|
/*
|
||||||
* Unused, skip it.
|
* Unused, skip it.
|
||||||
*/
|
*/
|
||||||
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
||||||
ptr += be16_to_cpu(dup->length);
|
offset += be16_to_cpu(dup->length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dep = (xfs_dir2_data_entry_t *)ptr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bump pointer for the next iteration.
|
* Bump pointer for the next iteration.
|
||||||
*/
|
*/
|
||||||
ptr += dp->d_ops->data_entsize(dep->namelen);
|
offset += dp->d_ops->data_entsize(dep->namelen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The entry is before the desired starting point, skip it.
|
* The entry is before the desired starting point, skip it.
|
||||||
*/
|
*/
|
||||||
if ((char *)dep - (char *)hdr < wantoff)
|
if (offset < wantoff)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
|
cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset);
|
||||||
(char *)dep - (char *)hdr);
|
|
||||||
|
|
||||||
ctx->pos = cook & 0x7fffffff;
|
ctx->pos = cook & 0x7fffffff;
|
||||||
filetype = dp->d_ops->data_get_ftype(dep);
|
filetype = dp->d_ops->data_get_ftype(dep);
|
||||||
|
Loading…
Reference in New Issue
Block a user