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