aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2011-07-13 07:43:48 -0400
committerChristoph Hellwig <hch@lst.de>2011-07-13 07:43:48 -0400
commit5792664070c62479b088e4909000582de3686396 (patch)
tree900e7d35b33da062fe8fad5694539fdad8c59266
parent2bcf6e970f5a88fa05dced5eeb0326e13d93c4a1 (diff)
xfs: reshuffle dir2 headers
Replace the current mess of dir2 headers with just three that have a clear purpose: - xfs_dir2_format.h for all format definitions, including the inline helpers to access our variable size structures - xfs_dir2_priv.h for all prototypes that are internal to the dir2 code and not needed by anything outside of the directory code. For this purpose xfs_da_btree.c, and phase6.c in xfs_repair are considered part of the directory code. - xfs_dir2.h for the public interface to the directory code In addition to the reshuffle I have also update the comments to not only match the new file structure, but also to describe the directory format better. 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_bmap.c4
-rw-r--r--fs/xfs/xfs_da_btree.c9
-rw-r--r--fs/xfs/xfs_dir2.c9
-rw-r--r--fs/xfs/xfs_dir2.h54
-rw-r--r--fs/xfs/xfs_dir2_block.c7
-rw-r--r--fs/xfs/xfs_dir2_block.h93
-rw-r--r--fs/xfs/xfs_dir2_data.c7
-rw-r--r--fs/xfs/xfs_dir2_data.h182
-rw-r--r--fs/xfs/xfs_dir2_format.h595
-rw-r--r--fs/xfs/xfs_dir2_leaf.c8
-rw-r--r--fs/xfs/xfs_dir2_leaf.h281
-rw-r--r--fs/xfs/xfs_dir2_node.c8
-rw-r--r--fs/xfs/xfs_dir2_node.h100
-rw-r--r--fs/xfs/xfs_dir2_priv.h135
-rw-r--r--fs/xfs/xfs_dir2_sf.c8
-rw-r--r--fs/xfs/xfs_dir2_sf.h151
16 files changed, 751 insertions, 900 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 2ce6aa644e7e..c51a3f903633 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -29,15 +29,11 @@
29#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
30#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
31#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
32#include "xfs_dir2_sf.h"
33#include "xfs_dinode.h" 32#include "xfs_dinode.h"
34#include "xfs_inode.h" 33#include "xfs_inode.h"
35#include "xfs_btree.h" 34#include "xfs_btree.h"
36#include "xfs_mount.h" 35#include "xfs_mount.h"
37#include "xfs_itable.h" 36#include "xfs_itable.h"
38#include "xfs_dir2_data.h"
39#include "xfs_dir2_leaf.h"
40#include "xfs_dir2_block.h"
41#include "xfs_inode_item.h" 37#include "xfs_inode_item.h"
42#include "xfs_extfree_item.h" 38#include "xfs_extfree_item.h"
43#include "xfs_alloc.h" 39#include "xfs_alloc.h"
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 18425717cbe6..a58a6410c58d 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -24,11 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir2_sf.h" 30#include "xfs_dir2.h"
31#include "xfs_dir2_format.h"
32#include "xfs_dir2_priv.h"
32#include "xfs_dinode.h" 33#include "xfs_dinode.h"
33#include "xfs_inode.h" 34#include "xfs_inode.h"
34#include "xfs_inode_item.h" 35#include "xfs_inode_item.h"
@@ -36,10 +37,6 @@
36#include "xfs_bmap.h" 37#include "xfs_bmap.h"
37#include "xfs_attr.h" 38#include "xfs_attr.h"
38#include "xfs_attr_leaf.h" 39#include "xfs_attr_leaf.h"
39#include "xfs_dir2_data.h"
40#include "xfs_dir2_leaf.h"
41#include "xfs_dir2_block.h"
42#include "xfs_dir2_node.h"
43#include "xfs_error.h" 40#include "xfs_error.h"
44#include "xfs_trace.h" 41#include "xfs_trace.h"
45 42
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 0dee57812f45..6effbeb24e5a 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -24,20 +24,17 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
32#include "xfs_dir2_sf.h"
33#include "xfs_dinode.h" 31#include "xfs_dinode.h"
34#include "xfs_inode.h" 32#include "xfs_inode.h"
35#include "xfs_inode_item.h" 33#include "xfs_inode_item.h"
36#include "xfs_bmap.h" 34#include "xfs_bmap.h"
37#include "xfs_dir2_data.h" 35#include "xfs_dir2.h"
38#include "xfs_dir2_leaf.h" 36#include "xfs_dir2_format.h"
39#include "xfs_dir2_block.h" 37#include "xfs_dir2_priv.h"
40#include "xfs_dir2_node.h"
41#include "xfs_error.h" 38#include "xfs_error.h"
42#include "xfs_vnodeops.h" 39#include "xfs_vnodeops.h"
43#include "xfs_trace.h" 40#include "xfs_trace.h"
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 74a3b1057685..e937d9991c18 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -16,49 +16,14 @@
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18#ifndef __XFS_DIR2_H__ 18#ifndef __XFS_DIR2_H__
19#define __XFS_DIR2_H__ 19#define __XFS_DIR2_H__
20 20
21struct uio;
22struct xfs_dabuf;
23struct xfs_da_args;
24struct xfs_dir2_put_args;
25struct xfs_bmap_free; 21struct xfs_bmap_free;
22struct xfs_da_args;
26struct xfs_inode; 23struct xfs_inode;
27struct xfs_mount; 24struct xfs_mount;
28struct xfs_trans; 25struct xfs_trans;
29 26
30/*
31 * Directory version 2.
32 * There are 4 possible formats:
33 * shortform
34 * single block - data with embedded leaf at the end
35 * multiple data blocks, single leaf+freeindex block
36 * data blocks, node&leaf blocks (btree), freeindex blocks
37 *
38 * The shortform format is in xfs_dir2_sf.h.
39 * The single block format is in xfs_dir2_block.h.
40 * The data block format is in xfs_dir2_data.h.
41 * The leaf and freeindex block formats are in xfs_dir2_leaf.h.
42 * Node blocks are the same as the other version, in xfs_da_btree.h.
43 */
44
45/*
46 * Byte offset in data block and shortform entry.
47 */
48typedef __uint16_t xfs_dir2_data_off_t;
49#define NULLDATAOFF 0xffffU
50typedef uint xfs_dir2_data_aoff_t; /* argument form */
51
52/*
53 * Directory block number (logical dirblk in file)
54 */
55typedef __uint32_t xfs_dir2_db_t;
56
57/*
58 * Byte offset in a directory.
59 */
60typedef xfs_off_t xfs_dir2_off_t;
61
62extern struct xfs_name xfs_name_dotdot; 27extern struct xfs_name xfs_name_dotdot;
63 28
64/* 29/*
@@ -86,21 +51,10 @@ extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
86 struct xfs_bmap_free *flist, xfs_extlen_t tot); 51 struct xfs_bmap_free *flist, xfs_extlen_t tot);
87extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, 52extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
88 struct xfs_name *name, uint resblks); 53 struct xfs_name *name, uint resblks);
89extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
90 54
91/* 55/*
92 * Utility routines for v2 directories. 56 * Direct call from the bmap code, bypassing the generic directory layer.
93 */ 57 */
94extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, 58extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
95 xfs_dir2_db_t *dbp);
96extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp,
97 int *vp);
98extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp,
99 int *vp);
100extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
101 struct xfs_dabuf *bp);
102
103extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
104 const unsigned char *name, int len);
105 59
106#endif /* __XFS_DIR2_H__ */ 60#endif /* __XFS_DIR2_H__ */
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 70fb0cb6bd69..9245e029b8ea 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -23,17 +23,14 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_inode_item.h" 31#include "xfs_inode_item.h"
34#include "xfs_dir2_data.h" 32#include "xfs_dir2_format.h"
35#include "xfs_dir2_leaf.h" 33#include "xfs_dir2_priv.h"
36#include "xfs_dir2_block.h"
37#include "xfs_error.h" 34#include "xfs_error.h"
38#include "xfs_trace.h" 35#include "xfs_trace.h"
39 36
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h
deleted file mode 100644
index de59677e38ba..000000000000
--- a/fs/xfs/xfs_dir2_block.h
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_BLOCK_H__
19#define __XFS_DIR2_BLOCK_H__
20
21/*
22 * Directory version 2, single block format structures.
23 *
24 * The single block format looks like the following drawing on disk:
25 *
26 * +-------------------------------------------------+
27 * | xfs_dir2_data_hdr_t |
28 * +-------------------------------------------------+
29 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
30 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
31 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
32 * | ... |
33 * +-------------------------------------------------+
34 * | unused space |
35 * +-------------------------------------------------+
36 * | ... |
37 * | xfs_dir2_leaf_entry_t |
38 * | xfs_dir2_leaf_entry_t |
39 * +-------------------------------------------------+
40 * | xfs_dir2_block_tail_t |
41 * +-------------------------------------------------+
42 *
43 * As all the entries are variable size structures the accessors in this
44 * file and xfs_dir2_data.h should be used to iterate over them.
45 */
46struct uio;
47struct xfs_dabuf;
48struct xfs_da_args;
49struct xfs_dir2_data_hdr;
50struct xfs_dir2_leaf_entry;
51struct xfs_inode;
52struct xfs_mount;
53struct xfs_trans;
54
55#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */
56
57typedef struct xfs_dir2_block_tail {
58 __be32 count; /* count of leaf entries */
59 __be32 stale; /* count of stale lf entries */
60} xfs_dir2_block_tail_t;
61
62/*
63 * Pointer to the leaf header embedded in a data block (1-block format)
64 */
65static inline xfs_dir2_block_tail_t *
66xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_data_hdr_t *hdr)
67{
68 return ((xfs_dir2_block_tail_t *)((char *)hdr + mp->m_dirblksize)) - 1;
69}
70
71/*
72 * Pointer to the leaf entries embedded in a data block (1-block format)
73 */
74static inline struct xfs_dir2_leaf_entry *
75xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
76{
77 return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
78}
79
80/*
81 * Function declarations.
82 */
83extern int xfs_dir2_block_addname(struct xfs_da_args *args);
84extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
85 xfs_off_t *offset, filldir_t filldir);
86extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
87extern int xfs_dir2_block_removename(struct xfs_da_args *args);
88extern int xfs_dir2_block_replace(struct xfs_da_args *args);
89extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
90 struct xfs_dabuf *lbp, struct xfs_dabuf *dbp);
91extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
92
93#endif /* __XFS_DIR2_BLOCK_H__ */
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 32dca4c531a6..5bbe2a8a023f 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -23,16 +23,13 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_dir2_data.h" 31#include "xfs_dir2_format.h"
34#include "xfs_dir2_leaf.h" 32#include "xfs_dir2_priv.h"
35#include "xfs_dir2_block.h"
36#include "xfs_error.h" 33#include "xfs_error.h"
37 34
38STATIC xfs_dir2_data_free_t * 35STATIC xfs_dir2_data_free_t *
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
deleted file mode 100644
index c50512584ebf..000000000000
--- a/fs/xfs/xfs_dir2_data.h
+++ /dev/null
@@ -1,182 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_DATA_H__
19#define __XFS_DIR2_DATA_H__
20
21/*
22 * Directory format 2, data block structures.
23 *
24 * A pure data block looks like the following drawing on disk:
25 *
26 * +-------------------------------------------------+
27 * | xfs_dir2_data_hdr_t |
28 * +-------------------------------------------------+
29 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
30 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
31 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
32 * | ... |
33 * +-------------------------------------------------+
34 * | unused space |
35 * +-------------------------------------------------+
36 *
37 * As all the entries are variable size structures the accessors in this
38 * file should be used to iterate over them.
39 */
40
41struct xfs_dabuf;
42struct xfs_da_args;
43struct xfs_inode;
44struct xfs_trans;
45
46/*
47 * Constants.
48 */
49#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */
50#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
51#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
52#define XFS_DIR2_DATA_FREE_TAG 0xffff
53#define XFS_DIR2_DATA_FD_COUNT 3
54
55/*
56 * Directory address space divided into sections,
57 * spaces separated by 32GB.
58 */
59#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
60#define XFS_DIR2_DATA_SPACE 0
61#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
62#define XFS_DIR2_DATA_FIRSTDB(mp) \
63 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
64
65/*
66 * Offsets of . and .. in data space (always block 0)
67 */
68#define XFS_DIR2_DATA_DOT_OFFSET \
69 ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t))
70#define XFS_DIR2_DATA_DOTDOT_OFFSET \
71 (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
72#define XFS_DIR2_DATA_FIRST_OFFSET \
73 (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
74
75/*
76 * Structures.
77 */
78
79/*
80 * Describe a free area in the data block.
81 * The freespace will be formatted as a xfs_dir2_data_unused_t.
82 */
83typedef struct xfs_dir2_data_free {
84 __be16 offset; /* start of freespace */
85 __be16 length; /* length of freespace */
86} xfs_dir2_data_free_t;
87
88/*
89 * Header for the data blocks.
90 * Always at the beginning of a directory-sized block.
91 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
92 */
93typedef struct xfs_dir2_data_hdr {
94 __be32 magic; /* XFS_DIR2_DATA_MAGIC */
95 /* or XFS_DIR2_BLOCK_MAGIC */
96 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
97} xfs_dir2_data_hdr_t;
98
99/*
100 * Active entry in a data block. Aligned to 8 bytes.
101 *
102 * After the variable length name field there is a 2 byte tag field, which
103 * can be accessed using xfs_dir2_data_entry_tag_p.
104 */
105typedef struct xfs_dir2_data_entry {
106 __be64 inumber; /* inode number */
107 __u8 namelen; /* name length */
108 __u8 name[]; /* name bytes, no null */
109 /* __be16 tag; */ /* starting offset of us */
110} xfs_dir2_data_entry_t;
111
112/*
113 * Unused entry in a data block. Aligned to 8 bytes.
114 * Tag appears as the last 2 bytes.
115 */
116typedef struct xfs_dir2_data_unused {
117 __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
118 __be16 length; /* total free length */
119 /* variable offset */
120 __be16 tag; /* starting offset of us */
121} xfs_dir2_data_unused_t;
122
123/*
124 * Size of a data entry.
125 */
126static inline int xfs_dir2_data_entsize(int n)
127{
128 return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \
129 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
130}
131
132/*
133 * Pointer to an entry's tag word.
134 */
135static inline __be16 *
136xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
137{
138 return (__be16 *)((char *)dep +
139 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
140}
141
142/*
143 * Pointer to a freespace's tag word.
144 */
145static inline __be16 *
146xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup)
147{
148 return (__be16 *)((char *)dup +
149 be16_to_cpu(dup->length) - sizeof(__be16));
150}
151
152/*
153 * Function declarations.
154 */
155#ifdef DEBUG
156extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
157#else
158#define xfs_dir2_data_check(dp,bp)
159#endif
160extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_hdr_t *hdr,
161 xfs_dir2_data_unused_t *dup, int *loghead);
162extern void xfs_dir2_data_freescan(struct xfs_mount *mp,
163 xfs_dir2_data_hdr_t *hdr, int *loghead);
164extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
165 struct xfs_dabuf **bpp);
166extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
167 xfs_dir2_data_entry_t *dep);
168extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
169 struct xfs_dabuf *bp);
170extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
171 xfs_dir2_data_unused_t *dup);
172extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
173 xfs_dir2_data_aoff_t offset,
174 xfs_dir2_data_aoff_t len, int *needlogp,
175 int *needscanp);
176extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
177 xfs_dir2_data_unused_t *dup,
178 xfs_dir2_data_aoff_t offset,
179 xfs_dir2_data_aoff_t len, int *needlogp,
180 int *needscanp);
181
182#endif /* __XFS_DIR2_DATA_H__ */
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h
new file mode 100644
index 000000000000..c3c4839eebd6
--- /dev/null
+++ b/fs/xfs/xfs_dir2_format.h
@@ -0,0 +1,595 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_FORMAT_H__
19#define __XFS_DIR2_FORMAT_H__
20
21/*
22 * Directory version 2.
23 *
24 * There are 4 possible formats:
25 * - shortform - embedded into the inode
26 * - single block - data with embedded leaf at the end
27 * - multiple data blocks, single leaf+freeindex block
28 * - data blocks, node and leaf blocks (btree), freeindex blocks
29 *
30 * Note: many node blocks structures and constants are shared with the attr
31 * code and defined in xfs_da_btree.h.
32 */
33
34#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: single block dirs */
35#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: multiblock dirs */
36#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F: free index blocks */
37
38/*
39 * Byte offset in data block and shortform entry.
40 */
41typedef __uint16_t xfs_dir2_data_off_t;
42#define NULLDATAOFF 0xffffU
43typedef uint xfs_dir2_data_aoff_t; /* argument form */
44
45/*
46 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
47 * Only need 16 bits, this is the byte offset into the single block form.
48 */
49typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
50
51/*
52 * Offset in data space of a data entry.
53 */
54typedef __uint32_t xfs_dir2_dataptr_t;
55#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff)
56#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
57
58/*
59 * Byte offset in a directory.
60 */
61typedef xfs_off_t xfs_dir2_off_t;
62
63/*
64 * Directory block number (logical dirblk in file)
65 */
66typedef __uint32_t xfs_dir2_db_t;
67
68/*
69 * Inode number stored as 8 8-bit values.
70 */
71typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
72
73/*
74 * Inode number stored as 4 8-bit values.
75 * Works a lot of the time, when all the inode numbers in a directory
76 * fit in 32 bits.
77 */
78typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
79
80typedef union {
81 xfs_dir2_ino8_t i8;
82 xfs_dir2_ino4_t i4;
83} xfs_dir2_inou_t;
84#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
85
86/*
87 * Directory layout when stored internal to an inode.
88 *
89 * Small directories are packed as tightly as possible so as to fit into the
90 * literal area of the inode. These "shortform" directories consist of a
91 * single xfs_dir2_sf_hdr header followed by zero or more xfs_dir2_sf_entry
92 * structures. Due the different inode number storage size and the variable
93 * length name field in the xfs_dir2_sf_entry all these structure are
94 * variable length, and the accessors in this file should be used to iterate
95 * over them.
96 */
97typedef struct xfs_dir2_sf_hdr {
98 __uint8_t count; /* count of entries */
99 __uint8_t i8count; /* count of 8-byte inode #s */
100 xfs_dir2_inou_t parent; /* parent dir inode number */
101} __arch_pack xfs_dir2_sf_hdr_t;
102
103typedef struct xfs_dir2_sf_entry {
104 __u8 namelen; /* actual name length */
105 xfs_dir2_sf_off_t offset; /* saved offset */
106 __u8 name[]; /* name, variable size */
107 /*
108 * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a
109 * variable offset after the name.
110 */
111} __arch_pack xfs_dir2_sf_entry_t;
112
113static inline int xfs_dir2_sf_hdr_size(int i8count)
114{
115 return sizeof(struct xfs_dir2_sf_hdr) -
116 (i8count == 0) *
117 (sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t));
118}
119
120static inline xfs_dir2_data_aoff_t
121xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
122{
123 return get_unaligned_be16(&sfep->offset.i);
124}
125
126static inline void
127xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
128{
129 put_unaligned_be16(off, &sfep->offset.i);
130}
131
132static inline int
133xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
134{
135 return sizeof(struct xfs_dir2_sf_entry) + /* namelen + offset */
136 len + /* name */
137 (hdr->i8count ? /* ino */
138 sizeof(xfs_dir2_ino8_t) :
139 sizeof(xfs_dir2_ino4_t));
140}
141
142static inline struct xfs_dir2_sf_entry *
143xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
144{
145 return (struct xfs_dir2_sf_entry *)
146 ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
147}
148
149static inline struct xfs_dir2_sf_entry *
150xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
151 struct xfs_dir2_sf_entry *sfep)
152{
153 return (struct xfs_dir2_sf_entry *)
154 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
155}
156
157
158/*
159 * Data block structures.
160 *
161 * A pure data block looks like the following drawing on disk:
162 *
163 * +-------------------------------------------------+
164 * | xfs_dir2_data_hdr_t |
165 * +-------------------------------------------------+
166 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
167 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
168 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
169 * | ... |
170 * +-------------------------------------------------+
171 * | unused space |
172 * +-------------------------------------------------+
173 *
174 * As all the entries are variable size structures the accessors below should
175 * be used to iterate over them.
176 *
177 * In addition to the pure data blocks for the data and node formats,
178 * most structures are also used for the combined data/freespace "block"
179 * format below.
180 */
181
182#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
183#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
184#define XFS_DIR2_DATA_FREE_TAG 0xffff
185#define XFS_DIR2_DATA_FD_COUNT 3
186
187/*
188 * Directory address space divided into sections,
189 * spaces separated by 32GB.
190 */
191#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
192#define XFS_DIR2_DATA_SPACE 0
193#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
194#define XFS_DIR2_DATA_FIRSTDB(mp) \
195 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
196
197/*
198 * Offsets of . and .. in data space (always block 0)
199 */
200#define XFS_DIR2_DATA_DOT_OFFSET \
201 ((xfs_dir2_data_aoff_t)sizeof(struct xfs_dir2_data_hdr))
202#define XFS_DIR2_DATA_DOTDOT_OFFSET \
203 (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
204#define XFS_DIR2_DATA_FIRST_OFFSET \
205 (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
206
207/*
208 * Describe a free area in the data block.
209 *
210 * The freespace will be formatted as a xfs_dir2_data_unused_t.
211 */
212typedef struct xfs_dir2_data_free {
213 __be16 offset; /* start of freespace */
214 __be16 length; /* length of freespace */
215} xfs_dir2_data_free_t;
216
217/*
218 * Header for the data blocks.
219 *
220 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
221 */
222typedef struct xfs_dir2_data_hdr {
223 __be32 magic; /* XFS_DIR2_DATA_MAGIC or */
224 /* XFS_DIR2_BLOCK_MAGIC */
225 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
226} xfs_dir2_data_hdr_t;
227
228/*
229 * Active entry in a data block.
230 *
231 * Aligned to 8 bytes. After the variable length name field there is a
232 * 2 byte tag field, which can be accessed using xfs_dir2_data_entry_tag_p.
233 */
234typedef struct xfs_dir2_data_entry {
235 __be64 inumber; /* inode number */
236 __u8 namelen; /* name length */
237 __u8 name[]; /* name bytes, no null */
238 /* __be16 tag; */ /* starting offset of us */
239} xfs_dir2_data_entry_t;
240
241/*
242 * Unused entry in a data block.
243 *
244 * Aligned to 8 bytes. Tag appears as the last 2 bytes and must be accessed
245 * using xfs_dir2_data_unused_tag_p.
246 */
247typedef struct xfs_dir2_data_unused {
248 __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
249 __be16 length; /* total free length */
250 /* variable offset */
251 __be16 tag; /* starting offset of us */
252} xfs_dir2_data_unused_t;
253
254/*
255 * Size of a data entry.
256 */
257static inline int xfs_dir2_data_entsize(int n)
258{
259 return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
260 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
261}
262
263/*
264 * Pointer to an entry's tag word.
265 */
266static inline __be16 *
267xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
268{
269 return (__be16 *)((char *)dep +
270 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
271}
272
273/*
274 * Pointer to a freespace's tag word.
275 */
276static inline __be16 *
277xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
278{
279 return (__be16 *)((char *)dup +
280 be16_to_cpu(dup->length) - sizeof(__be16));
281}
282
283/*
284 * Leaf block structures.
285 *
286 * A pure leaf block looks like the following drawing on disk:
287 *
288 * +---------------------------+
289 * | xfs_dir2_leaf_hdr_t |
290 * +---------------------------+
291 * | xfs_dir2_leaf_entry_t |
292 * | xfs_dir2_leaf_entry_t |
293 * | xfs_dir2_leaf_entry_t |
294 * | xfs_dir2_leaf_entry_t |
295 * | ... |
296 * +---------------------------+
297 * | xfs_dir2_data_off_t |
298 * | xfs_dir2_data_off_t |
299 * | xfs_dir2_data_off_t |
300 * | ... |
301 * +---------------------------+
302 * | xfs_dir2_leaf_tail_t |
303 * +---------------------------+
304 *
305 * The xfs_dir2_data_off_t members (bests) and tail are at the end of the block
306 * for single-leaf (magic = XFS_DIR2_LEAF1_MAGIC) blocks only, but not present
307 * for directories with separate leaf nodes and free space blocks
308 * (magic = XFS_DIR2_LEAFN_MAGIC).
309 *
310 * As all the entries are variable size structures the accessors below should
311 * be used to iterate over them.
312 */
313
314/*
315 * Offset of the leaf/node space. First block in this space
316 * is the btree root.
317 */
318#define XFS_DIR2_LEAF_SPACE 1
319#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
320#define XFS_DIR2_LEAF_FIRSTDB(mp) \
321 xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
322
323/*
324 * Leaf block header.
325 */
326typedef struct xfs_dir2_leaf_hdr {
327 xfs_da_blkinfo_t info; /* header for da routines */
328 __be16 count; /* count of entries */
329 __be16 stale; /* count of stale entries */
330} xfs_dir2_leaf_hdr_t;
331
332/*
333 * Leaf block entry.
334 */
335typedef struct xfs_dir2_leaf_entry {
336 __be32 hashval; /* hash value of name */
337 __be32 address; /* address of data entry */
338} xfs_dir2_leaf_entry_t;
339
340/*
341 * Leaf block tail.
342 */
343typedef struct xfs_dir2_leaf_tail {
344 __be32 bestcount;
345} xfs_dir2_leaf_tail_t;
346
347/*
348 * Leaf block.
349 */
350typedef struct xfs_dir2_leaf {
351 xfs_dir2_leaf_hdr_t hdr; /* leaf header */
352 xfs_dir2_leaf_entry_t ents[]; /* entries */
353} xfs_dir2_leaf_t;
354
355/*
356 * DB blocks here are logical directory block numbers, not filesystem blocks.
357 */
358
359static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
360{
361 return (mp->m_dirblksize - (uint)sizeof(struct xfs_dir2_leaf_hdr)) /
362 (uint)sizeof(struct xfs_dir2_leaf_entry);
363}
364
365/*
366 * Get address of the bestcount field in the single-leaf block.
367 */
368static inline struct xfs_dir2_leaf_tail *
369xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
370{
371 return (struct xfs_dir2_leaf_tail *)
372 ((char *)lp + mp->m_dirblksize -
373 sizeof(struct xfs_dir2_leaf_tail));
374}
375
376/*
377 * Get address of the bests array in the single-leaf block.
378 */
379static inline __be16 *
380xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
381{
382 return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
383}
384
385/*
386 * Convert dataptr to byte in file space
387 */
388static inline xfs_dir2_off_t
389xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
390{
391 return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
392}
393
394/*
395 * Convert byte in file space to dataptr. It had better be aligned.
396 */
397static inline xfs_dir2_dataptr_t
398xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
399{
400 return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
401}
402
403/*
404 * Convert byte in space to (DB) block
405 */
406static inline xfs_dir2_db_t
407xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
408{
409 return (xfs_dir2_db_t)
410 (by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
411}
412
413/*
414 * Convert dataptr to a block number
415 */
416static inline xfs_dir2_db_t
417xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
418{
419 return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
420}
421
422/*
423 * Convert byte in space to offset in a block
424 */
425static inline xfs_dir2_data_aoff_t
426xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
427{
428 return (xfs_dir2_data_aoff_t)(by &
429 ((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
430}
431
432/*
433 * Convert dataptr to a byte offset in a block
434 */
435static inline xfs_dir2_data_aoff_t
436xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
437{
438 return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
439}
440
441/*
442 * Convert block and offset to byte in space
443 */
444static inline xfs_dir2_off_t
445xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
446 xfs_dir2_data_aoff_t o)
447{
448 return ((xfs_dir2_off_t)db <<
449 (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
450}
451
452/*
453 * Convert block (DB) to block (dablk)
454 */
455static inline xfs_dablk_t
456xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
457{
458 return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
459}
460
461/*
462 * Convert byte in space to (DA) block
463 */
464static inline xfs_dablk_t
465xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
466{
467 return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
468}
469
470/*
471 * Convert block and offset to dataptr
472 */
473static inline xfs_dir2_dataptr_t
474xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
475 xfs_dir2_data_aoff_t o)
476{
477 return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
478}
479
480/*
481 * Convert block (dablk) to block (DB)
482 */
483static inline xfs_dir2_db_t
484xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
485{
486 return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
487}
488
489/*
490 * Convert block (dablk) to byte offset in space
491 */
492static inline xfs_dir2_off_t
493xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
494{
495 return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
496}
497
498/*
499 * Free space block defintions for the node format.
500 */
501
502/*
503 * Offset of the freespace index.
504 */
505#define XFS_DIR2_FREE_SPACE 2
506#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
507#define XFS_DIR2_FREE_FIRSTDB(mp) \
508 xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
509
510typedef struct xfs_dir2_free_hdr {
511 __be32 magic; /* XFS_DIR2_FREE_MAGIC */
512 __be32 firstdb; /* db of first entry */
513 __be32 nvalid; /* count of valid entries */
514 __be32 nused; /* count of used entries */
515} xfs_dir2_free_hdr_t;
516
517typedef struct xfs_dir2_free {
518 xfs_dir2_free_hdr_t hdr; /* block header */
519 __be16 bests[1]; /* best free counts */
520 /* unused entries are -1 */
521} xfs_dir2_free_t;
522
523#define XFS_DIR2_MAX_FREE_BESTS(mp) \
524 (((mp)->m_dirblksize - (uint)sizeof(struct xfs_dir2_free_hdr)) / \
525 (uint)sizeof(xfs_dir2_data_off_t))
526
527/*
528 * Convert data space db to the corresponding free db.
529 */
530static inline xfs_dir2_db_t
531xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
532{
533 return XFS_DIR2_FREE_FIRSTDB(mp) + db / XFS_DIR2_MAX_FREE_BESTS(mp);
534}
535
536/*
537 * Convert data space db to the corresponding index in a free db.
538 */
539static inline int
540xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
541{
542 return db % XFS_DIR2_MAX_FREE_BESTS(mp);
543}
544
545/*
546 * Single block format.
547 *
548 * The single block format looks like the following drawing on disk:
549 *
550 * +-------------------------------------------------+
551 * | xfs_dir2_data_hdr_t |
552 * +-------------------------------------------------+
553 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
554 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
555 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t :
556 * | ... |
557 * +-------------------------------------------------+
558 * | unused space |
559 * +-------------------------------------------------+
560 * | ... |
561 * | xfs_dir2_leaf_entry_t |
562 * | xfs_dir2_leaf_entry_t |
563 * +-------------------------------------------------+
564 * | xfs_dir2_block_tail_t |
565 * +-------------------------------------------------+
566 *
567 * As all the entries are variable size structures the accessors below should
568 * be used to iterate over them.
569 */
570
571typedef struct xfs_dir2_block_tail {
572 __be32 count; /* count of leaf entries */
573 __be32 stale; /* count of stale lf entries */
574} xfs_dir2_block_tail_t;
575
576/*
577 * Pointer to the leaf header embedded in a data block (1-block format)
578 */
579static inline struct xfs_dir2_block_tail *
580xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
581{
582 return ((struct xfs_dir2_block_tail *)
583 ((char *)hdr + mp->m_dirblksize)) - 1;
584}
585
586/*
587 * Pointer to the leaf entries embedded in a data block (1-block format)
588 */
589static inline struct xfs_dir2_leaf_entry *
590xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
591{
592 return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
593}
594
595#endif /* __XFS_DIR2_FORMAT_H__ */
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index d629b888ca28..487036d3751b 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -24,18 +24,14 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir2_sf.h"
32#include "xfs_dinode.h" 30#include "xfs_dinode.h"
33#include "xfs_inode.h" 31#include "xfs_inode.h"
34#include "xfs_bmap.h" 32#include "xfs_bmap.h"
35#include "xfs_dir2_data.h" 33#include "xfs_dir2_format.h"
36#include "xfs_dir2_leaf.h" 34#include "xfs_dir2_priv.h"
37#include "xfs_dir2_block.h"
38#include "xfs_dir2_node.h"
39#include "xfs_error.h" 35#include "xfs_error.h"
40#include "xfs_trace.h" 36#include "xfs_trace.h"
41 37
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
deleted file mode 100644
index 140281adc7e5..000000000000
--- a/fs/xfs/xfs_dir2_leaf.h
+++ /dev/null
@@ -1,281 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_LEAF_H__
19#define __XFS_DIR2_LEAF_H__
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
51struct uio;
52struct xfs_dabuf;
53struct xfs_da_args;
54struct xfs_inode;
55struct xfs_mount;
56struct xfs_trans;
57
58/*
59 * Offset of the leaf/node space. First block in this space
60 * is the btree root.
61 */
62#define XFS_DIR2_LEAF_SPACE 1
63#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
64#define XFS_DIR2_LEAF_FIRSTDB(mp) \
65 xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
66
67/*
68 * Offset in data space of a data entry.
69 */
70typedef __uint32_t xfs_dir2_dataptr_t;
71#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff)
72#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
73
74/*
75 * Leaf block header.
76 */
77typedef struct xfs_dir2_leaf_hdr {
78 xfs_da_blkinfo_t info; /* header for da routines */
79 __be16 count; /* count of entries */
80 __be16 stale; /* count of stale entries */
81} xfs_dir2_leaf_hdr_t;
82
83/*
84 * Leaf block entry.
85 */
86typedef struct xfs_dir2_leaf_entry {
87 __be32 hashval; /* hash value of name */
88 __be32 address; /* address of data entry */
89} xfs_dir2_leaf_entry_t;
90
91/*
92 * Leaf block tail.
93 */
94typedef struct xfs_dir2_leaf_tail {
95 __be32 bestcount;
96} xfs_dir2_leaf_tail_t;
97
98/*
99 * Leaf block.
100 */
101typedef struct xfs_dir2_leaf {
102 xfs_dir2_leaf_hdr_t hdr; /* leaf header */
103 xfs_dir2_leaf_entry_t ents[]; /* entries */
104} xfs_dir2_leaf_t;
105
106/*
107 * DB blocks here are logical directory block numbers, not filesystem blocks.
108 */
109
110static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
111{
112 return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) /
113 (uint)sizeof(xfs_dir2_leaf_entry_t));
114}
115
116/*
117 * Get address of the bestcount field in the single-leaf block.
118 */
119static inline xfs_dir2_leaf_tail_t *
120xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp)
121{
122 return (xfs_dir2_leaf_tail_t *)
123 ((char *)(lp) + (mp)->m_dirblksize -
124 (uint)sizeof(xfs_dir2_leaf_tail_t));
125}
126
127/*
128 * Get address of the bests array in the single-leaf block.
129 */
130static inline __be16 *
131xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp)
132{
133 return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
134}
135
136/*
137 * Convert dataptr to byte in file space
138 */
139static inline xfs_dir2_off_t
140xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
141{
142 return (xfs_dir2_off_t)(dp) << XFS_DIR2_DATA_ALIGN_LOG;
143}
144
145/*
146 * Convert byte in file space to dataptr. It had better be aligned.
147 */
148static inline xfs_dir2_dataptr_t
149xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
150{
151 return (xfs_dir2_dataptr_t)((by) >> XFS_DIR2_DATA_ALIGN_LOG);
152}
153
154/*
155 * Convert byte in space to (DB) block
156 */
157static inline xfs_dir2_db_t
158xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
159{
160 return (xfs_dir2_db_t)((by) >> \
161 ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog));
162}
163
164/*
165 * Convert dataptr to a block number
166 */
167static inline xfs_dir2_db_t
168xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
169{
170 return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
171}
172
173/*
174 * Convert byte in space to offset in a block
175 */
176static inline xfs_dir2_data_aoff_t
177xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
178{
179 return (xfs_dir2_data_aoff_t)((by) & \
180 ((1 << ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) - 1));
181}
182
183/*
184 * Convert dataptr to a byte offset in a block
185 */
186static inline xfs_dir2_data_aoff_t
187xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
188{
189 return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
190}
191
192/*
193 * Convert block and offset to byte in space
194 */
195static inline xfs_dir2_off_t
196xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
197 xfs_dir2_data_aoff_t o)
198{
199 return ((xfs_dir2_off_t)(db) << \
200 ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) + (o);
201}
202
203/*
204 * Convert block (DB) to block (dablk)
205 */
206static inline xfs_dablk_t
207xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
208{
209 return (xfs_dablk_t)((db) << (mp)->m_sb.sb_dirblklog);
210}
211
212/*
213 * Convert byte in space to (DA) block
214 */
215static inline xfs_dablk_t
216xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
217{
218 return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
219}
220
221/*
222 * Convert block and offset to dataptr
223 */
224static inline xfs_dir2_dataptr_t
225xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
226 xfs_dir2_data_aoff_t o)
227{
228 return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
229}
230
231/*
232 * Convert block (dablk) to block (DB)
233 */
234static inline xfs_dir2_db_t
235xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
236{
237 return (xfs_dir2_db_t)((da) >> (mp)->m_sb.sb_dirblklog);
238}
239
240/*
241 * Convert block (dablk) to byte offset in space
242 */
243static inline xfs_dir2_off_t
244xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
245{
246 return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
247}
248
249/*
250 * Function declarations.
251 */
252extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
253 struct xfs_dabuf *dbp);
254extern int xfs_dir2_leaf_addname(struct xfs_da_args *args);
255extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
256 struct xfs_dabuf *bp);
257extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
258 int *lowstalep, int *highstalep,
259 int *lowlogp, int *highlogp);
260extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
261 size_t bufsize, xfs_off_t *offset,
262 filldir_t filldir);
263extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
264 struct xfs_dabuf **bpp, int magic);
265extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
266 int first, int last);
267extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp,
268 struct xfs_dabuf *bp);
269extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
270extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
271extern int xfs_dir2_leaf_replace(struct xfs_da_args *args);
272extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
273 struct xfs_dabuf *lbp);
274extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
275 struct xfs_dabuf *lbp, xfs_dir2_db_t db);
276extern xfs_dir2_leaf_entry_t *xfs_dir2_leaf_find_entry(xfs_dir2_leaf_t *, int,
277 int, int, int,
278 int *, int *);
279extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
280
281#endif /* __XFS_DIR2_LEAF_H__ */
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 14571cdeb33f..ec0a23e96705 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -23,18 +23,14 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_bmap.h" 31#include "xfs_bmap.h"
34#include "xfs_dir2_data.h" 32#include "xfs_dir2_format.h"
35#include "xfs_dir2_leaf.h" 33#include "xfs_dir2_priv.h"
36#include "xfs_dir2_block.h"
37#include "xfs_dir2_node.h"
38#include "xfs_error.h" 34#include "xfs_error.h"
39#include "xfs_trace.h" 35#include "xfs_trace.h"
40 36
diff --git a/fs/xfs/xfs_dir2_node.h b/fs/xfs/xfs_dir2_node.h
deleted file mode 100644
index 82dfe7147195..000000000000
--- a/fs/xfs/xfs_dir2_node.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_NODE_H__
19#define __XFS_DIR2_NODE_H__
20
21/*
22 * Directory version 2, btree node format structures
23 */
24
25struct uio;
26struct xfs_dabuf;
27struct xfs_da_args;
28struct xfs_da_state;
29struct xfs_da_state_blk;
30struct xfs_inode;
31struct xfs_trans;
32
33/*
34 * Offset of the freespace index.
35 */
36#define XFS_DIR2_FREE_SPACE 2
37#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
38#define XFS_DIR2_FREE_FIRSTDB(mp) \
39 xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
40
41#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */
42
43typedef struct xfs_dir2_free_hdr {
44 __be32 magic; /* XFS_DIR2_FREE_MAGIC */
45 __be32 firstdb; /* db of first entry */
46 __be32 nvalid; /* count of valid entries */
47 __be32 nused; /* count of used entries */
48} xfs_dir2_free_hdr_t;
49
50typedef struct xfs_dir2_free {
51 xfs_dir2_free_hdr_t hdr; /* block header */
52 __be16 bests[1]; /* best free counts */
53 /* unused entries are -1 */
54} xfs_dir2_free_t;
55
56#define XFS_DIR2_MAX_FREE_BESTS(mp) \
57 (((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_free_hdr_t)) / \
58 (uint)sizeof(xfs_dir2_data_off_t))
59
60/*
61 * Convert data space db to the corresponding free db.
62 */
63static inline xfs_dir2_db_t
64xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
65{
66 return (XFS_DIR2_FREE_FIRSTDB(mp) + (db) / XFS_DIR2_MAX_FREE_BESTS(mp));
67}
68
69/*
70 * Convert data space db to the corresponding index in a free db.
71 */
72static inline int
73xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
74{
75 return ((db) % XFS_DIR2_MAX_FREE_BESTS(mp));
76}
77
78extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
79 struct xfs_dabuf *lbp);
80extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count);
81extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp,
82 struct xfs_da_args *args, int *indexp,
83 struct xfs_da_state *state);
84extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp,
85 struct xfs_dabuf *leaf2_bp);
86extern int xfs_dir2_leafn_split(struct xfs_da_state *state,
87 struct xfs_da_state_blk *oldblk,
88 struct xfs_da_state_blk *newblk);
89extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action);
90extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state,
91 struct xfs_da_state_blk *drop_blk,
92 struct xfs_da_state_blk *save_blk);
93extern int xfs_dir2_node_addname(struct xfs_da_args *args);
94extern int xfs_dir2_node_lookup(struct xfs_da_args *args);
95extern int xfs_dir2_node_removename(struct xfs_da_args *args);
96extern int xfs_dir2_node_replace(struct xfs_da_args *args);
97extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo,
98 int *rvalp);
99
100#endif /* __XFS_DIR2_NODE_H__ */
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h
new file mode 100644
index 000000000000..067f403ecf8a
--- /dev/null
+++ b/fs/xfs/xfs_dir2_priv.h
@@ -0,0 +1,135 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_PRIV_H__
19#define __XFS_DIR2_PRIV_H__
20
21/* xfs_dir2.c */
22extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
23extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
24extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
25extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
26 xfs_dir2_db_t *dbp);
27extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
28 struct xfs_dabuf *bp);
29extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
30 const unsigned char *name, int len);
31
32/* xfs_dir2_block.c */
33extern int xfs_dir2_block_addname(struct xfs_da_args *args);
34extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
35 xfs_off_t *offset, filldir_t filldir);
36extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
37extern int xfs_dir2_block_removename(struct xfs_da_args *args);
38extern int xfs_dir2_block_replace(struct xfs_da_args *args);
39extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
40 struct xfs_dabuf *lbp, struct xfs_dabuf *dbp);
41
42/* xfs_dir2_data.c */
43#ifdef DEBUG
44extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
45#else
46#define xfs_dir2_data_check(dp,bp)
47#endif
48extern struct xfs_dir2_data_free *
49xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,
50 struct xfs_dir2_data_unused *dup, int *loghead);
51extern void xfs_dir2_data_freescan(struct xfs_mount *mp,
52 struct xfs_dir2_data_hdr *hdr, int *loghead);
53extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
54 struct xfs_dabuf **bpp);
55extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
56 struct xfs_dir2_data_entry *dep);
57extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
58 struct xfs_dabuf *bp);
59extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
60 struct xfs_dir2_data_unused *dup);
61extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
62 xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
63 int *needlogp, int *needscanp);
64extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
65 struct xfs_dir2_data_unused *dup, xfs_dir2_data_aoff_t offset,
66 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
67
68/* xfs_dir2_leaf.c */
69extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
70 struct xfs_dabuf *dbp);
71extern int xfs_dir2_leaf_addname(struct xfs_da_args *args);
72extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
73 struct xfs_dabuf *bp);
74extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
75 int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
76extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
77 size_t bufsize, xfs_off_t *offset, filldir_t filldir);
78extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
79 struct xfs_dabuf **bpp, int magic);
80extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
81 int first, int last);
82extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp,
83 struct xfs_dabuf *bp);
84extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
85extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
86extern int xfs_dir2_leaf_replace(struct xfs_da_args *args);
87extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
88 struct xfs_dabuf *lbp);
89extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
90 struct xfs_dabuf *lbp, xfs_dir2_db_t db);
91extern struct xfs_dir2_leaf_entry *
92xfs_dir2_leaf_find_entry(struct xfs_dir2_leaf *leaf, int index, int compact,
93 int lowstale, int highstale,
94 int *lfloglow, int *lfloghigh);
95extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
96
97/* xfs_dir2_node.c */
98extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
99 struct xfs_dabuf *lbp);
100extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count);
101extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp,
102 struct xfs_da_args *args, int *indexp,
103 struct xfs_da_state *state);
104extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp,
105 struct xfs_dabuf *leaf2_bp);
106extern int xfs_dir2_leafn_split(struct xfs_da_state *state,
107 struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk);
108extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action);
109extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state,
110 struct xfs_da_state_blk *drop_blk,
111 struct xfs_da_state_blk *save_blk);
112extern int xfs_dir2_node_addname(struct xfs_da_args *args);
113extern int xfs_dir2_node_lookup(struct xfs_da_args *args);
114extern int xfs_dir2_node_removename(struct xfs_da_args *args);
115extern int xfs_dir2_node_replace(struct xfs_da_args *args);
116extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo,
117 int *rvalp);
118
119/* xfs_dir2_sf.c */
120extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp);
121extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp,
122 struct xfs_dir2_sf_entry *sfep);
123extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
124 struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp);
125extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
126 int size, xfs_dir2_sf_hdr_t *sfhp);
127extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
128extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
129extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
130 xfs_off_t *offset, filldir_t filldir);
131extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
132extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
133extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
134
135#endif /* __XFS_DIR2_PRIV_H__ */
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index 9d3dff2ae4c5..79d05e84e296 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -23,18 +23,16 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_inode_item.h" 31#include "xfs_inode_item.h"
34#include "xfs_error.h" 32#include "xfs_error.h"
35#include "xfs_dir2_data.h" 33#include "xfs_dir2.h"
36#include "xfs_dir2_leaf.h" 34#include "xfs_dir2_format.h"
37#include "xfs_dir2_block.h" 35#include "xfs_dir2_priv.h"
38#include "xfs_trace.h" 36#include "xfs_trace.h"
39 37
40/* 38/*
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h
deleted file mode 100644
index 26f062912395..000000000000
--- a/fs/xfs/xfs_dir2_sf.h
+++ /dev/null
@@ -1,151 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_SF_H__
19#define __XFS_DIR2_SF_H__
20
21/*
22 * Directory layout when stored internal to an inode.
23 *
24 * Small directories are packed as tightly as possible so as to fit into the
25 * literal area of the inode. They consist of a single xfs_dir2_sf_hdr header
26 * followed by zero or more xfs_dir2_sf_entry structures. Due the different
27 * inode number storage size and the variable length name field in
28 * the xfs_dir2_sf_entry all these structure are variable length, and the
29 * accessors in this file should be used to iterate over them.
30 */
31
32struct uio;
33struct xfs_dabuf;
34struct xfs_da_args;
35struct xfs_dir2_data_hdr;
36struct xfs_inode;
37struct xfs_mount;
38struct xfs_trans;
39
40/*
41 * Inode number stored as 8 8-bit values.
42 */
43typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
44
45/*
46 * Inode number stored as 4 8-bit values.
47 * Works a lot of the time, when all the inode numbers in a directory
48 * fit in 32 bits.
49 */
50typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
51
52typedef union {
53 xfs_dir2_ino8_t i8;
54 xfs_dir2_ino4_t i4;
55} xfs_dir2_inou_t;
56#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
57
58/*
59 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
60 * Only need 16 bits, this is the byte offset into the single block form.
61 */
62typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
63
64/*
65 * The parent directory has a dedicated field, and the self-pointer must
66 * be calculated on the fly.
67 *
68 * Entries are packed toward the top as tightly as possible, and thus may
69 * be misaligned. Care needs to be taken to access them through special
70 * helpers or copy them into aligned variables first.
71 */
72typedef struct xfs_dir2_sf_hdr {
73 __uint8_t count; /* count of entries */
74 __uint8_t i8count; /* count of 8-byte inode #s */
75 xfs_dir2_inou_t parent; /* parent dir inode number */
76} __arch_pack xfs_dir2_sf_hdr_t;
77
78typedef struct xfs_dir2_sf_entry {
79 __u8 namelen; /* actual name length */
80 xfs_dir2_sf_off_t offset; /* saved offset */
81 __u8 name[]; /* name, variable size */
82 /*
83 * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a
84 * variable offset after the name.
85 */
86} __arch_pack xfs_dir2_sf_entry_t;
87
88static inline int xfs_dir2_sf_hdr_size(int i8count)
89{
90 return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \
91 ((i8count) == 0) * \
92 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
93}
94
95static inline xfs_dir2_data_aoff_t
96xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
97{
98 return get_unaligned_be16(&sfep->offset.i);
99}
100
101static inline void
102xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
103{
104 put_unaligned_be16(off, &sfep->offset.i);
105}
106
107static inline int
108xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
109{
110 return sizeof(struct xfs_dir2_sf_entry) + /* namelen + offset */
111 len + /* name */
112 (hdr->i8count ? /* ino */
113 sizeof(xfs_dir2_ino8_t) :
114 sizeof(xfs_dir2_ino4_t));
115}
116
117static inline struct xfs_dir2_sf_entry *
118xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
119{
120 return (struct xfs_dir2_sf_entry *)
121 ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
122}
123
124static inline struct xfs_dir2_sf_entry *
125xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
126 struct xfs_dir2_sf_entry *sfep)
127{
128 return (struct xfs_dir2_sf_entry *)
129 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
130}
131
132/*
133 * Functions.
134 */
135extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp);
136extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp,
137 struct xfs_dir2_sf_entry *sfep);
138extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
139 struct xfs_dir2_data_hdr *block,
140 xfs_dir2_sf_hdr_t *sfhp);
141extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
142 int size, xfs_dir2_sf_hdr_t *sfhp);
143extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
144extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
145extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
146 xfs_off_t *offset, filldir_t filldir);
147extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
148extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
149extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
150
151#endif /* __XFS_DIR2_SF_H__ */