1235537Sgber/*- 2235537Sgber * Copyright (c) 2010-2012 Semihalf 3235537Sgber * Copyright (c) 2008, 2009 Reinoud Zandijk 4235537Sgber * All rights reserved. 5235537Sgber * 6235537Sgber * Redistribution and use in source and binary forms, with or without 7235537Sgber * modification, are permitted provided that the following conditions 8235537Sgber * are met: 9235537Sgber * 1. Redistributions of source code must retain the above copyright 10235537Sgber * notice, this list of conditions and the following disclaimer. 11235537Sgber * 2. Redistributions in binary form must reproduce the above copyright 12235537Sgber * notice, this list of conditions and the following disclaimer in the 13235537Sgber * documentation and/or other materials provided with the distribution. 14235537Sgber * 15235537Sgber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16235537Sgber * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17235537Sgber * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18235537Sgber * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19235537Sgber * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20235537Sgber * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21235537Sgber * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22235537Sgber * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23235537Sgber * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24235537Sgber * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25235537Sgber * 26235537Sgber * Original definitions written by Koji Sato <koji@osrg.net> 27235537Sgber * and Ryusuke Konishi <ryusuke@osrg.net> 28235537Sgber * From: NetBSD: nandfs_fs.h,v 1.1 2009/07/18 16:31:42 reinoud 29235537Sgber * 30235537Sgber * $FreeBSD$ 31235537Sgber */ 32235537Sgber 33235537Sgber#ifndef _NANDFS_FS_H 34235537Sgber#define _NANDFS_FS_H 35235537Sgber 36235537Sgber#include <sys/uuid.h> 37235537Sgber 38235537Sgber#define MNINDIR(fsdev) ((fsdev)->nd_blocksize / sizeof(nandfs_daddr_t)) 39235537Sgber 40235537Sgber/* 41235537Sgber * Inode structure. There are a few dedicated inode numbers that are 42235537Sgber * defined here first. 43235537Sgber */ 44235537Sgber#define NANDFS_WHT_INO 1 /* Whiteout ino */ 45235537Sgber#define NANDFS_ROOT_INO 2 /* Root file inode */ 46235537Sgber#define NANDFS_DAT_INO 3 /* DAT file */ 47235537Sgber#define NANDFS_CPFILE_INO 4 /* checkpoint file */ 48235537Sgber#define NANDFS_SUFILE_INO 5 /* segment usage file */ 49235537Sgber#define NANDFS_IFILE_INO 6 /* ifile */ 50235537Sgber#define NANDFS_GC_INO 7 /* Cleanerd node */ 51235537Sgber#define NANDFS_ATIME_INO 8 /* Atime file (reserved) */ 52235537Sgber#define NANDFS_XATTR_INO 9 /* Xattribute file (reserved) */ 53235537Sgber#define NANDFS_SKETCH_INO 10 /* Sketch file (obsolete) */ 54235537Sgber#define NANDFS_USER_INO 11 /* First user's file inode number */ 55235537Sgber 56235537Sgber#define NANDFS_SYS_NODE(ino) \ 57235537Sgber (((ino) >= NANDFS_DAT_INO) && ((ino) <= NANDFS_GC_INO)) 58235537Sgber 59235537Sgber#define NDADDR 12 /* Direct addresses in inode. */ 60235537Sgber#define NIADDR 3 /* Indirect addresses in inode. */ 61235537Sgber 62235537Sgbertypedef int64_t nandfs_daddr_t; 63235537Sgbertypedef int64_t nandfs_lbn_t; 64235537Sgber 65235537Sgberstruct nandfs_inode { 66235537Sgber uint64_t i_blocks; /* 0: size in device blocks */ 67235537Sgber uint64_t i_size; /* 8: size in bytes */ 68235537Sgber uint64_t i_ctime; /* 16: creation time in seconds */ 69235537Sgber uint64_t i_mtime; /* 24: modification time in seconds part*/ 70235537Sgber uint32_t i_ctime_nsec; /* 32: creation time nanoseconds part */ 71235537Sgber uint32_t i_mtime_nsec; /* 36: modification time in nanoseconds */ 72235537Sgber uint32_t i_uid; /* 40: user id */ 73235537Sgber uint32_t i_gid; /* 44: group id */ 74235537Sgber uint16_t i_mode; /* 48: file mode */ 75235537Sgber uint16_t i_links_count; /* 50: number of references to the inode*/ 76235537Sgber uint32_t i_flags; /* 52: NANDFS_*_FL flags */ 77235537Sgber nandfs_daddr_t i_special; /* 56: special */ 78235537Sgber nandfs_daddr_t i_db[NDADDR]; /* 64: Direct disk blocks. */ 79235537Sgber nandfs_daddr_t i_ib[NIADDR]; /* 160: Indirect disk blocks. */ 80235537Sgber uint64_t i_xattr; /* 184: reserved for extended attributes*/ 81235537Sgber uint32_t i_generation; /* 192: file generation for NFS */ 82235537Sgber uint32_t i_pad[15]; /* 196: make it 64 bits aligned */ 83235537Sgber}; 84235537Sgber 85235537Sgber#ifdef _KERNEL 86235537SgberCTASSERT(sizeof(struct nandfs_inode) == 256); 87235537Sgber#endif 88235537Sgber 89235537Sgber/* 90235537Sgber * Each checkpoint/snapshot has a super root. 91235537Sgber * 92235537Sgber * The super root holds the inodes of the three system files: `dat', `cp' and 93235537Sgber * 'su' files. All other FS state is defined by those. 94235537Sgber * 95235537Sgber * It is CRC checksum'ed and time stamped. 96235537Sgber */ 97235537Sgber 98235537Sgberstruct nandfs_super_root { 99235537Sgber uint32_t sr_sum; /* check-sum */ 100235537Sgber uint16_t sr_bytes; /* byte count of this structure */ 101235537Sgber uint16_t sr_flags; /* reserved for flags */ 102235537Sgber uint64_t sr_nongc_ctime; /* timestamp, not for cleaner(?) */ 103235537Sgber struct nandfs_inode sr_dat; /* DAT, virt->phys translation inode */ 104235537Sgber struct nandfs_inode sr_cpfile; /* CP, checkpoints inode */ 105235537Sgber struct nandfs_inode sr_sufile; /* SU, segment usage inode */ 106235537Sgber}; 107235537Sgber 108235537Sgber#define NANDFS_SR_MDT_OFFSET(inode_size, i) \ 109235537Sgber ((uint32_t)&((struct nandfs_super_root *)0)->sr_dat + \ 110235537Sgber (inode_size) * (i)) 111235537Sgber 112235537Sgber#define NANDFS_SR_DAT_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 0) 113235537Sgber#define NANDFS_SR_CPFILE_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 1) 114235537Sgber#define NANDFS_SR_SUFILE_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 2) 115235537Sgber#define NANDFS_SR_BYTES (sizeof(struct nandfs_super_root)) 116235537Sgber 117235537Sgber/* 118235537Sgber * The superblock describes the basic structure and mount history. It also 119235537Sgber * records some sizes of structures found on the disc for sanity checks. 120235537Sgber * 121235537Sgber * The superblock is stored at two places: NANDFS_SB_OFFSET_BYTES and 122235537Sgber * NANDFS_SB2_OFFSET_BYTES. 123235537Sgber */ 124235537Sgber 125235537Sgber/* File system states stored on media in superblock's sbp->s_state */ 126235537Sgber#define NANDFS_VALID_FS 0x0001 /* cleanly unmounted and all is ok */ 127235537Sgber#define NANDFS_ERROR_FS 0x0002 /* there were errors detected, fsck */ 128235537Sgber#define NANDFS_RESIZE_FS 0x0004 /* resize required, XXX unknown flag*/ 129235537Sgber#define NANDFS_MOUNT_STATE_BITS "\20\1VALID_FS\2ERROR_FS\3RESIZE_FS" 130235537Sgber 131235537Sgber/* 132235537Sgber * Brief description of control structures: 133235537Sgber * 134235537Sgber * NANDFS_NFSAREAS first blocks contain fsdata and some amount of super blocks. 135235537Sgber * Simple round-robin policy is used in order to choose which block will 136235537Sgber * contain new super block. 137235537Sgber * 138235537Sgber * Simple case with 2 blocks: 139235537Sgber * 1: fsdata sblock1 [sblock3 [sblock5 ..]] 140235537Sgber * 2: fsdata sblock2 [sblock4 [sblock6 ..]] 141235537Sgber */ 142235537Sgberstruct nandfs_fsdata { 143235537Sgber uint16_t f_magic; 144235537Sgber uint16_t f_bytes; 145235537Sgber 146235537Sgber uint32_t f_sum; /* checksum of fsdata */ 147235537Sgber uint32_t f_rev_level; /* major disk format revision */ 148235537Sgber 149235537Sgber uint64_t f_ctime; /* creation time (execution time 150235537Sgber of newfs) */ 151235537Sgber /* Block size represented as: blocksize = 1 << (f_log_block_size + 10) */ 152235537Sgber uint32_t f_log_block_size; 153235537Sgber 154235537Sgber uint16_t f_inode_size; /* size of an inode */ 155235537Sgber uint16_t f_dat_entry_size; /* size of a dat entry */ 156235537Sgber uint16_t f_checkpoint_size; /* size of a checkpoint */ 157235537Sgber uint16_t f_segment_usage_size; /* size of a segment usage */ 158235537Sgber 159235537Sgber uint16_t f_sbbytes; /* byte count of CRC calculation 160235537Sgber for super blocks. s_reserved 161235537Sgber is excluded! */ 162235537Sgber 163235537Sgber uint16_t f_errors; /* behaviour on detecting errors */ 164235537Sgber 165235537Sgber uint32_t f_erasesize; 166235537Sgber uint64_t f_nsegments; /* number of segm. in filesystem */ 167235537Sgber nandfs_daddr_t f_first_data_block; /* 1st seg disk block number */ 168235537Sgber uint32_t f_blocks_per_segment; /* number of blocks per segment */ 169235537Sgber uint32_t f_r_segments_percentage; /* reserved segments percentage */ 170235537Sgber 171235537Sgber struct uuid f_uuid; /* 128-bit uuid for volume */ 172235537Sgber char f_volume_name[16]; /* volume name */ 173235537Sgber uint32_t f_pad[104]; 174235537Sgber} __packed; 175235537Sgber 176235537Sgber#ifdef _KERNEL 177235537SgberCTASSERT(sizeof(struct nandfs_fsdata) == 512); 178235537Sgber#endif 179235537Sgber 180235537Sgberstruct nandfs_super_block { 181235537Sgber uint16_t s_magic; /* magic value for identification */ 182235537Sgber 183235537Sgber uint32_t s_sum; /* check sum of super block */ 184235537Sgber 185235537Sgber uint64_t s_last_cno; /* last checkpoint number */ 186235537Sgber uint64_t s_last_pseg; /* addr part. segm. written last */ 187235537Sgber uint64_t s_last_seq; /* seq.number of seg written last */ 188235537Sgber uint64_t s_free_blocks_count; /* free blocks count */ 189235537Sgber 190235537Sgber uint64_t s_mtime; /* mount time */ 191235537Sgber uint64_t s_wtime; /* write time */ 192235537Sgber uint16_t s_state; /* file system state */ 193235537Sgber 194235537Sgber char s_last_mounted[64]; /* directory where last mounted */ 195235537Sgber 196235537Sgber uint32_t s_c_interval; /* commit interval of segment */ 197235537Sgber uint32_t s_c_block_max; /* threshold of data amount for 198235537Sgber the segment construction */ 199235537Sgber uint32_t s_reserved[32]; /* padding to end of the block */ 200235537Sgber} __packed; 201235537Sgber 202235537Sgber#ifdef _KERNEL 203235537SgberCTASSERT(sizeof(struct nandfs_super_block) == 256); 204235537Sgber#endif 205235537Sgber 206235537Sgber#define NANDFS_FSDATA_MAGIC 0xf8da 207235537Sgber#define NANDFS_SUPER_MAGIC 0x8008 208235537Sgber 209235537Sgber#define NANDFS_NFSAREAS 4 210235537Sgber#define NANDFS_DATA_OFFSET_BYTES(esize) (NANDFS_NFSAREAS * (esize)) 211235537Sgber 212235537Sgber#define NANDFS_SBLOCK_OFFSET_BYTES (sizeof(struct nandfs_fsdata)) 213235537Sgber 214235537Sgber#define NANDFS_DEF_BLOCKSIZE 4096 215235537Sgber#define NANDFS_MIN_BLOCKSIZE 512 216235537Sgber 217235537Sgber#define NANDFS_DEF_ERASESIZE (2 << 16) 218235537Sgber 219235537Sgber#define NANDFS_MIN_SEGSIZE NANDFS_DEF_ERASESIZE 220235537Sgber 221235537Sgber#define NANDFS_CURRENT_REV 9 /* current major revision */ 222235537Sgber 223235537Sgber#define NANDFS_FSDATA_CRC_BYTES offsetof(struct nandfs_fsdata, f_pad) 224235537Sgber/* Bytes count of super_block for CRC-calculation */ 225235537Sgber#define NANDFS_SB_BYTES offsetof(struct nandfs_super_block, s_reserved) 226235537Sgber 227235537Sgber/* Maximal count of links to a file */ 228235537Sgber#define NANDFS_LINK_MAX 32000 229235537Sgber 230235537Sgber/* 231235537Sgber * Structure of a directory entry. 232235537Sgber * 233235537Sgber * Note that they can't span blocks; the rec_len fills out. 234235537Sgber */ 235235537Sgber 236235537Sgber#define NANDFS_NAME_LEN 255 237235537Sgberstruct nandfs_dir_entry { 238235537Sgber uint64_t inode; /* inode number */ 239235537Sgber uint16_t rec_len; /* directory entry length */ 240235537Sgber uint8_t name_len; /* name length */ 241235537Sgber uint8_t file_type; 242235537Sgber char name[NANDFS_NAME_LEN]; /* file name */ 243235537Sgber char pad; 244235537Sgber}; 245235537Sgber 246235537Sgber/* 247235537Sgber * NANDFS_DIR_PAD defines the directory entries boundaries 248235537Sgber * 249235537Sgber * NOTE: It must be a multiple of 8 250235537Sgber */ 251235537Sgber#define NANDFS_DIR_PAD 8 252235537Sgber#define NANDFS_DIR_ROUND (NANDFS_DIR_PAD - 1) 253235537Sgber#define NANDFS_DIR_NAME_OFFSET (offsetof(struct nandfs_dir_entry, name)) 254235537Sgber#define NANDFS_DIR_REC_LEN(name_len) \ 255235537Sgber (((name_len) + NANDFS_DIR_NAME_OFFSET + NANDFS_DIR_ROUND) \ 256235537Sgber & ~NANDFS_DIR_ROUND) 257235537Sgber#define NANDFS_DIR_NAME_LEN(name_len) \ 258235537Sgber (NANDFS_DIR_REC_LEN(name_len) - NANDFS_DIR_NAME_OFFSET) 259235537Sgber 260235537Sgber/* 261235537Sgber * NiLFS/NANDFS devides the disc into fixed length segments. Each segment is 262235537Sgber * filled with one or more partial segments of variable lengths. 263235537Sgber * 264235537Sgber * Each partial segment has a segment summary header followed by updates of 265235537Sgber * files and optionally a super root. 266235537Sgber */ 267235537Sgber 268235537Sgber/* 269235537Sgber * Virtual to physical block translation information. For data blocks it maps 270235537Sgber * logical block number bi_blkoff to virtual block nr bi_vblocknr. For non 271235537Sgber * datablocks it is the virtual block number assigned to an indirect block 272235537Sgber * and has no bi_blkoff. The physical block number is the next 273235537Sgber * available data block in the partial segment after all the binfo's. 274235537Sgber */ 275235537Sgberstruct nandfs_binfo_v { 276235537Sgber uint64_t bi_ino; /* file's inode */ 277235537Sgber uint64_t bi_vblocknr; /* assigned virtual block number */ 278235537Sgber uint64_t bi_blkoff; /* for file's logical block number */ 279235537Sgber}; 280235537Sgber 281235537Sgber/* 282235537Sgber * DAT allocation. For data blocks just the logical block number that maps on 283235537Sgber * the next available data block in the partial segment after the binfo's. 284235537Sgber */ 285235537Sgberstruct nandfs_binfo_dat { 286235537Sgber uint64_t bi_ino; 287235537Sgber uint64_t bi_blkoff; /* DAT file's logical block number */ 288235537Sgber uint8_t bi_level; /* whether this is meta block */ 289235537Sgber uint8_t bi_pad[7]; 290235537Sgber}; 291235537Sgber 292235537Sgber#ifdef _KERNEL 293235537SgberCTASSERT(sizeof(struct nandfs_binfo_v) == sizeof(struct nandfs_binfo_dat)); 294235537Sgber#endif 295235537Sgber 296235537Sgber/* Convenience union for both types of binfo's */ 297235537Sgberunion nandfs_binfo { 298235537Sgber struct nandfs_binfo_v bi_v; 299235537Sgber struct nandfs_binfo_dat bi_dat; 300235537Sgber}; 301235537Sgber 302235537Sgber/* Indirect buffers path */ 303235537Sgberstruct nandfs_indir { 304235537Sgber nandfs_daddr_t in_lbn; 305235537Sgber int in_off; 306235537Sgber}; 307235537Sgber 308235537Sgber/* The (partial) segment summary */ 309235537Sgberstruct nandfs_segment_summary { 310235537Sgber uint32_t ss_datasum; /* CRC of complete data block */ 311235537Sgber uint32_t ss_sumsum; /* CRC of segment summary only */ 312235537Sgber uint32_t ss_magic; /* magic to identify segment summary */ 313235537Sgber uint16_t ss_bytes; /* size of segment summary structure */ 314235537Sgber uint16_t ss_flags; /* NANDFS_SS_* flags */ 315235537Sgber uint64_t ss_seq; /* sequence number of this segm. sum */ 316235537Sgber uint64_t ss_create; /* creation timestamp in seconds */ 317235537Sgber uint64_t ss_next; /* blocknumber of next segment */ 318235537Sgber uint32_t ss_nblocks; /* number of blocks used by summary */ 319235537Sgber uint32_t ss_nbinfos; /* number of binfo structures */ 320235537Sgber uint32_t ss_sumbytes; /* total size of segment summary */ 321235537Sgber uint32_t ss_pad; 322235537Sgber /* stream of binfo structures */ 323235537Sgber}; 324235537Sgber 325235537Sgber#define NANDFS_SEGSUM_MAGIC 0x8e680011 /* segment summary magic number */ 326235537Sgber 327235537Sgber/* Segment summary flags */ 328235537Sgber#define NANDFS_SS_LOGBGN 0x0001 /* begins a logical segment */ 329235537Sgber#define NANDFS_SS_LOGEND 0x0002 /* ends a logical segment */ 330235537Sgber#define NANDFS_SS_SR 0x0004 /* has super root */ 331235537Sgber#define NANDFS_SS_SYNDT 0x0008 /* includes data only updates */ 332235537Sgber#define NANDFS_SS_GC 0x0010 /* segment written for cleaner operation */ 333235537Sgber#define NANDFS_SS_FLAG_BITS "\20\1LOGBGN\2LOGEND\3SR\4SYNDT\5GC" 334235537Sgber 335235537Sgber/* Segment summary constrains */ 336235537Sgber#define NANDFS_SEG_MIN_BLOCKS 16 /* minimum number of blocks in a 337235537Sgber full segment */ 338235537Sgber#define NANDFS_PSEG_MIN_BLOCKS 2 /* minimum number of blocks in a 339235537Sgber partial segment */ 340235537Sgber#define NANDFS_MIN_NRSVSEGS 8 /* minimum number of reserved 341235537Sgber segments */ 342235537Sgber 343235537Sgber/* 344235537Sgber * Structure of DAT/inode file. 345235537Sgber * 346235537Sgber * A DAT file is devided into groups. The maximum number of groups is the 347235537Sgber * number of block group descriptors that fit into one block; this descriptor 348235537Sgber * only gives the number of free entries in the associated group. 349235537Sgber * 350235537Sgber * Each group has a block sized bitmap indicating if an entry is taken or 351235537Sgber * empty. Each bit stands for a DAT entry. 352235537Sgber * 353235537Sgber * The inode file has exactly the same format only the entries are inode 354235537Sgber * entries. 355235537Sgber */ 356235537Sgber 357235537Sgberstruct nandfs_block_group_desc { 358235537Sgber uint32_t bg_nfrees; /* num. free entries in block group */ 359235537Sgber}; 360235537Sgber 361235537Sgber/* DAT entry in a super root's DAT file */ 362235537Sgberstruct nandfs_dat_entry { 363235537Sgber uint64_t de_blocknr; /* block number */ 364235537Sgber uint64_t de_start; /* valid from checkpoint */ 365235537Sgber uint64_t de_end; /* valid till checkpoint */ 366235537Sgber uint64_t de_rsv; /* reserved for future use */ 367235537Sgber}; 368235537Sgber 369235537Sgber/* 370235537Sgber * Structure of CP file. 371235537Sgber * 372235537Sgber * A snapshot is just a checkpoint only it's protected against removal by the 373235537Sgber * cleaner. The snapshots are kept on a double linked list of checkpoints. 374235537Sgber */ 375235537Sgberstruct nandfs_snapshot_list { 376235537Sgber uint64_t ssl_next; /* checkpoint nr. forward */ 377235537Sgber uint64_t ssl_prev; /* checkpoint nr. back */ 378235537Sgber}; 379235537Sgber 380235537Sgber/* Checkpoint entry structure */ 381235537Sgberstruct nandfs_checkpoint { 382235537Sgber uint32_t cp_flags; /* NANDFS_CHECKPOINT_* flags */ 383235537Sgber uint32_t cp_checkpoints_count; /* ZERO, not used anymore? */ 384235537Sgber struct nandfs_snapshot_list cp_snapshot_list; /* list of snapshots */ 385235537Sgber uint64_t cp_cno; /* checkpoint number */ 386235537Sgber uint64_t cp_create; /* creation timestamp */ 387235537Sgber uint64_t cp_nblk_inc; /* number of blocks incremented */ 388235537Sgber uint64_t cp_blocks_count; /* reserved (might be deleted) */ 389235537Sgber struct nandfs_inode cp_ifile_inode; /* inode file inode */ 390235537Sgber}; 391235537Sgber 392235537Sgber/* Checkpoint flags */ 393235537Sgber#define NANDFS_CHECKPOINT_SNAPSHOT 1 394235537Sgber#define NANDFS_CHECKPOINT_INVALID 2 395235537Sgber#define NANDFS_CHECKPOINT_SKETCH 4 396235537Sgber#define NANDFS_CHECKPOINT_MINOR 8 397235537Sgber#define NANDFS_CHECKPOINT_BITS "\20\1SNAPSHOT\2INVALID\3SKETCH\4MINOR" 398235537Sgber 399235537Sgber/* Header of the checkpoint file */ 400235537Sgberstruct nandfs_cpfile_header { 401235537Sgber uint64_t ch_ncheckpoints; /* number of checkpoints */ 402235537Sgber uint64_t ch_nsnapshots; /* number of snapshots */ 403235537Sgber struct nandfs_snapshot_list ch_snapshot_list; /* snapshot list */ 404235537Sgber}; 405235537Sgber 406235537Sgber#define NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET \ 407235537Sgber ((sizeof(struct nandfs_cpfile_header) + \ 408235537Sgber sizeof(struct nandfs_checkpoint) - 1) / \ 409235537Sgber sizeof(struct nandfs_checkpoint)) 410235537Sgber 411235537Sgber 412235537Sgber#define NANDFS_NOSEGMENT 0xffffffff 413235537Sgber 414235537Sgber/* 415235537Sgber * Structure of SU file. 416235537Sgber * 417235537Sgber * The segment usage file sums up how each of the segments are used. They are 418235537Sgber * indexed by their segment number. 419235537Sgber */ 420235537Sgber 421235537Sgber/* Segment usage entry */ 422235537Sgberstruct nandfs_segment_usage { 423235537Sgber uint64_t su_lastmod; /* last modified timestamp */ 424235537Sgber uint32_t su_nblocks; /* number of blocks in segment */ 425235537Sgber uint32_t su_flags; /* NANDFS_SEGMENT_USAGE_* flags */ 426235537Sgber}; 427235537Sgber 428235537Sgber/* Segment usage flag */ 429235537Sgber#define NANDFS_SEGMENT_USAGE_ACTIVE 1 430235537Sgber#define NANDFS_SEGMENT_USAGE_DIRTY 2 431235537Sgber#define NANDFS_SEGMENT_USAGE_ERROR 4 432235537Sgber#define NANDFS_SEGMENT_USAGE_GC 8 433235537Sgber#define NANDFS_SEGMENT_USAGE_BITS "\20\1ACTIVE\2DIRTY\3ERROR" 434235537Sgber 435235537Sgber/* Header of the segment usage file */ 436235537Sgberstruct nandfs_sufile_header { 437235537Sgber uint64_t sh_ncleansegs; /* number of segments marked clean */ 438235537Sgber uint64_t sh_ndirtysegs; /* number of segments marked dirty */ 439235537Sgber uint64_t sh_last_alloc; /* last allocated segment number */ 440235537Sgber}; 441235537Sgber 442235537Sgber#define NANDFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET \ 443235537Sgber ((sizeof(struct nandfs_sufile_header) + \ 444235537Sgber sizeof(struct nandfs_segment_usage) - 1) / \ 445235537Sgber sizeof(struct nandfs_segment_usage)) 446235537Sgber 447235537Sgberstruct nandfs_seg_stat { 448235537Sgber uint64_t nss_nsegs; 449235537Sgber uint64_t nss_ncleansegs; 450235537Sgber uint64_t nss_ndirtysegs; 451235537Sgber uint64_t nss_ctime; 452235537Sgber uint64_t nss_nongc_ctime; 453235537Sgber uint64_t nss_prot_seq; 454235537Sgber}; 455235537Sgber 456235537Sgberenum { 457235537Sgber NANDFS_CHECKPOINT, 458235537Sgber NANDFS_SNAPSHOT 459235537Sgber}; 460235537Sgber 461235537Sgber#define NANDFS_CPINFO_MAX 512 462235537Sgber 463235537Sgberstruct nandfs_cpinfo { 464235537Sgber uint32_t nci_flags; 465235537Sgber uint32_t nci_pad; 466235537Sgber uint64_t nci_cno; 467235537Sgber uint64_t nci_create; 468235537Sgber uint64_t nci_nblk_inc; 469235537Sgber uint64_t nci_blocks_count; 470235537Sgber uint64_t nci_next; 471235537Sgber}; 472235537Sgber 473235537Sgber#define NANDFS_SEGMENTS_MAX 512 474235537Sgber 475235537Sgberstruct nandfs_suinfo { 476235537Sgber uint64_t nsi_num; 477235537Sgber uint64_t nsi_lastmod; 478235537Sgber uint32_t nsi_blocks; 479235537Sgber uint32_t nsi_flags; 480235537Sgber}; 481235537Sgber 482235537Sgber#define NANDFS_VINFO_MAX 512 483235537Sgber 484235537Sgberstruct nandfs_vinfo { 485235537Sgber uint64_t nvi_ino; 486235537Sgber uint64_t nvi_vblocknr; 487235537Sgber uint64_t nvi_start; 488235537Sgber uint64_t nvi_end; 489235537Sgber uint64_t nvi_blocknr; 490235537Sgber int nvi_alive; 491235537Sgber}; 492235537Sgber 493235537Sgberstruct nandfs_cpmode { 494235537Sgber uint64_t ncpm_cno; 495235537Sgber uint32_t ncpm_mode; 496235537Sgber uint32_t ncpm_pad; 497235537Sgber}; 498235537Sgber 499235537Sgberstruct nandfs_argv { 500235537Sgber uint64_t nv_base; 501235537Sgber uint32_t nv_nmembs; 502235537Sgber uint16_t nv_size; 503235537Sgber uint16_t nv_flags; 504235537Sgber uint64_t nv_index; 505235537Sgber}; 506235537Sgber 507235537Sgberstruct nandfs_cpstat { 508235537Sgber uint64_t ncp_cno; 509235537Sgber uint64_t ncp_ncps; 510235537Sgber uint64_t ncp_nss; 511235537Sgber}; 512235537Sgber 513235537Sgberstruct nandfs_period { 514235537Sgber uint64_t p_start; 515235537Sgber uint64_t p_end; 516235537Sgber}; 517235537Sgber 518235537Sgberstruct nandfs_vdesc { 519235537Sgber uint64_t vd_ino; 520235537Sgber uint64_t vd_cno; 521235537Sgber uint64_t vd_vblocknr; 522235537Sgber struct nandfs_period vd_period; 523235537Sgber uint64_t vd_blocknr; 524235537Sgber uint64_t vd_offset; 525235537Sgber uint32_t vd_flags; 526235537Sgber uint32_t vd_pad; 527235537Sgber}; 528235537Sgber 529235537Sgberstruct nandfs_bdesc { 530235537Sgber uint64_t bd_ino; 531235537Sgber uint64_t bd_oblocknr; 532235537Sgber uint64_t bd_blocknr; 533235537Sgber uint64_t bd_offset; 534235537Sgber uint32_t bd_level; 535235537Sgber uint32_t bd_alive; 536235537Sgber}; 537235537Sgber 538235537Sgber#ifndef _KERNEL 539235537Sgber#ifndef MNAMELEN 540235537Sgber#define MNAMELEN 88 541235537Sgber#endif 542235537Sgber#endif 543235537Sgber 544235537Sgberstruct nandfs_fsinfo { 545235537Sgber struct nandfs_fsdata fs_fsdata; 546235537Sgber struct nandfs_super_block fs_super; 547235537Sgber char fs_dev[MNAMELEN]; 548235537Sgber}; 549235537Sgber 550235537Sgber#define NANDFS_MAX_MOUNTS 65535 551235537Sgber 552235537Sgber#define NANDFS_IOCTL_GET_SUSTAT _IOR('N', 100, struct nandfs_seg_stat) 553235537Sgber#define NANDFS_IOCTL_CHANGE_CPMODE _IOWR('N', 101, struct nandfs_cpmode) 554235537Sgber#define NANDFS_IOCTL_GET_CPINFO _IOWR('N', 102, struct nandfs_argv) 555235537Sgber#define NANDFS_IOCTL_DELETE_CP _IOWR('N', 103, uint64_t[2]) 556235537Sgber#define NANDFS_IOCTL_GET_CPSTAT _IOR('N', 104, struct nandfs_cpstat) 557235537Sgber#define NANDFS_IOCTL_GET_SUINFO _IOWR('N', 105, struct nandfs_argv) 558235537Sgber#define NANDFS_IOCTL_GET_VINFO _IOWR('N', 106, struct nandfs_argv) 559235537Sgber#define NANDFS_IOCTL_GET_BDESCS _IOWR('N', 107, struct nandfs_argv) 560235537Sgber#define NANDFS_IOCTL_GET_FSINFO _IOR('N', 108, struct nandfs_fsinfo) 561235537Sgber#define NANDFS_IOCTL_MAKE_SNAP _IOWR('N', 109, uint64_t) 562235537Sgber#define NANDFS_IOCTL_DELETE_SNAP _IOWR('N', 110, uint64_t) 563235537Sgber#define NANDFS_IOCTL_SYNC _IOWR('N', 111, uint64_t) 564235537Sgber 565235537Sgber#endif /* _NANDFS_FS_H */ 566