diff options
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 34 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.h | 37 |
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 | ||
1769 | static inline size_t | ||
1770 | xfs_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 | |||
21 | struct uio; | 51 | struct uio; |
22 | struct xfs_dabuf; | 52 | struct xfs_dabuf; |
23 | struct xfs_da_args; | 53 | struct 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 | */ |
73 | typedef struct xfs_dir2_leaf { | 101 | typedef 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 | /* |