xref: /freebsd-12.1/sys/fs/nandfs/nandfs_fs.h (revision d63027b6)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2010-2012 Semihalf
5  * Copyright (c) 2008, 2009 Reinoud Zandijk
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Original definitions written by Koji Sato <[email protected]>
29  *                    and Ryusuke Konishi <[email protected]>
30  * From: NetBSD: nandfs_fs.h,v 1.1 2009/07/18 16:31:42 reinoud
31  *
32  * $FreeBSD$
33  */
34 
35 #ifndef _NANDFS_FS_H
36 #define _NANDFS_FS_H
37 
38 #include <sys/uuid.h>
39 
40 #define	MNINDIR(fsdev)	((fsdev)->nd_blocksize / sizeof(nandfs_daddr_t))
41 
42 /*
43  * Inode structure. There are a few dedicated inode numbers that are
44  * defined here first.
45  */
46 #define	NANDFS_WHT_INO		1	/* Whiteout ino			*/
47 #define	NANDFS_ROOT_INO		2	/* Root file inode		*/
48 #define	NANDFS_DAT_INO		3	/* DAT file			*/
49 #define	NANDFS_CPFILE_INO	4	/* checkpoint file		*/
50 #define	NANDFS_SUFILE_INO	5	/* segment usage file		*/
51 #define	NANDFS_IFILE_INO	6	/* ifile			*/
52 #define	NANDFS_GC_INO		7	/* Cleanerd node		*/
53 #define	NANDFS_ATIME_INO	8	/* Atime file (reserved)	*/
54 #define	NANDFS_XATTR_INO	9	/* Xattribute file (reserved)	*/
55 #define	NANDFS_SKETCH_INO	10	/* Sketch file (obsolete)	*/
56 #define	NANDFS_USER_INO		11	/* First user's file inode number */
57 
58 #define	NANDFS_SYS_NODE(ino) \
59 	(((ino) >= NANDFS_DAT_INO) && ((ino) <= NANDFS_GC_INO))
60 
61 #define	NANDFS_NDADDR		12	/* Direct addresses in inode. */
62 #define	NANDFS_NIADDR		3	/* Indirect addresses in inode. */
63 
64 typedef	int64_t		nandfs_daddr_t;
65 typedef	int64_t		nandfs_lbn_t;
66 
67 struct nandfs_inode {
68 	uint64_t	i_blocks;	/* 0: size in device blocks		*/
69 	uint64_t	i_size;		/* 8: size in bytes			*/
70 	uint64_t	i_ctime;	/* 16: creation time in seconds		*/
71 	uint64_t	i_mtime;	/* 24: modification time in seconds part*/
72 	uint32_t	i_ctime_nsec;	/* 32: creation time nanoseconds part	*/
73 	uint32_t	i_mtime_nsec;	/* 36: modification time in nanoseconds	*/
74 	uint32_t	i_uid;		/* 40: user id				*/
75 	uint32_t	i_gid;		/* 44: group id				*/
76 	uint16_t	i_mode;		/* 48: file mode			*/
77 	uint16_t	i_links_count;	/* 50: number of references to the inode*/
78 	uint32_t	i_flags;	/* 52: NANDFS_*_FL flags		*/
79 	nandfs_daddr_t	i_special;	/* 56: special				*/
80 	nandfs_daddr_t	i_db[NANDFS_NDADDR]; /* 64: Direct disk blocks.		*/
81 	nandfs_daddr_t	i_ib[NANDFS_NIADDR]; /* 160: Indirect disk blocks.	*/
82 	uint64_t	i_xattr;	/* 184: reserved for extended attributes*/
83 	uint32_t	i_generation;	/* 192: file generation for NFS		*/
84 	uint32_t	i_pad[15];	/* 196: make it 64 bits aligned		*/
85 };
86 
87 #ifdef _KERNEL
88 CTASSERT(sizeof(struct nandfs_inode) == 256);
89 #endif
90 
91 /*
92  * Each checkpoint/snapshot has a super root.
93  *
94  * The super root holds the inodes of the three system files: `dat', `cp' and
95  * 'su' files. All other FS state is defined by those.
96  *
97  * It is CRC checksum'ed and time stamped.
98  */
99 
100 struct nandfs_super_root {
101 	uint32_t	sr_sum;		/* check-sum				*/
102 	uint16_t	sr_bytes;	/* byte count of this structure		*/
103 	uint16_t	sr_flags;	/* reserved for flags			*/
104 	uint64_t	sr_nongc_ctime;	/* timestamp, not for cleaner(?)	*/
105 	struct nandfs_inode sr_dat;	/* DAT, virt->phys translation inode	*/
106 	struct nandfs_inode sr_cpfile;	/* CP, checkpoints inode		*/
107 	struct nandfs_inode sr_sufile;	/* SU, segment usage inode		*/
108 };
109 
110 #define	NANDFS_SR_MDT_OFFSET(inode_size, i)			\
111 	((uint32_t)&((struct nandfs_super_root *)0)->sr_dat +	\
112 	(inode_size) * (i))
113 
114 #define	NANDFS_SR_DAT_OFFSET(inode_size)	NANDFS_SR_MDT_OFFSET(inode_size, 0)
115 #define	NANDFS_SR_CPFILE_OFFSET(inode_size)	NANDFS_SR_MDT_OFFSET(inode_size, 1)
116 #define	NANDFS_SR_SUFILE_OFFSET(inode_size)	NANDFS_SR_MDT_OFFSET(inode_size, 2)
117 #define	NANDFS_SR_BYTES			(sizeof(struct nandfs_super_root))
118 
119 /*
120  * The superblock describes the basic structure and mount history. It also
121  * records some sizes of structures found on the disc for sanity checks.
122  *
123  * The superblock is stored at two places: NANDFS_SB_OFFSET_BYTES and
124  * NANDFS_SB2_OFFSET_BYTES.
125  */
126 
127 /* File system states stored on media in superblock's sbp->s_state */
128 #define	NANDFS_VALID_FS		0x0001	/* cleanly unmounted and all is ok  */
129 #define	NANDFS_ERROR_FS		0x0002	/* there were errors detected, fsck */
130 #define	NANDFS_RESIZE_FS	0x0004	/* resize required, XXX unknown flag*/
131 #define	NANDFS_MOUNT_STATE_BITS	"\20\1VALID_FS\2ERROR_FS\3RESIZE_FS"
132 
133 /*
134  * Brief description of control structures:
135  *
136  * NANDFS_NFSAREAS first blocks contain fsdata and some amount of super blocks.
137  * Simple round-robin policy is used in order to choose which block will
138  * contain new super block.
139  *
140  * Simple case with 2 blocks:
141  * 1: fsdata sblock1 [sblock3 [sblock5 ..]]
142  * 2: fsdata sblock2 [sblock4 [sblock6 ..]]
143  */
144 struct nandfs_fsdata {
145 	uint16_t	f_magic;
146 	uint16_t	f_bytes;
147 
148 	uint32_t	f_sum;		/* checksum of fsdata		*/
149 	uint32_t	f_rev_level;	/* major disk format revision	*/
150 
151 	uint64_t	f_ctime;	/* creation time (execution time
152 					   of newfs)			*/
153 	/* Block size represented as: blocksize = 1 << (f_log_block_size + 10)	*/
154 	uint32_t	f_log_block_size;
155 
156 	uint16_t	f_inode_size;		/* size of an inode		*/
157 	uint16_t	f_dat_entry_size;	/* size of a dat entry		*/
158 	uint16_t	f_checkpoint_size;	/* size of a checkpoint		*/
159 	uint16_t	f_segment_usage_size;	/* size of a segment usage	*/
160 
161 	uint16_t	f_sbbytes;		/* byte count of CRC calculation
162 						   for super blocks. s_reserved
163 						   is excluded!			*/
164 
165 	uint16_t	f_errors;		/* behaviour on detecting errors	*/
166 
167 	uint32_t	f_erasesize;
168 	uint64_t	f_nsegments;		/* number of segm. in filesystem	*/
169 	nandfs_daddr_t	f_first_data_block;	/* 1st seg disk block number		*/
170 	uint32_t	f_blocks_per_segment;	/* number of blocks per segment		*/
171 	uint32_t	f_r_segments_percentage;	/* reserved segments percentage		*/
172 
173 	struct uuid	f_uuid;			/* 128-bit uuid for volume		*/
174 	char		f_volume_name[16];	/* volume name				*/
175 	uint32_t	f_pad[104];
176 } __packed;
177 
178 #ifdef _KERNEL
179 CTASSERT(sizeof(struct nandfs_fsdata) == 512);
180 #endif
181 
182 struct nandfs_super_block {
183 	uint16_t	s_magic;		/* magic value for identification */
184 
185 	uint32_t	s_sum;			/* check sum of super block       */
186 
187 	uint64_t	s_last_cno;		/* last checkpoint number         */
188 	uint64_t	s_last_pseg;		/* addr part. segm. written last  */
189 	uint64_t	s_last_seq;		/* seq.number of seg written last */
190 	uint64_t	s_free_blocks_count;	/* free blocks count              */
191 
192 	uint64_t	s_mtime;		/* mount time                     */
193 	uint64_t	s_wtime;		/* write time                     */
194 	uint16_t	s_state;		/* file system state              */
195 
196 	char		s_last_mounted[64];	/* directory where last mounted   */
197 
198 	uint32_t	s_c_interval;		/* commit interval of segment     */
199 	uint32_t	s_c_block_max;		/* threshold of data amount for
200 						   the segment construction */
201 	uint32_t	s_reserved[32];		/* padding to end of the block    */
202 } __packed;
203 
204 #ifdef _KERNEL
205 CTASSERT(sizeof(struct nandfs_super_block) == 256);
206 #endif
207 
208 #define	NANDFS_FSDATA_MAGIC	0xf8da
209 #define	NANDFS_SUPER_MAGIC	0x8008
210 
211 #define	NANDFS_NFSAREAS		4
212 #define	NANDFS_DATA_OFFSET_BYTES(esize)	(NANDFS_NFSAREAS * (esize))
213 
214 #define	NANDFS_SBLOCK_OFFSET_BYTES (sizeof(struct nandfs_fsdata))
215 
216 #define	NANDFS_DEF_BLOCKSIZE	4096
217 #define	NANDFS_MIN_BLOCKSIZE	512
218 
219 #define	NANDFS_DEF_ERASESIZE	(2 << 16)
220 
221 #define	NANDFS_MIN_SEGSIZE	NANDFS_DEF_ERASESIZE
222 
223 #define	NANDFS_CURRENT_REV	9	/* current major revision */
224 
225 #define	NANDFS_FSDATA_CRC_BYTES offsetof(struct nandfs_fsdata, f_pad)
226 /* Bytes count of super_block for CRC-calculation */
227 #define	NANDFS_SB_BYTES  offsetof(struct nandfs_super_block, s_reserved)
228 
229 /* Maximal count of links to a file */
230 #define	NANDFS_LINK_MAX		32000
231 
232 /*
233  * Structure of a directory entry.
234  *
235  * Note that they can't span blocks; the rec_len fills out.
236  */
237 
238 #define	NANDFS_NAME_LEN 255
239 struct nandfs_dir_entry {
240 	uint64_t	inode;			/* inode number */
241 	uint16_t	rec_len;		/* directory entry length */
242 	uint8_t		name_len;		/* name length */
243 	uint8_t		file_type;
244 	char		name[NANDFS_NAME_LEN];	/* file name */
245 	char		pad;
246 };
247 
248 /*
249  * NANDFS_DIR_PAD defines the directory entries boundaries
250  *
251  * NOTE: It must be a multiple of 8
252  */
253 #define	NANDFS_DIR_PAD			8
254 #define	NANDFS_DIR_ROUND		(NANDFS_DIR_PAD - 1)
255 #define	NANDFS_DIR_NAME_OFFSET		(offsetof(struct nandfs_dir_entry, name))
256 #define	NANDFS_DIR_REC_LEN(name_len)					\
257 	(((name_len) + NANDFS_DIR_NAME_OFFSET + NANDFS_DIR_ROUND)	\
258 	& ~NANDFS_DIR_ROUND)
259 #define	NANDFS_DIR_NAME_LEN(name_len)	\
260 	(NANDFS_DIR_REC_LEN(name_len) - NANDFS_DIR_NAME_OFFSET)
261 
262 /*
263  * NiLFS/NANDFS devides the disc into fixed length segments. Each segment is
264  * filled with one or more partial segments of variable lengths.
265  *
266  * Each partial segment has a segment summary header followed by updates of
267  * files and optionally a super root.
268  */
269 
270 /*
271  * Virtual to physical block translation information. For data blocks it maps
272  * logical block number bi_blkoff to virtual block nr bi_vblocknr. For non
273  * datablocks it is the virtual block number assigned to an indirect block
274  * and has no bi_blkoff. The physical block number is the next
275  * available data block in the partial segment after all the binfo's.
276  */
277 struct nandfs_binfo_v {
278 	uint64_t	bi_ino;		/* file's inode			     */
279 	uint64_t	bi_vblocknr;	/* assigned virtual block number     */
280 	uint64_t	bi_blkoff;	/* for file's logical block number   */
281 };
282 
283 /*
284  * DAT allocation. For data blocks just the logical block number that maps on
285  * the next available data block in the partial segment after the binfo's.
286  */
287 struct nandfs_binfo_dat {
288 	uint64_t	bi_ino;
289 	uint64_t	bi_blkoff;	/* DAT file's logical block number */
290 	uint8_t		bi_level;	/* whether this is meta block */
291 	uint8_t		bi_pad[7];
292 };
293 
294 #ifdef _KERNEL
295 CTASSERT(sizeof(struct nandfs_binfo_v) == sizeof(struct nandfs_binfo_dat));
296 #endif
297 
298 /* Convenience union for both types of binfo's */
299 union nandfs_binfo {
300 	struct nandfs_binfo_v bi_v;
301 	struct nandfs_binfo_dat bi_dat;
302 };
303 
304 /* Indirect buffers path */
305 struct nandfs_indir {
306 	nandfs_daddr_t	in_lbn;
307 	int		in_off;
308 };
309 
310 /* The (partial) segment summary */
311 struct nandfs_segment_summary {
312 	uint32_t	ss_datasum;	/* CRC of complete data block        */
313 	uint32_t	ss_sumsum;	/* CRC of segment summary only       */
314 	uint32_t	ss_magic;	/* magic to identify segment summary */
315 	uint16_t	ss_bytes;	/* size of segment summary structure */
316 	uint16_t	ss_flags;	/* NANDFS_SS_* flags                  */
317 	uint64_t	ss_seq;		/* sequence number of this segm. sum */
318 	uint64_t	ss_create;	/* creation timestamp in seconds     */
319 	uint64_t	ss_next;	/* blocknumber of next segment       */
320 	uint32_t	ss_nblocks;	/* number of blocks used by summary  */
321 	uint32_t	ss_nbinfos;	/* number of binfo structures	     */
322 	uint32_t	ss_sumbytes;	/* total size of segment summary     */
323 	uint32_t	ss_pad;
324 	/* stream of binfo structures */
325 };
326 
327 #define	NANDFS_SEGSUM_MAGIC	0x8e680011	/* segment summary magic number */
328 
329 /* Segment summary flags */
330 #define	NANDFS_SS_LOGBGN	0x0001	/* begins a logical segment */
331 #define	NANDFS_SS_LOGEND	0x0002	/* ends a logical segment */
332 #define	NANDFS_SS_SR		0x0004	/* has super root */
333 #define	NANDFS_SS_SYNDT		0x0008	/* includes data only updates */
334 #define	NANDFS_SS_GC		0x0010	/* segment written for cleaner operation */
335 #define	NANDFS_SS_FLAG_BITS	"\20\1LOGBGN\2LOGEND\3SR\4SYNDT\5GC"
336 
337 /* Segment summary constrains */
338 #define	NANDFS_SEG_MIN_BLOCKS	16	/* minimum number of blocks in a
339 					   full segment */
340 #define	NANDFS_PSEG_MIN_BLOCKS	2	/* minimum number of blocks in a
341 					   partial segment */
342 #define	NANDFS_MIN_NRSVSEGS	8	/* minimum number of reserved
343 					   segments */
344 
345 /*
346  * Structure of DAT/inode file.
347  *
348  * A DAT file is divided into groups. The maximum number of groups is the
349  * number of block group descriptors that fit into one block; this descriptor
350  * only gives the number of free entries in the associated group.
351  *
352  * Each group has a block sized bitmap indicating if an entry is taken or
353  * empty. Each bit stands for a DAT entry.
354  *
355  * The inode file has exactly the same format only the entries are inode
356  * entries.
357  */
358 
359 struct nandfs_block_group_desc {
360 	uint32_t	bg_nfrees;	/* num. free entries in block group  */
361 };
362 
363 /* DAT entry in a super root's DAT file */
364 struct nandfs_dat_entry {
365 	uint64_t	de_blocknr;	/* block number                      */
366 	uint64_t	de_start;	/* valid from checkpoint             */
367 	uint64_t	de_end;		/* valid till checkpoint             */
368 	uint64_t	de_rsv;		/* reserved for future use           */
369 };
370 
371 /*
372  * Structure of CP file.
373  *
374  * A snapshot is just a checkpoint only it's protected against removal by the
375  * cleaner. The snapshots are kept on a double linked list of checkpoints.
376  */
377 struct nandfs_snapshot_list {
378 	uint64_t	ssl_next;	/* checkpoint nr. forward */
379 	uint64_t	ssl_prev;	/* checkpoint nr. back    */
380 };
381 
382 /* Checkpoint entry structure */
383 struct nandfs_checkpoint {
384 	uint32_t	cp_flags;		/* NANDFS_CHECKPOINT_* flags          */
385 	uint32_t	cp_checkpoints_count;	/* ZERO, not used anymore?           */
386 	struct nandfs_snapshot_list cp_snapshot_list; /* list of snapshots   */
387 	uint64_t	cp_cno;			/* checkpoint number                 */
388 	uint64_t	cp_create;		/* creation timestamp                */
389 	uint64_t	cp_nblk_inc;		/* number of blocks incremented      */
390 	uint64_t	cp_blocks_count;	/* reserved (might be deleted)       */
391 	struct nandfs_inode cp_ifile_inode;	/* inode file inode          */
392 };
393 
394 /* Checkpoint flags */
395 #define	NANDFS_CHECKPOINT_SNAPSHOT	1
396 #define	NANDFS_CHECKPOINT_INVALID	2
397 #define	NANDFS_CHECKPOINT_SKETCH	4
398 #define	NANDFS_CHECKPOINT_MINOR		8
399 #define	NANDFS_CHECKPOINT_BITS		"\20\1SNAPSHOT\2INVALID\3SKETCH\4MINOR"
400 
401 /* Header of the checkpoint file */
402 struct nandfs_cpfile_header {
403 	uint64_t	ch_ncheckpoints;	/* number of checkpoints             */
404 	uint64_t	ch_nsnapshots;	/* number of snapshots               */
405 	struct nandfs_snapshot_list ch_snapshot_list;	/* snapshot list     */
406 };
407 
408 #define	NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET		\
409 	((sizeof(struct nandfs_cpfile_header) +		\
410 	sizeof(struct nandfs_checkpoint) - 1) /		\
411 	sizeof(struct nandfs_checkpoint))
412 
413 
414 #define NANDFS_NOSEGMENT        0xffffffff
415 
416 /*
417  * Structure of SU file.
418  *
419  * The segment usage file sums up how each of the segments are used. They are
420  * indexed by their segment number.
421  */
422 
423 /* Segment usage entry */
424 struct nandfs_segment_usage {
425 	uint64_t	su_lastmod;	/* last modified timestamp           */
426 	uint32_t	su_nblocks;	/* number of blocks in segment       */
427 	uint32_t	su_flags;	/* NANDFS_SEGMENT_USAGE_* flags       */
428 };
429 
430 /* Segment usage flag */
431 #define	NANDFS_SEGMENT_USAGE_ACTIVE	1
432 #define	NANDFS_SEGMENT_USAGE_DIRTY	2
433 #define	NANDFS_SEGMENT_USAGE_ERROR	4
434 #define	NANDFS_SEGMENT_USAGE_GC		8
435 #define	NANDFS_SEGMENT_USAGE_BITS	"\20\1ACTIVE\2DIRTY\3ERROR"
436 
437 /* Header of the segment usage file */
438 struct nandfs_sufile_header {
439 	uint64_t	sh_ncleansegs;	/* number of segments marked clean   */
440 	uint64_t	sh_ndirtysegs;	/* number of segments marked dirty   */
441 	uint64_t	sh_last_alloc;	/* last allocated segment number     */
442 };
443 
444 #define	NANDFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET	\
445 	((sizeof(struct nandfs_sufile_header) +		\
446 	sizeof(struct nandfs_segment_usage) - 1) /	\
447 	sizeof(struct nandfs_segment_usage))
448 
449 struct nandfs_seg_stat {
450 	uint64_t	nss_nsegs;
451 	uint64_t	nss_ncleansegs;
452 	uint64_t	nss_ndirtysegs;
453 	uint64_t	nss_ctime;
454 	uint64_t	nss_nongc_ctime;
455 	uint64_t	nss_prot_seq;
456 };
457 
458 enum {
459 	NANDFS_CHECKPOINT,
460 	NANDFS_SNAPSHOT
461 };
462 
463 #define	NANDFS_CPINFO_MAX		512
464 
465 struct nandfs_cpinfo {
466 	uint32_t	nci_flags;
467 	uint32_t	nci_pad;
468 	uint64_t	nci_cno;
469 	uint64_t	nci_create;
470 	uint64_t	nci_nblk_inc;
471 	uint64_t	nci_blocks_count;
472 	uint64_t	nci_next;
473 };
474 
475 #define	NANDFS_SEGMENTS_MAX	512
476 
477 struct nandfs_suinfo {
478 	uint64_t	nsi_num;
479 	uint64_t	nsi_lastmod;
480 	uint32_t	nsi_blocks;
481 	uint32_t	nsi_flags;
482 };
483 
484 #define	NANDFS_VINFO_MAX	512
485 
486 struct nandfs_vinfo {
487 	uint64_t	nvi_ino;
488 	uint64_t	nvi_vblocknr;
489 	uint64_t	nvi_start;
490 	uint64_t	nvi_end;
491 	uint64_t	nvi_blocknr;
492 	int		nvi_alive;
493 };
494 
495 struct nandfs_cpmode {
496 	uint64_t	ncpm_cno;
497 	uint32_t	ncpm_mode;
498 	uint32_t	ncpm_pad;
499 };
500 
501 struct nandfs_argv {
502 	uint64_t	nv_base;
503 	uint32_t	nv_nmembs;
504 	uint16_t	nv_size;
505 	uint16_t	nv_flags;
506 	uint64_t	nv_index;
507 };
508 
509 struct nandfs_cpstat {
510 	uint64_t	ncp_cno;
511 	uint64_t	ncp_ncps;
512 	uint64_t	ncp_nss;
513 };
514 
515 struct nandfs_period {
516 	uint64_t	p_start;
517 	uint64_t	p_end;
518 };
519 
520 struct nandfs_vdesc {
521 	uint64_t	vd_ino;
522 	uint64_t	vd_cno;
523 	uint64_t	vd_vblocknr;
524 	struct nandfs_period	vd_period;
525 	uint64_t	vd_blocknr;
526 	uint64_t	vd_offset;
527 	uint32_t	vd_flags;
528 	uint32_t	vd_pad;
529 };
530 
531 struct nandfs_bdesc {
532 	uint64_t	bd_ino;
533 	uint64_t	bd_oblocknr;
534 	uint64_t	bd_blocknr;
535 	uint64_t	bd_offset;
536 	uint32_t	bd_level;
537 	uint32_t	bd_alive;
538 };
539 
540 #ifndef _KERNEL
541 #ifndef	MNAMELEN
542 #define	MNAMELEN	1024
543 #endif
544 #endif
545 
546 struct nandfs_fsinfo {
547 	struct nandfs_fsdata		fs_fsdata;
548 	struct nandfs_super_block	fs_super;
549 	char				fs_dev[MNAMELEN];
550 };
551 
552 #define	NANDFS_MAX_MOUNTS	65535
553 
554 #define	NANDFS_IOCTL_GET_SUSTAT		_IOR('N', 100, struct nandfs_seg_stat)
555 #define	NANDFS_IOCTL_CHANGE_CPMODE	_IOWR('N', 101, struct nandfs_cpmode)
556 #define	NANDFS_IOCTL_GET_CPINFO		_IOWR('N', 102, struct nandfs_argv)
557 #define	NANDFS_IOCTL_DELETE_CP		_IOWR('N', 103, uint64_t[2])
558 #define	NANDFS_IOCTL_GET_CPSTAT		_IOR('N', 104, struct nandfs_cpstat)
559 #define	NANDFS_IOCTL_GET_SUINFO		_IOWR('N', 105, struct nandfs_argv)
560 #define	NANDFS_IOCTL_GET_VINFO		_IOWR('N', 106, struct nandfs_argv)
561 #define	NANDFS_IOCTL_GET_BDESCS		_IOWR('N', 107, struct nandfs_argv)
562 #define	NANDFS_IOCTL_GET_FSINFO		_IOR('N', 108, struct nandfs_fsinfo)
563 #define	NANDFS_IOCTL_MAKE_SNAP		_IOWR('N', 109, uint64_t)
564 #define	NANDFS_IOCTL_DELETE_SNAP	_IOWR('N', 110, uint64_t)
565 #define	NANDFS_IOCTL_SYNC		_IOWR('N', 111, uint64_t)
566 
567 #endif /* _NANDFS_FS_H */
568