Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255139
b: refs/heads/master
c: 2282396
h: refs/heads/master
i:
  255137: 5079610
  255135: 3702141
v: v3
  • Loading branch information
Christoph Hellwig committed Jul 8, 2011
1 parent f51e66c commit 925bd20
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 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: 3ed8638f8867b4d0df1ec606231a087ff06c4a59
refs/heads/master: 2282396d8157033503318fe4dee77ba82dc9d144
34 changes: 25 additions & 9 deletions trunk/fs/xfs/xfs_dir2_leaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,12 @@ xfs_dir2_leaf_addname(
/*
* How many bytes do we need in the leaf block?
*/
needbytes =
(leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) +
(use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0]));
needbytes = 0;
if (!leaf->hdr.stale)
needbytes += sizeof(xfs_dir2_leaf_entry_t);
if (use_block == -1)
needbytes += sizeof(xfs_dir2_data_off_t);

/*
* Now kill use_block if it refers to a missing block, so we
* can use it as an indication of allocation needed.
Expand Down Expand Up @@ -1763,6 +1766,20 @@ xfs_dir2_leaf_trim_data(
return 0;
}

static inline size_t
xfs_dir2_leaf_size(
struct xfs_dir2_leaf_hdr *hdr,
int counts)
{
int entries;

entries = be16_to_cpu(hdr->count) - be16_to_cpu(hdr->stale);
return sizeof(xfs_dir2_leaf_hdr_t) +
entries * sizeof(xfs_dir2_leaf_entry_t) +
counts * sizeof(xfs_dir2_data_off_t) +
sizeof(xfs_dir2_leaf_tail_t);
}

/*
* Convert node form directory to leaf form directory.
* The root of the node form dir needs to already be a LEAFN block.
Expand Down Expand Up @@ -1844,18 +1861,17 @@ xfs_dir2_node_to_leaf(
free = fbp->data;
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
ASSERT(!free->hdr.firstdb);

/*
* Now see if the leafn and free data will fit in a leaf1.
* If not, release the buffer and give up.
*/
if ((uint)sizeof(leaf->hdr) +
(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) +
be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) +
(uint)sizeof(leaf->tail) >
mp->m_dirblksize) {
if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) >
mp->m_dirblksize) {
xfs_da_brelse(tp, fbp);
return 0;
}

/*
* If the leaf has any stale entries in it, compress them out.
* The compact routine will log the header.
Expand All @@ -1874,7 +1890,7 @@ xfs_dir2_node_to_leaf(
* Set up the leaf bests table.
*/
memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests,
be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0]));
be32_to_cpu(ltp->bestcount) * sizeof(xfs_dir2_data_off_t));
xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
xfs_dir2_leaf_log_tail(tp, lbp);
xfs_dir2_leaf_check(dp, lbp);
Expand Down
37 changes: 31 additions & 6 deletions trunk/fs/xfs/xfs_dir2_leaf.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,36 @@
#ifndef __XFS_DIR2_LEAF_H__
#define __XFS_DIR2_LEAF_H__

/*
* Directory format 2, leaf block structures.
*
* A pure data block looks like the following drawing on disk:
*
* +---------------------------+
* | xfs_dir2_leaf_hdr_t |
* +---------------------------+
* | xfs_dir2_leaf_entry_t |
* | xfs_dir2_leaf_entry_t |
* | xfs_dir2_leaf_entry_t |
* | xfs_dir2_leaf_entry_t |
* | ... |
* +---------------------------+
* | xfs_dir2_data_off_t |
* | xfs_dir2_data_off_t |
* | xfs_dir2_data_off_t |
* | ... |
* +---------------------------+
* | xfs_dir2_leaf_tail_t |
* +---------------------------+
*
* The bests (xfs_dir2_data_off_t members) and tail are at the end of the
* block for single-leaf only (magic = XFS_DIR2_LEAF1_MAGIC not
* XFS_DIR2_LEAFN_MAGIC).
*
* As all the entries are variable size structures the accessors in this
* file should be used to iterate over them.
*/

struct uio;
struct xfs_dabuf;
struct xfs_da_args;
Expand Down Expand Up @@ -67,15 +97,10 @@ typedef struct xfs_dir2_leaf_tail {

/*
* Leaf block.
* bests and tail are at the end of the block for single-leaf only
* (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC).
*/
typedef struct xfs_dir2_leaf {
xfs_dir2_leaf_hdr_t hdr; /* leaf header */
xfs_dir2_leaf_entry_t ents[1]; /* entries */
/* ... */
xfs_dir2_data_off_t bests[1]; /* best free counts */
xfs_dir2_leaf_tail_t tail; /* leaf tail */
xfs_dir2_leaf_entry_t ents[]; /* entries */
} xfs_dir2_leaf_t;

/*
Expand Down

0 comments on commit 925bd20

Please sign in to comment.