]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/dir2sf.c
xfs_db: write values into dir/attr blocks and recalculate CRCs
[thirdparty/xfsprogs-dev.git] / db / dir2sf.c
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
19 #include "libxfs.h"
20 #include "type.h"
21 #include "faddr.h"
22 #include "fprint.h"
23 #include "field.h"
24 #include "bit.h"
25 #include "dir2.h"
26 #include "dir2sf.h"
27 #include "init.h"
28
29 static int dir2_inou_i4_count(void *obj, int startoff);
30 static int dir2_inou_i8_count(void *obj, int startoff);
31 static int dir2_sf_entry_inumber_offset(void *obj, int startoff, int idx);
32 static int dir2_sf_entry_name_count(void *obj, int startoff);
33 static int dir2_sf_list_count(void *obj, int startoff);
34 static int dir2_sf_list_offset(void *obj, int startoff, int idx);
35
36 #define OFF(f) bitize(offsetof(struct xfs_dir2_sf_hdr, f))
37 const field_t dir2sf_flds[] = {
38 { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(count)), C1, 0, TYP_NONE },
39 { "list", FLDT_DIR2_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count,
40 FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE },
41 { NULL }
42 };
43
44 const field_t dir2_inou_flds[] = {
45 { "i8", FLDT_DIR2_INO8, 0, dir2_inou_i8_count, FLD_COUNT, TYP_INODE },
46 { "i4", FLDT_DIR2_INO4, 0, dir2_inou_i4_count, FLD_COUNT, TYP_INODE },
47 { NULL }
48 };
49
50 #define HOFF(f) bitize(offsetof(xfs_dir2_sf_hdr_t, f))
51 const field_t dir2_sf_hdr_flds[] = {
52 { "count", FLDT_UINT8D, OI(HOFF(count)), C1, 0, TYP_NONE },
53 { "i8count", FLDT_UINT8D, OI(HOFF(i8count)), C1, 0, TYP_NONE },
54 { "parent", FLDT_DIR2_INOU, OI(HOFF(parent)), C1, 0, TYP_NONE },
55 { NULL }
56 };
57
58 #define EOFF(f) bitize(offsetof(xfs_dir2_sf_entry_t, f))
59 const field_t dir2_sf_entry_flds[] = {
60 { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE },
61 { "offset", FLDT_DIR2_SF_OFF, OI(EOFF(offset)), C1, 0, TYP_NONE },
62 { "name", FLDT_CHARNS, OI(EOFF(name)), dir2_sf_entry_name_count,
63 FLD_COUNT, TYP_NONE },
64 { "inumber", FLDT_DIR2_INOU, dir2_sf_entry_inumber_offset, C1,
65 FLD_OFFSET, TYP_NONE },
66 { NULL }
67 };
68
69 /*ARGSUSED*/
70 static int
71 dir2_inou_i4_count(
72 void *obj,
73 int startoff)
74 {
75 struct xfs_dinode *dip = obj;
76 struct xfs_dir2_sf_hdr *sf;
77
78 ASSERT(bitoffs(startoff) == 0);
79 sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
80 return sf->i8count == 0;
81 }
82
83 /*ARGSUSED*/
84 static int
85 dir2_inou_i8_count(
86 void *obj,
87 int startoff)
88 {
89 struct xfs_dinode *dip = obj;
90 struct xfs_dir2_sf_hdr *sf;
91
92 ASSERT(bitoffs(startoff) == 0);
93 sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
94 return sf->i8count != 0;
95 }
96
97 /*ARGSUSED*/
98 int
99 dir2_inou_size(
100 void *obj,
101 int startoff,
102 int idx)
103 {
104 struct xfs_dinode *dip = obj;
105 struct xfs_dir2_sf_hdr *sf;
106
107 ASSERT(bitoffs(startoff) == 0);
108 ASSERT(idx == 0);
109 sf = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
110 return bitize(sf->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE);
111 }
112
113 static int
114 dir2_sf_entry_name_count(
115 void *obj,
116 int startoff)
117 {
118 xfs_dir2_sf_entry_t *e;
119
120 ASSERT(bitoffs(startoff) == 0);
121 e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff));
122 return e->namelen;
123 }
124
125 static int
126 dir2_sf_entry_inumber_offset(
127 void *obj,
128 int startoff,
129 int idx)
130 {
131 xfs_dir2_sf_entry_t *e;
132
133 ASSERT(bitoffs(startoff) == 0);
134 ASSERT(idx == 0);
135 e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff));
136 return bitize((int)((char *)xfs_dir2_sf_inumberp(e) - (char *)e));
137 }
138
139 static int
140 dir3_sf_entry_inumber_offset(
141 void *obj,
142 int startoff,
143 int idx)
144 {
145 xfs_dir2_sf_entry_t *e;
146
147 ASSERT(bitoffs(startoff) == 0);
148 ASSERT(idx == 0);
149 e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff));
150 /* plus 1 to skip the ftype entry */
151 return bitize((int)((char *)xfs_dir2_sf_inumberp(e) + 1 - (char *)e));
152 }
153
154 static int
155 dir3_sf_entry_ftype_offset(
156 void *obj,
157 int startoff,
158 int idx)
159 {
160 xfs_dir2_sf_entry_t *e;
161
162 ASSERT(bitoffs(startoff) == 0);
163 ASSERT(idx == 0);
164 e = (xfs_dir2_sf_entry_t *)((char *)obj + byteize(startoff));
165 return bitize((int)((char *)&e->name[e->namelen] - (char *)e));
166 }
167
168 int
169 dir2_sf_entry_size(
170 void *obj,
171 int startoff,
172 int idx)
173 {
174 xfs_dir2_sf_entry_t *e;
175 int i;
176 struct xfs_dir2_sf_hdr *sf;
177
178 ASSERT(bitoffs(startoff) == 0);
179 sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
180 e = xfs_dir2_sf_firstentry(sf);
181 for (i = 0; i < idx; i++)
182 e = M_DIROPS(mp)->sf_nextentry(sf, e);
183 return bitize((int)M_DIROPS(mp)->sf_entsize(sf, e->namelen));
184 }
185
186 /*ARGSUSED*/
187 int
188 dir2_sf_hdr_size(
189 void *obj,
190 int startoff,
191 int idx)
192 {
193 struct xfs_dir2_sf_hdr *sf;
194
195 ASSERT(bitoffs(startoff) == 0);
196 ASSERT(idx == 0);
197 sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
198 return bitize(xfs_dir2_sf_hdr_size(sf->i8count));
199 }
200
201 static int
202 dir2_sf_list_count(
203 void *obj,
204 int startoff)
205 {
206 struct xfs_dir2_sf_hdr *sf;
207
208 ASSERT(bitoffs(startoff) == 0);
209 sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
210 return sf->count;
211 }
212
213 static int
214 dir2_sf_list_offset(
215 void *obj,
216 int startoff,
217 int idx)
218 {
219 xfs_dir2_sf_entry_t *e;
220 int i;
221 struct xfs_dir2_sf_hdr *sf;
222
223 ASSERT(bitoffs(startoff) == 0);
224 sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
225 e = xfs_dir2_sf_firstentry(sf);
226 for (i = 0; i < idx; i++)
227 e = M_DIROPS(mp)->sf_nextentry(sf, e);
228 return bitize((int)((char *)e - (char *)sf));
229 }
230
231 /*ARGSUSED*/
232 int
233 dir2sf_size(
234 void *obj,
235 int startoff,
236 int idx)
237 {
238 xfs_dir2_sf_entry_t *e;
239 int i;
240 struct xfs_dir2_sf_hdr *sf;
241
242 ASSERT(bitoffs(startoff) == 0);
243 ASSERT(idx == 0);
244 sf = (struct xfs_dir2_sf_hdr *)((char *)obj + byteize(startoff));
245 e = xfs_dir2_sf_firstentry(sf);
246 for (i = 0; i < sf->count; i++)
247 e = M_DIROPS(mp)->sf_nextentry(sf, e);
248 return bitize((int)((char *)e - (char *)sf));
249 }
250
251 #define OFF(f) bitize(offsetof(struct xfs_dir2_sf_hdr, f))
252 const field_t dir3sf_flds[] = {
253 { "hdr", FLDT_DIR2_SF_HDR, OI(OFF(count)), C1, 0, TYP_NONE },
254 { "list", FLDT_DIR3_SF_ENTRY, dir2_sf_list_offset, dir2_sf_list_count,
255 FLD_ARRAY|FLD_COUNT|FLD_OFFSET, TYP_NONE },
256 { NULL }
257 };
258
259 #define E3OFF(f) bitize(offsetof(xfs_dir2_sf_entry_t, f))
260 const field_t dir3_sf_entry_flds[] = {
261 { "namelen", FLDT_UINT8D, OI(EOFF(namelen)), C1, 0, TYP_NONE },
262 { "offset", FLDT_DIR2_SF_OFF, OI(EOFF(offset)), C1, 0, TYP_NONE },
263 { "name", FLDT_CHARNS, OI(EOFF(name)), dir2_sf_entry_name_count,
264 FLD_COUNT, TYP_NONE },
265 { "inumber", FLDT_DIR2_INOU, dir3_sf_entry_inumber_offset, C1,
266 FLD_OFFSET, TYP_NONE },
267 { "filetype", FLDT_UINT8D, dir3_sf_entry_ftype_offset, C1,
268 FLD_OFFSET, TYP_NONE },
269 { NULL }
270 };