Commit 4fb44c82 authored by Christoph Hellwig's avatar Christoph Hellwig

xfs: factor out xfs_dir2_leaf_find_entry

Add a new xfs_dir2_leaf_find_entry helper to factor out some duplicate code
from xfs_dir2_leaf_addname xfs_dir2_leafn_add.  Found by Eric Sandeen using
an automated code duplication checker.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarAlex Elder <aelder@sgi.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 29d104af
...@@ -152,6 +152,123 @@ xfs_dir2_block_to_leaf( ...@@ -152,6 +152,123 @@ xfs_dir2_block_to_leaf(
return 0; return 0;
} }
struct xfs_dir2_leaf_entry *
xfs_dir2_leaf_find_entry(
xfs_dir2_leaf_t *leaf, /* leaf structure */
int index, /* leaf table position */
int compact, /* need to compact leaves */
int lowstale, /* index of prev stale leaf */
int highstale, /* index of next stale leaf */
int *lfloglow, /* low leaf logging index */
int *lfloghigh) /* high leaf logging index */
{
if (!leaf->hdr.stale) {
xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */
/*
* Now we need to make room to insert the leaf entry.
*
* If there are no stale entries, just insert a hole at index.
*/
lep = &leaf->ents[index];
if (index < be16_to_cpu(leaf->hdr.count))
memmove(lep + 1, lep,
(be16_to_cpu(leaf->hdr.count) - index) *
sizeof(*lep));
/*
* Record low and high logging indices for the leaf.
*/
*lfloglow = index;
*lfloghigh = be16_to_cpu(leaf->hdr.count);
be16_add_cpu(&leaf->hdr.count, 1);
return lep;
}
/*
* There are stale entries.
*
* We will use one of them for the new entry. It's probably not at
* the right location, so we'll have to shift some up or down first.
*
* If we didn't compact before, we need to find the nearest stale
* entries before and after our insertion point.
*/
if (compact == 0) {
/*
* Find the first stale entry before the insertion point,
* if any.
*/
for (lowstale = index - 1;
lowstale >= 0 &&
be32_to_cpu(leaf->ents[lowstale].address) !=
XFS_DIR2_NULL_DATAPTR;
lowstale--)
continue;
/*
* Find the next stale entry at or after the insertion point,
* if any. Stop if we go so far that the lowstale entry
* would be better.
*/
for (highstale = index;
highstale < be16_to_cpu(leaf->hdr.count) &&
be32_to_cpu(leaf->ents[highstale].address) !=
XFS_DIR2_NULL_DATAPTR &&
(lowstale < 0 ||
index - lowstale - 1 >= highstale - index);
highstale++)
continue;
}
/*
* If the low one is better, use it.
*/
if (lowstale >= 0 &&
(highstale == be16_to_cpu(leaf->hdr.count) ||
index - lowstale - 1 < highstale - index)) {
ASSERT(index - lowstale - 1 >= 0);
ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
XFS_DIR2_NULL_DATAPTR);
/*
* Copy entries up to cover the stale entry and make room
* for the new entry.
*/
if (index - lowstale - 1 > 0) {
memmove(&leaf->ents[lowstale],
&leaf->ents[lowstale + 1],
(index - lowstale - 1) *
sizeof(xfs_dir2_leaf_entry_t));
}
*lfloglow = MIN(lowstale, *lfloglow);
*lfloghigh = MAX(index - 1, *lfloghigh);
be16_add_cpu(&leaf->hdr.stale, -1);
return &leaf->ents[index - 1];
}
/*
* The high one is better, so use that one.
*/
ASSERT(highstale - index >= 0);
ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
XFS_DIR2_NULL_DATAPTR);
/*
* Copy entries down to cover the stale entry and make room for the
* new entry.
*/
if (highstale - index > 0) {
memmove(&leaf->ents[index + 1],
&leaf->ents[index],
(highstale - index) * sizeof(xfs_dir2_leaf_entry_t));
}
*lfloglow = MIN(index, *lfloglow);
*lfloghigh = MAX(highstale, *lfloghigh);
be16_add_cpu(&leaf->hdr.stale, -1);
return &leaf->ents[index];
}
/* /*
* Add an entry to a leaf form directory. * Add an entry to a leaf form directory.
*/ */
...@@ -430,102 +547,10 @@ xfs_dir2_leaf_addname( ...@@ -430,102 +547,10 @@ xfs_dir2_leaf_addname(
if (!grown) if (!grown)
xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
} }
/*
* Now we need to make room to insert the leaf entry. lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
* If there are no stale entries, we just insert a hole at index. highstale, &lfloglow, &lfloghigh);
*/
if (!leaf->hdr.stale) {
/*
* lep is still good as the index leaf entry.
*/
if (index < be16_to_cpu(leaf->hdr.count))
memmove(lep + 1, lep,
(be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
/*
* Record low and high logging indices for the leaf.
*/
lfloglow = index;
lfloghigh = be16_to_cpu(leaf->hdr.count);
be16_add_cpu(&leaf->hdr.count, 1);
}
/*
* There are stale entries.
* We will use one of them for the new entry.
* It's probably not at the right location, so we'll have to
* shift some up or down first.
*/
else {
/*
* If we didn't compact before, we need to find the nearest
* stale entries before and after our insertion point.
*/
if (compact == 0) {
/*
* Find the first stale entry before the insertion
* point, if any.
*/
for (lowstale = index - 1;
lowstale >= 0 &&
be32_to_cpu(leaf->ents[lowstale].address) !=
XFS_DIR2_NULL_DATAPTR;
lowstale--)
continue;
/*
* Find the next stale entry at or after the insertion
* point, if any. Stop if we go so far that the
* lowstale entry would be better.
*/
for (highstale = index;
highstale < be16_to_cpu(leaf->hdr.count) &&
be32_to_cpu(leaf->ents[highstale].address) !=
XFS_DIR2_NULL_DATAPTR &&
(lowstale < 0 ||
index - lowstale - 1 >= highstale - index);
highstale++)
continue;
}
/*
* If the low one is better, use it.
*/
if (lowstale >= 0 &&
(highstale == be16_to_cpu(leaf->hdr.count) ||
index - lowstale - 1 < highstale - index)) {
ASSERT(index - lowstale - 1 >= 0);
ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
XFS_DIR2_NULL_DATAPTR);
/*
* Copy entries up to cover the stale entry
* and make room for the new entry.
*/
if (index - lowstale - 1 > 0)
memmove(&leaf->ents[lowstale],
&leaf->ents[lowstale + 1],
(index - lowstale - 1) * sizeof(*lep));
lep = &leaf->ents[index - 1];
lfloglow = MIN(lowstale, lfloglow);
lfloghigh = MAX(index - 1, lfloghigh);
}
/*
* The high one is better, so use that one.
*/
else {
ASSERT(highstale - index >= 0);
ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
XFS_DIR2_NULL_DATAPTR);
/*
* Copy entries down to cover the stale entry
* and make room for the new entry.
*/
if (highstale - index > 0)
memmove(&leaf->ents[index + 1],
&leaf->ents[index],
(highstale - index) * sizeof(*lep));
lep = &leaf->ents[index];
lfloglow = MIN(index, lfloglow);
lfloghigh = MAX(highstale, lfloghigh);
}
be16_add_cpu(&leaf->hdr.stale, -1);
}
/* /*
* Fill in the new leaf entry. * Fill in the new leaf entry.
*/ */
......
...@@ -248,6 +248,9 @@ extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args, ...@@ -248,6 +248,9 @@ extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
struct xfs_dabuf *lbp); struct xfs_dabuf *lbp);
extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
struct xfs_dabuf *lbp, xfs_dir2_db_t db); struct xfs_dabuf *lbp, xfs_dir2_db_t db);
extern xfs_dir2_leaf_entry_t *xfs_dir2_leaf_find_entry(xfs_dir2_leaf_t *, int,
int, int, int,
int *, int *);
extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
#endif /* __XFS_DIR2_LEAF_H__ */ #endif /* __XFS_DIR2_LEAF_H__ */
...@@ -244,89 +244,13 @@ xfs_dir2_leafn_add( ...@@ -244,89 +244,13 @@ xfs_dir2_leafn_add(
lfloglow = be16_to_cpu(leaf->hdr.count); lfloglow = be16_to_cpu(leaf->hdr.count);
lfloghigh = -1; lfloghigh = -1;
} }
/*
* No stale entries, just insert a space for the new entry.
*/
if (!leaf->hdr.stale) {
lep = &leaf->ents[index];
if (index < be16_to_cpu(leaf->hdr.count))
memmove(lep + 1, lep,
(be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
lfloglow = index;
lfloghigh = be16_to_cpu(leaf->hdr.count);
be16_add_cpu(&leaf->hdr.count, 1);
}
/*
* There are stale entries. We'll use one for the new entry.
*/
else {
/*
* If we didn't do a compact then we need to figure out
* which stale entry will be used.
*/
if (compact == 0) {
/*
* Find first stale entry before our insertion point.
*/
for (lowstale = index - 1;
lowstale >= 0 &&
be32_to_cpu(leaf->ents[lowstale].address) !=
XFS_DIR2_NULL_DATAPTR;
lowstale--)
continue;
/*
* Find next stale entry after insertion point.
* Stop looking if the answer would be worse than
* lowstale already found.
*/
for (highstale = index;
highstale < be16_to_cpu(leaf->hdr.count) &&
be32_to_cpu(leaf->ents[highstale].address) !=
XFS_DIR2_NULL_DATAPTR &&
(lowstale < 0 ||
index - lowstale - 1 >= highstale - index);
highstale++)
continue;
}
/*
* Using the low stale entry.
* Shift entries up toward the stale slot.
*/
if (lowstale >= 0 &&
(highstale == be16_to_cpu(leaf->hdr.count) ||
index - lowstale - 1 < highstale - index)) {
ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
XFS_DIR2_NULL_DATAPTR);
ASSERT(index - lowstale - 1 >= 0);
if (index - lowstale - 1 > 0)
memmove(&leaf->ents[lowstale],
&leaf->ents[lowstale + 1],
(index - lowstale - 1) * sizeof(*lep));
lep = &leaf->ents[index - 1];
lfloglow = MIN(lowstale, lfloglow);
lfloghigh = MAX(index - 1, lfloghigh);
}
/*
* Using the high stale entry.
* Shift entries down toward the stale slot.
*/
else {
ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
XFS_DIR2_NULL_DATAPTR);
ASSERT(highstale - index >= 0);
if (highstale - index > 0)
memmove(&leaf->ents[index + 1],
&leaf->ents[index],
(highstale - index) * sizeof(*lep));
lep = &leaf->ents[index];
lfloglow = MIN(index, lfloglow);
lfloghigh = MAX(highstale, lfloghigh);
}
be16_add_cpu(&leaf->hdr.stale, -1);
}
/* /*
* Insert the new entry, log everything. * Insert the new entry, log everything.
*/ */
lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
highstale, &lfloglow, &lfloghigh);
lep->hashval = cpu_to_be32(args->hashval); lep->hashval = cpu_to_be32(args->hashval);
lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp,
args->blkno, args->index)); args->blkno, args->index));
......
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