Line data Source code
1 : #include <stdint.h>
2 : #include <string.h>
3 : #include <uuid.h>
4 : #include "libgfs2.h"
5 : #include "clusterautoconfig.h"
6 :
7 : #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
8 : #define SYM(x) { x, #x, 0 },
9 : #define PREFIX_SYM(p,x) { p##x, #p #x, sizeof #p - 1 },
10 :
11 : const struct lgfs2_symbolic lgfs2_metatypes[] = {
12 : SYM(GFS2_METATYPE_NONE)
13 : SYM(GFS2_METATYPE_SB)
14 : SYM(GFS2_METATYPE_RG)
15 : SYM(GFS2_METATYPE_RB)
16 : SYM(GFS2_METATYPE_DI)
17 : SYM(GFS2_METATYPE_IN)
18 : SYM(GFS2_METATYPE_LF)
19 : SYM(GFS2_METATYPE_JD)
20 : SYM(GFS2_METATYPE_LH)
21 : SYM(GFS2_METATYPE_LD)
22 : SYM(GFS2_METATYPE_LB)
23 : SYM(GFS2_METATYPE_EA)
24 : SYM(GFS2_METATYPE_ED)
25 : SYM(GFS2_METATYPE_QC)
26 : };
27 :
28 : const unsigned lgfs2_metatype_size = ARRAY_SIZE(lgfs2_metatypes);
29 :
30 : const struct lgfs2_symbolic lgfs2_metaformats[] = {
31 : SYM(GFS2_FORMAT_NONE)
32 : SYM(GFS2_FORMAT_SB)
33 : SYM(GFS2_FORMAT_RG)
34 : SYM(GFS2_FORMAT_RB)
35 : SYM(GFS2_FORMAT_DI)
36 : SYM(GFS2_FORMAT_IN)
37 : SYM(GFS2_FORMAT_LF)
38 : SYM(GFS2_FORMAT_JD)
39 : SYM(GFS2_FORMAT_LH)
40 : SYM(GFS2_FORMAT_LD)
41 : SYM(GFS2_FORMAT_LB)
42 : SYM(GFS2_FORMAT_EA)
43 : SYM(GFS2_FORMAT_ED)
44 : SYM(GFS2_FORMAT_QC)
45 : SYM(GFS2_FORMAT_RI)
46 : SYM(GFS2_FORMAT_DE)
47 : SYM(GFS2_FORMAT_QU)
48 : };
49 :
50 : const unsigned lgfs2_metaformat_size = ARRAY_SIZE(lgfs2_metaformats);
51 :
52 : const struct lgfs2_symbolic lgfs2_di_flags[] = {
53 : SYM(GFS2_DIF_JDATA)
54 : SYM(GFS2_DIF_EXHASH)
55 : SYM(GFS2_DIF_UNUSED)
56 : SYM(GFS2_DIF_EA_INDIRECT)
57 : SYM(GFS2_DIF_DIRECTIO)
58 : SYM(GFS2_DIF_IMMUTABLE)
59 : SYM(GFS2_DIF_APPENDONLY)
60 : SYM(GFS2_DIF_NOATIME)
61 : SYM(GFS2_DIF_SYNC)
62 : SYM(GFS2_DIF_SYSTEM)
63 : SYM(GFS2_DIF_TRUNC_IN_PROG)
64 : SYM(GFS2_DIF_INHERIT_DIRECTIO)
65 : SYM(GFS2_DIF_INHERIT_JDATA)
66 : };
67 :
68 : const unsigned lgfs2_di_flag_size = ARRAY_SIZE(lgfs2_di_flags);
69 :
70 : const struct lgfs2_symbolic lgfs2_lh_flags[] = {
71 : PREFIX_SYM(GFS2_LOG_HEAD_, UNMOUNT)
72 : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, NORMAL)
73 : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, SYNC)
74 : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, SHUTDOWN)
75 : PREFIX_SYM(GFS2_LOG_HEAD_FLUSH_, FREEZE)
76 : PREFIX_SYM(GFS2_LOG_HEAD_, RECOVERY)
77 : PREFIX_SYM(GFS2_LOG_HEAD_, USERSPACE)
78 :
79 : /* Log flush callers */
80 : PREFIX_SYM(GFS2_LFC_, SHUTDOWN)
81 : PREFIX_SYM(GFS2_LFC_, JDATA_WPAGES)
82 : PREFIX_SYM(GFS2_LFC_, SET_FLAGS)
83 : PREFIX_SYM(GFS2_LFC_, AIL_EMPTY_GL)
84 : PREFIX_SYM(GFS2_LFC_, AIL_FLUSH)
85 : PREFIX_SYM(GFS2_LFC_, RGRP_GO_SYNC)
86 : PREFIX_SYM(GFS2_LFC_, INODE_GO_SYNC)
87 : PREFIX_SYM(GFS2_LFC_, INODE_GO_INVAL)
88 : PREFIX_SYM(GFS2_LFC_, FREEZE_GO_SYNC)
89 : PREFIX_SYM(GFS2_LFC_, KILL_SB)
90 : PREFIX_SYM(GFS2_LFC_, DO_SYNC)
91 : PREFIX_SYM(GFS2_LFC_, INPLACE_RESERVE)
92 : PREFIX_SYM(GFS2_LFC_, WRITE_INODE)
93 : PREFIX_SYM(GFS2_LFC_, MAKE_FS_RO)
94 : PREFIX_SYM(GFS2_LFC_, SYNC_FS)
95 : PREFIX_SYM(GFS2_LFC_, EVICT_INODE)
96 : PREFIX_SYM(GFS2_LFC_, TRANS_END)
97 : PREFIX_SYM(GFS2_LFC_, LOGD_JFLUSH_REQD)
98 : PREFIX_SYM(GFS2_LFC_, LOGD_AIL_FLUSH_REQD)
99 : };
100 :
101 : const unsigned int lgfs2_lh_flag_size = ARRAY_SIZE(lgfs2_lh_flags);
102 :
103 : const struct lgfs2_symbolic lgfs2_ld_types[] = {
104 : SYM(GFS2_LOG_DESC_METADATA)
105 : SYM(GFS2_LOG_DESC_REVOKE)
106 : SYM(GFS2_LOG_DESC_JDATA)
107 : };
108 :
109 : const unsigned int lgfs2_ld_type_size = ARRAY_SIZE(lgfs2_ld_types);
110 :
111 : #undef SYM
112 :
113 :
114 :
115 :
116 : #define F(f,...) { .name = #f, \
117 : .offset = offsetof(struct STRUCT, f), \
118 : .length = sizeof(((struct STRUCT *)(0))->f), \
119 : __VA_ARGS__ },
120 : #define FP(f,...) F(f, .flags = LGFS2_MFF_POINTER, __VA_ARGS__)
121 : #define RF(f) F(f, .flags = LGFS2_MFF_RESERVED)
122 : #define RFP(f,...) F(f, .flags = LGFS2_MFF_POINTER|LGFS2_MFF_RESERVED, __VA_ARGS__)
123 :
124 :
125 : #define MH(f) F(f.mh_magic) \
126 : F(f.mh_type, .flags = LGFS2_MFF_ENUM, .symtab=lgfs2_metatypes, .nsyms=ARRAY_SIZE(lgfs2_metatypes)) \
127 : RF(f.__pad0) \
128 : F(f.mh_format, .flags = LGFS2_MFF_ENUM, .symtab=lgfs2_metaformats, .nsyms=ARRAY_SIZE(lgfs2_metaformats)) \
129 : F(f.mh_jid)
130 :
131 : #define IN(f,...) F(f.no_formal_ino) \
132 : FP(f.no_addr, __VA_ARGS__)
133 :
134 : #define INR(f,...) RF(f.no_formal_ino) \
135 : RFP(f.no_addr, __VA_ARGS__)
136 : #define ANY_COMMON_BLOCK (1 << LGFS2_MT_DIR_LEAF) | \
137 : (1 << LGFS2_MT_JRNL_DATA) | \
138 : (1 << LGFS2_MT_EA_ATTR) | \
139 : (1 << LGFS2_MT_EA_DATA) | \
140 : (1 << LGFS2_MT_DATA)
141 :
142 : #define ANY_GFS2_BLOCK (1 << LGFS2_MT_GFS2_DINODE) | \
143 : (1 << LGFS2_MT_GFS2_INDIRECT) | \
144 : (1 << LGFS2_MT_GFS2_LOG_HEADER) | \
145 : (1 << LGFS2_MT_GFS2_LOG_DESC) | \
146 : (1 << LGFS2_MT_GFS2_LOG_BLOCK) | \
147 : ANY_COMMON_BLOCK
148 :
149 : #define ANY_GFS_BLOCK (1 << LGFS2_MT_GFS_DINODE) | \
150 : (1 << LGFS2_MT_GFS_INDIRECT) | \
151 : ANY_COMMON_BLOCK
152 :
153 : #undef STRUCT
154 : #define STRUCT gfs2_sb
155 :
156 : static const struct lgfs2_metafield gfs2_sb_fields[] = {
157 : MH(sb_header)
158 : F(sb_fs_format)
159 : F(sb_multihost_format)
160 : RF(__pad0)
161 : F(sb_bsize, .flags = LGFS2_MFF_BYTES)
162 : F(sb_bsize_shift, .flags = LGFS2_MFF_BYTES|LGFS2_MFF_SHIFT)
163 : RF(__pad1)
164 : IN(sb_master_dir, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
165 : INR(__pad2, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
166 : IN(sb_root_dir, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
167 : F(sb_lockproto, .flags = LGFS2_MFF_STRING)
168 : F(sb_locktable, .flags = LGFS2_MFF_STRING)
169 : INR(__pad3, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
170 : INR(__pad4, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
171 : F(sb_uuid, .flags = LGFS2_MFF_UUID)
172 : };
173 :
174 : #undef STRUCT
175 : #define STRUCT gfs2_rindex
176 :
177 : static const struct lgfs2_metafield gfs2_rindex_fields[] = {
178 : FP(ri_addr, .points_to = (1 << LGFS2_MT_GFS2_RGRP))
179 : F(ri_length, .flags = LGFS2_MFF_FSBLOCKS)
180 : RF(__pad)
181 : FP(ri_data0, .points_to = ANY_GFS2_BLOCK|(1 << LGFS2_MT_FREE))
182 : F(ri_data, .flags = LGFS2_MFF_FSBLOCKS)
183 : F(ri_bitbytes, .flags = LGFS2_MFF_BYTES)
184 : F(ri_reserved)
185 : };
186 :
187 : #undef STRUCT
188 : #define STRUCT gfs2_rgrp
189 :
190 : static const struct lgfs2_metafield gfs2_rgrp_fields[] = {
191 : MH(rg_header)
192 : F(rg_flags)
193 : F(rg_free, .flags = LGFS2_MFF_FSBLOCKS)
194 : F(rg_dinodes, .flags = LGFS2_MFF_FSBLOCKS)
195 : FP(rg_skip, .points_to = (1 << LGFS2_MT_GFS2_RGRP))
196 : F(rg_igeneration)
197 : FP(rg_data0, .points_to = ANY_GFS2_BLOCK|(1 << LGFS2_MT_FREE))
198 : F(rg_data, .flags = LGFS2_MFF_FSBLOCKS)
199 : F(rg_bitbytes, .flags = LGFS2_MFF_BYTES)
200 : F(rg_crc, .flags = LGFS2_MFF_CHECK)
201 : RF(rg_reserved)
202 : };
203 :
204 : #undef STRUCT
205 : struct gfs2_rgrp_bitmap { struct gfs2_meta_header rb_header; };
206 : #define STRUCT gfs2_rgrp_bitmap
207 :
208 : static const struct lgfs2_metafield gfs2_rgrp_bitmap_fields[] = {
209 : MH(rb_header)
210 : };
211 :
212 : #undef STRUCT
213 : #define STRUCT gfs2_dinode
214 :
215 : static const struct lgfs2_metafield gfs2_dinode_fields[] = {
216 : MH(di_header)
217 : IN(di_num, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
218 : F(di_mode, .flags = LGFS2_MFF_MODE)
219 : F(di_uid, .flags = LGFS2_MFF_UID)
220 : F(di_gid, .flags = LGFS2_MFF_GID)
221 : F(di_nlink)
222 : F(di_size, .flags = LGFS2_MFF_BYTES)
223 : F(di_blocks, .flags = LGFS2_MFF_FSBLOCKS)
224 : F(di_atime, .flags = LGFS2_MFF_SECS)
225 : F(di_mtime, .flags = LGFS2_MFF_SECS)
226 : F(di_ctime, .flags = LGFS2_MFF_SECS)
227 : F(di_major, .flags = LGFS2_MFF_MAJOR)
228 : F(di_minor, .flags = LGFS2_MFF_MINOR)
229 : FP(di_goal_meta, .points_to = ANY_GFS2_BLOCK | (1 << LGFS2_MT_FREE))
230 : FP(di_goal_data, .points_to = ANY_GFS2_BLOCK | (1 << LGFS2_MT_FREE))
231 : F(di_generation)
232 : F(di_flags, .flags = LGFS2_MFF_MASK, .symtab=lgfs2_di_flags, .nsyms=ARRAY_SIZE(lgfs2_di_flags))
233 : F(di_payload_format)
234 : RF(__pad1)
235 : F(di_height)
236 : RF(__pad2)
237 : RF(__pad3)
238 : F(di_depth)
239 : F(di_entries)
240 : INR(__pad4, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
241 : FP(di_eattr, .points_to = (1 << LGFS2_MT_EA_ATTR)|(1 << LGFS2_MT_GFS2_INDIRECT))
242 : F(di_atime_nsec, .flags = LGFS2_MFF_NSECS)
243 : F(di_mtime_nsec, .flags = LGFS2_MFF_NSECS)
244 : F(di_ctime_nsec, .flags = LGFS2_MFF_NSECS)
245 : RF(di_reserved)
246 : };
247 :
248 : #undef STRUCT
249 : struct gfs2_indirect { struct gfs2_meta_header in_header; };
250 : #define STRUCT gfs2_indirect
251 :
252 : static const struct lgfs2_metafield gfs2_indirect_fields[] = {
253 : MH(in_header)
254 : };
255 :
256 : #undef STRUCT
257 : #define STRUCT gfs2_leaf
258 :
259 : static const struct lgfs2_metafield gfs2_leaf_fields[] = {
260 : MH(lf_header)
261 : F(lf_depth)
262 : F(lf_entries)
263 : F(lf_dirent_format)
264 : F(lf_next)
265 : #ifdef GFS2_HAS_LEAF_HINTS
266 : FP(lf_inode, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
267 : F(lf_dist)
268 : F(lf_nsec, .flags = LGFS2_MFF_NSECS)
269 : F(lf_sec, .flags = LGFS2_MFF_SECS)
270 : RF(lf_reserved2)
271 : #else
272 : RF(lf_reserved)
273 : #endif
274 : };
275 :
276 : #undef STRUCT
277 : struct gfs2_jrnl_data { struct gfs2_meta_header jd_header; };
278 : #define STRUCT gfs2_jrnl_data
279 :
280 : static const struct lgfs2_metafield gfs2_jdata_fields[] = {
281 : MH(jd_header)
282 : };
283 :
284 : #undef STRUCT
285 : #define STRUCT gfs2_log_header
286 :
287 : static const struct lgfs2_metafield gfs2_log_header_fields[] = {
288 : MH(lh_header)
289 : F(lh_sequence)
290 : F(lh_flags, .flags = LGFS2_MFF_MASK, .symtab = lgfs2_lh_flags, .nsyms = ARRAY_SIZE(lgfs2_lh_flags))
291 : F(lh_tail)
292 : F(lh_blkno)
293 : F(lh_hash, .flags = LGFS2_MFF_CHECK)
294 : F(lh_crc, .flags = LGFS2_MFF_CHECK)
295 : F(lh_nsec, .flags = LGFS2_MFF_NSECS)
296 : F(lh_sec, .flags = LGFS2_MFF_SECS)
297 : FP(lh_addr, .points_to = (1 << LGFS2_MT_GFS2_LOG_BLOCK))
298 : FP(lh_jinode, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
299 : FP(lh_statfs_addr, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
300 : FP(lh_quota_addr, .points_to = (1 << LGFS2_MT_GFS2_DINODE))
301 : F(lh_local_total, .flags = LGFS2_MFF_FSBLOCKS)
302 : F(lh_local_free, .flags = LGFS2_MFF_FSBLOCKS)
303 : F(lh_local_dinodes, .flags = LGFS2_MFF_FSBLOCKS)
304 : };
305 :
306 : #undef STRUCT
307 : #define STRUCT gfs2_log_descriptor
308 :
309 : static const struct lgfs2_metafield gfs2_log_desc_fields[] = {
310 : MH(ld_header)
311 : F(ld_type, .flags = LGFS2_MFF_ENUM, .symtab = lgfs2_ld_types, .nsyms = ARRAY_SIZE(lgfs2_ld_types))
312 : F(ld_length, .flags = LGFS2_MFF_FSBLOCKS)
313 : F(ld_data1)
314 : F(ld_data2)
315 : RF(ld_reserved)
316 : };
317 :
318 : #undef STRUCT
319 : struct gfs2_log_block { struct gfs2_meta_header lb_header; };
320 : #define STRUCT gfs2_log_block
321 :
322 : static const struct lgfs2_metafield gfs2_log_block_fields[] = {
323 : MH(lb_header)
324 : };
325 :
326 : #undef STRUCT
327 : struct gfs2_ea_attr { struct gfs2_meta_header ea_header; };
328 : #define STRUCT gfs2_ea_attr
329 :
330 : static const struct lgfs2_metafield gfs2_ea_attr_fields[] = {
331 : MH(ea_header)
332 : };
333 :
334 : #undef STRUCT
335 : struct gfs2_ea_data { struct gfs2_meta_header ed_header; };
336 : #define STRUCT gfs2_ea_data
337 :
338 : static const struct lgfs2_metafield gfs2_ea_data_fields[] = {
339 : MH(ed_header)
340 : };
341 :
342 : #undef STRUCT
343 : #define STRUCT gfs2_quota_change
344 :
345 : static const struct lgfs2_metafield gfs2_quota_change_fields[] = {
346 : F(qc_change, .flags = LGFS2_MFF_FSBLOCKS)
347 : F(qc_flags)
348 : F(qc_id)
349 : };
350 :
351 : #undef STRUCT
352 : #define STRUCT gfs2_dirent
353 :
354 : static const struct lgfs2_metafield gfs2_dirent_fields[] = {
355 : IN(de_inum, .points_to = (1 << LGFS2_MT_GFS_DINODE)|(1 << LGFS2_MT_GFS2_DINODE))
356 : F(de_hash, .flags = LGFS2_MFF_CHECK)
357 : F(de_rec_len, .flags = LGFS2_MFF_BYTES)
358 : F(de_name_len, .flags = LGFS2_MFF_BYTES)
359 : F(de_type)
360 : F(de_rahead)
361 : F(de_cookie)
362 : RF(pad3)
363 : };
364 :
365 : #undef STRUCT
366 : #define STRUCT gfs2_ea_header
367 :
368 : static const struct lgfs2_metafield gfs2_ea_header_fields[] = {
369 : F(ea_rec_len, .flags = LGFS2_MFF_BYTES)
370 : F(ea_data_len, .flags = LGFS2_MFF_BYTES)
371 : F(ea_name_len, .flags = LGFS2_MFF_BYTES)
372 : F(ea_type)
373 : F(ea_flags)
374 : F(ea_num_ptrs)
375 : RF(__pad)
376 : };
377 :
378 : #undef STRUCT
379 : #define STRUCT gfs2_inum_range
380 :
381 : static const struct lgfs2_metafield gfs2_inum_range_fields[] = {
382 : F(ir_start)
383 : F(ir_length)
384 : };
385 :
386 : #undef STRUCT
387 : #define STRUCT gfs2_statfs_change
388 :
389 : static const struct lgfs2_metafield gfs2_statfs_change_fields[] = {
390 : F(sc_total, .flags = LGFS2_MFF_FSBLOCKS)
391 : F(sc_free, .flags = LGFS2_MFF_FSBLOCKS)
392 : F(sc_dinodes, .flags = LGFS2_MFF_FSBLOCKS)
393 : };
394 :
395 : #undef STRUCT
396 :
397 : const struct lgfs2_metadata lgfs2_metadata[] = {
398 : [LGFS2_MT_GFS2_SB] = {
399 : .header = 1,
400 : .mh_type = GFS2_METATYPE_SB,
401 : .mh_format = GFS2_FORMAT_SB,
402 : .name = "gfs2_sb",
403 : .display = "superblock",
404 : .fields = gfs2_sb_fields,
405 : .nfields = ARRAY_SIZE(gfs2_sb_fields),
406 : .size = sizeof(struct gfs2_sb),
407 : },
408 : [LGFS2_MT_RINDEX] = {
409 : .name = "gfs2_rindex",
410 : .display = "resource group index",
411 : .fields = gfs2_rindex_fields,
412 : .nfields = ARRAY_SIZE(gfs2_rindex_fields),
413 : .size = sizeof(struct gfs2_rindex),
414 : },
415 : [LGFS2_MT_GFS2_RGRP] = {
416 : .header = 1,
417 : .mh_type = GFS2_METATYPE_RG,
418 : .mh_format = GFS2_FORMAT_RG,
419 : .name = "gfs2_rgrp",
420 : .display = "resource group",
421 : .fields = gfs2_rgrp_fields,
422 : .nfields = ARRAY_SIZE(gfs2_rgrp_fields),
423 : .size = sizeof(struct gfs2_rgrp),
424 : },
425 : [LGFS2_MT_RGRP_BITMAP] = {
426 : .header = 1,
427 : .mh_type = GFS2_METATYPE_RB,
428 : .mh_format = GFS2_FORMAT_RB,
429 : .name = "gfs2_rgrp_bitmap",
430 : .display = "allocation bitmap",
431 : .fields = gfs2_rgrp_bitmap_fields,
432 : .nfields = ARRAY_SIZE(gfs2_rgrp_bitmap_fields),
433 : .size = sizeof(struct gfs2_meta_header),
434 : },
435 : [LGFS2_MT_GFS2_DINODE] = {
436 : .header = 1,
437 : .mh_type = GFS2_METATYPE_DI,
438 : .mh_format = GFS2_FORMAT_DI,
439 : .name = "gfs2_dinode",
440 : .display = "inode",
441 : .fields = gfs2_dinode_fields,
442 : .nfields = ARRAY_SIZE(gfs2_dinode_fields),
443 : .size = sizeof(struct gfs2_dinode),
444 : },
445 : [LGFS2_MT_GFS2_INDIRECT] = {
446 : .header = 1,
447 : .mh_type = GFS2_METATYPE_IN,
448 : .mh_format = GFS2_FORMAT_IN,
449 : .name = "gfs2_indirect",
450 : .display = "indirect",
451 : .fields = gfs2_indirect_fields,
452 : .nfields = ARRAY_SIZE(gfs2_indirect_fields),
453 : .size = sizeof(struct gfs2_meta_header),
454 : },
455 : [LGFS2_MT_DIR_LEAF] = {
456 : .header = 1,
457 : .mh_type = GFS2_METATYPE_LF,
458 : .mh_format = GFS2_FORMAT_LF,
459 : .name = "gfs2_leaf",
460 : .display = "leaf",
461 : .fields = gfs2_leaf_fields,
462 : .nfields = ARRAY_SIZE(gfs2_leaf_fields),
463 : .size = sizeof(struct gfs2_leaf),
464 : },
465 : [LGFS2_MT_JRNL_DATA] = {
466 : .header = 1,
467 : .mh_type = GFS2_METATYPE_JD,
468 : .mh_format = GFS2_FORMAT_JD,
469 : .name = "gfs2_jdata",
470 : .display = "journal data",
471 : .fields = gfs2_jdata_fields,
472 : .nfields = ARRAY_SIZE(gfs2_jdata_fields),
473 : .size = sizeof(struct gfs2_meta_header),
474 : },
475 : [LGFS2_MT_GFS2_LOG_HEADER] = {
476 : .header = 1,
477 : .mh_type = GFS2_METATYPE_LH,
478 : .mh_format = GFS2_FORMAT_LH,
479 : .name = "gfs2_log_header",
480 : .display = "log header",
481 : .fields = gfs2_log_header_fields,
482 : .nfields = ARRAY_SIZE(gfs2_log_header_fields),
483 : .size = sizeof(struct gfs2_log_header),
484 : },
485 : [LGFS2_MT_GFS2_LOG_DESC] = {
486 : .header = 1,
487 : .mh_type = GFS2_METATYPE_LD,
488 : .mh_format = GFS2_FORMAT_LD,
489 : .name = "gfs2_log_desc",
490 : .display = "log descriptor",
491 : .fields = gfs2_log_desc_fields,
492 : .nfields = ARRAY_SIZE(gfs2_log_desc_fields),
493 : .size = sizeof(struct gfs2_log_descriptor),
494 : },
495 : [LGFS2_MT_GFS2_LOG_BLOCK] = {
496 : .header = 1,
497 : .mh_type = GFS2_METATYPE_LB,
498 : .mh_format = GFS2_FORMAT_LB,
499 : .name = "gfs2_log_block",
500 : .display = "log",
501 : .fields = gfs2_log_block_fields,
502 : .nfields = ARRAY_SIZE(gfs2_log_block_fields),
503 : .size = sizeof(struct gfs2_meta_header),
504 : },
505 : [LGFS2_MT_EA_ATTR] = {
506 : .header = 1,
507 : .mh_type = GFS2_METATYPE_EA,
508 : .mh_format = GFS2_FORMAT_EA,
509 : .name = "gfs2_ea_attr",
510 : .display = "extended attribute",
511 : .fields = gfs2_ea_attr_fields,
512 : .nfields = ARRAY_SIZE(gfs2_ea_attr_fields),
513 : .size = sizeof(struct gfs2_meta_header),
514 : },
515 : [LGFS2_MT_EA_DATA] = {
516 : .header = 1,
517 : .mh_type = GFS2_METATYPE_ED,
518 : .mh_format = GFS2_FORMAT_ED,
519 : .name = "gfs2_ea_data",
520 : .display = "extended attribute data",
521 : .fields = gfs2_ea_data_fields,
522 : .nfields = ARRAY_SIZE(gfs2_ea_data_fields),
523 : .size = sizeof(struct gfs2_meta_header),
524 : },
525 : [LGFS2_MT_GFS2_QUOTA_CHANGE] = {
526 : .name = "gfs2_quota_change",
527 : .display = "quota change",
528 : .fields = gfs2_quota_change_fields,
529 : .nfields = ARRAY_SIZE(gfs2_quota_change_fields),
530 : .size = sizeof(struct gfs2_quota_change),
531 : },
532 : [LGFS2_MT_DIRENT] = {
533 : .name = "gfs2_dirent",
534 : .display = "directory entry",
535 : .fields = gfs2_dirent_fields,
536 : .nfields = ARRAY_SIZE(gfs2_dirent_fields),
537 : .size = sizeof(struct gfs2_dirent),
538 : },
539 : [LGFS2_MT_EA_HEADER] = {
540 : .name = "gfs2_ea_header",
541 : .display = "extended attribute header",
542 : .fields = gfs2_ea_header_fields,
543 : .nfields = ARRAY_SIZE(gfs2_ea_header_fields),
544 : .size = sizeof(struct gfs2_ea_header),
545 : },
546 : [LGFS2_MT_GFS2_INUM_RANGE] = {
547 : .name = "gfs2_inum_range",
548 : .display = "inum range",
549 : .fields = gfs2_inum_range_fields,
550 : .nfields = ARRAY_SIZE(gfs2_inum_range_fields),
551 : .size = sizeof(struct gfs2_inum_range),
552 : },
553 : [LGFS2_MT_STATFS_CHANGE] = {
554 : .name = "gfs2_statfs_change",
555 : .display = "statfs change",
556 : .fields = gfs2_statfs_change_fields,
557 : .nfields = ARRAY_SIZE(gfs2_statfs_change_fields),
558 : .size = sizeof(struct gfs2_statfs_change),
559 : },
560 : [LGFS2_MT_DATA] = {
561 : .name = "data",
562 : .display = "data",
563 : },
564 : [LGFS2_MT_FREE] = {
565 : .name = "free",
566 : .display = "free",
567 : },
568 : };
569 :
570 : const unsigned lgfs2_metadata_size = ARRAY_SIZE(lgfs2_metadata);
571 :
572 16 : const struct lgfs2_metafield *lgfs2_find_mfield_name(const char *name, const struct lgfs2_metadata *mtype)
573 : {
574 : int j;
575 : const struct lgfs2_metafield *f;
576 :
577 210 : for (j = 0; j < mtype->nfields; j++) {
578 210 : f = &mtype->fields[j];
579 210 : if (strcmp(f->name, name) == 0)
580 16 : return f;
581 : }
582 0 : return NULL;
583 : }
584 :
585 23 : const struct lgfs2_metadata *lgfs2_find_mtype(uint32_t mh_type)
586 : {
587 23 : const struct lgfs2_metadata *m = lgfs2_metadata;
588 23 : unsigned n = 0;
589 :
590 : do {
591 107 : if (m[n].mh_type == mh_type)
592 23 : return &m[n];
593 84 : n++;
594 84 : } while (n < lgfs2_metadata_size);
595 :
596 0 : return NULL;
597 : }
598 :
599 0 : const struct lgfs2_metadata *lgfs2_find_mtype_name(const char *name)
600 : {
601 0 : const struct lgfs2_metadata *m = lgfs2_metadata;
602 0 : unsigned n = 0;
603 :
604 : do {
605 0 : if (!strcmp(m[n].name, name))
606 0 : return &m[n];
607 0 : n++;
608 0 : } while (n < lgfs2_metadata_size);
609 :
610 0 : return NULL;
611 : }
612 :
613 8 : int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct lgfs2_metafield *field, int hex)
614 : {
615 8 : const char *fieldp = blk + field->offset;
616 :
617 8 : errno = EINVAL;
618 8 : if (str == NULL)
619 0 : return 1;
620 :
621 8 : if (field->flags & LGFS2_MFF_UUID) {
622 : char readable_uuid[36+1];
623 : uuid_t uuid;
624 :
625 1 : memcpy(uuid, fieldp, sizeof(uuid_t));
626 1 : uuid_unparse(uuid, readable_uuid);
627 1 : snprintf(str, size, "%s", readable_uuid);
628 7 : } else if (field->flags & LGFS2_MFF_STRING) {
629 0 : snprintf(str, size, "%s", fieldp);
630 : } else {
631 : uint64_t value;
632 :
633 7 : switch(field->length) {
634 0 : case sizeof(uint8_t):
635 0 : value = *(uint8_t *)fieldp;
636 0 : break;
637 0 : case sizeof(uint16_t):
638 0 : value = be16_to_cpu(*(__be16 *)fieldp);
639 0 : break;
640 6 : case sizeof(uint32_t):
641 6 : value = be32_to_cpu(*(__be32 *)fieldp);
642 6 : break;
643 1 : case sizeof(uint64_t):
644 1 : value = be64_to_cpu(*(__be64 *)fieldp);
645 1 : break;
646 0 : default:
647 0 : *str = 0;
648 0 : goto out;
649 : }
650 :
651 7 : if (hex) {
652 4 : snprintf(str, size, "%"PRIx64, value);
653 4 : goto out;
654 : }
655 3 : if (field->flags & LGFS2_MFF_MASK) {
656 0 : char *s = str, *end = str + size;
657 : unsigned n;
658 :
659 0 : for (n = 0; n < field->nsyms; n++) {
660 0 : const struct lgfs2_symbolic *sym = &field->symtab[n];
661 :
662 0 : if (!(value & sym->key))
663 0 : continue;
664 0 : if (s != str && s < end)
665 0 : *s++ = '/';
666 0 : if (s < end) {
667 0 : const char *v = sym->value + sym->prefix;
668 0 : size_t len = strlen(v);
669 :
670 0 : if (len > end - s)
671 0 : len = end - s;
672 0 : memcpy(s, v, len);
673 0 : s += len;
674 : }
675 : }
676 0 : if (s < end)
677 0 : *s = '\0';
678 0 : goto out;
679 : }
680 3 : snprintf(str, size, "%"PRIu64, value);
681 : }
682 8 : out:
683 8 : str[size - 1] = '\0';
684 8 : return 0;
685 : }
686 :
687 9 : int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val)
688 : {
689 9 : char *fieldp = blk + field->offset;
690 9 : uint64_t num = *(uint64_t *)val;
691 :
692 9 : if (field->flags & LGFS2_MFF_UUID) {
693 0 : memcpy(fieldp, val, 16);
694 0 : return 0;
695 : }
696 :
697 9 : errno = EINVAL;
698 9 : if (field->flags & LGFS2_MFF_STRING) {
699 0 : size_t len = strnlen(val, field->length);
700 :
701 0 : if (len >= field->length)
702 0 : return 1;
703 0 : strncpy(fieldp, val, field->length - 1);
704 0 : fieldp[field->length - 1] = '\0';
705 0 : return 0;
706 : }
707 :
708 9 : switch(field->length) {
709 0 : case sizeof(uint8_t):
710 0 : *fieldp = (uint8_t)num;
711 0 : return 0;
712 0 : case sizeof(uint16_t):
713 0 : *(__be16 *)fieldp = cpu_to_be16((uint16_t)num);
714 0 : return 0;
715 8 : case sizeof(uint32_t):
716 8 : *(__be32 *)fieldp = cpu_to_be32((uint32_t)num);
717 8 : return 0;
718 1 : case sizeof(uint64_t):
719 1 : *(__be64 *)fieldp = cpu_to_be64((uint64_t)num);
720 1 : return 0;
721 0 : default:
722 : /* Will never happen */
723 0 : break;
724 : }
725 :
726 0 : return 1;
727 : }
|