xref: /netbsd/sys/fs/nilfs/nilfs_fs.h (revision 3ac92065)
1 /* $NetBSD: nilfs_fs.h,v 1.4 2022/02/16 22:00:56 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 constrains */
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
560 
561