Lines Matching +full:layer +full:- +full:buffer +full:- +full:offset
1 /*-
47 * The structures below represent the on-disk format for a HAMMER
48 * filesystem. Note that all fields for on-disk structures are naturally
49 * aligned. HAMMER uses little endian for fields in on-disk structures.
60 * A HAMMER filesystem uses a 16K filesystem buffer size. All filesystem
63 * 64K X-bufs are used for blocks >= a file's 1MB mark.
65 * Per-volume storage limit: 52 bits 4096 TB
66 * Per-Zone storage limit: 60 bits 1 MTB
67 * Per-filesystem storage limit: 60 bits 1 MTB
73 #define HAMMER_BUFMASK (HAMMER_BUFSIZE - 1)
74 #define HAMMER_XBUFMASK (HAMMER_XBUFSIZE - 1)
84 #define HAMMER_OFF_SHORT_MASK 0x000FFFFFFFFFFFFFULL /* offset portion */
85 #define HAMMER_OFF_LONG_MASK 0x0FFFFFFFFFFFFFFFULL /* offset portion */
87 #define HAMMER_OFF_BAD ((hammer_off_t)-1)
89 #define HAMMER_BUFSIZE_DOALIGN(offset) \ argument
90 (((offset) + HAMMER_BUFMASK) & ~HAMMER_BUFMASK)
91 #define HAMMER_BUFSIZE64_DOALIGN(offset) \ argument
92 (((offset) + HAMMER_BUFMASK64) & ~HAMMER_BUFMASK64)
94 #define HAMMER_XBUFSIZE_DOALIGN(offset) \ argument
95 (((offset) + HAMMER_XBUFMASK) & ~HAMMER_XBUFMASK)
96 #define HAMMER_XBUFSIZE64_DOALIGN(offset) \ argument
97 (((offset) + HAMMER_XBUFMASK64) & ~HAMMER_XBUFMASK64)
116 * and volume number in addition to the offset. Most offsets are required
126 #define HAMMER_MIN_KEY -0x8000000000000000LL /* signed */
140 * In other words, HAMMER's logical filesystem offset consists of 64 bits,
144 * zone 0: available, a big-block that contains the offset is unused
145 * zone 1 (z,v,o): raw volume relative (offset 0 is the volume header)
146 * zone 2 (z,v,o): raw buffer relative (offset 0 is the first buffer)
147 * zone 3 (z,o): undo/redo fifo - fixed zone-2 offset array in volume header
148 * zone 4 (z,v,o): freemap - only real blockmap
149 * zone 8 (z,v,o): B-Tree - actually zone-2 address
150 * zone 9 (z,v,o): meta - actually zone-2 address
151 * zone 10 (z,v,o): large-data - actually zone-2 address
152 * zone 11 (z,v,o): small-data - actually zone-2 address
153 * zone 15: unavailable, usually the offset is beyond volume size
157 * 2^8(max volumes) * 2^52(max volume size) = 2^60 = 1EB (long offset)
158 * <------------------------------------------------------------->
159 * 8bits 52bits (short offset)
160 * <------><----------------------------------------------------->
162 * ----111111111111 1111112222222222 222222222ooooooo oooooooooooooooo
163 * <-----------------><------------------><---------------------->
165 * <------------------------------------------------------------->
166 * 2^18(layer1) * 2^19(layer2) * 2^23(big-block) = 2^60 = 1EB
170 * +-------------------------> offset 0 of a device/partition
173 * +-------------------------> vol_bot_beg
175 * +-------------------------> vol_mem_beg
177 * +-------------------------> vol_buf_beg (physical offset of zone-2)
178 * | zone-4 big-block for layer1
179 * +-------------------------> vol_buf_beg + HAMMER_BIGBLOCK_SIZE
180 * | zone-4 big-blocks for layer2
181 * | ... (1 big-block per 4TB space)
182 * +-------------------------> vol_buf_beg + HAMMER_BIGBLOCK_SIZE * ...
183 * | zone-3 big-blocks for UNDO/REDO FIFO
184 * | ... (max 128 big-blocks)
185 * +-------------------------> vol_buf_beg + HAMMER_BIGBLOCK_SIZE * ...
186 * | zone-8 big-block for root B-Tree node/etc
187 * +-------------------------> vol_buf_beg + HAMMER_BIGBLOCK_SIZE * ...
188 * | zone-9 big-block for root inode/PFS/etc
189 * +-------------------------> vol_buf_beg + HAMMER_BIGBLOCK_SIZE * ...
190 * | zone-X big-blocks
191 * | ... (big-blocks for new zones after newfs_hammer)
196 * +-------------------------> vol_buf_end (HAMMER_BUFSIZE aligned)
197 * +-------------------------> end of a device/partition
200 * +-------------------------> offset 0 of a device/partition
203 * +-------------------------> vol_bot_beg
205 * +-------------------------> vol_mem_beg
207 * +-------------------------> vol_buf_beg (physical offset of zone-2)
208 * | zone-4 big-blocks for layer2
209 * | ... (1 big-block per 4TB space)
210 * +-------------------------> vol_buf_beg + HAMMER_BIGBLOCK_SIZE * ...
211 * | zone-X big-blocks
212 * | ... (unused until volume#(N-1) runs out of space)
217 * +-------------------------> vol_buf_end (HAMMER_BUFSIZE aligned)
218 * +-------------------------> end of a device/partition
249 #define HAMMER_ZONE(offset) ((offset) & HAMMER_OFF_ZONE_MASK) argument
251 #define hammer_is_zone_raw_volume(offset) \ argument
252 (HAMMER_ZONE(offset) == HAMMER_ZONE_RAW_VOLUME)
253 #define hammer_is_zone_raw_buffer(offset) \ argument
254 (HAMMER_ZONE(offset) == HAMMER_ZONE_RAW_BUFFER)
255 #define hammer_is_zone_undo(offset) \ argument
256 (HAMMER_ZONE(offset) == HAMMER_ZONE_UNDO)
257 #define hammer_is_zone_freemap(offset) \ argument
258 (HAMMER_ZONE(offset) == HAMMER_ZONE_FREEMAP)
259 #define hammer_is_zone_btree(offset) \ argument
260 (HAMMER_ZONE(offset) == HAMMER_ZONE_BTREE)
261 #define hammer_is_zone_meta(offset) \ argument
262 (HAMMER_ZONE(offset) == HAMMER_ZONE_META)
263 #define hammer_is_zone_large_data(offset) \ argument
264 (HAMMER_ZONE(offset) == HAMMER_ZONE_LARGE_DATA)
265 #define hammer_is_zone_small_data(offset) \ argument
266 (HAMMER_ZONE(offset) == HAMMER_ZONE_SMALL_DATA)
267 #define hammer_is_zone_unavail(offset) \ argument
268 (HAMMER_ZONE(offset) == HAMMER_ZONE_UNAVAIL)
269 #define hammer_is_zone_data(offset) \ argument
270 (hammer_is_zone_large_data(offset) || hammer_is_zone_small_data(offset))
276 #define hammer_is_zone_record(offset) \ argument
277 hammer_is_index_record(HAMMER_ZONE_DECODE(offset))
284 #define hammer_is_zone_direct_xlated(offset) \ argument
285 hammer_is_index_direct_xlated(HAMMER_ZONE_DECODE(offset))
297 #define HAMMER_OFF_SHORT_ENCODE(offset) \ argument
298 ((hammer_off_t)(offset) & HAMMER_OFF_SHORT_MASK)
299 #define HAMMER_OFF_LONG_ENCODE(offset) \ argument
300 ((hammer_off_t)(offset) & HAMMER_OFF_LONG_MASK)
302 #define HAMMER_ENCODE(zone, vol_no, offset) \ argument
305 HAMMER_OFF_SHORT_ENCODE(offset))
306 #define HAMMER_ENCODE_RAW_VOLUME(vol_no, offset) \ argument
307 HAMMER_ENCODE(HAMMER_ZONE_RAW_VOLUME_INDEX, vol_no, offset)
308 #define HAMMER_ENCODE_RAW_BUFFER(vol_no, offset) \ argument
309 HAMMER_ENCODE(HAMMER_ZONE_RAW_BUFFER_INDEX, vol_no, offset)
310 #define HAMMER_ENCODE_UNDO(offset) \ argument
311 HAMMER_ENCODE(HAMMER_ZONE_UNDO_INDEX, HAMMER_ROOT_VOLNO, offset)
312 #define HAMMER_ENCODE_FREEMAP(vol_no, offset) \ argument
313 HAMMER_ENCODE(HAMMER_ZONE_FREEMAP_INDEX, vol_no, offset)
316 * Translate a zone address to zone-X address.
318 #define hammer_xlate_to_zoneX(zone, offset) \ argument
319 HAMMER_ZONE_ENCODE((zone), (offset) & ~HAMMER_OFF_ZONE_MASK)
320 #define hammer_xlate_to_zone2(offset) \ argument
321 hammer_xlate_to_zoneX(HAMMER_ZONE_RAW_BUFFER_INDEX, (offset))
333 * Big-Block backing store
335 * A blockmap is a two-level map which translates a blockmap-backed zone
336 * offset into a raw zone 2 offset. The layer 1 handles 18 bits and the
337 * layer 2 handles 19 bits. The 8M big-block size is 23 bits so two
345 #define HAMMER_HINTBLOCK_MASK64 ((uint64_t)HAMMER_HINTBLOCK_SIZE - 1)
348 #define HAMMER_BIGBLOCK_MASK (HAMMER_BIGBLOCK_SIZE - 1)
349 #define HAMMER_BIGBLOCK_MASK64 ((uint64_t)HAMMER_BIGBLOCK_SIZE - 1)
361 (HAMMER_BUFFERS_PER_BIGBLOCK - 1)
365 #define HAMMER_BIGBLOCK_DOALIGN(offset) \ argument
366 (((offset) + HAMMER_BIGBLOCK_MASK64) & ~HAMMER_BIGBLOCK_MASK64)
369 * Maximum number of mirrors operating in master mode (multi-master
371 * multi-master clustering as of 2015.
380 * zone:2 raw buffer (no blockmap)
383 * zone:8-15 zone id used to classify big-block only, address is actually
384 * a zone-2 address.
387 hammer_off_t phys_offset; /* zone-2 offset only used by zone-4 */
388 hammer_off_t first_offset; /* zone-X offset only used by zone-3 */
389 hammer_off_t next_offset; /* zone-X offset for allocation */
390 hammer_off_t alloc_offset; /* zone-X offset only used by zone-3 */
399 * The blockmap is a 2-layer entity made up of big-blocks. The first layer
400 * contains 262144 32-byte entries (18 bits), the second layer contains
401 * 524288 16-byte entries (19 bits), representing 8MB (23 bit) blockmaps.
405 * All primary data/meta-data zones actually encode a zone-2 address
408 * The freemap uses the upper 8 bits of layer-1 to identify the volume,
410 * to a zone:2 (or zone:8-15) address.
412 * zone-X blockmap offset: [zone:4][layer1:18][layer2:19][big-block:23]
416 * 32 bytes layer1 entry for 8MB big-block.
417 * A big-block can hold 2^23 / 2^5 = 2^18 layer1 entries,
418 * which equals bits assigned for layer1 in zone-2 address.
421 hammer_off_t blocks_free; /* big-blocks free */
422 hammer_off_t phys_offset; /* UNAVAIL or zone-2 */
433 * 16 bytes layer2 entry for 8MB big-blocks.
434 * A big-block can hold 2^23 / 2^4 = 2^19 layer2 entries,
435 * which equals bits assigned for layer2 in zone-2 address.
438 * de-dup occurs. This field will never go higher than
440 * the big-block is completely free.
447 int32_t bytes_free; /* bytes free within this big-block */
454 #define HAMMER_BLOCKMAP_UNAVAIL ((hammer_off_t)-1LL)
466 #define HAMMER_BLOCKMAP_LAYER1_MASK (HAMMER_BLOCKMAP_LAYER1 - 1)
467 #define HAMMER_BLOCKMAP_LAYER2_MASK (HAMMER_BLOCKMAP_LAYER2 - 1)
469 #define HAMMER_BLOCKMAP_LAYER2_DOALIGN(offset) \ argument
470 (((offset) + HAMMER_BLOCKMAP_LAYER2_MASK) & \
474 * Index within layer1 or layer2 big-block for the entry representing
475 * a zone-2 physical offset.
486 * Byte offset within layer1 or layer2 big-block for the entry representing
487 * a zone-2 physical offset. Multiply the index by sizeof(blockmap_layer).
498 * Move on to offset 0 of the next layer1 or layer2.
500 #define HAMMER_ZONE_LAYER1_NEXT_OFFSET(offset) \ argument
501 (((offset) + HAMMER_BLOCKMAP_LAYER2) & ~HAMMER_BLOCKMAP_LAYER2_MASK)
503 #define HAMMER_ZONE_LAYER2_NEXT_OFFSET(offset) \ argument
504 (((offset) + HAMMER_BIGBLOCK_SIZE) & ~HAMMER_BIGBLOCK_MASK64)
508 * header with an array of zone-2 offsets. A maximum of (128x8MB) = 1GB,
516 * All on-disk HAMMER structures which make up elements of the UNDO FIFO
520 * in higher level hammer on-disk structures while the tail is typically
521 * out-of-band. hdr_size is the size of the whole mess, including the tail.
524 * buffer boundary. Most undo structures are fairly small. Data spaces
536 * representing raw meta-data operations.
544 * without relying on the 32-bit crc and to definitively identify the current
566 #define HAMMER_HEAD_ALIGN_MASK (HAMMER_HEAD_ALIGN - 1)
572 #define HAMMER_UNDO_MASK (HAMMER_UNDO_ALIGN - 1)
573 #define HAMMER_UNDO_MASK64 (HAMMER_UNDO_ALIGN64 - 1)
574 #define HAMMER_UNDO_DOALIGN(offset) \ argument
575 (((offset) + HAMMER_UNDO_MASK) & ~HAMMER_UNDO_MASK64)
611 * UNDO - Raw meta-data media updates.
615 hammer_off_t undo_offset; /* zone-1,2 offset */
622 * REDO (HAMMER version 4+) - Logical file writes/truncates.
624 * REDOs contain information which will be duplicated in a later meta-data
633 * WRITE - Write logical file (with payload). Executed both
634 * out-of-span and in-span. Out-of-span WRITEs may be
637 * TRUNC - Truncate logical file (no payload). Executed both
638 * out-of-span and in-span. Out-of-span WRITEs may be
641 * TERM_* - Indicates meta-data was committed (if out-of-span) or
642 * will be rolled-back (in-span). Any out-of-span TERMs
645 * commit (which is not being rolled-back).
647 * SYNC - The earliest in-span SYNC (the last one when scanning
648 * backwards) tells the recovery code how far out-of-span
662 hammer_off_t redo_offset; /* logical offset in file */
692 * A HAMMER filesystem can be built from 1-256 block devices, each block
704 * vol_bot_beg - offset of boot area (mem_beg - bot_beg bytes)
705 * vol_mem_beg - offset of memory log (buf_beg - mem_beg bytes)
706 * vol_buf_beg - offset of the first buffer in volume
707 * vol_buf_end - offset of volume EOF (on buffer boundary)
715 * The buffer offset is a physical offset of zone-2 offset. The lower
716 * 52 bits of the zone-2 offset is added to the buffer offset of each
717 * volume to generate an actual I/O offset within the block device.
743 * These are relative to block device offset, not zone offsets.
745 int64_t vol_bot_beg; /* offset of boot area */
746 int64_t vol_mem_beg; /* offset of memory log */
747 int64_t vol_buf_beg; /* offset of the first buffer in volume */
748 int64_t vol_buf_end; /* offset of volume EOF (on buffer boundary) */
769 * include big-blocks for freemap and undomap initially allocated
772 int64_t vol0_stat_bigblocks; /* total big-blocks when fs is empty */
773 int64_t vol0_stat_freebigblocks;/* number of free big-blocks */
777 hammer_off_t vol0_btree_root; /* B-Tree root offset in zone-8 */
788 * Array of zone-2 addresses for undo FIFO.
800 (sizeof(struct hammer_volume_ondisk) - HAMMER_VOL_CRCSIZE1 - \
817 * Translate a zone-2 address to physical address
820 ((volume)->vol_buf_beg + HAMMER_OFF_SHORT_ENCODE(zone2_offset))
823 * Translate a zone-3 address to zone-2 address
829 ((volume)->vol0_undo_array[HAMMER_UNDO_INDEX(zone3_offset)] + \
833 * Effective per-volume filesystem capacity including big-blocks for layer1/2
836 ((volume)->vol_buf_end - (volume)->vol_buf_beg)
839 * Record types are fairly straightforward. The B-Tree includes the record
859 #define HAMMER_OBJTYPE_UNKNOWN 0 /* never exists on-disk as unknown */
877 * parent_obj_id is only valid for directories (which cannot be hard-linked),
879 * for non-directory inodes as a recovery aid, but can wind up holding
882 * A parent_obj_id of 0 means it's a root inode of root or non-root PFS.
907 uint64_t mtime; /* mtime must be second-to-last */
912 * Neither mtime nor atime updates are CRCd by the B-Tree element.
925 * HAMMER_INODE_CAP_DIR_LOCAL_INO - Use inode B-Tree localization
935 #define HAMMER_DATA_DOALIGN(offset) \ argument
936 (((offset) + 15) & ~15)
937 #define HAMMER_DATA_DOALIGN_WITH(type, offset) \ argument
938 (((type)(offset) + 15) & (~(type)15))
942 * namespace. It is hooked into a pseudo-filesystem (with its own inode
948 * offset. A portion of the namekey is an iterator/randomizer to deal
951 * NOTE: leaf.base.obj_type from the related B-Tree leaf entry holds
959 uint32_t localization; /* identify pseudo-filesystem */
979 * pseudo-fs may be tagged with an optional data structure using
983 * When operating as a slave CD's into the node automatically become read-only
984 * and as-of sync_end_tid.
990 * end-point, after which full history is available.
992 * We need to pack this structure making it equally sized on both 32-bit and
993 * 64-bit machines as it is part of struct hammer_ioc_mrecord_pfs which is
994 * send over the wire in hammer mirror operations. Only on 64-bit machines
996 * situation where old 64-bit systems (using the non-packed structure),
997 * which were never able to mirror to/from 32-bit systems, are now no longer
998 * able to mirror to/from newer 64-bit systems (using the packed structure).
1004 uint64_t sync_beg_ts; /* real-time of last completed sync */
1026 (((pfsd)->mirror_flags & HAMMER_PFSD_SLAVE) != 0)
1030 (((pfsd)->mirror_flags & HAMMER_PFSD_DELETED) != 0)
1033 #define HAMMER_MAX_PFSID (HAMMER_MAX_PFS - 1)
1037 * Snapshot meta-data { Objid = HAMMER_OBJID_ROOT, Key = tid, rectype = SNAPSHOT }.
1043 * NOTE: The b-tree key is signed, the tid is not, so callers must still sort the
1050 uint64_t ts; /* real-time when snapshot was made */
1053 char label[64]; /* user-supplied description */
1058 * Config meta-data { ObjId = HAMMER_OBJID_ROOT, Key = 0, rectype = CONFIG }.
1079 * Ondisk layout of B-Tree related structures
1086 (((ino_data)->cap_flags & HAMMER_INODE_CAP_DIR_LOCAL_INO) ? \