aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2011-07-08 08:35:53 -0400
committerChristoph Hellwig <hch@lst.de>2011-07-08 08:35:53 -0400
commit2282396d8157033503318fe4dee77ba82dc9d144 (patch)
tree5aab6f55e2e4c37c5cbd4036dab4b8b8c78daf82
parent3ed8638f8867b4d0df1ec606231a087ff06c4a59 (diff)
xfs: cleanup struct xfs_dir2_leaf
Simplify the confusing xfs_dir2_leaf structure. It is supposed to describe an XFS dir2 leaf format btree block, but due to the variable sized nature of almost all elements in it it can't actuall do anything close to that job. Remove the members that are after the first variable sized array, given that they could only be used for sizeof expressions that can as well just use the underlying types directly, and make the ents array a real C99 variable sized array. Also factor out the xfs_dir2_leaf_size, to make the sizing of a leaf entry which already was convoluted somewhat readable after using the longer type names in the sizeof expressions. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Alex Elder <aelder@sgi.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--fs/xfs/xfs_dir2_leaf.c34
-rw-r--r--fs/xfs/xfs_dir2_leaf.h37
2 files changed, 56 insertions, 15 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 067a6abdeabe..5d2651f1c759 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -367,9 +367,12 @@ xfs_dir2_leaf_addname(
367 /* 367 /*
368 * How many bytes do we need in the leaf block? 368 * How many bytes do we need in the leaf block?
369 */ 369 */
370 needbytes = 370 needbytes = 0;
371 (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) + 371 if (!leaf->hdr.stale)
372 (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0])); 372 needbytes += sizeof(xfs_dir2_leaf_entry_t);
373 if (use_block == -1)
374 needbytes += sizeof(xfs_dir2_data_off_t);
375
373 /* 376 /*
374 * Now kill use_block if it refers to a missing block, so we 377 * Now kill use_block if it refers to a missing block, so we
375 * can use it as an indication of allocation needed. 378 * can use it as an indication of allocation needed.
@@ -1763,6 +1766,20 @@ xfs_dir2_leaf_trim_data(
1763 return 0; 1766 return 0;
1764} 1767}
1765 1768
1769static inline size_t
1770xfs_dir2_leaf_size(
1771 struct xfs_dir2_leaf_hdr *hdr,
1772 int counts)
1773{
1774 int entries;
1775
1776 entries = be16_to_cpu(hdr->count) - be16_to_cpu(hdr->stale);
1777 return sizeof(xfs_dir2_leaf_hdr_t) +
1778 entries * sizeof(xfs_dir2_leaf_entry_t) +
1779 counts * sizeof(xfs_dir2_data_off_t) +
1780 sizeof(xfs_dir2_leaf_tail_t);
1781}
1782
1766/* 1783/*
1767 * Convert node form directory to leaf form directory. 1784 * Convert node form directory to leaf form directory.
1768 * The root of the node form dir needs to already be a LEAFN block. 1785 * The root of the node form dir needs to already be a LEAFN block.
@@ -1844,18 +1861,17 @@ xfs_dir2_node_to_leaf(
1844 free = fbp->data; 1861 free = fbp->data;
1845 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 1862 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
1846 ASSERT(!free->hdr.firstdb); 1863 ASSERT(!free->hdr.firstdb);
1864
1847 /* 1865 /*
1848 * Now see if the leafn and free data will fit in a leaf1. 1866 * Now see if the leafn and free data will fit in a leaf1.
1849 * If not, release the buffer and give up. 1867 * If not, release the buffer and give up.
1850 */ 1868 */
1851 if ((uint)sizeof(leaf->hdr) + 1869 if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) >
1852 (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) + 1870 mp->m_dirblksize) {
1853 be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) +
1854 (uint)sizeof(leaf->tail) >
1855 mp->m_dirblksize) {
1856 xfs_da_brelse(tp, fbp); 1871 xfs_da_brelse(tp, fbp);
1857 return 0; 1872 return 0;
1858 } 1873 }
1874
1859 /* 1875 /*
1860 * If the leaf has any stale entries in it, compress them out. 1876 * If the leaf has any stale entries in it, compress them out.
1861 * The compact routine will log the header. 1877 * The compact routine will log the header.
@@ -1874,7 +1890,7 @@ xfs_dir2_node_to_leaf(
1874 * Set up the leaf bests table. 1890 * Set up the leaf bests table.
1875 */ 1891 */
1876 memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests, 1892 memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests,
1877 be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); 1893 be32_to_cpu(ltp->bestcount) * sizeof(xfs_dir2_data_off_t));
1878 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1894 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1879 xfs_dir2_leaf_log_tail(tp, lbp); 1895 xfs_dir2_leaf_log_tail(tp, lbp);
1880 xfs_dir2_leaf_check(dp, lbp); 1896 xfs_dir2_leaf_check(dp, lbp);
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
index bc620622c342..140281adc7e5 100644
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -18,6 +18,36 @@
18#ifndef __XFS_DIR2_LEAF_H__ 18#ifndef __XFS_DIR2_LEAF_H__
19#define __XFS_DIR2_LEAF_H__ 19#define __XFS_DIR2_LEAF_H__
20 20
21/*
22 * Directory format 2, leaf block structures.
23 *
24 * A pure data block looks like the following drawing on disk:
25 *
26 * +---------------------------+
27 * | xfs_dir2_leaf_hdr_t |
28 * +---------------------------+
29 * | xfs_dir2_leaf_entry_t |
30 * | xfs_dir2_leaf_entry_t |
31 * | xfs_dir2_leaf_entry_t |
32 * | xfs_dir2_leaf_entry_t |
33 * | ... |
34 * +---------------------------+
35 * | xfs_dir2_data_off_t |
36 * | xfs_dir2_data_off_t |
37 * | xfs_dir2_data_off_t |
38 * | ... |
39 * +---------------------------+
40 * | xfs_dir2_leaf_tail_t |
41 * +---------------------------+
42 *
43 * The bests (xfs_dir2_data_off_t members) and tail are at the end of the
44 * block for single-leaf only (magic = XFS_DIR2_LEAF1_MAGIC not
45 * XFS_DIR2_LEAFN_MAGIC).
46 *
47 * As all the entries are variable size structures the accessors in this
48 * file should be used to iterate over them.
49 */
50
21struct uio; 51struct uio;
22struct xfs_dabuf; 52struct xfs_dabuf;
23struct xfs_da_args; 53struct xfs_da_args;
@@ -67,15 +97,10 @@ typedef struct xfs_dir2_leaf_tail {
67 97
68/* 98/*
69 * Leaf block. 99 * Leaf block.
70 * bests and tail are at the end of the block for single-leaf only
71 * (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC).
72 */ 100 */
73typedef struct xfs_dir2_leaf { 101typedef struct xfs_dir2_leaf {
74 xfs_dir2_leaf_hdr_t hdr; /* leaf header */ 102 xfs_dir2_leaf_hdr_t hdr; /* leaf header */
75 xfs_dir2_leaf_entry_t ents[1]; /* entries */ 103 xfs_dir2_leaf_entry_t ents[]; /* entries */
76 /* ... */
77 xfs_dir2_data_off_t bests[1]; /* best free counts */
78 xfs_dir2_leaf_tail_t tail; /* leaf tail */
79} xfs_dir2_leaf_t; 104} xfs_dir2_leaf_t;
80 105
81/* 106/*