]>
Commit | Line | Data |
---|---|---|
959ef981 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2bd0ea18 | 2 | /* |
da23017d NS |
3 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
4 | * All Rights Reserved. | |
2bd0ea18 NS |
5 | */ |
6 | ||
6b803e5a | 7 | #include "libxfs.h" |
2bd0ea18 NS |
8 | #include "type.h" |
9 | #include "faddr.h" | |
10 | #include "fprint.h" | |
11 | #include "field.h" | |
12 | #include "bit.h" | |
a2ceac1f | 13 | #include "dir2.h" |
2bd0ea18 | 14 | #include "dir2sf.h" |
494434d7 | 15 | #include "init.h" |
2bd0ea18 NS |
16 | |
17 | static int dir2_inou_i4_count(void *obj, int startoff); | |
18 | static int dir2_inou_i8_count(void *obj, int startoff); | |
19 | static int dir2_sf_entry_inumber_offset(void *obj, int startoff, int idx); | |
20 | static int dir2_sf_entry_name_count(void *obj, int startoff); | |
21 | static int dir2_sf_list_count(void *obj, int startoff); | |
22 | static int dir2_sf_list_offset(void *obj, int startoff, int idx); | |
23 | ||
eb0cb950 | 24 | #define OFF(f) bitize(offsetof(struct xfs_dir2_sf_hdr, f)) |
2bd0ea18 | 25 | const field_t dir2sf_flds[] = { |
eb0cb950 | 26 | { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(count)), C1, 0, TYP_NONE }, |
2bd0ea18 NS |
27 | { "list", FLDT_DIR2_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count, |
28 | FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, | |
29 | { NULL } | |
30 | }; | |
31 | ||
2bd0ea18 | 32 | const field_t dir2_inou_flds[] = { |
3dd2705a ES |
33 | { "i8", FLDT_DIR2_INO8, NULL, dir2_inou_i8_count, FLD_COUNT, TYP_INODE}, |
34 | { "i4", FLDT_DIR2_INO4, NULL, dir2_inou_i4_count, FLD_COUNT, TYP_INODE}, | |
2bd0ea18 NS |
35 | { NULL } |
36 | }; | |
37 | ||
38 | #define HOFF(f) bitize(offsetof(xfs_dir2_sf_hdr_t, f)) | |
39 | const field_t dir2_sf_hdr_flds[] = { | |
40 | { "count", FLDT_UINT8D, OI(HOFF(count)), C1, 0, TYP_NONE }, | |
41 | { "i8count", FLDT_UINT8D, OI(HOFF(i8count)), C1, 0, TYP_NONE }, | |
42 | { "parent", FLDT_DIR2_INOU, OI(HOFF(parent)), C1, 0, TYP_NONE }, | |
43 | { NULL } | |
44 | }; | |
45 | ||
46 | #define EOFF(f) bitize(offsetof(xfs_dir2_sf_entry_t, f)) | |
47 | const field_t dir2_sf_entry_flds[] = { | |
48 | { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE }, | |
49 | { "offset", FLDT_DIR2_SF_OFF, OI(EOFF(offset)), C1, 0, TYP_NONE }, | |
50 | { "name", FLDT_CHARNS, OI(EOFF(name)), dir2_sf_entry_name_count, | |
51 | FLD_COUNT, TYP_NONE }, | |
52 | { "inumber", FLDT_DIR2_INOU, dir2_sf_entry_inumber_offset, C1, | |
53 | FLD_OFFSET, TYP_NONE }, | |
54 | { NULL } | |
55 | }; | |
56 | ||
57 | /*ARGSUSED*/ | |
58 | static int | |
59 | dir2_inou_i4_count( | |
60 | void *obj, | |
61 | int startoff) | |
62 | { | |
41ce5f36 | 63 | struct xfs_dinode *dip = obj; |
eb0cb950 | 64 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
65 | |
66 | ASSERT(bitoffs(startoff) == 0); | |
eb0cb950 DC |
67 | sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); |
68 | return sf->i8count == 0; | |
2bd0ea18 NS |
69 | } |
70 | ||
71 | /*ARGSUSED*/ | |
72 | static int | |
73 | dir2_inou_i8_count( | |
74 | void *obj, | |
75 | int startoff) | |
76 | { | |
41ce5f36 | 77 | struct xfs_dinode *dip = obj; |
eb0cb950 | 78 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
79 | |
80 | ASSERT(bitoffs(startoff) == 0); | |
eb0cb950 DC |
81 | sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); |
82 | return sf->i8count != 0; | |
2bd0ea18 NS |
83 | } |
84 | ||
85 | /*ARGSUSED*/ | |
86 | int | |
87 | dir2_inou_size( | |
88 | void *obj, | |
89 | int startoff, | |
90 | int idx) | |
91 | { | |
41ce5f36 | 92 | struct xfs_dinode *dip = obj; |
eb0cb950 | 93 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
94 | |
95 | ASSERT(bitoffs(startoff) == 0); | |
96 | ASSERT(idx == 0); | |
eb0cb950 | 97 | sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip); |
d8bf9c63 | 98 | return bitize(sf->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE); |
2bd0ea18 NS |
99 | } |
100 | ||
101 | static int | |
102 | dir2_sf_entry_name_count( | |
103 | void *obj, | |
104 | int startoff) | |
105 | { | |
106 | xfs_dir2_sf_entry_t *e; | |
107 | ||
108 | ASSERT(bitoffs(startoff) == 0); | |
109 | e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); | |
110 | return e->namelen; | |
111 | } | |
112 | ||
2bd0ea18 NS |
113 | static int |
114 | dir2_sf_entry_inumber_offset( | |
115 | void *obj, | |
116 | int startoff, | |
117 | int idx) | |
118 | { | |
119 | xfs_dir2_sf_entry_t *e; | |
120 | ||
121 | ASSERT(bitoffs(startoff) == 0); | |
122 | ASSERT(idx == 0); | |
123 | e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); | |
5e656dbb | 124 | return bitize((int)((char *)xfs_dir2_sf_inumberp(e) - (char *)e)); |
2bd0ea18 NS |
125 | } |
126 | ||
3beed08e DC |
127 | static int |
128 | dir3_sf_entry_inumber_offset( | |
129 | void *obj, | |
130 | int startoff, | |
131 | int idx) | |
132 | { | |
133 | xfs_dir2_sf_entry_t *e; | |
134 | ||
135 | ASSERT(bitoffs(startoff) == 0); | |
136 | ASSERT(idx == 0); | |
137 | e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); | |
138 | /* plus 1 to skip the ftype entry */ | |
139 | return bitize((int)((char *)xfs_dir2_sf_inumberp(e) + 1 - (char *)e)); | |
140 | } | |
141 | ||
142 | static int | |
143 | dir3_sf_entry_ftype_offset( | |
144 | void *obj, | |
145 | int startoff, | |
146 | int idx) | |
147 | { | |
148 | xfs_dir2_sf_entry_t *e; | |
149 | ||
150 | ASSERT(bitoffs(startoff) == 0); | |
151 | ASSERT(idx == 0); | |
152 | e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff)); | |
153 | return bitize((int)((char *)&e->name[e->namelen] - (char *)e)); | |
154 | } | |
155 | ||
2bd0ea18 NS |
156 | int |
157 | dir2_sf_entry_size( | |
158 | void *obj, | |
159 | int startoff, | |
160 | int idx) | |
161 | { | |
162 | xfs_dir2_sf_entry_t *e; | |
163 | int i; | |
eb0cb950 | 164 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
165 | |
166 | ASSERT(bitoffs(startoff) == 0); | |
eb0cb950 DC |
167 | sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); |
168 | e = xfs_dir2_sf_firstentry(sf); | |
2bd0ea18 | 169 | for (i = 0; i < idx; i++) |
660836c9 CH |
170 | e = libxfs_dir2_sf_nextentry(mp, sf, e); |
171 | return bitize((int)libxfs_dir2_sf_entsize(mp, sf, e->namelen)); | |
2bd0ea18 NS |
172 | } |
173 | ||
174 | /*ARGSUSED*/ | |
175 | int | |
176 | dir2_sf_hdr_size( | |
177 | void *obj, | |
178 | int startoff, | |
179 | int idx) | |
180 | { | |
eb0cb950 | 181 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
182 | |
183 | ASSERT(bitoffs(startoff) == 0); | |
184 | ASSERT(idx == 0); | |
eb0cb950 DC |
185 | sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); |
186 | return bitize(xfs_dir2_sf_hdr_size(sf->i8count)); | |
2bd0ea18 NS |
187 | } |
188 | ||
189 | static int | |
190 | dir2_sf_list_count( | |
191 | void *obj, | |
192 | int startoff) | |
193 | { | |
eb0cb950 | 194 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
195 | |
196 | ASSERT(bitoffs(startoff) == 0); | |
eb0cb950 DC |
197 | sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); |
198 | return sf->count; | |
2bd0ea18 NS |
199 | } |
200 | ||
201 | static int | |
202 | dir2_sf_list_offset( | |
203 | void *obj, | |
204 | int startoff, | |
205 | int idx) | |
206 | { | |
207 | xfs_dir2_sf_entry_t *e; | |
208 | int i; | |
eb0cb950 | 209 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
210 | |
211 | ASSERT(bitoffs(startoff) == 0); | |
eb0cb950 DC |
212 | sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); |
213 | e = xfs_dir2_sf_firstentry(sf); | |
2bd0ea18 | 214 | for (i = 0; i < idx; i++) |
660836c9 | 215 | e = libxfs_dir2_sf_nextentry(mp, sf, e); |
2bd0ea18 NS |
216 | return bitize((int)((char *)e - (char *)sf)); |
217 | } | |
218 | ||
219 | /*ARGSUSED*/ | |
220 | int | |
221 | dir2sf_size( | |
222 | void *obj, | |
223 | int startoff, | |
224 | int idx) | |
225 | { | |
226 | xfs_dir2_sf_entry_t *e; | |
227 | int i; | |
eb0cb950 | 228 | struct xfs_dir2_sf_hdr *sf; |
2bd0ea18 NS |
229 | |
230 | ASSERT(bitoffs(startoff) == 0); | |
231 | ASSERT(idx == 0); | |
eb0cb950 DC |
232 | sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff)); |
233 | e = xfs_dir2_sf_firstentry(sf); | |
234 | for (i = 0; i < sf->count; i++) | |
660836c9 | 235 | e = libxfs_dir2_sf_nextentry(mp, sf, e); |
2bd0ea18 NS |
236 | return bitize((int)((char *)e - (char *)sf)); |
237 | } | |
3beed08e DC |
238 | |
239 | #define OFF(f) bitize(offsetof(struct xfs_dir2_sf_hdr, f)) | |
240 | const field_t dir3sf_flds[] = { | |
241 | { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(count)), C1, 0, TYP_NONE }, | |
242 | { "list", FLDT_DIR3_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count, | |
243 | FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE }, | |
244 | { NULL } | |
245 | }; | |
246 | ||
247 | #define E3OFF(f) bitize(offsetof(xfs_dir2_sf_entry_t, f)) | |
248 | const field_t dir3_sf_entry_flds[] = { | |
d878935d XH |
249 | { "namelen", FLDT_UINT8D, OI(E3OFF(namelen)), C1, 0, TYP_NONE }, |
250 | { "offset", FLDT_DIR2_SF_OFF, OI(E3OFF(offset)), C1, 0, TYP_NONE }, | |
251 | { "name", FLDT_CHARNS, OI(E3OFF(name)), dir2_sf_entry_name_count, | |
3beed08e DC |
252 | FLD_COUNT, TYP_NONE }, |
253 | { "inumber", FLDT_DIR2_INOU, dir3_sf_entry_inumber_offset, C1, | |
254 | FLD_OFFSET, TYP_NONE }, | |
255 | { "filetype", FLDT_UINT8D, dir3_sf_entry_ftype_offset, C1, | |
256 | FLD_OFFSET, TYP_NONE }, | |
257 | { NULL } | |
258 | }; |