Commit 2f4369a8 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong

xfs: cleanup xfs_dir2_leaf_getdents

Use an offset as the main means for iteration, and only do pointer
arithmetics to find the data/unused entries.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 263dde86
...@@ -348,16 +348,15 @@ xfs_dir2_leaf_getdents( ...@@ -348,16 +348,15 @@ xfs_dir2_leaf_getdents(
{ {
struct xfs_inode *dp = args->dp; struct xfs_inode *dp = args->dp;
struct xfs_buf *bp = NULL; /* data block buffer */ struct xfs_buf *bp = NULL; /* data block buffer */
xfs_dir2_data_hdr_t *hdr; /* data block header */
xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_entry_t *dep; /* data entry */
xfs_dir2_data_unused_t *dup; /* unused entry */ xfs_dir2_data_unused_t *dup; /* unused entry */
char *ptr = NULL; /* pointer to current data */
struct xfs_da_geometry *geo = args->geo; struct xfs_da_geometry *geo = args->geo;
xfs_dablk_t rablk = 0; /* current readahead block */ xfs_dablk_t rablk = 0; /* current readahead block */
xfs_dir2_off_t curoff; /* current overall offset */ xfs_dir2_off_t curoff; /* current overall offset */
int length; /* temporary length value */ int length; /* temporary length value */
int byteoff; /* offset in current block */ int byteoff; /* offset in current block */
int lock_mode; int lock_mode;
unsigned int offset = 0;
int error = 0; /* error return value */ int error = 0; /* error return value */
/* /*
...@@ -384,7 +383,7 @@ xfs_dir2_leaf_getdents( ...@@ -384,7 +383,7 @@ xfs_dir2_leaf_getdents(
* If we have no buffer, or we're off the end of the * If we have no buffer, or we're off the end of the
* current buffer, need to get another one. * current buffer, need to get another one.
*/ */
if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) { if (!bp || offset >= geo->blksize) {
if (bp) { if (bp) {
xfs_trans_brelse(args->trans, bp); xfs_trans_brelse(args->trans, bp);
bp = NULL; bp = NULL;
...@@ -397,12 +396,11 @@ xfs_dir2_leaf_getdents( ...@@ -397,12 +396,11 @@ xfs_dir2_leaf_getdents(
if (error || !bp) if (error || !bp)
break; break;
hdr = bp->b_addr;
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
/* /*
* Find our position in the block. * Find our position in the block.
*/ */
ptr = (char *)dp->d_ops->data_entry_p(hdr); offset = dp->d_ops->data_entry_offset;
byteoff = xfs_dir2_byte_to_off(geo, curoff); byteoff = xfs_dir2_byte_to_off(geo, curoff);
/* /*
* Skip past the header. * Skip past the header.
...@@ -413,20 +411,20 @@ xfs_dir2_leaf_getdents( ...@@ -413,20 +411,20 @@ xfs_dir2_leaf_getdents(
* Skip past entries until we reach our offset. * Skip past entries until we reach our offset.
*/ */
else { else {
while ((char *)ptr - (char *)hdr < byteoff) { while (offset < byteoff) {
dup = (xfs_dir2_data_unused_t *)ptr; dup = bp->b_addr + offset;
if (be16_to_cpu(dup->freetag) if (be16_to_cpu(dup->freetag)
== XFS_DIR2_DATA_FREE_TAG) { == XFS_DIR2_DATA_FREE_TAG) {
length = be16_to_cpu(dup->length); length = be16_to_cpu(dup->length);
ptr += length; offset += length;
continue; continue;
} }
dep = (xfs_dir2_data_entry_t *)ptr; dep = bp->b_addr + offset;
length = length =
dp->d_ops->data_entsize(dep->namelen); dp->d_ops->data_entsize(dep->namelen);
ptr += length; offset += length;
} }
/* /*
* Now set our real offset. * Now set our real offset.
...@@ -434,28 +432,28 @@ xfs_dir2_leaf_getdents( ...@@ -434,28 +432,28 @@ xfs_dir2_leaf_getdents(
curoff = curoff =
xfs_dir2_db_off_to_byte(geo, xfs_dir2_db_off_to_byte(geo,
xfs_dir2_byte_to_db(geo, curoff), xfs_dir2_byte_to_db(geo, curoff),
(char *)ptr - (char *)hdr); offset);
if (ptr >= (char *)hdr + geo->blksize) { if (offset >= geo->blksize)
continue; continue;
} }
} }
}
/* /*
* We have a pointer to an entry. * We have a pointer to an entry. Is it a live one?
* Is it a live one?
*/ */
dup = (xfs_dir2_data_unused_t *)ptr; dup = bp->b_addr + offset;
/* /*
* No, it's unused, skip over it. * No, it's unused, skip over it.
*/ */
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
length = be16_to_cpu(dup->length); length = be16_to_cpu(dup->length);
ptr += length; offset += length;
curoff += length; curoff += length;
continue; continue;
} }
dep = (xfs_dir2_data_entry_t *)ptr; dep = bp->b_addr + offset;
length = dp->d_ops->data_entsize(dep->namelen); length = dp->d_ops->data_entsize(dep->namelen);
filetype = dp->d_ops->data_get_ftype(dep); filetype = dp->d_ops->data_get_ftype(dep);
...@@ -474,7 +472,7 @@ xfs_dir2_leaf_getdents( ...@@ -474,7 +472,7 @@ xfs_dir2_leaf_getdents(
/* /*
* Advance to next entry in the block. * Advance to next entry in the block.
*/ */
ptr += length; offset += length;
curoff += length; curoff += length;
/* bufsize may have just been a guess; don't go negative */ /* bufsize may have just been a guess; don't go negative */
bufsize = bufsize > length ? bufsize - length : 0; bufsize = bufsize > length ? bufsize - length : 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment