Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255130
b: refs/heads/master
c: 4fb44c8
h: refs/heads/master
v: v3
  • Loading branch information
Christoph Hellwig committed Jul 8, 2011
1 parent d8969f4 commit 72409ea
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 177 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 29d104af0a92ba1eac74b636da7fcf88242e1180
refs/heads/master: 4fb44c8272a071290d2ad76164c532fa2902b604
217 changes: 121 additions & 96 deletions trunk/fs/xfs/xfs_dir2_leaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,123 @@ xfs_dir2_block_to_leaf(
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.
*/
Expand Down Expand Up @@ -430,102 +547,10 @@ xfs_dir2_leaf_addname(
if (!grown)
xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
}
/*
* Now we need to make room to insert the leaf entry.
* If there are no stale entries, we just insert a hole at index.
*/
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);
}

lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
highstale, &lfloglow, &lfloghigh);

/*
* Fill in the new leaf entry.
*/
Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/xfs/xfs_dir2_leaf.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
struct xfs_dabuf *lbp);
extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
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);

#endif /* __XFS_DIR2_LEAF_H__ */
84 changes: 4 additions & 80 deletions trunk/fs/xfs/xfs_dir2_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,89 +244,13 @@ xfs_dir2_leafn_add(
lfloglow = be16_to_cpu(leaf->hdr.count);
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.
*/
lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
highstale, &lfloglow, &lfloghigh);

lep->hashval = cpu_to_be32(args->hashval);
lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp,
args->blkno, args->index));
Expand Down

0 comments on commit 72409ea

Please sign in to comment.