| 1 | /* $NetBSD: nilfs_fs.h,v 1.5 2024/12/26 21:16:26 andvar Exp $ */ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 2008, 2009 Reinoud Zandijk |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | * |
| 27 | * NilFS on disc structures |
| 28 | * |
| 29 | * Original definitions written by Koji Sato <koji@osrg.net> |
| 30 | * and Ryusuke Konishi <ryusuke@osrg.net> |
| 31 | */ |
| 32 | |
| 33 | #ifndef _NILFS_FS_H |
| 34 | #define _NILFS_FS_H |
| 35 | |
| 36 | /* |
| 37 | * NiLFS stores ext2fs compatible flags in its Inode. NetBSD uses a comparable |
| 38 | * mechanism with file flags to be mutated with chflags(2). |
| 39 | * |
| 40 | * For completion, i mention all ext2-fs flags currently stored in NiLFS |
| 41 | * inodes. |
| 42 | */ |
| 43 | #define NILFS_SECRM_FL 0x00000001 /* no mapping; delete securely */ |
| 44 | #define NILFS_UNRM_FL 0x00000002 /* no mapping; allow undelete */ |
| 45 | #define NILFS_SYNC_FL 0x00000008 /* no mapping; sychrone update */ |
| 46 | #define NILFS_IMMUTABLE_FL 0x00000010 /* SF_IMMUTABLE | UF_IMMUTABLE */ |
| 47 | #define NILFS_APPEND_FL 0x00000020 /* SF_APPEND | UF_APPEND */ |
| 48 | #define NILFS_NODUMP_FL 0x00000040 /* UF_NODUMP */ |
| 49 | #define NILFS_NOATIME_FL 0x00000080 /* no mapping; no atime update */ |
| 50 | /* intermediate bits are reserved for compression settings */ |
| 51 | #define NILFS_NOTAIL_FL 0x00008000 /* no mapping; dont merge tail */ |
| 52 | #define NILFS_DIRSYNC_FL 0x00010000 /* no mapping; dirsync */ |
| 53 | |
| 54 | #define NILFS_FL_USER_VISIBLE 0x0003DFFF /* flags visible to user */ |
| 55 | #define NILFS_FL_USER_MODIFIABLE 0x000380FF /* flags modifiable by user */ |
| 56 | |
| 57 | |
| 58 | |
| 59 | /* |
| 60 | * NiLFS stores files in hierarchical B-trees in tupels of (dkey, dptr). |
| 61 | * Entries in a level N btree point to a btree of level N-1. As dkey value the |
| 62 | * first block number to be found in the level N-1 btree is taken. |
| 63 | * |
| 64 | * To conserve disk space and to reduce an extra lookup, small B-tree's of |
| 65 | * level 0 consisting of only the first [0..NILFS_DIRECT_KEY_MAX> entries are |
| 66 | * stored directly into the inode without dkey. Otherwise the entries point to |
| 67 | * the B-tree's of level N-1. |
| 68 | * |
| 69 | * In all B-trees, but of the system DAT-file, the dptr values are virtual |
| 70 | * block numbers. The dptr values in the B-tree of the system DAT-file are |
| 71 | * physical block numbers since the DAT performs virtual to physical block |
| 72 | * mapping. |
| 73 | */ |
| 74 | |
| 75 | #define NILFS_INODE_BMAP_SIZE 7 |
| 76 | |
| 77 | #define NILFS_BMAP_SIZE		(NILFS_INODE_BMAP_SIZE * sizeof(uint64_t)) |
| 78 | #define NILFS_BMAP_INVALID_PTR	0 |
| 79 | |
| 80 | #define NILFS_DIRECT_NBLOCKS	(NILFS_BMAP_SIZE / sizeof(uint64_t) - 1) |
| 81 | #define NILFS_DIRECT_KEY_MIN	0 |
| 82 | #define NILFS_DIRECT_KEY_MAX	(NILFS_DIRECT_NBLOCKS - 1) |
| 83 | |
| 84 | #define NILFS_BMAP_SMALL_LOW	NILFS_DIRECT_KEY_MIN |
| 85 | #define NILFS_BMAP_SMALL_HIGH	NILFS_DIRECT_KEY_MAX |
| 86 | #define NILFS_BMAP_LARGE_LOW	NILFS_BTREE_ROOT_NCHILDREN_MAX |
| 87 | #define NILFS_BMAP_LARGE_HIGH	NILFS_BTREE_KEY_MAX |
| 88 | |
| 89 | |
| 90 | /* |
| 91 | * B-tree header found on all btree blocks and in the direct-entry. Its size |
| 92 | * should be 64 bits. In a direct entry, it is followed by 64 bits block |
| 93 | * numbers for the translation of block [0..NILFS_DIRECT_KEY_MAX>. In large |
| 94 | * bmaps its followed by pairs of 64 bit dkey and 64 bit dptr. |
| 95 | */ |
| 96 | |
| 97 | struct nilfs_btree_node { |
| 98 | 	uint8_t bn_flags;		/* btree flags */ |
| 99 | 	uint8_t bn_level;		/* level of btree */ |
| 100 | 	uint16_t bn_nchildren;		/* number of children in this record */ |
| 101 | 	uint32_t bn_pad;		/* pad to 64 bits */ |
| 102 | }; |
| 103 | |
| 104 | |
| 105 | /* btree flags stored in nilfs_btree_node->bn_flags */ |
| 106 | #define NILFS_BTREE_NODE_ROOT	0x01 |
| 107 | #define NILFS_BMAP_LARGE	0x01	/* equivalent to BTREE_NODE_ROOT */ |
| 108 | |
| 109 | /* btree levels stored in nilfs_btree_node->bn_level */ |
| 110 | #define NILFS_BTREE_LEVEL_DATA		0 |
| 111 | #define NILFS_BTREE_LEVEL_NODE_MIN	(NILFS_BTREE_LEVEL_DATA + 1) |
| 112 | #define NILFS_BTREE_LEVEL_MAX		14 |
| 113 | |
| 114 | /* |
| 115 | * Calculate number of entries that fit into the `direct' space |
| 116 | */ |
| 117 | #define NILFS_BTREE_ROOT_SIZE		NILFS_BMAP_SIZE |
| 118 | #define NILFS_BTREE_ROOT_NCHILDREN_MAX					\ |
| 119 | 	((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) /	\ |
| 120 | 	 (sizeof(uint64_t /* dkey */) + sizeof(uint64_t /* dptr */))) |
| 121 | #define NILFS_BTREE_ROOT_NCHILDREN_MIN	0 |
| 122 | |
| 123 | /* |
| 124 | * Calculate number of entries that fit into a non LEVEL_DATA nodes. Each of |
| 125 | * those nodes are padded with one extra 64 bit (extension?) |
| 126 | */ |
| 127 | #define NILFS_BTREE_NODE_EXTRA_PAD_SIZE	(sizeof(uint64_t)) |
| 128 | #define NILFS_BTREE_NODE_NCHILDREN_MAX(nodesize)			\ |
| 129 | 	(((nodesize) - sizeof(struct nilfs_btree_node) -		\ |
| 130 | 		NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /			\ |
| 131 | 	 (sizeof(uint64_t /* dkey */) + sizeof(uint64_t /* dptr */))) |
| 132 | #define NILFS_BTREE_NODE_NCHILDREN_MIN(nodesize)			\ |
| 133 | 	((NILFS_BTREE_NODE_NCHILDREN_MAX(nodesize) - 1) / 2 + 1) |
| 134 | #define NILFS_BTREE_KEY_MIN	( (uint64_t) 0) |
| 135 | #define NILFS_BTREE_KEY_MAX	(~(uint64_t) 0) |
| 136 | |
| 137 | |
| 138 | /* |
| 139 | * NiLFS inode structure. There are a few dedicated inode numbers that are |
| 140 | * defined here first. |
| 141 | */ |
| 142 | |
| 143 | #define NILFS_ROOT_INO 2 /* Root file inode */ |
| 144 | #define NILFS_DAT_INO 3 /* DAT file */ |
| 145 | #define NILFS_CPFILE_INO 4 /* checkpoint file */ |
| 146 | #define NILFS_SUFILE_INO 5 /* segment usage file */ |
| 147 | #define NILFS_IFILE_INO 6 /* ifile */ |
| 148 | #define NILFS_ATIME_INO 7 /* Atime file (reserved) */ |
| 149 | #define NILFS_XATTR_INO 8 /* Xattribute file (reserved) */ |
| 150 | #define NILFS_SKETCH_INO 10 /* Sketch file (obsolete) */ |
| 151 | #define NILFS_USER_INO 11 /* First user's file inode number */ |
| 152 | |
| 153 | struct nilfs_inode { |
| 154 | uint64_t i_blocks;		/* size in device blocks */ |
| 155 | uint64_t i_size;		/* size in bytes */ |
| 156 | uint64_t i_ctime;		/* creation time in seconds part */ |
| 157 | uint64_t i_mtime;		/* modification time in seconds part */ |
| 158 | uint32_t i_ctime_nsec;		/* creation time nanoseconds part */ |
| 159 | 	 uint32_t i_mtime_nsec;		/* modification time in nanoseconds */ |
| 160 | uint32_t i_uid;		/* user id */ |
| 161 | uint32_t i_gid;		/* group id */ |
| 162 | uint16_t i_mode;		/* file mode */ |
| 163 | uint16_t i_links_count;	/* number of references to the inode */ |
| 164 | uint32_t i_flags;		/* NILFS_*_FL flags */ |
| 165 | uint64_t i_bmap[NILFS_INODE_BMAP_SIZE]; /* btree direct/large */ |
| 166 | #define i_device_code i_bmap[0]	/* 64 bits composed of major+minor */ |
| 167 | uint64_t i_xattr;		/* reserved for extended attributes */ |
| 168 | uint32_t i_generation;		/* file generation for NFS */ |
| 169 | uint32_t i_pad;		/* make it 64 bits aligned */ |
| 170 | }; |
| 171 | |
| 172 | |
| 173 | /* |
| 174 | * In NiLFS each checkpoint/snapshot has a super root. |
| 175 | * |
| 176 | * The super root holds the inodes of the three system files: `dat', `cp' and |
| 177 | * 'su' files. All other FS state is defined by those. |
| 178 | * |
| 179 | * It is crc checksum'ed and time stamped. |
| 180 | */ |
| 181 | |
| 182 | struct nilfs_super_root { |
| 183 | uint32_t sr_sum;		/* check-sum */ |
| 184 | uint16_t sr_bytes;		/* byte count of this structure */ |
| 185 | uint16_t sr_flags;		/* reserved for flags */ |
| 186 | uint64_t sr_nongc_ctime;	/* timestamp, not for cleaner(?) */ |
| 187 | struct nilfs_inode sr_dat;	/* DAT, virt->phys translation inode */ |
| 188 | struct nilfs_inode sr_cpfile;	/* CP, checkpoints inode */ |
| 189 | struct nilfs_inode sr_sufile; /* SU, segment usage inode */ |
| 190 | }; |
| 191 | |
| 192 | #define NILFS_SR_MDT_OFFSET(inode_size, i) \ |
| 193 | ((uint32_t)&((struct nilfs_super_root *)0)->sr_dat + \ |
| 194 | (inode_size) * (i)) |
| 195 | #define NILFS_SR_DAT_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 0) |
| 196 | #define NILFS_SR_CPFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 1) |
| 197 | #define NILFS_SR_SUFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 2) |
| 198 | #define NILFS_SR_BYTES (sizeof(struct nilfs_super_root)) |
| 199 | |
| 200 | |
| 201 | |
| 202 | /* |
| 203 | * NiLFS has a superblock that describes the basic structure and mount |
| 204 | * history. It also records some sizes of structures found on the disc for |
| 205 | * sanity checks. |
| 206 | * |
| 207 | * The superblock is stored at two places: NILFS_SB_OFFSET_BYTES and |
| 208 | * NILFS_SB2_OFFSET_BYTES. |
| 209 | */ |
| 210 | |
| 211 | #define NILFS_DFL_MAX_MNT_COUNT 50 /* default 50 mounts before fsck */ |
| 212 | #define NILFS_EIO_RETRY_COUNT 4	/* then give up, not used yet */ |
| 213 | |
| 214 | /* File system states stored on disc in superblock's sbp->s_state */ |
| 215 | #define NILFS_VALID_FS 0x0001 /* cleanly unmounted and all is ok */ |
| 216 | #define NILFS_ERROR_FS 0x0002 /* there were errors detected, fsck */ |
| 217 | #define NILFS_RESIZE_FS 0x0004 /* resize required, XXX unknown flag*/ |
| 218 | #define NILFS_MOUNT_STATE_BITS	"\20\1VALID_FS\2ERROR_FS\3RESIZE_FS" |
| 219 | |
| 220 | /* Mount option flags passed in Linux; Not used but here for reference */ |
| 221 | #define NILFS_MOUNT_ERROR_MODE 0x0070 /* error mode mask */ |
| 222 | #define NILFS_MOUNT_ERRORS_CONT 0x0010 /* continue on errors */ |
| 223 | #define NILFS_MOUNT_ERRORS_RO 0x0020 /* remount fs ro on errors */ |
| 224 | #define NILFS_MOUNT_ERRORS_PANIC 0x0040 /* panic on errors */ |
| 225 | #define NILFS_MOUNT_SNAPSHOT 0x0080 /* snapshot flag */ |
| 226 | #define NILFS_MOUNT_BARRIER 0x1000 /* use block barriers XXX what is this? */ |
| 227 | #define NILFS_MOUNT_STRICT_ORDER 0x2000 /* apply strict in-order; */ |
| 228 | /* semantics also for data */ |
| 229 | |
| 230 | struct nilfs_super_block { |
| 231 | uint32_t s_rev_level; /* major disk format revision */ |
| 232 | uint16_t s_minor_rev_level; /* minor disc format revision */ |
| 233 | uint16_t s_magic; /* magic value for identification */ |
| 234 | |
| 235 | uint16_t s_bytes; /* byte count of CRC calculation |
| 236 | for this structure. s_reserved |
| 237 | is excluded! */ |
| 238 | uint16_t s_flags; /* linux mount flags, XXX can they |
| 239 | 					 be ignored? */ |
| 240 | uint32_t s_crc_seed; /* seed value of CRC calculation */ |
| 241 | uint32_t s_sum; /* check sum of super block */ |
| 242 | |
| 243 | 	 /* Block size represented as follows |
| 244 | blocksize = 1 << (s_log_block_size + 10) */ |
| 245 | uint32_t s_log_block_size; |
| 246 | uint64_t s_nsegments; /* number of segm. in filesystem */ |
| 247 | uint64_t s_dev_size; /* block device size in bytes */ |
| 248 | uint64_t s_first_data_block; /* 1st seg disk block number */ |
| 249 | uint32_t s_blocks_per_segment; /* number of blocks per segment */ |
| 250 | uint32_t s_r_segments_percentage; /* reserved segments percentage */ |
| 251 | |
| 252 | uint64_t s_last_cno; /* last checkpoint number */ |
| 253 | uint64_t s_last_pseg; /* addr part. segm. written last */ |
| 254 | uint64_t s_last_seq; /* seq.number of seg written last */ |
| 255 | uint64_t s_free_blocks_count; /* free blocks count */ |
| 256 | |
| 257 | uint64_t s_ctime; /* creation time (execution time |
| 258 | 					 of newfs) */ |
| 259 | uint64_t s_mtime; /* mount time */ |
| 260 | uint64_t s_wtime; /* write time */ |
| 261 | uint16_t s_mnt_count; /* mount count */ |
| 262 | uint16_t s_max_mnt_count; /* maximal mount count */ |
| 263 | uint16_t s_state; /* file system state */ |
| 264 | uint16_t s_errors; /* behaviour on detecting errors */ |
| 265 | uint64_t s_lastcheck; /* time of last checked */ |
| 266 | |
| 267 | uint32_t s_checkinterval; /* max. time between checks */ |
| 268 | uint32_t s_creator_os; /* OS that created it */ |
| 269 | uint16_t s_def_resuid; /* default uid for reserv. blocks */ |
| 270 | uint16_t s_def_resgid; /* default gid for reserv. blocks */ |
| 271 | uint32_t s_first_ino; /* first non-reserved inode */ |
| 272 | |
| 273 | uint16_t s_inode_size; /* size of an inode */ |
| 274 | uint16_t s_dat_entry_size; /* size of a dat entry */ |
| 275 | uint16_t s_checkpoint_size; /* size of a checkpoint */ |
| 276 | uint16_t s_segment_usage_size; /* size of a segment usage */ |
| 277 | |
| 278 | uint8_t s_uuid[16]; /* 128-bit uuid for volume */ |
| 279 | char s_volume_name[80]; /* volume name */ |
| 280 | |
| 281 | uint32_t s_c_interval; /* commit interval of segment */ |
| 282 | uint32_t s_c_block_max; /* threshold of data amount for |
| 283 | the segment construction */ |
| 284 | uint32_t s_reserved[192]; /* padding to end of the block */ |
| 285 | }; |
| 286 | |
| 287 | #define NILFS_SUPER_MAGIC 0x3434 /* NILFS filesystem magic number */ |
| 288 | #define NILFS_SB_OFFSET_BYTES 1024 /* byte offset of nilfs superblock */ |
| 289 | #define NILFS_SB2_OFFSET_BYTES(devsize)	((((devsize) >> 12) - 1) << 12) |
| 290 | |
| 291 | |
| 292 | /* codes for operating systems in superblock */ |
| 293 | #define NILFS_OS_LINUX 0 |
| 294 | #define NILFS_OS_UNK1		 1	/* ext2 */ |
| 295 | #define NILFS_OS_UNK2		 2	/* ext2 */ |
| 296 | #define NILFS_OS_UNK3		 3	/* ext2 */ |
| 297 | #define NILFS_OS_NETBSD		10	/* temp */ |
| 298 | |
| 299 | /* NiLFS revision levels */ |
| 300 | #define NILFS_CURRENT_REV 2 /* current major revision */ |
| 301 | #define NILFS_MINOR_REV 0 /* minor revision */ |
| 302 | |
| 303 | /* Bytes count of super_block for CRC-calculation */ |
| 304 | #define NILFS_SB_BYTES \ |
| 305 | ((uint32_t)&((struct nilfs_super_block *)0)->s_reserved) |
| 306 | |
| 307 | /* Maximal count of links to a file */ |
| 308 | #define NILFS_LINK_MAX 32000 |
| 309 | |
| 310 | |
| 311 | /* |
| 312 | * Structure of a directory entry, same as ext2. |
| 313 | * |
| 314 | * The `file_type' is chosen there since filenames are limited to 256 bytes |
| 315 | * and the name_len in ext2 is a two byter. |
| 316 | * |
| 317 | * Note that they can't span blocks; the rec_len fills out. |
| 318 | */ |
| 319 | |
| 320 | #define NILFS_NAME_LEN 255 |
| 321 | struct nilfs_dir_entry { |
| 322 | uint64_t inode; /* inode number */ |
| 323 | uint16_t rec_len; /* directory entry length */ |
| 324 | uint8_t name_len; /* name length */ |
| 325 | uint8_t file_type; |
| 326 | char name[NILFS_NAME_LEN]; /* file name */ |
| 327 | char pad; |
| 328 | }; |
| 329 | |
| 330 | /* |
| 331 | * NILFS directory file types. Only the low 3 bits are used. The |
| 332 | * other bits are reserved for now. |
| 333 | */ |
| 334 | enum { |
| 335 | NILFS_FT_UNKNOWN, |
| 336 | NILFS_FT_REG_FILE, |
| 337 | NILFS_FT_DIR, |
| 338 | NILFS_FT_CHRDEV, |
| 339 | NILFS_FT_BLKDEV, |
| 340 | NILFS_FT_FIFO, |
| 341 | NILFS_FT_SOCK, |
| 342 | NILFS_FT_SYMLINK, |
| 343 | NILFS_FT_MAX |
| 344 | }; |
| 345 | |
| 346 | /* |
| 347 | * NILFS_DIR_PAD defines the directory entries boundaries |
| 348 | * |
| 349 | * NOTE: It must be a multiple of 8 |
| 350 | */ |
| 351 | #define NILFS_DIR_PAD 8 |
| 352 | #define NILFS_DIR_ROUND (NILFS_DIR_PAD - 1) |
| 353 | #define NILFS_DIR_REC_LEN(name_len) (((name_len) + 12 + NILFS_DIR_ROUND) & \ |
| 354 | ~NILFS_DIR_ROUND) |
| 355 | |
| 356 | /* |
| 357 | * NiLFS devides the disc into fixed length segments. Each segment is filled |
| 358 | * with one or more partial segments of variable lengths. |
| 359 | * |
| 360 | * Each partial segment has a segment summary header followed by updates of |
| 361 | * files and optionally a super root. |
| 362 | */ |
| 363 | |
| 364 | struct nilfs_finfo { |
| 365 | uint64_t fi_ino;		/* inode number */ |
| 366 | uint64_t fi_cno;		/* checkpoint associated with this */ |
| 367 | uint32_t fi_nblocks;		/* size in blocks of this finfo */ |
| 368 | uint32_t fi_ndatablk;		/* number of data blocks */ |
| 369 | 	 /* For the DAT file */ |
| 370 | 	 /* 	fi_ndatablk * nilfs_binfo.bi_dat.bi_blkoff */ |
| 371 | 	 /*	fi_nblocks - fi_ndatablks * nilfs_binfo.bi_dat */ |
| 372 | 	 /* Other files */ |
| 373 | 	 /* fi_ndatablk * nilfs_binfo.bi_v */ |
| 374 | 	 /* fi_nblocks - fi_ndatablks * nilfs_binfo.bi_v.bi_vblocknr */ |
| 375 | }; |
| 376 | |
| 377 | |
| 378 | /* |
| 379 | * Virtual to physical block translation information. For data blocks it maps |
| 380 | * logical block number bi_blkoff to virtual block nr bi_vblocknr. For non |
| 381 | * datablocks it is the virtual block number assigned to an inserted btree |
| 382 | * level and thus has no bi_blkoff. The physical block number is the next |
| 383 | * available data block in the partial segment after all the finfo's. |
| 384 | */ |
| 385 | struct nilfs_binfo_v { |
| 386 | uint64_t bi_vblocknr;		/* assigned virtual block number */ |
| 387 | uint64_t bi_blkoff;		/* for file's logical block number */ |
| 388 | }; |
| 389 | |
| 390 | |
| 391 | /* |
| 392 | * DAT allocation. For data blocks just the logical block number that maps on |
| 393 | * the next available data block in the partial segment after the finfo's. |
| 394 | * Intermediate btree blocks are looked up by their blkoffset dkey and their |
| 395 | * level and given the next available data block. |
| 396 | */ |
| 397 | struct nilfs_binfo_dat { |
| 398 | uint64_t bi_blkoff;		/* DAT file's logical block number */ |
| 399 | uint8_t bi_level;		/* btree level */ |
| 400 | uint8_t bi_pad[7]; |
| 401 | }; |
| 402 | |
| 403 | |
| 404 | /* Convenience union for both types of binfo's */ |
| 405 | union nilfs_binfo { |
| 406 | struct nilfs_binfo_v bi_v; |
| 407 | struct nilfs_binfo_dat bi_dat; |
| 408 | }; |
| 409 | |
| 410 | |
| 411 | /* The (partial) segment summary itself */ |
| 412 | struct nilfs_segment_summary { |
| 413 | uint32_t ss_datasum;		/* CRC of complete data block */ |
| 414 | uint32_t ss_sumsum;		/* CRC of segment summary only */ |
| 415 | uint32_t ss_magic;		/* magic to identify segment summary */ |
| 416 | uint16_t ss_bytes;		/* size of segment summary structure */ |
| 417 | uint16_t ss_flags;		/* NILFS_SS_* flags */ |
| 418 | uint64_t ss_seq;		/* sequence number of this segm. sum */ |
| 419 | uint64_t ss_create;		/* creation timestamp in seconds */ |
| 420 | uint64_t ss_next;		/* blocknumber of next segment */ |
| 421 | uint32_t ss_nblocks;		/* number of blocks follow */ |
| 422 | uint32_t ss_nfinfo;		/* number of finfo structures follow */ |
| 423 | uint32_t ss_sumbytes;		/* total size of segment summary */ |
| 424 | uint32_t ss_pad; |
| 425 | 	 uint64_t ss_cno;		/* latest checkpoint number known */ |
| 426 | /* stream of finfo structures */ |
| 427 | }; |
| 428 | |
| 429 | #define NILFS_SEGSUM_MAGIC 0x1eaffa11 /* segment summary magic number */ |
| 430 | |
| 431 | /* Segment summary flags */ |
| 432 | #define NILFS_SS_LOGBGN 0x0001 /* begins a logical segment */ |
| 433 | #define NILFS_SS_LOGEND 0x0002 /* ends a logical segment */ |
| 434 | #define NILFS_SS_SR 0x0004 /* has super root */ |
| 435 | #define NILFS_SS_SYNDT 0x0008 /* includes data only updates */ |
| 436 | #define NILFS_SS_GC 0x0010 /* segment written for cleaner operation */ |
| 437 | #define NILFS_SS_FLAG_BITS "\20\1LOGBGN\2LOGEND\3SR\4SYNDT\5GC" |
| 438 | |
| 439 | /* Segment summary constraints */ |
| 440 | #define NILFS_SEG_MIN_BLOCKS 16 /* minimum number of blocks in a |
| 441 | 					 full segment */ |
| 442 | #define NILFS_PSEG_MIN_BLOCKS 2 /* minimum number of blocks in a |
| 443 | 					 partial segment */ |
| 444 | #define NILFS_MIN_NRSVSEGS 8 /* minimum number of reserved |
| 445 | 					 segments */ |
| 446 | |
| 447 | /* |
| 448 | * Structure of DAT/inode file. |
| 449 | * |
| 450 | * A DAT file is divided into groups. The maximum number of groups is the |
| 451 | * number of block group descriptors that fit into one block; this descriptor |
| 452 | * only gives the number of free entries in the associated group. |
| 453 | * |
| 454 | * Each group has a block sized bitmap indicating if an entry is taken or |
| 455 | * empty. Each bit stands for a DAT entry. |
| 456 | * |
| 457 | * The inode file has exactly the same format only the entries are inode |
| 458 | * entries. |
| 459 | */ |
| 460 | |
| 461 | struct nilfs_block_group_desc { |
| 462 | uint32_t bg_nfrees;		/* num. free entries in block group */ |
| 463 | }; |
| 464 | |
| 465 | |
| 466 | /* DAT entry in a super root's DAT file */ |
| 467 | struct nilfs_dat_entry { |
| 468 | uint64_t de_blocknr;		/* block number */ |
| 469 | uint64_t de_start;		/* valid from checkpoint */ |
| 470 | uint64_t de_end;		/* valid till checkpoint */ |
| 471 | uint64_t de_rsv;		/* reserved for future use */ |
| 472 | }; |
| 473 | |
| 474 | |
| 475 | /* |
| 476 | * Structure of CP file. |
| 477 | * |
| 478 | * A snapshot is just a checkpoint only its protected against removal by the |
| 479 | * cleaner. The snapshots are kept on a double linked list of checkpoints. |
| 480 | */ |
| 481 | |
| 482 | struct nilfs_snapshot_list { |
| 483 | uint64_t ssl_next;		/* checkpoint nr. forward */ |
| 484 | uint64_t ssl_prev;		/* checkpoint nr. back */ |
| 485 | }; |
| 486 | |
| 487 | |
| 488 | /* checkpoint entry structure */ |
| 489 | struct nilfs_checkpoint { |
| 490 | uint32_t cp_flags;		/* NILFS_CHECKPOINT_* flags */ |
| 491 | uint32_t cp_checkpoints_count;	/* ZERO, not used anymore? */ |
| 492 | struct nilfs_snapshot_list cp_snapshot_list; /* list of snapshots */ |
| 493 | uint64_t cp_cno;		/* checkpoint number */ |
| 494 | uint64_t cp_create;		/* creation timestamp */ |
| 495 | uint64_t cp_nblk_inc;		/* number of blocks incremented */ |
| 496 | uint64_t cp_inodes_count;	/* number of inodes in this cp. */ |
| 497 | uint64_t cp_blocks_count; /* reserved (might be deleted) */ |
| 498 | struct nilfs_inode cp_ifile_inode;	/* inode file inode */ |
| 499 | }; |
| 500 | |
| 501 | /* checkpoint flags */ |
| 502 | #define NILFS_CHECKPOINT_SNAPSHOT 1 |
| 503 | #define NILFS_CHECKPOINT_INVALID 2 |
| 504 | #define NILFS_CHECKPOINT_SKETCH 4 |
| 505 | #define NILFS_CHECKPOINT_MINOR	 8 |
| 506 | #define NILFS_CHECKPOINT_BITS "\20\1SNAPSHOT\2INVALID\3SKETCH\4MINOR" |
| 507 | |
| 508 | |
| 509 | /* header of the checkpoint file */ |
| 510 | struct nilfs_cpfile_header { |
| 511 | uint64_t ch_ncheckpoints;	/* number of checkpoints */ |
| 512 | uint64_t ch_nsnapshots;	/* number of snapshots */ |
| 513 | struct nilfs_snapshot_list ch_snapshot_list;	/* snapshot list */ |
| 514 | }; |
| 515 | |
| 516 | /* to accommodate with the header */ |
| 517 | #define NILFS_CPFILE_FIRST_CHECKPOINT_OFFSET \ |
| 518 | ((sizeof(struct nilfs_cpfile_header) + \ |
| 519 | sizeof(struct nilfs_checkpoint) - 1) / \ |
| 520 | sizeof(struct nilfs_checkpoint)) |
| 521 | |
| 522 | |
| 523 | /* |
| 524 | * Structure of SU file. |
| 525 | * |
| 526 | * The segment usage file sums up how each of the segments are used. They are |
| 527 | * indexed by their segment number. |
| 528 | */ |
| 529 | |
| 530 | /* segment usage entry */ |
| 531 | struct nilfs_segment_usage { |
| 532 | uint64_t su_lastmod;		/* last modified timestamp */ |
| 533 | uint32_t su_nblocks;		/* number of blocks in segment */ |
| 534 | uint32_t su_flags;		/* NILFS_SEGMENT_USAGE_* flags */ |
| 535 | }; |
| 536 | |
| 537 | /* segment usage flag */ |
| 538 | #define NILFS_SEGMENT_USAGE_ACTIVE	 1 |
| 539 | #define NILFS_SEGMENT_USAGE_DIRTY	 2 |
| 540 | #define NILFS_SEGMENT_USAGE_ERROR	 4 |
| 541 | #define NILFS_SEGMENT_USAGE_BITS "\20\1ACTIVE\2DIRTY\3ERROR" |
| 542 | |
| 543 | |
| 544 | /* header of the segment usage file */ |
| 545 | struct nilfs_sufile_header { |
| 546 | uint64_t sh_ncleansegs;	/* number of segments marked clean */ |
| 547 | uint64_t sh_ndirtysegs;	/* number of segments marked dirty */ |
| 548 | uint64_t sh_last_alloc;	/* last allocated segment number */ |
| 549 | /* ... */ |
| 550 | }; |
| 551 | |
| 552 | /* to accommodate with the header */ |
| 553 | #define NILFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET \ |
| 554 | ((sizeof(struct nilfs_sufile_header) + \ |
| 555 | sizeof(struct nilfs_segment_usage) - 1) / \ |
| 556 | sizeof(struct nilfs_segment_usage)) |
| 557 | |
| 558 | |
| 559 | #endif |