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 REDCORE_H 30 #define REDCORE_H 31 32 33 #include <redstat.h> 34 #include <redvolume.h> 35 #include "rednodes.h" 36 #include "redcoremacs.h" 37 #include "redcorevol.h" 38 39 40 #define META_SIG_MASTER ( 0x5453414DU ) /* 'MAST' */ 41 #define META_SIG_METAROOT ( 0x4154454DU ) /* 'META' */ 42 #define META_SIG_IMAP ( 0x50414D49U ) /* 'IMAP' */ 43 #define META_SIG_INODE ( 0x444F4E49U ) /* 'INOD' */ 44 #define META_SIG_DINDIR ( 0x494C4244U ) /* 'DBLI' */ 45 #define META_SIG_INDIR ( 0x49444E49U ) /* 'INDI' */ 46 47 48 REDSTATUS RedIoRead( uint8_t bVolNum, 49 uint32_t ulBlockStart, 50 uint32_t ulBlockCount, 51 void * pBuffer ); 52 #if REDCONF_READ_ONLY == 0 53 REDSTATUS RedIoWrite( uint8_t bVolNum, 54 uint32_t ulBlockStart, 55 uint32_t ulBlockCount, 56 const void * pBuffer ); 57 REDSTATUS RedIoFlush( uint8_t bVolNum ); 58 #endif 59 60 61 /** Indicates a block buffer is dirty (its contents are different than the 62 * contents of the corresponding block on disk); or, when passed into 63 * RedBufferGet(), indicates that the buffer should be marked dirty. 64 */ 65 #define BFLAG_DIRTY ( ( uint16_t ) 0x0001U ) 66 67 /** Tells RedBufferGet() that the buffer is for a newly allocated block, and its 68 * contents should be zeroed instead of being read from disk. Always used in 69 * combination with BFLAG_DIRTY. 70 */ 71 #define BFLAG_NEW ( ( uint16_t ) 0x0002U ) 72 73 /** Indicates that a block buffer is a master block (MASTERBLOCK) metadata node. 74 */ 75 #define BFLAG_META_MASTER ( ( uint16_t ) ( 0x0004U | BFLAG_META ) ) 76 77 /** Indicates that a block buffer is an imap (IMAPNODE) metadata node. 78 */ 79 #define BFLAG_META_IMAP ( ( uint16_t ) ( 0x0008U | BFLAG_META ) ) 80 81 /** Indicates that a block buffer is an inode (INODE) metadata node. 82 */ 83 #define BFLAG_META_INODE ( ( uint16_t ) ( 0x0010U | BFLAG_META ) ) 84 85 /** Indicates that a block buffer is an indirect (INDIR) metadata node. 86 */ 87 #define BFLAG_META_INDIR ( ( uint16_t ) ( 0x0020U | BFLAG_META ) ) 88 89 /** Indicates that a block buffer is a double indirect (DINDIR) metadata node. 90 */ 91 #define BFLAG_META_DINDIR ( ( uint16_t ) ( 0x0040U | BFLAG_META ) ) 92 93 /** Indicates that a block buffer is a metadata node. Callers of RedBufferGet() 94 * should not use this flag; instead, use one of the BFLAG_META_* flags. 95 */ 96 #define BFLAG_META ( ( uint16_t ) 0x8000U ) 97 98 99 void RedBufferInit( void ); 100 REDSTATUS RedBufferGet( uint32_t ulBlock, 101 uint16_t uFlags, 102 void ** ppBuffer ); 103 void RedBufferPut( const void * pBuffer ); 104 #if REDCONF_READ_ONLY == 0 105 REDSTATUS RedBufferFlush( uint32_t ulBlockStart, 106 uint32_t ulBlockCount ); 107 void RedBufferDirty( const void * pBuffer ); 108 void RedBufferBranch( const void * pBuffer, 109 uint32_t ulBlockNew ); 110 #if ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED 111 void RedBufferDiscard( const void * pBuffer ); 112 #endif 113 #endif 114 REDSTATUS RedBufferDiscardRange( uint32_t ulBlockStart, 115 uint32_t ulBlockCount ); 116 117 118 /** @brief Allocation state of a block. 119 */ 120 typedef enum 121 { 122 ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */ 123 ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */ 124 ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */ 125 ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */ 126 } ALLOCSTATE; 127 128 REDSTATUS RedImapBlockGet( uint8_t bMR, 129 uint32_t ulBlock, 130 bool * pfAllocated ); 131 #if REDCONF_READ_ONLY == 0 132 REDSTATUS RedImapBlockSet( uint32_t ulBlock, 133 bool fAllocated ); 134 REDSTATUS RedImapAllocBlock( uint32_t * pulBlock ); 135 #endif 136 REDSTATUS RedImapBlockState( uint32_t ulBlock, 137 ALLOCSTATE * pState ); 138 139 #if REDCONF_IMAP_INLINE == 1 140 REDSTATUS RedImapIBlockGet( uint8_t bMR, 141 uint32_t ulBlock, 142 bool * pfAllocated ); 143 REDSTATUS RedImapIBlockSet( uint32_t ulBlock, 144 bool fAllocated ); 145 #endif 146 147 #if REDCONF_IMAP_EXTERNAL == 1 148 REDSTATUS RedImapEBlockGet( uint8_t bMR, 149 uint32_t ulBlock, 150 bool * pfAllocated ); 151 REDSTATUS RedImapEBlockSet( uint32_t ulBlock, 152 bool fAllocated ); 153 uint32_t RedImapNodeBlock( uint8_t bMR, 154 uint32_t ulImapNode ); 155 #endif 156 157 158 /** @brief Cached inode structure. 159 */ 160 typedef struct 161 { 162 uint32_t ulInode; /**< The inode number of the cached inode. */ 163 #if REDCONF_API_POSIX == 1 164 bool fDirectory; /**< True if the inode is a directory. */ 165 #endif 166 #if REDCONF_READ_ONLY == 0 167 bool fBranched; /**< True if the inode is branched (writeable). */ 168 bool fDirty; /**< True if the inode buffer is dirty. */ 169 #endif 170 bool fCoordInited; /**< True after the first seek. */ 171 172 INODE * pInodeBuf; /**< Pointer to the inode buffer. */ 173 #if DINDIR_POINTERS > 0U 174 DINDIR * pDindir; /**< Pointer to the double indirect node buffer. */ 175 #endif 176 #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES 177 INDIR * pIndir; /**< Pointer to the indirect node buffer. */ 178 #endif 179 uint8_t * pbData; /**< Pointer to the data block buffer. */ 180 181 /* All the members below this point are part of the seek coordinates; see 182 * RedInodeDataSeek(). 183 */ 184 uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */ 185 #if DINDIR_POINTERS > 0U 186 uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */ 187 #endif 188 #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES 189 uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */ 190 #endif 191 uint32_t ulDataBlock; /**< Physical block number of the file data block. */ 192 193 uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */ 194 #if DINDIR_POINTERS > 0U 195 uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */ 196 #endif 197 #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES 198 uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */ 199 #endif 200 } CINODE; 201 202 #define CINODE_IS_MOUNTED( pInode ) ( ( ( pInode ) != NULL ) && INODE_IS_VALID( ( pInode )->ulInode ) && ( ( pInode )->pInodeBuf != NULL ) ) 203 #define CINODE_IS_DIRTY( pInode ) ( CINODE_IS_MOUNTED( pInode ) && ( pInode )->fDirty ) 204 205 206 #define IPUT_UPDATE_ATIME ( 0x01U ) 207 #define IPUT_UPDATE_MTIME ( 0x02U ) 208 #define IPUT_UPDATE_CTIME ( 0x04U ) 209 #define IPUT_UPDATE_MASK ( IPUT_UPDATE_ATIME | IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME ) 210 211 212 REDSTATUS RedInodeMount( CINODE * pInode, 213 FTYPE type, 214 bool fBranch ); 215 #if REDCONF_READ_ONLY == 0 216 REDSTATUS RedInodeBranch( CINODE * pInode ); 217 #endif 218 #if ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED ) 219 REDSTATUS RedInodeCreate( CINODE * pInode, 220 uint32_t ulPInode, 221 uint16_t uMode ); 222 #endif 223 #if DELETE_SUPPORTED 224 REDSTATUS RedInodeDelete( CINODE * pInode ); 225 REDSTATUS RedInodeLinkDec( CINODE * pInode ); 226 #endif 227 #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX == 1 ) 228 REDSTATUS RedInodeFree( CINODE * pInode ); 229 #endif 230 void RedInodePut( CINODE * pInode, 231 uint8_t bTimeFields ); 232 void RedInodePutCoord( CINODE * pInode ); 233 #if DINDIR_POINTERS > 0U 234 void RedInodePutDindir( CINODE * pInode ); 235 #endif 236 #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES 237 void RedInodePutIndir( CINODE * pInode ); 238 #endif 239 void RedInodePutData( CINODE * pInode ); 240 #if ( ( REDCONF_READ_ONLY == 0 ) && ( ( REDCONF_API_POSIX == 1 ) || FORMAT_SUPPORTED ) ) || ( REDCONF_CHECKER == 1 ) 241 REDSTATUS RedInodeIsFree( uint32_t ulInode, 242 bool * pfFree ); 243 #endif 244 REDSTATUS RedInodeBitGet( uint8_t bMR, 245 uint32_t ulInode, 246 uint8_t bWhich, 247 bool * pfAllocated ); 248 249 REDSTATUS RedInodeDataRead( CINODE * pInode, 250 uint64_t ullStart, 251 uint32_t * pulLen, 252 void * pBuffer ); 253 #if REDCONF_READ_ONLY == 0 254 REDSTATUS RedInodeDataWrite( CINODE * pInode, 255 uint64_t ullStart, 256 uint32_t * pulLen, 257 const void * pBuffer ); 258 #if DELETE_SUPPORTED || TRUNCATE_SUPPORTED 259 REDSTATUS RedInodeDataTruncate( CINODE * pInode, 260 uint64_t ullSize ); 261 #endif 262 #endif 263 REDSTATUS RedInodeDataSeekAndRead( CINODE * pInode, 264 uint32_t ulBlock ); 265 REDSTATUS RedInodeDataSeek( CINODE * pInode, 266 uint32_t ulBlock ); 267 268 #if REDCONF_API_POSIX == 1 269 #if REDCONF_READ_ONLY == 0 270 REDSTATUS RedDirEntryCreate( CINODE * pPInode, 271 const char * pszName, 272 uint32_t ulInode ); 273 #endif 274 #if DELETE_SUPPORTED 275 REDSTATUS RedDirEntryDelete( CINODE * pPInode, 276 uint32_t ulDeleteIdx ); 277 #endif 278 REDSTATUS RedDirEntryLookup( CINODE * pPInode, 279 const char * pszName, 280 uint32_t * pulEntryIdx, 281 uint32_t * pulInode ); 282 #if ( REDCONF_API_POSIX_READDIR == 1 ) || ( REDCONF_CHECKER == 1 ) 283 REDSTATUS RedDirEntryRead( CINODE * pPInode, 284 uint32_t * pulIdx, 285 char * pszName, 286 uint32_t * pulInode ); 287 #endif 288 #if ( REDCONF_READ_ONLY == 0 ) && ( REDCONF_API_POSIX_RENAME == 1 ) 289 REDSTATUS RedDirEntryRename( CINODE * pSrcPInode, 290 const char * pszSrcName, 291 CINODE * pSrcInode, 292 CINODE * pDstPInode, 293 const char * pszDstName, 294 CINODE * pDstInode ); 295 #endif 296 #endif /* if REDCONF_API_POSIX == 1 */ 297 298 REDSTATUS RedVolMount( void ); 299 REDSTATUS RedVolMountMaster( void ); 300 REDSTATUS RedVolMountMetaroot( void ); 301 #if REDCONF_READ_ONLY == 0 302 REDSTATUS RedVolTransact( void ); 303 #endif 304 void RedVolCriticalError( const char * pszFileName, 305 uint32_t ulLineNum ); 306 REDSTATUS RedVolSeqNumIncrement( void ); 307 308 #if FORMAT_SUPPORTED 309 REDSTATUS RedVolFormat( void ); 310 #endif 311 312 313 #endif /* ifndef REDCORE_H */ 314