]>
Commit | Line | Data |
---|---|---|
372d9655 JB |
1 | /****************************************************************************** |
2 | ******************************************************************************* | |
3 | ** | |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | |
5 | ** Copyright (C) 2004 Red Hat, Inc. All rights reserved. | |
6 | ** | |
7 | ** This copyrighted material is made available to anyone wishing to use, | |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | |
9 | ** of the GNU General Public License v.2. | |
10 | ** | |
11 | ******************************************************************************* | |
12 | ******************************************************************************/ | |
13 | ||
14 | /* | |
15 | * On-disk structures. | |
16 | * | |
17 | * THE BIG PICTURE of on-disk layout: | |
18 | * | |
19 | * GFS filesystem code views the entire filesystem, including journals, as | |
20 | * one contiguous group of blocks on one (perhaps virtual) storage device. | |
21 | * The filesystem space is shared, not distributed; each node in the cluster | |
22 | * must see the entire filesystem space. | |
23 | * | |
24 | * If the filesystem is spread across multiple physical storage devices, | |
25 | * volume management (device mapping) must be used to present the fileystem | |
26 | * space to GFS as one (virtual) device, with contiguous blocks. | |
27 | * | |
28 | * The superblock contains basic information about the filesytem, and appears | |
29 | * at a location 64 KBytes into the filesystem. The first 64 KBytes of the | |
30 | * filesystem are empty, providing a safety buffer against wayward volume | |
31 | * management software (that sometimes write data into the first few bytes of | |
32 | * a device) or administrators. | |
33 | * | |
34 | * After the superblock, the rest of the filesystem is divided into multiple | |
35 | * Resource Groups and several journals. | |
36 | * | |
37 | * The Resource Groups (RGs or rgrps) contain the allocatable blocks that are | |
38 | * used for storing files, directories, etc., and all of the associated | |
39 | * metadata. Each RG has its own set of block allocation statistics (within | |
40 | * the RG header), a number of blocks containing the block allocation bitmap, | |
41 | * and a large number of allocatable blocks for file data and metadata. | |
42 | * Multiple RGs allow multiple nodes to simultaneously allocate blocks from the | |
43 | * filesystem (using different RGs), enhancing parallel access. RG size and | |
44 | * number of RGs are determined by gfs_mkfs when creating the filesystem. | |
45 | * An administrator can specify RG size (see man gfs_mkfs). | |
46 | * | |
47 | * The journals contain temporary copies of metadata blocks, along with | |
48 | * other data, that allow GFS to recover the filesystem to a consistent state | |
49 | * (at least as far as metadata is concerned) if a node fails in the midst | |
50 | * of performing a write transaction. There must be one journal for each node | |
51 | * in the cluster. Since access to the entire filesystem space is shared, | |
52 | * if a node crashes, another node will be able to read the crashed node's | |
53 | * journal, and perform recovery. | |
54 | * | |
55 | * Currently, gfs_mkfs places the journals right in the middle of a freshly | |
56 | * created filesystem space, between 2 large groups of RGs. From a filesystem | |
57 | * layout perspective, this placement is not a requirement; the journals | |
58 | * could be placed anywhere within the filesystem space. | |
59 | * | |
60 | * New Resource Groups and Journals may be added to the filesystem after the | |
61 | * filesystem has been created, if the filesystem's (virtual) device is made | |
62 | * larger. See man gfs_grow and gfs_jadd. | |
63 | * | |
64 | * A few special hidden inodes are contained in a GFS filesystem. They do | |
65 | * not appear in any directories; instead, the superblock points to them | |
66 | * using block numbers for their location. The special inodes are: | |
67 | * | |
68 | * Root inode: Root directory of the filesystem | |
69 | * Resource Group Index: A file containing block numbers and sizes of all RGs | |
70 | * Journal Index: A file containing block numbers and sizes of all journals | |
71 | * Quota: A file containing all quota information for the filesystem | |
72 | * License: A file containing license information | |
73 | * | |
74 | * Note that there is NOTHING RELATED TO INTER-NODE LOCK MANAGEMENT ON-DISK. | |
75 | * Locking is handled completely off-disk, typically via LAN. | |
76 | * | |
77 | * NOTE: | |
78 | * If you add 8 byte fields to these structures, they must be 8 byte | |
79 | * aligned. 4 byte field must be 4 byte aligned, etc... | |
80 | * | |
81 | * All structures must be a multiple of 8 bytes long. | |
82 | * | |
83 | * GRIPES: | |
84 | * We should have forgetten about supporting 512B FS block sizes | |
85 | * and made the di_reserved field in the struct gfs_dinode structure | |
86 | * much bigger. | |
87 | * | |
88 | * de_rec_len in struct gfs_dirent should really have been a 32-bit value | |
89 | * as it now limits us to a 64k FS block size (with the current code | |
90 | * in dir.c). | |
91 | */ | |
92 | ||
93 | #ifndef __GFS_ONDISK_DOT_H__ | |
94 | #define __GFS_ONDISK_DOT_H__ | |
95 | ||
96 | #define GFS_MAGIC (0x01161970) /* for all on-disk headers */ | |
97 | #define GFS_BASIC_BLOCK (512) /* "basic block" = "sector" = 512B */ | |
98 | #define GFS_BASIC_BLOCK_SHIFT (9) | |
99 | ||
100 | /* Controls how much data can be logged in-core before dumping log to disk */ | |
101 | ||
102 | #define GFS_DUMPS_PER_LOG (4) /* 1/4 of on-disk journal size*/ | |
103 | ||
104 | /* Lock numbers of the LM_TYPE_NONDISK type. These protect certain | |
105 | * cluster-wide operations (rather than on-disk entities). | |
106 | * Currently, the LIVE lock is not used for any real purpose. */ | |
107 | ||
108 | #define GFS_MOUNT_LOCK (0) /* only one node can Mount at a time */ | |
109 | #define GFS_LIVE_LOCK (1) /* shared by all mounted nodes */ | |
110 | #define GFS_TRANS_LOCK (2) /* Transaction, protects jrnl recovery */ | |
111 | #define GFS_RENAME_LOCK (3) /* only one node can Rename at a time */ | |
112 | ||
113 | /* On-disk format (version) numbers for various metadata types, | |
114 | * used in gfs_meta_header */ | |
115 | ||
116 | #define GFS_FORMAT_SB (100) /* Super-Block */ | |
117 | #define GFS_FORMAT_RG (200) /* Resource Group Header */ | |
118 | #define GFS_FORMAT_RB (300) /* Resource Group Block Alloc BitBlock */ | |
119 | #define GFS_FORMAT_DI (400) /* "Disk" inode (dinode) */ | |
120 | #define GFS_FORMAT_IN (500) /* Indirect dinode block list */ | |
121 | #define GFS_FORMAT_LF (600) /* Leaf dinode block list */ | |
122 | #define GFS_FORMAT_JD (700) /* Journal Data */ | |
123 | #define GFS_FORMAT_LH (800) /* Log Header */ | |
124 | #define GFS_FORMAT_LD (900) /* Log Descriptor */ | |
125 | /* These don't have actual struct gfs_meta_header structures to go with them */ | |
126 | #define GFS_FORMAT_JI (1000) /* Journal Index */ | |
127 | #define GFS_FORMAT_RI (1100) /* Resource Group Index */ | |
128 | #define GFS_FORMAT_DE (1200) /* Directory Entry */ | |
129 | #define GFS_FORMAT_QU (1500) /* Quota */ | |
130 | #define GFS_FORMAT_EA (1600) /* Extended Attribute */ | |
131 | #define GFS_FORMAT_ED (1700) /* Extended Attribute data */ | |
132 | /* These version #s are embedded in the superblock */ | |
133 | #define GFS_FORMAT_FS (1309) /* Filesystem (all-encompassing) */ | |
134 | #define GFS_FORMAT_MULTI (1401) /* Multi-Host */ | |
135 | ||
136 | /* | |
137 | * An on-disk inode number | |
138 | * Initially, the on-disk block address of the inode block is assigned as the | |
139 | * formal (permanent) ID as well. Block address can change (to move inode | |
140 | * on-disk), but formal ID must stay unchanged once assigned. | |
141 | */ | |
142 | ||
143 | #define gfs_inum_equal(ino1, ino2) \ | |
144 | (((ino1)->no_formal_ino == (ino2)->no_formal_ino) && \ | |
145 | ((ino1)->no_addr == (ino2)->no_addr)) | |
146 | ||
147 | struct gfs_inum { | |
148 | uint64_t no_formal_ino; /* inode identifier */ | |
149 | uint64_t no_addr; /* block # of dinode block */ | |
150 | }; | |
151 | ||
152 | /* | |
153 | * Generic metadata head structure | |
154 | * | |
155 | * Every inplace buffer logged in the journal must start | |
156 | * with a struct gfs_meta_header. | |
157 | * | |
158 | * In addition to telling what kind of metadata is in the block, | |
159 | * the metaheader contains the important generation and incarnation | |
160 | * numbers. | |
161 | * | |
162 | * The generation number is used during journal recovery to determine | |
163 | * whether an in-place block on-disk is older than an on-disk journaled copy | |
164 | * of the block. If so, GFS overwrites the in-place block with the journaled | |
165 | * version of the block. | |
166 | * | |
167 | * A meta block's generation number must increment monotonically across the | |
168 | * cluster, each time new contents are committed to the block. This means | |
169 | * that whenever GFS allocates a pre-existing metadata block, GFS must read | |
170 | * that block from disk (in case another node has incremented it). It also | |
171 | * means that GFS must sync the block (with incremented generation number) | |
172 | * to disk (both log and in-place blocks), not only after changing contents | |
173 | * of the block, but also after de-allocating the block (GFS can't just throw | |
174 | * away incore metadata for a file that it's just erased). | |
175 | * | |
176 | * The incarnation number is used only for on-disk (d)inodes. GFS increments | |
177 | * it each time it de-allocates a dinode block (i.e. each time the dinode | |
178 | * loses its identity with a particular file, directory, etc.). When the | |
179 | * dinode is later allocated (i.e. to be identified with a new file, etc.), | |
180 | * GFS copies the incarnation number into the VFS inode's i_generation member. | |
181 | * If GFS is used as the backing store for an NFS server, GFS uses this | |
182 | * i_generation number as part of the NFS filehandle, which differentiates | |
183 | * it from the previous identity of the dinode, and helps protect against | |
184 | * filesystem corruption that could happen with the use of outdated, | |
185 | * invalid, or malicious filehandles. See ops_export.c. | |
186 | * | |
187 | * GFS caches de-allocated meta-headers, to minimize disk reads. | |
188 | * See struct gfs_meta_header_cache. | |
189 | */ | |
190 | ||
191 | #define GFS_METATYPE_NONE (0) | |
192 | #define GFS_METATYPE_SB (1) /* Super-Block */ | |
193 | #define GFS_METATYPE_RG (2) /* Resource Group Header */ | |
194 | #define GFS_METATYPE_RB (3) /* Resource Group Block Alloc BitBlock */ | |
195 | #define GFS_METATYPE_DI (4) /* "Disk" inode (dinode) */ | |
196 | #define GFS_METATYPE_IN (5) /* Indirect dinode block list */ | |
197 | #define GFS_METATYPE_LF (6) /* Leaf dinode block list */ | |
198 | #define GFS_METATYPE_JD (7) /* Journal Data */ | |
199 | #define GFS_METATYPE_LH (8) /* Log Header (gfs_log_header) */ | |
200 | #define GFS_METATYPE_LD (9) /* Log Descriptor (gfs_log_descriptor) */ | |
201 | #define GFS_METATYPE_EA (10) /* Extended Attribute */ | |
202 | #define GFS_METATYPE_ED (11) /* Extended Attribute data */ | |
203 | ||
204 | #define GFS_META_CLUMP (64) /* # blocks to convert fm data to meta */ | |
205 | ||
206 | struct gfs_meta_header { | |
207 | uint32_t mh_magic; /* GFS_MAGIC sanity check magic number */ | |
208 | uint32_t mh_type; /* GFS_METATYPE_XX type of metadata block */ | |
209 | uint64_t mh_generation; /* increment before writing to journal */ | |
210 | uint32_t mh_format; /* GFS_FORMAT_XX (version # for this type) */ | |
211 | uint32_t mh_incarn; /* increment when marking dinode "unused" */ | |
212 | }; | |
213 | ||
214 | /* | |
215 | * super-block structure | |
216 | * | |
217 | * One of these is at beginning of filesystem. | |
218 | * It's probably good if SIZEOF_SB <= GFS_BASIC_BLOCK (512 bytes) | |
219 | */ | |
220 | ||
221 | /* Address of SuperBlock in GFS basic blocks. 1st 64K of filesystem is empty | |
222 | for safety against getting clobbered by wayward volume managers, etc. | |
223 | 64k was chosen because it's the largest GFS-supported fs block size. */ | |
224 | #define GFS_SB_ADDR (128) | |
225 | ||
226 | /* The lock number for the superblock (must be zero) */ | |
227 | #define GFS_SB_LOCK (0) | |
228 | #define GFS_CRAP_LOCK (1) | |
229 | ||
230 | /* Requirement: GFS_LOCKNAME_LEN % 8 == 0 | |
231 | Includes: the fencing zero at the end */ | |
232 | #define GFS_LOCKNAME_LEN (64) | |
233 | ||
234 | struct gfs_sb { | |
235 | /* Order is important; need to be able to read old superblocks | |
236 | in order to support on-disk version upgrades */ | |
237 | struct gfs_meta_header sb_header; | |
238 | ||
239 | uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ | |
240 | uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ | |
241 | uint32_t sb_flags; /* ?? */ | |
242 | ||
243 | uint32_t sb_bsize; /* fundamental FS block size in bytes */ | |
244 | uint32_t sb_bsize_shift; /* log2(sb_bsize) */ | |
245 | uint32_t sb_seg_size; /* Journal segment size in FS blocks */ | |
246 | ||
247 | /* These special inodes do not appear in any on-disk directory. */ | |
248 | struct gfs_inum sb_jindex_di; /* journal index inode */ | |
249 | struct gfs_inum sb_rindex_di; /* resource group index inode */ | |
250 | struct gfs_inum sb_root_di; /* root directory inode */ | |
251 | ||
252 | /* Default inter-node locking protocol (lock module) and namespace */ | |
253 | char sb_lockproto[GFS_LOCKNAME_LEN]; /* lock protocol name */ | |
254 | char sb_locktable[GFS_LOCKNAME_LEN]; /* unique name for this FS */ | |
255 | ||
256 | /* More special inodes */ | |
257 | struct gfs_inum sb_quota_di; /* quota inode */ | |
258 | struct gfs_inum sb_license_di; /* license inode */ | |
259 | ||
260 | char sb_reserved[96]; | |
261 | }; | |
262 | ||
263 | /* | |
264 | * journal index structure | |
265 | * | |
266 | * One for each journal used by the filesystem. | |
267 | * These descriptors are packed contiguously within the jindex inode (file). | |
268 | */ | |
269 | ||
270 | struct gfs_jindex { | |
271 | uint64_t ji_addr; /* starting block of the journal */ | |
272 | uint32_t ji_nsegment; /* number (quantity) of segments in journal */ | |
273 | uint32_t ji_pad; | |
274 | ||
275 | char ji_reserved[64]; | |
276 | }; | |
277 | ||
278 | /* | |
279 | * resource index structure | |
280 | * | |
281 | * One of these for each resource group in the filesystem. | |
282 | * These descriptors are packed contiguously within the rindex inode (file). | |
283 | * Also see struct gfs_rgrp. | |
284 | */ | |
285 | ||
286 | struct gfs_rindex { | |
287 | uint64_t ri_addr; /* block # of 1st block (header) in rgrp */ | |
288 | uint32_t ri_length; /* # fs blocks containing rgrp header & bitmap */ | |
289 | uint32_t ri_pad; | |
290 | ||
291 | uint64_t ri_data1; /* block # of first data/meta block in rgrp */ | |
292 | uint32_t ri_data; /* number (qty) of data/meta blocks in rgrp */ | |
293 | ||
294 | uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */ | |
295 | ||
296 | char ri_reserved[64]; | |
297 | }; | |
298 | ||
299 | /* | |
300 | * resource group header structure | |
301 | * | |
302 | * One of these at beginning of the first block of an rgrp, | |
303 | * followed by block alloc bitmap data in remainder of first block. | |
304 | * Each resource group contains: | |
305 | * Header block, including block allocation statistics (struct gfs_rgrp) | |
306 | * and first part of block alloc bitmap. | |
307 | * Bitmap block(s), continuing block alloc bitmap started in header block. | |
308 | * Data/meta blocks, allocatable blocks containing file data and metadata. | |
309 | * | |
310 | * In older versions, now-unused (but previously allocated) dinodes were | |
311 | * saved for re-use in an on-disk linked list (chain). This is no longer | |
312 | * done, but support still exists for reclaiming dinodes from this list, | |
313 | * to support upgrades from older on-disk formats. | |
314 | */ | |
315 | ||
316 | /* Each data block within rgrp is represented by 2 bits in the alloc bitmap */ | |
317 | #define GFS_NBBY (4) /* # blocks represented by 1 bitmap byte */ | |
318 | #define GFS_BIT_SIZE (2) | |
319 | #define GFS_BIT_MASK (0x00000003) | |
320 | ||
321 | /* | |
322 | * 4 possible block allocation states: | |
323 | * bit 0 = alloc(1)/free(0) | |
324 | * bit 1 = metadata(1)/data(0) | |
325 | */ | |
326 | #define GFS_BLKST_FREE (0) | |
327 | #define GFS_BLKST_USED (1) | |
328 | #define GFS_BLKST_FREEMETA (2) | |
329 | #define GFS_BLKST_USEDMETA (3) | |
330 | ||
331 | struct gfs_rgrp { | |
332 | struct gfs_meta_header rg_header; | |
333 | ||
334 | uint32_t rg_flags; /* ?? */ | |
335 | ||
336 | uint32_t rg_free; /* Number (qty) of free data blocks */ | |
337 | ||
338 | /* Dinodes are USEDMETA, but are handled separately from other METAs */ | |
339 | uint32_t rg_useddi; /* Number (qty) of dinodes (used or free) */ | |
340 | uint32_t rg_freedi; /* Number (qty) of unused (free) dinodes */ | |
341 | struct gfs_inum rg_freedi_list; /* 1st block in chain of free dinodes */ | |
342 | ||
343 | /* These META statistics do not include dinodes (used or free) */ | |
344 | uint32_t rg_usedmeta; /* Number (qty) of used metadata blocks */ | |
345 | uint32_t rg_freemeta; /* Number (qty) of unused metadata blocks */ | |
346 | ||
347 | char rg_reserved[64]; | |
348 | }; | |
349 | ||
350 | /* | |
351 | * quota structure | |
352 | */ | |
353 | ||
354 | struct gfs_quota { | |
355 | uint64_t qu_limit; | |
356 | uint64_t qu_warn; | |
357 | int64_t qu_value; | |
358 | ||
359 | char qu_reserved[64]; | |
360 | }; | |
361 | ||
362 | /* | |
363 | * dinode (disk inode) structure | |
364 | * The ondisk representation of inodes | |
365 | * One for each file, directory, etc. | |
366 | * GFS does not put more than one inode in a single block. | |
367 | * The inode may be "stuffed", carrying file data along with metadata, | |
368 | * if the file data is small enough. | |
369 | * Otherwise, the inode block contains pointers to other blocks that contain | |
370 | * either file data or other pointers to other blocks (indirect addressing | |
371 | * via a metadata tree). | |
372 | */ | |
373 | ||
374 | #define GFS_MAX_META_HEIGHT (10) | |
375 | #define GFS_DIR_MAX_DEPTH (17) | |
376 | ||
377 | /* Dinode types */ | |
378 | #define GFS_FILE_NON (0) | |
379 | #define GFS_FILE_REG (1) /* regular file */ | |
380 | #define GFS_FILE_DIR (2) /* directory */ | |
381 | #define GFS_FILE_LNK (5) /* link */ | |
382 | #define GFS_FILE_BLK (7) /* block device node */ | |
383 | #define GFS_FILE_CHR (8) /* character device node */ | |
384 | #define GFS_FILE_FIFO (101) /* fifo/pipe */ | |
385 | #define GFS_FILE_SOCK (102) /* socket */ | |
386 | ||
387 | /* Dinode flags */ | |
388 | #define GFS_DIF_JDATA (0x00000001) /* jrnl all data for this file */ | |
389 | #define GFS_DIF_EXHASH (0x00000002) /* hashed directory (leaves) */ | |
390 | #define GFS_DIF_UNUSED (0x00000004) /* unused dinode */ | |
391 | #define GFS_DIF_EA_INDIRECT (0x00000008) /* extended attribute, indirect*/ | |
392 | #define GFS_DIF_DIRECTIO (0x00000010) | |
393 | #define GFS_DIF_IMMUTABLE (0x00000020) /* Can't change file */ | |
394 | #define GFS_DIF_APPENDONLY (0x00000040) /* Can only add to end of file */ | |
395 | #define GFS_DIF_NOATIME (0x00000080) /* Don't update access time | |
396 | (currently unused/ignored) */ | |
397 | #define GFS_DIF_SYNC (0x00000100) /* Flush to disk, don't cache | |
398 | (currently unused/ignored) */ | |
399 | #define GFS_DIF_INHERIT_DIRECTIO (0x40000000) /* new files get DIRECTIO flag */ | |
400 | #define GFS_DIF_INHERIT_JDATA (0x80000000) /* new files get JDATA flag */ | |
401 | ||
402 | struct gfs_dinode { | |
403 | struct gfs_meta_header di_header; | |
404 | ||
405 | struct gfs_inum di_num; /* formal inode # and block address */ | |
406 | ||
407 | uint32_t di_mode; /* mode of file */ | |
408 | uint32_t di_uid; /* owner's user id */ | |
409 | uint32_t di_gid; /* owner's group id */ | |
410 | uint32_t di_nlink; /* number (qty) of links to this file */ | |
411 | uint64_t di_size; /* number (qty) of bytes in file */ | |
412 | uint64_t di_blocks; /* number (qty) of blocks in file */ | |
413 | int64_t di_atime; /* time last accessed */ | |
414 | int64_t di_mtime; /* time last modified */ | |
415 | int64_t di_ctime; /* time last changed */ | |
416 | ||
417 | /* Non-zero only for character or block device nodes */ | |
418 | uint32_t di_major; /* device major number */ | |
419 | uint32_t di_minor; /* device minor number */ | |
420 | ||
421 | /* Block allocation strategy */ | |
422 | uint64_t di_rgrp; /* dinode rgrp block number */ | |
423 | uint64_t di_goal_rgrp; /* rgrp to alloc from next */ | |
424 | uint32_t di_goal_dblk; /* data block goal */ | |
425 | uint32_t di_goal_mblk; /* metadata block goal */ | |
426 | ||
427 | uint32_t di_flags; /* GFS_DIF_... */ | |
428 | ||
429 | /* struct gfs_rindex, struct gfs_jindex, or struct gfs_dirent */ | |
430 | uint32_t di_payload_format; /* GFS_FORMAT_... */ | |
431 | uint16_t di_type; /* GFS_FILE_... type of file */ | |
432 | uint16_t di_height; /* height of metadata (0 == stuffed) */ | |
433 | uint32_t di_incarn; /* incarnation (unused, see gfs_meta_header) */ | |
434 | uint16_t di_pad; | |
435 | ||
436 | /* These only apply to directories */ | |
437 | uint16_t di_depth; /* Number of bits in the table */ | |
438 | uint32_t di_entries; /* The # (qty) of entries in the directory */ | |
439 | ||
440 | /* This formed an on-disk chain of unused dinodes */ | |
441 | struct gfs_inum di_next_unused; /* used in old versions only */ | |
442 | ||
443 | uint64_t di_eattr; /* extended attribute block number */ | |
444 | ||
445 | char di_reserved[56]; | |
446 | }; | |
447 | ||
448 | /* | |
449 | * indirect block header | |
450 | * | |
451 | * A component of a dinode's indirect addressing metadata tree. | |
452 | * These are pointed to by pointers in dinodes or other indirect blocks. | |
453 | */ | |
454 | ||
455 | struct gfs_indirect { | |
456 | struct gfs_meta_header in_header; | |
457 | ||
458 | char in_reserved[64]; | |
459 | }; | |
460 | ||
461 | /* | |
462 | * directory structure - many of these per directory file | |
463 | * | |
464 | * See comments at beginning of dir.c | |
465 | */ | |
466 | ||
467 | #define GFS_FNAMESIZE (255) | |
468 | #define GFS_DIRENT_SIZE(name_len) ((sizeof(struct gfs_dirent) + (name_len) + 7) & ~7) | |
469 | ||
470 | struct gfs_dirent { | |
471 | struct gfs_inum de_inum; /* formal inode number and block address */ | |
472 | uint32_t de_hash; /* hash of the filename */ | |
473 | uint16_t de_rec_len; /* the length of the dirent */ | |
474 | uint16_t de_name_len; /* the length of the name */ | |
475 | uint16_t de_type; /* GFS_FILE_... type of dinode this points to */ | |
476 | ||
477 | char de_reserved[14]; | |
478 | }; | |
479 | ||
480 | /* | |
481 | * Header of leaf directory nodes | |
482 | * | |
483 | * See comments at beginning of dir.c | |
484 | */ | |
485 | ||
486 | struct gfs_leaf { | |
487 | struct gfs_meta_header lf_header; | |
488 | ||
489 | uint16_t lf_depth; /* Depth of leaf */ | |
490 | uint16_t lf_entries; /* Number of dirents in leaf */ | |
491 | uint32_t lf_dirent_format; /* GFS_FORMAT_DE (version #) */ | |
492 | uint64_t lf_next; /* Next leaf, if overflow */ | |
493 | ||
494 | char lf_reserved[64]; | |
495 | }; | |
496 | ||
497 | /* | |
498 | * Log header structure | |
499 | * | |
500 | * Two of these are in the first block of a transaction log: | |
501 | * 1) at beginning of block | |
502 | * 2) at end of first 512-byte sector within block | |
503 | */ | |
504 | ||
505 | #define GFS_LOG_HEAD_UNMOUNT (0x00000001) /* log is clean, can unmount fs */ | |
506 | ||
507 | struct gfs_log_header { | |
508 | struct gfs_meta_header lh_header; | |
509 | ||
510 | uint32_t lh_flags; /* GFS_LOG_HEAD_... */ | |
511 | uint32_t lh_pad; | |
512 | ||
513 | uint64_t lh_first; /* Block number of first header in this trans */ | |
514 | uint64_t lh_sequence; /* Sequence number of this transaction */ | |
515 | ||
516 | uint64_t lh_tail; /* Block number of log tail */ | |
517 | uint64_t lh_last_dump; /* Block number of last dump */ | |
518 | ||
519 | char lh_reserved[64]; | |
520 | }; | |
521 | ||
522 | /* | |
523 | * Log type descriptor | |
524 | * | |
525 | * One of these for each chunk in a transaction | |
526 | */ | |
527 | ||
528 | #define GFS_LOG_DESC_METADATA (300) /* metadata */ | |
529 | /* ld_data1 is the number (quantity) of metadata blocks in the descriptor. | |
530 | ld_data2 is unused. | |
531 | */ | |
532 | ||
533 | #define GFS_LOG_DESC_IUL (400) /* unlinked inode */ | |
534 | /* ld_data1 is TRUE if this is a dump. | |
535 | ld_data2 is unused. | |
536 | FixMe!!! ld_data1 should be the number (quantity) of entries. | |
537 | ld_data2 should be "TRUE if this is a dump". | |
538 | */ | |
539 | ||
540 | #define GFS_LOG_DESC_IDA (401) /* de-allocated inode */ | |
541 | /* ld_data1 is unused. | |
542 | ld_data2 is unused. | |
543 | FixMe!!! ld_data1 should be the number (quantity) of entries. | |
544 | */ | |
545 | ||
546 | #define GFS_LOG_DESC_Q (402) /* quota */ | |
547 | /* ld_data1 is the number of quota changes in the descriptor. | |
548 | ld_data2 is TRUE if this is a dump. | |
549 | */ | |
550 | ||
551 | #define GFS_LOG_DESC_LAST (500) /* final in a logged transaction */ | |
552 | /* ld_data1 is unused. | |
553 | ld_data2 is unused. | |
554 | */ | |
555 | ||
556 | struct gfs_log_descriptor { | |
557 | struct gfs_meta_header ld_header; | |
558 | ||
559 | uint32_t ld_type; /* GFS_LOG_DESC_... Type of this log chunk */ | |
560 | uint32_t ld_length; /* Number of buffers in this chunk */ | |
561 | uint32_t ld_data1; /* descriptor-specific field */ | |
562 | uint32_t ld_data2; /* descriptor-specific field */ | |
563 | ||
564 | char ld_reserved[64]; | |
565 | }; | |
566 | ||
567 | /* | |
568 | * Metadata block tags | |
569 | * | |
570 | * One for each logged block. Tells where block really belongs on-disk. | |
571 | * These descriptor tags are packed contiguously after a gfs_log_descriptor. | |
572 | */ | |
573 | ||
574 | struct gfs_block_tag { | |
575 | uint64_t bt_blkno; /* inplace block number */ | |
576 | uint32_t bt_flags; /* ?? */ | |
577 | uint32_t bt_pad; | |
578 | }; | |
579 | ||
580 | /* | |
581 | * Quota Journal Tag | |
582 | */ | |
583 | ||
584 | #define GFS_QTF_USER (0x00000001) | |
585 | ||
586 | struct gfs_quota_tag { | |
587 | int64_t qt_change; | |
588 | uint32_t qt_flags; /* GFS_QTF_... */ | |
589 | uint32_t qt_id; | |
590 | }; | |
591 | ||
592 | /* | |
593 | * Extended attribute header format | |
594 | */ | |
595 | ||
596 | #define GFS_EA_MAX_NAME_LEN (255) | |
597 | #define GFS_EA_MAX_DATA_LEN (65536) | |
598 | ||
599 | #define GFS_EATYPE_UNUSED (0) | |
600 | #define GFS_EATYPE_USR (1) /* user attribute */ | |
601 | #define GFS_EATYPE_SYS (2) /* system attribute */ | |
602 | ||
603 | #define GFS_EATYPE_LAST (2) | |
604 | #define GFS_EATYPE_VALID(x) ((x) <= GFS_EATYPE_LAST) | |
605 | ||
606 | #define GFS_EAFLAG_LAST (0x01) /* last ea in block */ | |
607 | ||
608 | struct gfs_ea_header { | |
609 | uint32_t ea_rec_len; /* total record length: hdr + name + data */ | |
610 | uint32_t ea_data_len; /* data length, in bytes */ | |
611 | uint8_t ea_name_len; /* no NULL pointer after the string */ | |
612 | uint8_t ea_type; /* GFS_EATYPE_... */ | |
613 | uint8_t ea_flags; /* GFS_EAFLAG_... */ | |
614 | uint8_t ea_num_ptrs; /* # fs blocks needed for EA */ | |
615 | uint32_t ea_pad; | |
616 | }; | |
617 | ||
618 | /* Endian functions */ | |
619 | ||
620 | #define GFS_ENDIAN_BIG | |
621 | ||
622 | #ifdef GFS_ENDIAN_BIG | |
623 | ||
624 | #define gfs16_to_cpu be16_to_cpu | |
625 | #define gfs32_to_cpu be32_to_cpu | |
626 | #define gfs64_to_cpu be64_to_cpu | |
627 | ||
628 | #define cpu_to_gfs16 cpu_to_be16 | |
629 | #define cpu_to_gfs32 cpu_to_be32 | |
630 | #define cpu_to_gfs64 cpu_to_be64 | |
631 | ||
632 | #else /* GFS_ENDIAN_BIG */ | |
633 | ||
634 | #define gfs16_to_cpu le16_to_cpu | |
635 | #define gfs32_to_cpu le32_to_cpu | |
636 | #define gfs64_to_cpu le64_to_cpu | |
637 | ||
638 | #define cpu_to_gfs16 cpu_to_le16 | |
639 | #define cpu_to_gfs32 cpu_to_le32 | |
640 | #define cpu_to_gfs64 cpu_to_le64 | |
641 | ||
642 | #endif /* GFS_ENDIAN_BIG */ | |
643 | ||
644 | /* Translation functions */ | |
645 | ||
646 | void gfs_inum_in(struct gfs_inum *no, char *buf); | |
647 | void gfs_inum_out(struct gfs_inum *no, char *buf); | |
648 | void gfs_meta_header_in(struct gfs_meta_header *mh, char *buf); | |
649 | void gfs_meta_header_out(struct gfs_meta_header *mh, char *buf); | |
650 | void gfs_sb_in(struct gfs_sb *sb, char *buf); | |
651 | void gfs_sb_out(struct gfs_sb *sb, char *buf); | |
652 | void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); | |
653 | void gfs_jindex_out(struct gfs_jindex *jindex, char *buf); | |
654 | void gfs_rindex_in(struct gfs_rindex *rindex, char *buf); | |
655 | void gfs_rindex_out(struct gfs_rindex *rindex, char *buf); | |
656 | void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf); | |
657 | void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf); | |
658 | void gfs_quota_in(struct gfs_quota *quota, char *buf); | |
659 | void gfs_quota_out(struct gfs_quota *quota, char *buf); | |
660 | void gfs_dinode_in(struct gfs_dinode *dinode, char *buf); | |
661 | void gfs_dinode_out(struct gfs_dinode *dinode, char *buf); | |
662 | void gfs_indirect_in(struct gfs_indirect *indirect, char *buf); | |
663 | void gfs_indirect_out(struct gfs_indirect *indirect, char *buf); | |
664 | void gfs_dirent_in(struct gfs_dirent *dirent, char *buf); | |
665 | void gfs_dirent_out(struct gfs_dirent *dirent, char *buf); | |
666 | void gfs_leaf_in(struct gfs_leaf *leaf, char *buf); | |
667 | void gfs_leaf_out(struct gfs_leaf *leaf, char *buf); | |
668 | void gfs_log_header_in(struct gfs_log_header *head, char *buf); | |
669 | void gfs_log_header_out(struct gfs_log_header *head, char *buf); | |
670 | void gfs_desc_in(struct gfs_log_descriptor *desc, char *buf); | |
671 | void gfs_desc_out(struct gfs_log_descriptor *desc, char *buf); | |
672 | void gfs_block_tag_in(struct gfs_block_tag *btag, char *buf); | |
673 | void gfs_block_tag_out(struct gfs_block_tag *btag, char *buf); | |
674 | void gfs_quota_tag_in(struct gfs_quota_tag *qtag, char *buf); | |
675 | void gfs_quota_tag_out(struct gfs_quota_tag *qtag, char *buf); | |
676 | void gfs_ea_header_in(struct gfs_ea_header *qtag, char *buf); | |
677 | void gfs_ea_header_out(struct gfs_ea_header *qtag, char *buf); | |
678 | ||
679 | /* Printing functions */ | |
680 | ||
681 | void gfs_inum_print(struct gfs_inum *no); | |
682 | void gfs_meta_header_print(struct gfs_meta_header *mh); | |
683 | void gfs_sb_print(struct gfs_sb *sb); | |
684 | void gfs_jindex_print(struct gfs_jindex *jindex); | |
685 | void gfs_rindex_print(struct gfs_rindex *rindex); | |
686 | void gfs_rgrp_print(struct gfs_rgrp *rgrp); | |
687 | void gfs_quota_print(struct gfs_quota *quota); | |
688 | void gfs_dinode_print(struct gfs_dinode *dinode); | |
689 | void gfs_indirect_print(struct gfs_indirect *indirect); | |
690 | void gfs_dirent_print(struct gfs_dirent *dirent, char *name); | |
691 | void gfs_leaf_print(struct gfs_leaf *leaf); | |
692 | void gfs_log_header_print(struct gfs_log_header *head); | |
693 | void gfs_desc_print(struct gfs_log_descriptor *desc); | |
694 | void gfs_block_tag_print(struct gfs_block_tag *tag); | |
695 | void gfs_quota_tag_print(struct gfs_quota_tag *tag); | |
696 | void gfs_ea_header_print(struct gfs_ea_header *ea, char *name); | |
697 | ||
698 | /* The hash function for ExHash directories */ | |
699 | ||
700 | uint32_t gfs_dir_hash(const char *data, int len); | |
701 | ||
702 | #endif /* __GFS_ONDISK_DOT_H__ */ | |
703 | ||
704 | ||
705 | ||
706 | #ifdef WANT_GFS_CONVERSION_FUNCTIONS | |
707 | ||
708 | #define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} | |
709 | #define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} | |
710 | #define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} | |
711 | #define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} | |
712 | #define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} | |
713 | #define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} | |
714 | #define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} | |
715 | #define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} | |
716 | ||
717 | #define pa(struct, member, count) print_array(#member, struct->member, count); | |
718 | ||
719 | /** | |
720 | * print_array - Print out an array of bytes | |
721 | * @title: what to print before the array | |
722 | * @buf: the array | |
723 | * @count: the number of bytes | |
724 | * | |
725 | */ | |
726 | ||
727 | static void | |
728 | print_array(char *title, char *buf, int count) | |
729 | { | |
730 | int x; | |
731 | ||
732 | printk(" %s =\n", title); | |
733 | for (x = 0; x < count; x++) { | |
734 | printk("%.2X ", (unsigned char)buf[x]); | |
735 | if (x % 16 == 15) | |
736 | printk("\n"); | |
737 | } | |
738 | if (x % 16) | |
739 | printk("\n"); | |
740 | } | |
741 | ||
742 | /** | |
743 | * gfs_inum_in - Read in an inode number | |
744 | * @no: the cpu-order structure | |
745 | * @buf: the disk-order buffer | |
746 | * | |
747 | */ | |
748 | ||
749 | void | |
750 | gfs_inum_in(struct gfs_inum *no, char *buf) | |
751 | { | |
752 | struct gfs_inum *str = (struct gfs_inum *)buf; | |
753 | ||
754 | CPIN_64(no, str, no_formal_ino); | |
755 | CPIN_64(no, str, no_addr); | |
756 | } | |
757 | ||
758 | /** | |
759 | * gfs_inum_out - Write out an inode number | |
760 | * @no: the cpu-order structure | |
761 | * @buf: the disk-order buffer | |
762 | * | |
763 | */ | |
764 | ||
765 | void | |
766 | gfs_inum_out(struct gfs_inum *no, char *buf) | |
767 | { | |
768 | struct gfs_inum *str = (struct gfs_inum *)buf; | |
769 | ||
770 | CPOUT_64(no, str, no_formal_ino); | |
771 | CPOUT_64(no, str, no_addr); | |
772 | } | |
773 | ||
774 | /** | |
775 | * gfs_inum_print - Print out a inode number | |
776 | * @no: the cpu-order buffer | |
777 | * | |
778 | */ | |
779 | ||
780 | void | |
781 | gfs_inum_print(struct gfs_inum *no) | |
782 | { | |
783 | pv(no, no_formal_ino, "%"PRIu64); | |
784 | pv(no, no_addr, "%"PRIu64); | |
785 | } | |
786 | ||
787 | /** | |
788 | * gfs_meta_header_in - Read in a metadata header | |
789 | * @mh: the cpu-order structure | |
790 | * @buf: the disk-order buffer | |
791 | * | |
792 | */ | |
793 | ||
794 | void | |
795 | gfs_meta_header_in(struct gfs_meta_header *mh, char *buf) | |
796 | { | |
797 | struct gfs_meta_header *str = (struct gfs_meta_header *)buf; | |
798 | ||
799 | CPIN_32(mh, str, mh_magic); | |
800 | CPIN_32(mh, str, mh_type); | |
801 | CPIN_64(mh, str, mh_generation); | |
802 | CPIN_32(mh, str, mh_format); | |
803 | CPIN_32(mh, str, mh_incarn); | |
804 | } | |
805 | ||
806 | /** | |
807 | * gfs_meta_header_in - Write out a metadata header | |
808 | * @mh: the cpu-order structure | |
809 | * @buf: the disk-order buffer | |
810 | * | |
811 | * Don't ever change the generation number in this routine. | |
812 | * It's done manually in increment_generation(). | |
813 | */ | |
814 | ||
815 | void | |
816 | gfs_meta_header_out(struct gfs_meta_header *mh, char *buf) | |
817 | { | |
818 | struct gfs_meta_header *str = (struct gfs_meta_header *)buf; | |
819 | ||
820 | CPOUT_32(mh, str, mh_magic); | |
821 | CPOUT_32(mh, str, mh_type); | |
822 | #if 0 | |
823 | /* Don't do this! | |
824 | Mh_generation should only be change manually. */ | |
825 | CPOUT_64(mh, str, mh_generation); | |
826 | #endif | |
827 | CPOUT_32(mh, str, mh_format); | |
828 | CPOUT_32(mh, str, mh_incarn); | |
829 | } | |
830 | ||
831 | /** | |
832 | * gfs_meta_header_print - Print out a metadata header | |
833 | * @mh: the cpu-order buffer | |
834 | * | |
835 | */ | |
836 | ||
837 | void | |
838 | gfs_meta_header_print(struct gfs_meta_header *mh) | |
839 | { | |
840 | pv(mh, mh_magic, "0x%.8X"); | |
841 | pv(mh, mh_type, "%u"); | |
842 | pv(mh, mh_generation, "%"PRIu64); | |
843 | pv(mh, mh_format, "%u"); | |
844 | pv(mh, mh_incarn, "%u"); | |
845 | } | |
846 | ||
847 | /** | |
848 | * gfs_sb_in - Read in a superblock | |
849 | * @sb: the cpu-order structure | |
850 | * @buf: the disk-order buffer | |
851 | * | |
852 | */ | |
853 | ||
854 | void | |
855 | gfs_sb_in(struct gfs_sb *sb, char *buf) | |
856 | { | |
857 | struct gfs_sb *str = (struct gfs_sb *)buf; | |
858 | ||
859 | gfs_meta_header_in(&sb->sb_header, buf); | |
860 | ||
861 | CPIN_32(sb, str, sb_fs_format); | |
862 | CPIN_32(sb, str, sb_multihost_format); | |
863 | CPIN_32(sb, str, sb_flags); | |
864 | ||
865 | CPIN_32(sb, str, sb_bsize); | |
866 | CPIN_32(sb, str, sb_bsize_shift); | |
867 | CPIN_32(sb, str, sb_seg_size); | |
868 | ||
869 | gfs_inum_in(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); | |
870 | gfs_inum_in(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); | |
871 | gfs_inum_in(&sb->sb_root_di, (char *)&str->sb_root_di); | |
872 | ||
873 | CPIN_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); | |
874 | CPIN_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); | |
875 | ||
876 | gfs_inum_in(&sb->sb_quota_di, (char *)&str->sb_quota_di); | |
877 | gfs_inum_in(&sb->sb_license_di, (char *)&str->sb_license_di); | |
878 | ||
879 | CPIN_08(sb, str, sb_reserved, 96); | |
880 | } | |
881 | ||
882 | /** | |
883 | * gfs_sb_out - Write out a superblock | |
884 | * @sb: the cpu-order structure | |
885 | * @buf: the disk-order buffer | |
886 | * | |
887 | */ | |
888 | ||
889 | void | |
890 | gfs_sb_out(struct gfs_sb *sb, char *buf) | |
891 | { | |
892 | struct gfs_sb *str = (struct gfs_sb *)buf; | |
893 | ||
894 | gfs_meta_header_out(&sb->sb_header, buf); | |
895 | ||
896 | CPOUT_32(sb, str, sb_fs_format); | |
897 | CPOUT_32(sb, str, sb_multihost_format); | |
898 | CPOUT_32(sb, str, sb_flags); | |
899 | ||
900 | CPOUT_32(sb, str, sb_bsize); | |
901 | CPOUT_32(sb, str, sb_bsize_shift); | |
902 | CPOUT_32(sb, str, sb_seg_size); | |
903 | ||
904 | gfs_inum_out(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); | |
905 | gfs_inum_out(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); | |
906 | gfs_inum_out(&sb->sb_root_di, (char *)&str->sb_root_di); | |
907 | ||
908 | CPOUT_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); | |
909 | CPOUT_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); | |
910 | ||
911 | gfs_inum_out(&sb->sb_quota_di, (char *)&str->sb_quota_di); | |
912 | gfs_inum_out(&sb->sb_license_di, (char *)&str->sb_license_di); | |
913 | ||
914 | CPOUT_08(sb, str, sb_reserved, 96); | |
915 | } | |
916 | ||
917 | /** | |
918 | * gfs_sb_print - Print out a superblock | |
919 | * @sb: the cpu-order buffer | |
920 | * | |
921 | */ | |
922 | ||
923 | void | |
924 | gfs_sb_print(struct gfs_sb *sb) | |
925 | { | |
926 | gfs_meta_header_print(&sb->sb_header); | |
927 | ||
928 | pv(sb, sb_fs_format, "%u"); | |
929 | pv(sb, sb_multihost_format, "%u"); | |
930 | pv(sb, sb_flags, "%u"); | |
931 | ||
932 | pv(sb, sb_bsize, "%u"); | |
933 | pv(sb, sb_bsize_shift, "%u"); | |
934 | pv(sb, sb_seg_size, "%u"); | |
935 | ||
936 | gfs_inum_print(&sb->sb_jindex_di); | |
937 | gfs_inum_print(&sb->sb_rindex_di); | |
938 | gfs_inum_print(&sb->sb_root_di); | |
939 | ||
940 | pv(sb, sb_lockproto, "%s"); | |
941 | pv(sb, sb_locktable, "%s"); | |
942 | ||
943 | gfs_inum_print(&sb->sb_quota_di); | |
944 | gfs_inum_print(&sb->sb_license_di); | |
945 | ||
946 | pa(sb, sb_reserved, 96); | |
947 | } | |
948 | ||
949 | /** | |
950 | * gfs_jindex_in - Read in a journal index structure | |
951 | * @jindex: the cpu-order structure | |
952 | * @buf: the disk-order buffer | |
953 | * | |
954 | */ | |
955 | ||
956 | void | |
957 | gfs_jindex_in(struct gfs_jindex *jindex, char *buf) | |
958 | { | |
959 | struct gfs_jindex *str = (struct gfs_jindex *)buf; | |
960 | ||
961 | CPIN_64(jindex, str, ji_addr); | |
962 | CPIN_32(jindex, str, ji_nsegment); | |
963 | CPIN_32(jindex, str, ji_pad); | |
964 | ||
965 | CPIN_08(jindex, str, ji_reserved, 64); | |
966 | } | |
967 | ||
968 | /** | |
969 | * gfs_jindex_out - Write out a journal index structure | |
970 | * @jindex: the cpu-order structure | |
971 | * @buf: the disk-order buffer | |
972 | * | |
973 | */ | |
974 | ||
975 | void | |
976 | gfs_jindex_out(struct gfs_jindex *jindex, char *buf) | |
977 | { | |
978 | struct gfs_jindex *str = (struct gfs_jindex *)buf; | |
979 | ||
980 | CPOUT_64(jindex, str, ji_addr); | |
981 | CPOUT_32(jindex, str, ji_nsegment); | |
982 | CPOUT_32(jindex, str, ji_pad); | |
983 | ||
984 | CPOUT_08(jindex, str, ji_reserved, 64); | |
985 | } | |
986 | ||
987 | /** | |
988 | * gfs_jindex_print - Print out a journal index structure | |
989 | * @ji: the cpu-order buffer | |
990 | * | |
991 | */ | |
992 | ||
993 | void | |
994 | gfs_jindex_print(struct gfs_jindex *ji) | |
995 | { | |
996 | pv(ji, ji_addr, "%"PRIu64); | |
997 | pv(ji, ji_nsegment, "%u"); | |
998 | pv(ji, ji_pad, "%u"); | |
999 | ||
1000 | pa(ji, ji_reserved, 64); | |
1001 | } | |
1002 | ||
1003 | /** | |
1004 | * gfs_rindex_in - Read in a resource index structure | |
1005 | * @rindex: the cpu-order structure | |
1006 | * @buf: the disk-order buffer | |
1007 | * | |
1008 | */ | |
1009 | ||
1010 | void | |
1011 | gfs_rindex_in(struct gfs_rindex *rindex, char *buf) | |
1012 | { | |
1013 | struct gfs_rindex *str = (struct gfs_rindex *)buf; | |
1014 | ||
1015 | CPIN_64(rindex, str, ri_addr); | |
1016 | CPIN_32(rindex, str, ri_length); | |
1017 | CPIN_32(rindex, str, ri_pad); | |
1018 | ||
1019 | CPIN_64(rindex, str, ri_data1); | |
1020 | CPIN_32(rindex, str, ri_data); | |
1021 | ||
1022 | CPIN_32(rindex, str, ri_bitbytes); | |
1023 | ||
1024 | CPIN_08(rindex, str, ri_reserved, 64); | |
1025 | } | |
1026 | ||
1027 | /** | |
1028 | * gfs_rindex_out - Write out a resource index structure | |
1029 | * @rindex: the cpu-order structure | |
1030 | * @buf: the disk-order buffer | |
1031 | * | |
1032 | */ | |
1033 | ||
1034 | void | |
1035 | gfs_rindex_out(struct gfs_rindex *rindex, char *buf) | |
1036 | { | |
1037 | struct gfs_rindex *str = (struct gfs_rindex *)buf; | |
1038 | ||
1039 | CPOUT_64(rindex, str, ri_addr); | |
1040 | CPOUT_32(rindex, str, ri_length); | |
1041 | CPOUT_32(rindex, str, ri_pad); | |
1042 | ||
1043 | CPOUT_64(rindex, str, ri_data1); | |
1044 | CPOUT_32(rindex, str, ri_data); | |
1045 | ||
1046 | CPOUT_32(rindex, str, ri_bitbytes); | |
1047 | ||
1048 | CPOUT_08(rindex, str, ri_reserved, 64); | |
1049 | } | |
1050 | ||
1051 | /** | |
1052 | * gfs_rindex_print - Print out a resource index structure | |
1053 | * @ri: the cpu-order buffer | |
1054 | * | |
1055 | */ | |
1056 | ||
1057 | void | |
1058 | gfs_rindex_print(struct gfs_rindex *ri) | |
1059 | { | |
1060 | pv(ri, ri_addr, "%"PRIu64); | |
1061 | pv(ri, ri_length, "%u"); | |
1062 | pv(ri, ri_pad, "%u"); | |
1063 | ||
1064 | pv(ri, ri_data1, "%"PRIu64); | |
1065 | pv(ri, ri_data, "%u"); | |
1066 | ||
1067 | pv(ri, ri_bitbytes, "%u"); | |
1068 | ||
1069 | pa(ri, ri_reserved, 64); | |
1070 | } | |
1071 | ||
1072 | /** | |
1073 | * gfs_rgrp_in - Read in a resource group header | |
1074 | * @rgrp: the cpu-order structure | |
1075 | * @buf: the disk-order buffer | |
1076 | * | |
1077 | */ | |
1078 | ||
1079 | void | |
1080 | gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf) | |
1081 | { | |
1082 | struct gfs_rgrp *str = (struct gfs_rgrp *)buf; | |
1083 | ||
1084 | gfs_meta_header_in(&rgrp->rg_header, buf); | |
1085 | ||
1086 | CPIN_32(rgrp, str, rg_flags); | |
1087 | ||
1088 | CPIN_32(rgrp, str, rg_free); | |
1089 | ||
1090 | CPIN_32(rgrp, str, rg_useddi); | |
1091 | CPIN_32(rgrp, str, rg_freedi); | |
1092 | gfs_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); | |
1093 | ||
1094 | CPIN_32(rgrp, str, rg_usedmeta); | |
1095 | CPIN_32(rgrp, str, rg_freemeta); | |
1096 | ||
1097 | CPIN_08(rgrp, str, rg_reserved, 64); | |
1098 | } | |
1099 | ||
1100 | /** | |
1101 | * gfs_rgrp_out - Write out a resource group header | |
1102 | * @rgrp: the cpu-order structure | |
1103 | * @buf: the disk-order buffer | |
1104 | * | |
1105 | */ | |
1106 | ||
1107 | void | |
1108 | gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf) | |
1109 | { | |
1110 | struct gfs_rgrp *str = (struct gfs_rgrp *)buf; | |
1111 | ||
1112 | gfs_meta_header_out(&rgrp->rg_header, buf); | |
1113 | ||
1114 | CPOUT_32(rgrp, str, rg_flags); | |
1115 | ||
1116 | CPOUT_32(rgrp, str, rg_free); | |
1117 | ||
1118 | CPOUT_32(rgrp, str, rg_useddi); | |
1119 | CPOUT_32(rgrp, str, rg_freedi); | |
1120 | gfs_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); | |
1121 | ||
1122 | CPOUT_32(rgrp, str, rg_usedmeta); | |
1123 | CPOUT_32(rgrp, str, rg_freemeta); | |
1124 | ||
1125 | CPOUT_08(rgrp, str, rg_reserved, 64); | |
1126 | } | |
1127 | ||
1128 | /** | |
1129 | * gfs_rgrp_print - Print out a resource group header | |
1130 | * @rg: the cpu-order buffer | |
1131 | * | |
1132 | */ | |
1133 | ||
1134 | void | |
1135 | gfs_rgrp_print(struct gfs_rgrp *rg) | |
1136 | { | |
1137 | gfs_meta_header_print(&rg->rg_header); | |
1138 | ||
1139 | pv(rg, rg_flags, "%u"); | |
1140 | ||
1141 | pv(rg, rg_free, "%u"); | |
1142 | ||
1143 | pv(rg, rg_useddi, "%u"); | |
1144 | pv(rg, rg_freedi, "%u"); | |
1145 | gfs_inum_print(&rg->rg_freedi_list); | |
1146 | ||
1147 | pv(rg, rg_usedmeta, "%u"); | |
1148 | pv(rg, rg_freemeta, "%u"); | |
1149 | ||
1150 | pa(rg, rg_reserved, 64); | |
1151 | } | |
1152 | ||
1153 | /** | |
1154 | * gfs_quota_in - Read in a quota structures | |
1155 | * @quota: the cpu-order structure | |
1156 | * @buf: the disk-order buffer | |
1157 | * | |
1158 | */ | |
1159 | ||
1160 | void | |
1161 | gfs_quota_in(struct gfs_quota *quota, char *buf) | |
1162 | { | |
1163 | struct gfs_quota *str = (struct gfs_quota *)buf; | |
1164 | ||
1165 | CPIN_64(quota, str, qu_limit); | |
1166 | CPIN_64(quota, str, qu_warn); | |
1167 | CPIN_64(quota, str, qu_value); | |
1168 | ||
1169 | CPIN_08(quota, str, qu_reserved, 64); | |
1170 | } | |
1171 | ||
1172 | /** | |
1173 | * gfs_quota_out - Write out a quota structure | |
1174 | * @quota: the cpu-order structure | |
1175 | * @buf: the disk-order buffer | |
1176 | * | |
1177 | */ | |
1178 | ||
1179 | void | |
1180 | gfs_quota_out(struct gfs_quota *quota, char *buf) | |
1181 | { | |
1182 | struct gfs_quota *str = (struct gfs_quota *)buf; | |
1183 | ||
1184 | CPOUT_64(quota, str, qu_limit); | |
1185 | CPOUT_64(quota, str, qu_warn); | |
1186 | CPOUT_64(quota, str, qu_value); | |
1187 | ||
1188 | CPOUT_08(quota, str, qu_reserved, 64); | |
1189 | } | |
1190 | ||
1191 | /** | |
1192 | * gfs_quota_print - Print out a quota structure | |
1193 | * @quota: the cpu-order buffer | |
1194 | * | |
1195 | */ | |
1196 | ||
1197 | void | |
1198 | gfs_quota_print(struct gfs_quota *quota) | |
1199 | { | |
1200 | pv(quota, qu_limit, "%"PRIu64); | |
1201 | pv(quota, qu_warn, "%"PRIu64); | |
1202 | pv(quota, qu_value, "%"PRId64); | |
1203 | ||
1204 | pa(quota, qu_reserved, 64); | |
1205 | } | |
1206 | ||
1207 | /** | |
1208 | * gfs_dinode_in - Read in a dinode | |
1209 | * @dinode: the cpu-order structure | |
1210 | * @buf: the disk-order buffer | |
1211 | * | |
1212 | */ | |
1213 | ||
1214 | void | |
1215 | gfs_dinode_in(struct gfs_dinode *dinode, char *buf) | |
1216 | { | |
1217 | struct gfs_dinode *str = (struct gfs_dinode *)buf; | |
1218 | ||
1219 | gfs_meta_header_in(&dinode->di_header, buf); | |
1220 | ||
1221 | gfs_inum_in(&dinode->di_num, (char *)&str->di_num); | |
1222 | ||
1223 | CPIN_32(dinode, str, di_mode); | |
1224 | CPIN_32(dinode, str, di_uid); | |
1225 | CPIN_32(dinode, str, di_gid); | |
1226 | CPIN_32(dinode, str, di_nlink); | |
1227 | CPIN_64(dinode, str, di_size); | |
1228 | CPIN_64(dinode, str, di_blocks); | |
1229 | CPIN_64(dinode, str, di_atime); | |
1230 | CPIN_64(dinode, str, di_mtime); | |
1231 | CPIN_64(dinode, str, di_ctime); | |
1232 | CPIN_32(dinode, str, di_major); | |
1233 | CPIN_32(dinode, str, di_minor); | |
1234 | ||
1235 | CPIN_64(dinode, str, di_rgrp); | |
1236 | CPIN_64(dinode, str, di_goal_rgrp); | |
1237 | CPIN_32(dinode, str, di_goal_dblk); | |
1238 | CPIN_32(dinode, str, di_goal_mblk); | |
1239 | CPIN_32(dinode, str, di_flags); | |
1240 | CPIN_32(dinode, str, di_payload_format); | |
1241 | CPIN_16(dinode, str, di_type); | |
1242 | CPIN_16(dinode, str, di_height); | |
1243 | CPIN_32(dinode, str, di_incarn); | |
1244 | CPIN_16(dinode, str, di_pad); | |
1245 | ||
1246 | CPIN_16(dinode, str, di_depth); | |
1247 | CPIN_32(dinode, str, di_entries); | |
1248 | ||
1249 | gfs_inum_in(&dinode->di_next_unused, (char *)&str->di_next_unused); | |
1250 | ||
1251 | CPIN_64(dinode, str, di_eattr); | |
1252 | ||
1253 | CPIN_08(dinode, str, di_reserved, 56); | |
1254 | } | |
1255 | ||
1256 | /** | |
1257 | * gfs_dinode_out - Write out a dinode | |
1258 | * @dinode: the cpu-order structure | |
1259 | * @buf: the disk-order buffer | |
1260 | * | |
1261 | */ | |
1262 | ||
1263 | void | |
1264 | gfs_dinode_out(struct gfs_dinode *dinode, char *buf) | |
1265 | { | |
1266 | struct gfs_dinode *str = (struct gfs_dinode *)buf; | |
1267 | ||
1268 | gfs_meta_header_out(&dinode->di_header, buf); | |
1269 | ||
1270 | gfs_inum_out(&dinode->di_num, (char *)&str->di_num); | |
1271 | ||
1272 | CPOUT_32(dinode, str, di_mode); | |
1273 | CPOUT_32(dinode, str, di_uid); | |
1274 | CPOUT_32(dinode, str, di_gid); | |
1275 | CPOUT_32(dinode, str, di_nlink); | |
1276 | CPOUT_64(dinode, str, di_size); | |
1277 | CPOUT_64(dinode, str, di_blocks); | |
1278 | CPOUT_64(dinode, str, di_atime); | |
1279 | CPOUT_64(dinode, str, di_mtime); | |
1280 | CPOUT_64(dinode, str, di_ctime); | |
1281 | CPOUT_32(dinode, str, di_major); | |
1282 | CPOUT_32(dinode, str, di_minor); | |
1283 | ||
1284 | CPOUT_64(dinode, str, di_rgrp); | |
1285 | CPOUT_64(dinode, str, di_goal_rgrp); | |
1286 | CPOUT_32(dinode, str, di_goal_dblk); | |
1287 | CPOUT_32(dinode, str, di_goal_mblk); | |
1288 | CPOUT_32(dinode, str, di_flags); | |
1289 | CPOUT_32(dinode, str, di_payload_format); | |
1290 | CPOUT_16(dinode, str, di_type); | |
1291 | CPOUT_16(dinode, str, di_height); | |
1292 | CPOUT_32(dinode, str, di_incarn); | |
1293 | CPOUT_16(dinode, str, di_pad); | |
1294 | ||
1295 | CPOUT_16(dinode, str, di_depth); | |
1296 | CPOUT_32(dinode, str, di_entries); | |
1297 | ||
1298 | gfs_inum_out(&dinode->di_next_unused, (char *)&str->di_next_unused); | |
1299 | ||
1300 | CPOUT_64(dinode, str, di_eattr); | |
1301 | ||
1302 | CPOUT_08(dinode, str, di_reserved, 56); | |
1303 | } | |
1304 | ||
1305 | /** | |
1306 | * gfs_dinode_print - Print out a dinode | |
1307 | * @di: the cpu-order buffer | |
1308 | * | |
1309 | */ | |
1310 | ||
1311 | void | |
1312 | gfs_dinode_print(struct gfs_dinode *di) | |
1313 | { | |
1314 | gfs_meta_header_print(&di->di_header); | |
1315 | ||
1316 | gfs_inum_print(&di->di_num); | |
1317 | ||
1318 | pv(di, di_mode, "0%o"); | |
1319 | pv(di, di_uid, "%u"); | |
1320 | pv(di, di_gid, "%u"); | |
1321 | pv(di, di_nlink, "%u"); | |
1322 | pv(di, di_size, "%"PRIu64); | |
1323 | pv(di, di_blocks, "%"PRIu64); | |
1324 | pv(di, di_atime, "%"PRId64); | |
1325 | pv(di, di_mtime, "%"PRId64); | |
1326 | pv(di, di_ctime, "%"PRId64); | |
1327 | pv(di, di_major, "%u"); | |
1328 | pv(di, di_minor, "%u"); | |
1329 | ||
1330 | pv(di, di_rgrp, "%"PRIu64); | |
1331 | pv(di, di_goal_rgrp, "%"PRIu64); | |
1332 | pv(di, di_goal_dblk, "%u"); | |
1333 | pv(di, di_goal_mblk, "%u"); | |
1334 | pv(di, di_flags, "0x%.8X"); | |
1335 | pv(di, di_payload_format, "%u"); | |
1336 | pv(di, di_type, "%u"); | |
1337 | pv(di, di_height, "%u"); | |
1338 | pv(di, di_incarn, "%u"); | |
1339 | pv(di, di_pad, "%u"); | |
1340 | ||
1341 | pv(di, di_depth, "%u"); | |
1342 | pv(di, di_entries, "%u"); | |
1343 | ||
1344 | gfs_inum_print(&di->di_next_unused); | |
1345 | ||
1346 | pv(di, di_eattr, "%"PRIu64); | |
1347 | ||
1348 | pa(di, di_reserved, 56); | |
1349 | } | |
1350 | ||
1351 | /** | |
1352 | * gfs_indirect_in - copy in the header of an indirect block | |
1353 | * @indirect: the in memory copy | |
1354 | * @buf: the buffer copy | |
1355 | * | |
1356 | */ | |
1357 | ||
1358 | void | |
1359 | gfs_indirect_in(struct gfs_indirect *indirect, char *buf) | |
1360 | { | |
1361 | struct gfs_indirect *str = (struct gfs_indirect *)buf; | |
1362 | ||
1363 | gfs_meta_header_in(&indirect->in_header, buf); | |
1364 | ||
1365 | CPIN_08(indirect, str, in_reserved, 64); | |
1366 | } | |
1367 | ||
1368 | /** | |
1369 | * gfs_indirect_out - copy out the header of an indirect block | |
1370 | * @indirect: the in memory copy | |
1371 | * @buf: the buffer copy | |
1372 | * | |
1373 | */ | |
1374 | ||
1375 | void | |
1376 | gfs_indirect_out(struct gfs_indirect *indirect, char *buf) | |
1377 | { | |
1378 | struct gfs_indirect *str = (struct gfs_indirect *)buf; | |
1379 | ||
1380 | gfs_meta_header_out(&indirect->in_header, buf); | |
1381 | ||
1382 | CPOUT_08(indirect, str, in_reserved, 64); | |
1383 | } | |
1384 | ||
1385 | /** | |
1386 | * gfs_indirect_print - Print out a indirect block header | |
1387 | * @indirect: the cpu-order buffer | |
1388 | * | |
1389 | */ | |
1390 | ||
1391 | void | |
1392 | gfs_indirect_print(struct gfs_indirect *indirect) | |
1393 | { | |
1394 | gfs_meta_header_print(&indirect->in_header); | |
1395 | ||
1396 | pa(indirect, in_reserved, 64); | |
1397 | } | |
1398 | ||
1399 | /** | |
1400 | * gfs_dirent_in - Read in a directory entry | |
1401 | * @dirent: the cpu-order structure | |
1402 | * @buf: the disk-order buffer | |
1403 | * | |
1404 | */ | |
1405 | ||
1406 | void | |
1407 | gfs_dirent_in(struct gfs_dirent *dirent, char *buf) | |
1408 | { | |
1409 | struct gfs_dirent *str = (struct gfs_dirent *)buf; | |
1410 | ||
1411 | gfs_inum_in(&dirent->de_inum, (char *)&str->de_inum); | |
1412 | CPIN_32(dirent, str, de_hash); | |
1413 | CPIN_16(dirent, str, de_rec_len); | |
1414 | CPIN_16(dirent, str, de_name_len); | |
1415 | CPIN_16(dirent, str, de_type); | |
1416 | ||
1417 | CPIN_08(dirent, str, de_reserved, 14); | |
1418 | } | |
1419 | ||
1420 | /** | |
1421 | * gfs_dirent_out - Write out a directory entry | |
1422 | * @dirent: the cpu-order structure | |
1423 | * @buf: the disk-order buffer | |
1424 | * | |
1425 | */ | |
1426 | ||
1427 | void | |
1428 | gfs_dirent_out(struct gfs_dirent *dirent, char *buf) | |
1429 | { | |
1430 | struct gfs_dirent *str = (struct gfs_dirent *)buf; | |
1431 | ||
1432 | gfs_inum_out(&dirent->de_inum, (char *)&str->de_inum); | |
1433 | CPOUT_32(dirent, str, de_hash); | |
1434 | CPOUT_16(dirent, str, de_rec_len); | |
1435 | CPOUT_16(dirent, str, de_name_len); | |
1436 | CPOUT_16(dirent, str, de_type); | |
1437 | ||
1438 | CPOUT_08(dirent, str, de_reserved, 14); | |
1439 | } | |
1440 | ||
1441 | /** | |
1442 | * gfs_dirent_print - Print out a directory entry | |
1443 | * @de: the cpu-order buffer | |
1444 | * @name: the filename | |
1445 | * | |
1446 | */ | |
1447 | ||
1448 | void | |
1449 | gfs_dirent_print(struct gfs_dirent *de, char *name) | |
1450 | { | |
1451 | char buf[GFS_FNAMESIZE + 1]; | |
1452 | ||
1453 | gfs_inum_print(&de->de_inum); | |
1454 | pv(de, de_hash, "0x%.8X"); | |
1455 | pv(de, de_rec_len, "%u"); | |
1456 | pv(de, de_name_len, "%u"); | |
1457 | pv(de, de_type, "%u"); | |
1458 | ||
1459 | pa(de, de_reserved, 14); | |
1460 | ||
1461 | memset(buf, 0, GFS_FNAMESIZE + 1); | |
1462 | memcpy(buf, name, de->de_name_len); | |
1463 | printk(" name = %s\n", buf); | |
1464 | } | |
1465 | ||
1466 | /** | |
1467 | * gfs_leaf_in - Read in a directory leaf header | |
1468 | * @leaf: the cpu-order structure | |
1469 | * @buf: the disk-order buffer | |
1470 | * | |
1471 | */ | |
1472 | ||
1473 | void | |
1474 | gfs_leaf_in(struct gfs_leaf *leaf, char *buf) | |
1475 | { | |
1476 | struct gfs_leaf *str = (struct gfs_leaf *)buf; | |
1477 | ||
1478 | gfs_meta_header_in(&leaf->lf_header, buf); | |
1479 | ||
1480 | CPIN_16(leaf, str, lf_depth); | |
1481 | CPIN_16(leaf, str, lf_entries); | |
1482 | CPIN_32(leaf, str, lf_dirent_format); | |
1483 | CPIN_64(leaf, str, lf_next); | |
1484 | ||
1485 | CPIN_08(leaf, str, lf_reserved, 64); | |
1486 | } | |
1487 | ||
1488 | /** | |
1489 | * gfs_leaf_out - Write out a directory leaf header | |
1490 | * @leaf: the cpu-order structure | |
1491 | * @buf: the disk-order buffer | |
1492 | * | |
1493 | */ | |
1494 | ||
1495 | void | |
1496 | gfs_leaf_out(struct gfs_leaf *leaf, char *buf) | |
1497 | { | |
1498 | struct gfs_leaf *str = (struct gfs_leaf *)buf; | |
1499 | ||
1500 | gfs_meta_header_out(&leaf->lf_header, buf); | |
1501 | ||
1502 | CPOUT_16(leaf, str, lf_depth); | |
1503 | CPOUT_16(leaf, str, lf_entries); | |
1504 | CPOUT_32(leaf, str, lf_dirent_format); | |
1505 | CPOUT_64(leaf, str, lf_next); | |
1506 | ||
1507 | CPOUT_08(leaf, str, lf_reserved, 64); | |
1508 | } | |
1509 | ||
1510 | /** | |
1511 | * gfs_leaf_print - Print out a directory leaf header | |
1512 | * @lf: the cpu-order buffer | |
1513 | * | |
1514 | */ | |
1515 | ||
1516 | void | |
1517 | gfs_leaf_print(struct gfs_leaf *lf) | |
1518 | { | |
1519 | gfs_meta_header_print(&lf->lf_header); | |
1520 | ||
1521 | pv(lf, lf_depth, "%u"); | |
1522 | pv(lf, lf_entries, "%u"); | |
1523 | pv(lf, lf_dirent_format, "%u"); | |
1524 | pv(lf, lf_next, "%"PRIu64); | |
1525 | ||
1526 | pa(lf, lf_reserved, 64); | |
1527 | } | |
1528 | ||
1529 | /** | |
1530 | * gfs_log_header_in - Read in a log header | |
1531 | * @head: the cpu-order structure | |
1532 | * @buf: the disk-order buffer | |
1533 | * | |
1534 | */ | |
1535 | ||
1536 | void | |
1537 | gfs_log_header_in(struct gfs_log_header *head, char *buf) | |
1538 | { | |
1539 | struct gfs_log_header *str = (struct gfs_log_header *)buf; | |
1540 | ||
1541 | gfs_meta_header_in(&head->lh_header, buf); | |
1542 | ||
1543 | CPIN_32(head, str, lh_flags); | |
1544 | CPIN_32(head, str, lh_pad); | |
1545 | ||
1546 | CPIN_64(head, str, lh_first); | |
1547 | CPIN_64(head, str, lh_sequence); | |
1548 | ||
1549 | CPIN_64(head, str, lh_tail); | |
1550 | CPIN_64(head, str, lh_last_dump); | |
1551 | ||
1552 | CPIN_08(head, str, lh_reserved, 64); | |
1553 | } | |
1554 | ||
1555 | /** | |
1556 | * gfs_log_header_out - Write out a log header | |
1557 | * @head: the cpu-order structure | |
1558 | * @buf: the disk-order buffer | |
1559 | * | |
1560 | */ | |
1561 | ||
1562 | void | |
1563 | gfs_log_header_out(struct gfs_log_header *head, char *buf) | |
1564 | { | |
1565 | struct gfs_log_header *str = (struct gfs_log_header *)buf; | |
1566 | ||
1567 | gfs_meta_header_out(&head->lh_header, buf); | |
1568 | ||
1569 | CPOUT_32(head, str, lh_flags); | |
1570 | CPOUT_32(head, str, lh_pad); | |
1571 | ||
1572 | CPOUT_64(head, str, lh_first); | |
1573 | CPOUT_64(head, str, lh_sequence); | |
1574 | ||
1575 | CPOUT_64(head, str, lh_tail); | |
1576 | CPOUT_64(head, str, lh_last_dump); | |
1577 | ||
1578 | CPOUT_08(head, str, lh_reserved, 64); | |
1579 | } | |
1580 | ||
1581 | /** | |
1582 | * gfs_log_header_print - Print out a log header | |
1583 | * @head: the cpu-order buffer | |
1584 | * | |
1585 | */ | |
1586 | ||
1587 | void | |
1588 | gfs_log_header_print(struct gfs_log_header *lh) | |
1589 | { | |
1590 | gfs_meta_header_print(&lh->lh_header); | |
1591 | ||
1592 | pv(lh, lh_flags, "0x%.8X"); | |
1593 | pv(lh, lh_pad, "%u"); | |
1594 | ||
1595 | pv(lh, lh_first, "%"PRIu64); | |
1596 | pv(lh, lh_sequence, "%"PRIu64); | |
1597 | ||
1598 | pv(lh, lh_tail, "%"PRIu64); | |
1599 | pv(lh, lh_last_dump, "%"PRIu64); | |
1600 | ||
1601 | pa(lh, lh_reserved, 64); | |
1602 | } | |
1603 | ||
1604 | /** | |
1605 | * gfs_desc_in - Read in a log descriptor | |
1606 | * @desc: the cpu-order structure | |
1607 | * @buf: the disk-order buffer | |
1608 | * | |
1609 | */ | |
1610 | ||
1611 | void | |
1612 | gfs_desc_in(struct gfs_log_descriptor *desc, char *buf) | |
1613 | { | |
1614 | struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; | |
1615 | ||
1616 | gfs_meta_header_in(&desc->ld_header, buf); | |
1617 | ||
1618 | CPIN_32(desc, str, ld_type); | |
1619 | CPIN_32(desc, str, ld_length); | |
1620 | CPIN_32(desc, str, ld_data1); | |
1621 | CPIN_32(desc, str, ld_data2); | |
1622 | ||
1623 | CPIN_08(desc, str, ld_reserved, 64); | |
1624 | } | |
1625 | ||
1626 | /** | |
1627 | * gfs_desc_out - Write out a log descriptor | |
1628 | * @desc: the cpu-order structure | |
1629 | * @buf: the disk-order buffer | |
1630 | * | |
1631 | */ | |
1632 | ||
1633 | void | |
1634 | gfs_desc_out(struct gfs_log_descriptor *desc, char *buf) | |
1635 | { | |
1636 | struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; | |
1637 | ||
1638 | gfs_meta_header_out(&desc->ld_header, buf); | |
1639 | ||
1640 | CPOUT_32(desc, str, ld_type); | |
1641 | CPOUT_32(desc, str, ld_length); | |
1642 | CPOUT_32(desc, str, ld_data1); | |
1643 | CPOUT_32(desc, str, ld_data2); | |
1644 | ||
1645 | CPOUT_08(desc, str, ld_reserved, 64); | |
1646 | } | |
1647 | ||
1648 | /** | |
1649 | * gfs_desc_print - Print out a log descriptor | |
1650 | * @ld: the cpu-order buffer | |
1651 | * | |
1652 | */ | |
1653 | ||
1654 | void | |
1655 | gfs_desc_print(struct gfs_log_descriptor *ld) | |
1656 | { | |
1657 | gfs_meta_header_print(&ld->ld_header); | |
1658 | ||
1659 | pv(ld, ld_type, "%u"); | |
1660 | pv(ld, ld_length, "%u"); | |
1661 | pv(ld, ld_data1, "%u"); | |
1662 | pv(ld, ld_data2, "%u"); | |
1663 | ||
1664 | pa(ld, ld_reserved, 64); | |
1665 | } | |
1666 | ||
1667 | /** | |
1668 | * gfs_block_tag_in - Read in a block tag | |
1669 | * @tag: the cpu-order structure | |
1670 | * @buf: the disk-order buffer | |
1671 | * | |
1672 | */ | |
1673 | ||
1674 | void | |
1675 | gfs_block_tag_in(struct gfs_block_tag *tag, char *buf) | |
1676 | { | |
1677 | struct gfs_block_tag *str = (struct gfs_block_tag *)buf; | |
1678 | ||
1679 | CPIN_64(tag, str, bt_blkno); | |
1680 | CPIN_32(tag, str, bt_flags); | |
1681 | CPIN_32(tag, str, bt_pad); | |
1682 | } | |
1683 | ||
1684 | /** | |
1685 | * gfs_block_tag_out - Write out a block tag | |
1686 | * @tag: the cpu-order structure | |
1687 | * @buf: the disk-order buffer | |
1688 | * | |
1689 | */ | |
1690 | ||
1691 | void | |
1692 | gfs_block_tag_out(struct gfs_block_tag *tag, char *buf) | |
1693 | { | |
1694 | struct gfs_block_tag *str = (struct gfs_block_tag *)buf; | |
1695 | ||
1696 | CPOUT_64(tag, str, bt_blkno); | |
1697 | CPOUT_32(tag, str, bt_flags); | |
1698 | CPOUT_32(tag, str, bt_pad); | |
1699 | } | |
1700 | ||
1701 | /** | |
1702 | * gfs_block_tag_print - Print out a block tag | |
1703 | * @tag: the cpu-order buffer | |
1704 | * | |
1705 | */ | |
1706 | ||
1707 | void | |
1708 | gfs_block_tag_print(struct gfs_block_tag *tag) | |
1709 | { | |
1710 | pv(tag, bt_blkno, "%"PRIu64); | |
1711 | pv(tag, bt_flags, "%u"); | |
1712 | pv(tag, bt_pad, "%u"); | |
1713 | } | |
1714 | ||
1715 | /** | |
1716 | * gfs_quota_tag_in - Read in a quota tag | |
1717 | * @tag: the cpu-order structure | |
1718 | * @buf: the disk-order buffer | |
1719 | * | |
1720 | */ | |
1721 | ||
1722 | void | |
1723 | gfs_quota_tag_in(struct gfs_quota_tag *tag, char *buf) | |
1724 | { | |
1725 | struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; | |
1726 | ||
1727 | CPIN_64(tag, str, qt_change); | |
1728 | CPIN_32(tag, str, qt_flags); | |
1729 | CPIN_32(tag, str, qt_id); | |
1730 | } | |
1731 | ||
1732 | /** | |
1733 | * gfs_quota_tag_out - Write out a quota tag | |
1734 | * @tag: the cpu-order structure | |
1735 | * @buf: the disk-order buffer | |
1736 | * | |
1737 | */ | |
1738 | ||
1739 | void | |
1740 | gfs_quota_tag_out(struct gfs_quota_tag *tag, char *buf) | |
1741 | { | |
1742 | struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; | |
1743 | ||
1744 | CPOUT_64(tag, str, qt_change); | |
1745 | CPOUT_32(tag, str, qt_flags); | |
1746 | CPOUT_32(tag, str, qt_id); | |
1747 | } | |
1748 | ||
1749 | /** | |
1750 | * gfs_quota_tag_print - Print out a quota tag | |
1751 | * @tag: the cpu-order buffer | |
1752 | * | |
1753 | */ | |
1754 | ||
1755 | void | |
1756 | gfs_quota_tag_print(struct gfs_quota_tag *tag) | |
1757 | { | |
1758 | pv(tag, qt_change, "%"PRId64); | |
1759 | pv(tag, qt_flags, "0x%.8X"); | |
1760 | pv(tag, qt_id, "%u"); | |
1761 | } | |
1762 | ||
1763 | /** | |
1764 | * gfs_ea_header_in - Read in a Extended Attribute header | |
1765 | * @tag: the cpu-order structure | |
1766 | * @buf: the disk-order buffer | |
1767 | * | |
1768 | */ | |
1769 | ||
1770 | void | |
1771 | gfs_ea_header_in(struct gfs_ea_header *ea, char *buf) | |
1772 | { | |
1773 | struct gfs_ea_header *str = (struct gfs_ea_header *)buf; | |
1774 | ||
1775 | CPIN_32(ea, str, ea_rec_len); | |
1776 | CPIN_32(ea, str, ea_data_len); | |
1777 | ea->ea_name_len = str->ea_name_len; | |
1778 | ea->ea_type = str->ea_type; | |
1779 | ea->ea_flags = str->ea_flags; | |
1780 | ea->ea_num_ptrs = str->ea_num_ptrs; | |
1781 | CPIN_32(ea, str, ea_pad); | |
1782 | } | |
1783 | ||
1784 | /** | |
1785 | * gfs_ea_header_out - Write out a Extended Attribute header | |
1786 | * @ea: the cpu-order structure | |
1787 | * @buf: the disk-order buffer | |
1788 | * | |
1789 | */ | |
1790 | ||
1791 | void | |
1792 | gfs_ea_header_out(struct gfs_ea_header *ea, char *buf) | |
1793 | { | |
1794 | struct gfs_ea_header *str = (struct gfs_ea_header *)buf; | |
1795 | ||
1796 | CPOUT_32(ea, str, ea_rec_len); | |
1797 | CPOUT_32(ea, str, ea_data_len); | |
1798 | str->ea_name_len = ea->ea_name_len; | |
1799 | str->ea_type = ea->ea_type; | |
1800 | str->ea_flags = ea->ea_flags; | |
1801 | str->ea_num_ptrs = ea->ea_num_ptrs; | |
1802 | CPOUT_32(ea, str, ea_pad); | |
1803 | } | |
1804 | ||
1805 | /** | |
1806 | * gfs_ea_header_printt - Print out a Extended Attribute header | |
1807 | * @ea: the cpu-order buffer | |
1808 | * | |
1809 | */ | |
1810 | ||
1811 | void | |
1812 | gfs_ea_header_print(struct gfs_ea_header *ea, char *name) | |
1813 | { | |
1814 | char buf[GFS_EA_MAX_NAME_LEN + 1]; | |
1815 | ||
1816 | pv(ea, ea_rec_len, "%u"); | |
1817 | pv(ea, ea_data_len, "%u"); | |
1818 | pv(ea, ea_name_len, "%u"); | |
1819 | pv(ea, ea_type, "%u"); | |
1820 | pv(ea, ea_flags, "%u"); | |
1821 | pv(ea, ea_num_ptrs, "%u"); | |
1822 | pv(ea, ea_pad, "%u"); | |
1823 | ||
1824 | memset(buf, 0, GFS_EA_MAX_NAME_LEN + 1); | |
1825 | memcpy(buf, name, ea->ea_name_len); | |
1826 | printk(" name = %s\n", buf); | |
1827 | } | |
1828 | ||
1829 | static const uint32_t crc_32_tab[] = | |
1830 | { | |
1831 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, | |
1832 | 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, | |
1833 | 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | |
1834 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, | |
1835 | 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, | |
1836 | 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | |
1837 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, | |
1838 | 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, | |
1839 | 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | |
1840 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, | |
1841 | 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, | |
1842 | 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | |
1843 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, | |
1844 | 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, | |
1845 | 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | |
1846 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, | |
1847 | 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, | |
1848 | 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | |
1849 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, | |
1850 | 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, | |
1851 | 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | |
1852 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, | |
1853 | 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, | |
1854 | 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | |
1855 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, | |
1856 | 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, | |
1857 | 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | |
1858 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, | |
1859 | 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, | |
1860 | 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | |
1861 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, | |
1862 | 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d | |
1863 | }; | |
1864 | ||
1865 | /** | |
1866 | * gfs_dir_hash - hash an array of data | |
1867 | * @data: the data to be hashed | |
1868 | * @len: the length of data to be hashed | |
1869 | * | |
1870 | * Take some data and convert it to a 32-bit hash. | |
1871 | * | |
1872 | * The hash function is a 32-bit CRC of the data. The algorithm uses | |
1873 | * the crc_32_tab table above. | |
1874 | * | |
1875 | * This may not be the fastest hash function, but it does a fair bit better | |
1876 | * at providing uniform results than the others I've looked at. That's | |
1877 | * really important for efficient directories. | |
1878 | * | |
1879 | * Returns: the hash | |
1880 | */ | |
1881 | ||
1882 | uint32_t | |
1883 | gfs_dir_hash(const char *data, int len) | |
1884 | { | |
1885 | uint32_t hash = 0xFFFFFFFF; | |
1886 | ||
1887 | for (; len--; data++) | |
1888 | hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); | |
1889 | ||
1890 | hash = ~hash; | |
1891 | ||
1892 | return hash; | |
1893 | } | |
1894 | ||
1895 | #endif /* WANT_GFS_CONVERSION_FUNCTIONS */ | |
1896 |