Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify it | |
5 | * under the terms of version 2 of the GNU General Public License as | |
6 | * published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope that it would be useful, but | |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
11 | * | |
12 | * Further, this software is distributed without any warranty that it is | |
13 | * free of the rightful claim of any third person regarding infringement | |
14 | * or the like. Any license provided herein, whether implied or | |
15 | * otherwise, applies only to this software file. Patent licenses, if | |
16 | * any, provided herein do not apply to combinations of this program with | |
17 | * other software, or any other product whatsoever. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License along | |
20 | * with this program; if not, write the Free Software Foundation, Inc., 59 | |
21 | * Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
22 | * | |
23 | * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, | |
24 | * Mountain View, CA 94043, or: | |
25 | * | |
26 | * http://www.sgi.com | |
27 | * | |
28 | * For further information regarding this notice, see: | |
29 | * | |
30 | * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ | |
31 | */ | |
32 | #ifndef __XFS_DIR2_SF_H__ | |
33 | #define __XFS_DIR2_SF_H__ | |
34 | ||
35 | /* | |
36 | * Directory layout when stored internal to an inode. | |
37 | * | |
38 | * Small directories are packed as tightly as possible so as to | |
39 | * fit into the literal area of the inode. | |
40 | */ | |
41 | ||
42 | struct uio; | |
43 | struct xfs_dabuf; | |
44 | struct xfs_da_args; | |
45 | struct xfs_dir2_block; | |
46 | struct xfs_inode; | |
47 | struct xfs_mount; | |
48 | struct xfs_trans; | |
49 | ||
50 | /* | |
51 | * Maximum size of a shortform directory. | |
52 | */ | |
53 | #define XFS_DIR2_SF_MAX_SIZE \ | |
54 | (XFS_DINODE_MAX_SIZE - (uint)sizeof(xfs_dinode_core_t) - \ | |
55 | (uint)sizeof(xfs_agino_t)) | |
56 | ||
57 | /* | |
58 | * Inode number stored as 8 8-bit values. | |
59 | */ | |
60 | typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; | |
61 | ||
62 | /* | |
63 | * Inode number stored as 4 8-bit values. | |
64 | * Works a lot of the time, when all the inode numbers in a directory | |
65 | * fit in 32 bits. | |
66 | */ | |
67 | typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; | |
68 | ||
69 | typedef union { | |
70 | xfs_dir2_ino8_t i8; | |
71 | xfs_dir2_ino4_t i4; | |
72 | } xfs_dir2_inou_t; | |
73 | #define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) | |
74 | ||
75 | /* | |
76 | * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. | |
77 | * Only need 16 bits, this is the byte offset into the single block form. | |
78 | */ | |
79 | typedef struct { __uint8_t i[2]; } xfs_dir2_sf_off_t; | |
80 | ||
81 | /* | |
82 | * The parent directory has a dedicated field, and the self-pointer must | |
83 | * be calculated on the fly. | |
84 | * | |
85 | * Entries are packed toward the top as tightly as possible. The header | |
86 | * and the elements must be memcpy'd out into a work area to get correct | |
87 | * alignment for the inode number fields. | |
88 | */ | |
89 | typedef struct xfs_dir2_sf_hdr { | |
90 | __uint8_t count; /* count of entries */ | |
91 | __uint8_t i8count; /* count of 8-byte inode #s */ | |
92 | xfs_dir2_inou_t parent; /* parent dir inode number */ | |
93 | } xfs_dir2_sf_hdr_t; | |
94 | ||
95 | typedef struct xfs_dir2_sf_entry { | |
96 | __uint8_t namelen; /* actual name length */ | |
97 | xfs_dir2_sf_off_t offset; /* saved offset */ | |
98 | __uint8_t name[1]; /* name, variable size */ | |
99 | xfs_dir2_inou_t inumber; /* inode number, var. offset */ | |
100 | } xfs_dir2_sf_entry_t; | |
101 | ||
102 | typedef struct xfs_dir2_sf { | |
103 | xfs_dir2_sf_hdr_t hdr; /* shortform header */ | |
104 | xfs_dir2_sf_entry_t list[1]; /* shortform entries */ | |
105 | } xfs_dir2_sf_t; | |
106 | ||
107 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_HDR_SIZE) | |
108 | int xfs_dir2_sf_hdr_size(int i8count); | |
109 | #define XFS_DIR2_SF_HDR_SIZE(i8count) xfs_dir2_sf_hdr_size(i8count) | |
110 | #else | |
111 | #define XFS_DIR2_SF_HDR_SIZE(i8count) \ | |
112 | ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ | |
113 | ((i8count) == 0) * \ | |
114 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))) | |
115 | #endif | |
116 | ||
117 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_INUMBERP) | |
118 | xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep); | |
119 | #define XFS_DIR2_SF_INUMBERP(sfep) xfs_dir2_sf_inumberp(sfep) | |
120 | #else | |
121 | #define XFS_DIR2_SF_INUMBERP(sfep) \ | |
122 | ((xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]) | |
123 | #endif | |
124 | ||
125 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_GET_INUMBER) | |
126 | xfs_intino_t xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from); | |
127 | #define XFS_DIR2_SF_GET_INUMBER(sfp, from) \ | |
128 | xfs_dir2_sf_get_inumber(sfp, from) | |
129 | ||
130 | #else | |
131 | #define XFS_DIR2_SF_GET_INUMBER(sfp, from) \ | |
132 | ((sfp)->hdr.i8count == 0 ? \ | |
133 | (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \ | |
134 | (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)) | |
135 | #endif | |
136 | ||
137 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_PUT_INUMBER) | |
138 | void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, | |
139 | xfs_dir2_inou_t *to); | |
140 | #define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \ | |
141 | xfs_dir2_sf_put_inumber(sfp,from,to) | |
142 | #else | |
143 | #define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \ | |
144 | if ((sfp)->hdr.i8count == 0) { \ | |
145 | XFS_PUT_DIR_INO4(*(from), (to)->i4); \ | |
146 | } else { \ | |
147 | XFS_PUT_DIR_INO8(*(from), (to)->i8); \ | |
148 | } | |
149 | #endif | |
150 | ||
151 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_GET_OFFSET) | |
152 | xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep); | |
153 | #define XFS_DIR2_SF_GET_OFFSET(sfep) \ | |
154 | xfs_dir2_sf_get_offset(sfep) | |
155 | #else | |
156 | #define XFS_DIR2_SF_GET_OFFSET(sfep) \ | |
157 | INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i) | |
158 | #endif | |
159 | ||
160 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_PUT_OFFSET) | |
161 | void xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, | |
162 | xfs_dir2_data_aoff_t off); | |
163 | #define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \ | |
164 | xfs_dir2_sf_put_offset(sfep,off) | |
165 | #else | |
166 | #define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \ | |
167 | INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i,off) | |
168 | #endif | |
169 | ||
170 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_ENTSIZE_BYNAME) | |
171 | int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len); | |
172 | #define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) \ | |
173 | xfs_dir2_sf_entsize_byname(sfp,len) | |
174 | #else | |
175 | #define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) /* space a name uses */ \ | |
176 | ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ | |
177 | ((sfp)->hdr.i8count == 0) * \ | |
178 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))) | |
179 | #endif | |
180 | ||
181 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_ENTSIZE_BYENTRY) | |
182 | int xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep); | |
183 | #define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) \ | |
184 | xfs_dir2_sf_entsize_byentry(sfp,sfep) | |
185 | #else | |
186 | #define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) /* space an entry uses */ \ | |
187 | ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ | |
188 | ((sfp)->hdr.i8count == 0) * \ | |
189 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))) | |
190 | #endif | |
191 | ||
192 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_FIRSTENTRY) | |
193 | xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp); | |
194 | #define XFS_DIR2_SF_FIRSTENTRY(sfp) xfs_dir2_sf_firstentry(sfp) | |
195 | #else | |
196 | #define XFS_DIR2_SF_FIRSTENTRY(sfp) /* first entry in struct */ \ | |
197 | ((xfs_dir2_sf_entry_t *) \ | |
198 | ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count))) | |
199 | #endif | |
200 | ||
201 | #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_NEXTENTRY) | |
202 | xfs_dir2_sf_entry_t *xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, | |
203 | xfs_dir2_sf_entry_t *sfep); | |
204 | #define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep) | |
205 | #else | |
206 | #define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) /* next entry in struct */ \ | |
207 | ((xfs_dir2_sf_entry_t *) \ | |
208 | ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep))) | |
209 | #endif | |
210 | ||
211 | /* | |
212 | * Functions. | |
213 | */ | |
214 | ||
215 | extern int | |
216 | xfs_dir2_block_sfsize(struct xfs_inode *dp, | |
217 | struct xfs_dir2_block *block, | |
218 | xfs_dir2_sf_hdr_t *sfhp); | |
219 | ||
220 | extern int | |
221 | xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, | |
222 | int size, xfs_dir2_sf_hdr_t *sfhp); | |
223 | ||
224 | extern int | |
225 | xfs_dir2_sf_addname(struct xfs_da_args *args); | |
226 | ||
227 | extern int | |
228 | xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); | |
229 | ||
230 | extern int | |
231 | xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp, | |
232 | struct xfs_dirent *dbp, xfs_dir2_put_t put); | |
233 | ||
234 | extern int | |
235 | xfs_dir2_sf_lookup(struct xfs_da_args *args); | |
236 | ||
237 | extern int | |
238 | xfs_dir2_sf_removename(struct xfs_da_args *args); | |
239 | ||
240 | extern int | |
241 | xfs_dir2_sf_replace(struct xfs_da_args *args); | |
242 | ||
243 | #endif /* __XFS_DIR2_SF_H__ */ |