]>
Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
7b718769 NS |
2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | |
1da177e4 | 4 | * |
7b718769 NS |
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 | |
1da177e4 LT |
7 | * published by the Free Software Foundation. |
8 | * | |
7b718769 NS |
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. | |
1da177e4 | 13 | * |
7b718769 NS |
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 | |
1da177e4 LT |
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 | |
25 | * fit into the literal area of the inode. | |
26 | */ | |
27 | ||
28 | struct uio; | |
29 | struct xfs_dabuf; | |
30 | struct xfs_da_args; | |
31 | struct xfs_dir2_block; | |
32 | struct xfs_inode; | |
33 | struct xfs_mount; | |
34 | struct xfs_trans; | |
35 | ||
36 | /* | |
37 | * Maximum size of a shortform directory. | |
38 | */ | |
39 | #define XFS_DIR2_SF_MAX_SIZE \ | |
40 | (XFS_DINODE_MAX_SIZE - (uint)sizeof(xfs_dinode_core_t) - \ | |
41 | (uint)sizeof(xfs_agino_t)) | |
42 | ||
43 | /* | |
44 | * Inode number stored as 8 8-bit values. | |
45 | */ | |
46 | typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; | |
47 | ||
48 | /* | |
49 | * Inode number stored as 4 8-bit values. | |
50 | * Works a lot of the time, when all the inode numbers in a directory | |
51 | * fit in 32 bits. | |
52 | */ | |
53 | typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; | |
54 | ||
55 | typedef union { | |
56 | xfs_dir2_ino8_t i8; | |
57 | xfs_dir2_ino4_t i4; | |
58 | } xfs_dir2_inou_t; | |
59 | #define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) | |
60 | ||
61 | /* | |
62 | * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. | |
63 | * Only need 16 bits, this is the byte offset into the single block form. | |
64 | */ | |
65 | typedef struct { __uint8_t i[2]; } xfs_dir2_sf_off_t; | |
66 | ||
67 | /* | |
68 | * The parent directory has a dedicated field, and the self-pointer must | |
69 | * be calculated on the fly. | |
70 | * | |
71 | * Entries are packed toward the top as tightly as possible. The header | |
72 | * and the elements must be memcpy'd out into a work area to get correct | |
73 | * alignment for the inode number fields. | |
74 | */ | |
75 | typedef struct xfs_dir2_sf_hdr { | |
76 | __uint8_t count; /* count of entries */ | |
77 | __uint8_t i8count; /* count of 8-byte inode #s */ | |
78 | xfs_dir2_inou_t parent; /* parent dir inode number */ | |
79 | } xfs_dir2_sf_hdr_t; | |
80 | ||
81 | typedef struct xfs_dir2_sf_entry { | |
82 | __uint8_t namelen; /* actual name length */ | |
83 | xfs_dir2_sf_off_t offset; /* saved offset */ | |
84 | __uint8_t name[1]; /* name, variable size */ | |
85 | xfs_dir2_inou_t inumber; /* inode number, var. offset */ | |
86 | } xfs_dir2_sf_entry_t; | |
87 | ||
88 | typedef struct xfs_dir2_sf { | |
89 | xfs_dir2_sf_hdr_t hdr; /* shortform header */ | |
90 | xfs_dir2_sf_entry_t list[1]; /* shortform entries */ | |
91 | } xfs_dir2_sf_t; | |
92 | ||
1da177e4 | 93 | #define XFS_DIR2_SF_HDR_SIZE(i8count) xfs_dir2_sf_hdr_size(i8count) |
a844f451 NS |
94 | static inline int xfs_dir2_sf_hdr_size(int i8count) |
95 | { | |
96 | return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ | |
97 | ((i8count) == 0) * \ | |
98 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | |
99 | } | |
100 | ||
1da177e4 | 101 | #define XFS_DIR2_SF_INUMBERP(sfep) xfs_dir2_sf_inumberp(sfep) |
a844f451 NS |
102 | static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) |
103 | { | |
104 | return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; | |
105 | } | |
1da177e4 | 106 | |
a844f451 NS |
107 | #define XFS_DIR2_SF_GET_INUMBER(sfp, from) \ |
108 | xfs_dir2_sf_get_inumber(sfp, from) | |
109 | static inline xfs_intino_t | |
110 | xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) | |
111 | { | |
112 | return ((sfp)->hdr.i8count == 0 ? \ | |
1da177e4 | 113 | (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \ |
a844f451 NS |
114 | (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); |
115 | } | |
1da177e4 | 116 | |
a844f451 | 117 | #define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \ |
1da177e4 | 118 | xfs_dir2_sf_put_inumber(sfp,from,to) |
a844f451 NS |
119 | static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, |
120 | xfs_dir2_inou_t *to) | |
121 | { | |
122 | if ((sfp)->hdr.i8count == 0) | |
123 | XFS_PUT_DIR_INO4(*(from), (to)->i4); | |
124 | else | |
125 | XFS_PUT_DIR_INO8(*(from), (to)->i8); | |
126 | } | |
127 | ||
1da177e4 LT |
128 | #define XFS_DIR2_SF_GET_OFFSET(sfep) \ |
129 | xfs_dir2_sf_get_offset(sfep) | |
a844f451 NS |
130 | static inline xfs_dir2_data_aoff_t |
131 | xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) | |
132 | { | |
133 | return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); | |
134 | } | |
1da177e4 | 135 | |
1da177e4 LT |
136 | #define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \ |
137 | xfs_dir2_sf_put_offset(sfep,off) | |
a844f451 NS |
138 | static inline void |
139 | xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) | |
140 | { | |
141 | INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); | |
142 | } | |
1da177e4 | 143 | |
1da177e4 LT |
144 | #define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) \ |
145 | xfs_dir2_sf_entsize_byname(sfp,len) | |
a844f451 NS |
146 | static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) |
147 | { | |
148 | return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ | |
149 | ((sfp)->hdr.i8count == 0) * \ | |
150 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | |
151 | } | |
152 | ||
1da177e4 LT |
153 | #define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) \ |
154 | xfs_dir2_sf_entsize_byentry(sfp,sfep) | |
a844f451 NS |
155 | static inline int |
156 | xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) | |
157 | { | |
158 | return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ | |
159 | ((sfp)->hdr.i8count == 0) * \ | |
160 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | |
161 | } | |
162 | ||
1da177e4 | 163 | #define XFS_DIR2_SF_FIRSTENTRY(sfp) xfs_dir2_sf_firstentry(sfp) |
a844f451 NS |
164 | static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) |
165 | { | |
166 | return ((xfs_dir2_sf_entry_t *) \ | |
167 | ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count))); | |
168 | } | |
169 | ||
170 | #define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep) | |
171 | static inline xfs_dir2_sf_entry_t * | |
172 | xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) | |
173 | { | |
174 | return ((xfs_dir2_sf_entry_t *) \ | |
175 | ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep))); | |
176 | } | |
1da177e4 LT |
177 | |
178 | /* | |
179 | * Functions. | |
180 | */ | |
a844f451 NS |
181 | extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, |
182 | struct xfs_dir2_block *block, | |
183 | xfs_dir2_sf_hdr_t *sfhp); | |
184 | extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, | |
185 | int size, xfs_dir2_sf_hdr_t *sfhp); | |
186 | extern int xfs_dir2_sf_addname(struct xfs_da_args *args); | |
187 | extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); | |
188 | extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, | |
189 | int *eofp, struct xfs_dirent *dbp, | |
190 | xfs_dir2_put_t put); | |
191 | extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); | |
192 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); | |
193 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); | |
1da177e4 LT |
194 | |
195 | #endif /* __XFS_DIR2_SF_H__ */ |