1 /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- 2 * 3 * Copyright (c) 2014-2015 Datalight, Inc. 4 * All Rights Reserved Worldwide. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; use version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 /* Businesses and individuals that for commercial or other reasons cannot 21 * comply with the terms of the GPLv2 license may obtain a commercial license 22 * before incorporating Reliance Edge into proprietary software for 23 * distribution in any form. Visit http://www.datalight.com/reliance-edge for 24 * more information. 25 */ 26 27 /** @file 28 */ 29 #ifndef REDNODES_H 30 #define REDNODES_H 31 32 33 #define NODEHEADER_SIZE ( 16U ) 34 #define NODEHEADER_OFFSET_SIG ( 0U ) 35 #define NODEHEADER_OFFSET_CRC ( 4U ) 36 #define NODEHEADER_OFFSET_SEQ ( 8U ) 37 38 /** @brief Common header for all metadata nodes. 39 */ 40 typedef struct 41 { 42 uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */ 43 uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */ 44 uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */ 45 } NODEHEADER; 46 47 48 /** Flag set in the master block when REDCONF_API_POSIX == 1. */ 49 #define MBFLAG_API_POSIX ( 0x01U ) 50 51 /** Flag set in the master block when REDCONF_INODE_TIMESTAMPS == 1. */ 52 #define MBFLAG_INODE_TIMESTAMPS ( 0x02U ) 53 54 /** Flag set in the master block when REDCONF_INODE_BLOCKS == 1. */ 55 #define MBFLAG_INODE_BLOCKS ( 0x04U ) 56 57 /** Flag set in the master block when (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1). */ 58 #define MBFLAG_INODE_NLINK ( 0x08U ) 59 60 61 /** @brief Node which identifies the volume and stores static volume information. 62 */ 63 typedef struct 64 { 65 NODEHEADER hdr; /**< Common node header. */ 66 67 uint32_t ulVersion; /**< On-disk layout version number. */ 68 char acBuildNum[ 8U ]; /**< Build number of the product (not null terminated). */ 69 uint32_t ulFormatTime; /**< Date and time the volume was formatted. */ 70 uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */ 71 uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */ 72 uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */ 73 uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */ 74 uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */ 75 uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */ 76 uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */ 77 } MASTERBLOCK; 78 79 80 #if REDCONF_API_POSIX == 1 81 #define METAROOT_HEADER_SIZE ( NODEHEADER_SIZE + 16U ) /* Size in bytes of the metaroot header fields. */ 82 #else 83 #define METAROOT_HEADER_SIZE ( NODEHEADER_SIZE + 12U ) /* Size in bytes of the metaroot header fields. */ 84 #endif 85 #define METAROOT_ENTRY_BYTES ( REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE ) /* Number of bytes remaining in the metaroot block for entries. */ 86 #define METAROOT_ENTRIES ( METAROOT_ENTRY_BYTES * 8U ) 87 88 /** @brief Metadata root node; each volume has two. 89 */ 90 typedef struct 91 { 92 NODEHEADER hdr; /**< Common node header. */ 93 94 uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */ 95 uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */ 96 #if REDCONF_API_POSIX == 1 97 uint32_t ulFreeInodes; /**< Number of inode slots that are free. */ 98 #endif 99 uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */ 100 101 /** Imap bitmap. With inline imaps, this is the imap bitmap that indicates 102 * which inode blocks are used and which allocable blocks are used. 103 * Otherwise, this bitmap toggles nodes in the external imap between one 104 * of two possible block locations. 105 */ 106 uint8_t abEntries[ METAROOT_ENTRY_BYTES ]; 107 } METAROOT; 108 109 110 #if REDCONF_IMAP_EXTERNAL == 1 111 #define IMAPNODE_HEADER_SIZE ( NODEHEADER_SIZE ) /* Size in bytes of the imap node header fields. */ 112 #define IMAPNODE_ENTRY_BYTES ( REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE ) /* Number of bytes remaining in the imap node for entries. */ 113 #define IMAPNODE_ENTRIES ( IMAPNODE_ENTRY_BYTES * 8U ) 114 115 /** @brief One node of the external imap. 116 */ 117 typedef struct 118 { 119 NODEHEADER hdr; /**< Common node header. */ 120 121 /** Bitmap which indicates which inode blocks are used and which allocable 122 * blocks are used. 123 */ 124 uint8_t abEntries[ IMAPNODE_ENTRY_BYTES ]; 125 } IMAPNODE; 126 #endif /* if REDCONF_IMAP_EXTERNAL == 1 */ 127 128 129 #define INODE_HEADER_SIZE \ 130 ( NODEHEADER_SIZE + 8U + ( ( REDCONF_INODE_BLOCKS == 1 ) ? 4U : 0U ) + \ 131 ( ( REDCONF_INODE_TIMESTAMPS == 1 ) ? 12U : 0U ) + 4U + ( ( REDCONF_API_POSIX == 1 ) ? 4U : 0U ) ) 132 #define INODE_ENTRIES ( ( REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE ) / 4U ) 133 134 #if ( REDCONF_DIRECT_POINTERS < 0 ) || ( REDCONF_DIRECT_POINTERS > ( INODE_ENTRIES - REDCONF_INDIRECT_POINTERS ) ) 135 #error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS" 136 #endif 137 #if ( REDCONF_INDIRECT_POINTERS < 0 ) || ( REDCONF_INDIRECT_POINTERS > ( INODE_ENTRIES - REDCONF_DIRECT_POINTERS ) ) 138 #error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS" 139 #endif 140 141 /** @brief Stores metadata for a file or directory. 142 */ 143 typedef struct 144 { 145 NODEHEADER hdr; /**< Common node header. */ 146 147 uint64_t ullSize; /**< Size of the inode, in bytes. */ 148 #if REDCONF_INODE_BLOCKS == 1 149 uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */ 150 #endif 151 #if REDCONF_INODE_TIMESTAMPS == 1 152 uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */ 153 uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */ 154 uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */ 155 #endif 156 uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */ 157 #if ( REDCONF_API_POSIX == 1 ) && ( REDCONF_API_POSIX_LINK == 1 ) 158 uint16_t uNLink; /**< Link count, number of names pointing to the inode. */ 159 #else 160 uint8_t abPadding[ 2 ]; /**< Padding to 32-bit align the next member. */ 161 #endif 162 #if REDCONF_API_POSIX == 1 163 uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */ 164 #endif 165 166 /** Block numbers for lower levels of the file metadata structure. Some 167 * fraction of these entries are for direct pointers (file data block 168 * numbers), some for indirect pointers, some for double-indirect 169 * pointers; the number allocated to each is static but user-configurable. 170 * For all types, an array slot is zero if the range is sparse or beyond 171 * the end of file. 172 */ 173 uint32_t aulEntries[ INODE_ENTRIES ]; 174 } INODE; 175 176 177 #define INDIR_HEADER_SIZE ( NODEHEADER_SIZE + 4U ) 178 #define INDIR_ENTRIES ( ( REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE ) / 4U ) 179 180 /** @brief Node for storing block pointers. 181 */ 182 typedef struct 183 { 184 NODEHEADER hdr; /**< Common node header. */ 185 186 uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */ 187 188 /** For indirect nodes, stores block numbers of file data. For double 189 * indirect nodes, stores block numbers of indirect nodes. An array 190 * slot is zero if the corresponding block or indirect range is beyond 191 * the end of file or entirely sparse. 192 */ 193 uint32_t aulEntries[ INDIR_ENTRIES ]; 194 } INDIR, DINDIR; 195 196 197 #endif /* ifndef REDNODES_H */ 198