44
44
REDSTATUS RedVolFormat (void )
45
45
{
46
46
REDSTATUS ret ;
47
+ REDSTATUS ret2 ;
48
+ bool fBDevOpen = false;
49
+ bool fGeoInited = false;
47
50
48
51
if (gpRedVolume -> fMounted )
49
52
{
@@ -52,193 +55,200 @@ REDSTATUS RedVolFormat(void)
52
55
else
53
56
{
54
57
ret = RedBDevOpen (gbRedVolNum , BDEV_O_RDWR );
58
+ fBDevOpen = (ret == 0 );
55
59
}
56
60
57
61
if (ret == 0 )
58
62
{
59
- REDSTATUS ret2 ;
60
-
61
63
/* fReadOnly might still be true from the last time the volume was
62
64
mounted (or from the checker). Clear it now to avoid assertions in
63
65
lower-level code.
64
66
*/
65
67
gpRedVolume -> fReadOnly = false;
66
68
67
69
ret = RedVolInitGeometry ();
70
+ fGeoInited = (ret == 0 );
71
+ }
68
72
69
- if (ret == 0 )
70
- {
71
- MASTERBLOCK * pMB ;
72
-
73
- /* Overwrite the master block with zeroes, so that if formatting is
74
- interrupted, the volume will not be mountable.
75
- */
76
- ret = RedBufferGet (BLOCK_NUM_MASTER , BFLAG_NEW | BFLAG_DIRTY , CAST_VOID_PTR_PTR (& pMB ));
77
-
78
- if (ret == 0 )
79
- {
80
- ret = RedBufferFlush (BLOCK_NUM_MASTER , 1U );
73
+ if (ret == 0 )
74
+ {
75
+ MASTERBLOCK * pMB ;
81
76
82
- RedBufferDiscard (pMB );
83
- }
84
- }
77
+ /* Overwrite the master block with zeroes, so that if formatting is
78
+ interrupted, the volume will not be mountable.
79
+ */
80
+ ret = RedBufferGet (BLOCK_NUM_MASTER , BFLAG_NEW | BFLAG_DIRTY , CAST_VOID_PTR_PTR (& pMB ));
85
81
86
82
if (ret == 0 )
87
83
{
88
- ret = RedIoFlush (gbRedVolNum );
89
- }
90
-
91
- #if REDCONF_IMAP_EXTERNAL == 1
92
- if ((ret == 0 ) && !gpRedCoreVol -> fImapInline )
93
- {
94
- uint32_t ulImapBlock ;
95
- uint32_t ulImapBlockLimit = gpRedCoreVol -> ulImapStartBN + (gpRedCoreVol -> ulImapNodeCount * 2U );
96
- uint16_t uImapFlags = (uint16_t )((uint32_t )BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY );
97
-
98
- /* Technically it is only necessary to create one copy of each imap
99
- node (the copy the metaroot points at), but creating them both
100
- avoids headaches during disk image analysis from stale imaps
101
- left over from previous formats.
102
- */
103
- for (ulImapBlock = gpRedCoreVol -> ulImapStartBN ; ulImapBlock < ulImapBlockLimit ; ulImapBlock ++ )
104
- {
105
- IMAPNODE * pImap ;
106
-
107
- ret = RedBufferGet (ulImapBlock , uImapFlags , CAST_VOID_PTR_PTR (& pImap ));
108
- if (ret != 0 )
109
- {
110
- break ;
111
- }
84
+ ret = RedBufferFlush (BLOCK_NUM_MASTER , 1U );
112
85
113
- RedBufferPut (pImap );
114
- }
86
+ RedBufferDiscard (pMB );
115
87
}
116
- #endif
117
-
118
- /* Write the first metaroot.
119
- */
120
- if (ret == 0 )
121
- {
122
- RedMemSet (gpRedMR , 0U , sizeof (* gpRedMR ));
123
-
124
- gpRedMR -> ulFreeBlocks = gpRedVolume -> ulBlocksAllocable ;
125
- #if REDCONF_API_POSIX == 1
126
- gpRedMR -> ulFreeInodes = gpRedVolConf -> ulInodeCount ;
127
- #endif
128
- gpRedMR -> ulAllocNextBlock = gpRedCoreVol -> ulFirstAllocableBN ;
129
-
130
- /* The branched flag is typically set automatically when bits in
131
- the imap change. It is set here explicitly because the imap has
132
- only been initialized, not changed.
133
- */
134
- gpRedCoreVol -> fBranched = true;
88
+ }
135
89
136
- ret = RedVolTransact ();
137
- }
90
+ if (ret == 0 )
91
+ {
92
+ ret = RedIoFlush (gbRedVolNum );
93
+ }
138
94
139
- #if REDCONF_API_POSIX == 1
140
- /* Create the root directory.
95
+ #if REDCONF_IMAP_EXTERNAL == 1
96
+ if ((ret == 0 ) && !gpRedCoreVol -> fImapInline )
97
+ {
98
+ uint32_t ulImapBlock ;
99
+ uint32_t ulImapBlockLimit = gpRedCoreVol -> ulImapStartBN + (gpRedCoreVol -> ulImapNodeCount * 2U );
100
+ uint16_t uImapFlags = (uint16_t )((uint32_t )BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY );
101
+
102
+ /* Technically it is only necessary to create one copy of each imap
103
+ node (the copy the metaroot points at), but creating them both
104
+ avoids headaches during disk image analysis from stale imaps left
105
+ over from previous formats.
141
106
*/
142
- if ( ret == 0 )
107
+ for ( ulImapBlock = gpRedCoreVol -> ulImapStartBN ; ulImapBlock < ulImapBlockLimit ; ulImapBlock ++ )
143
108
{
144
- CINODE rootdir ;
109
+ IMAPNODE * pImap ;
145
110
146
- rootdir .ulInode = INODE_ROOTDIR ;
147
- ret = RedInodeCreate (& rootdir , INODE_INVALID , RED_S_IFDIR );
148
-
149
- if (ret == 0 )
111
+ ret = RedBufferGet (ulImapBlock , uImapFlags , CAST_VOID_PTR_PTR (& pImap ));
112
+ if (ret != 0 )
150
113
{
151
- RedInodePut ( & rootdir , 0U ) ;
114
+ break ;
152
115
}
116
+
117
+ RedBufferPut (pImap );
153
118
}
119
+ }
120
+ #endif
121
+
122
+ /* Write the first metaroot.
123
+ */
124
+ if (ret == 0 )
125
+ {
126
+ RedMemSet (gpRedMR , 0U , sizeof (* gpRedMR ));
127
+
128
+ gpRedMR -> ulFreeBlocks = gpRedVolume -> ulBlocksAllocable ;
129
+ #if REDCONF_API_POSIX == 1
130
+ gpRedMR -> ulFreeInodes = gpRedVolConf -> ulInodeCount ;
154
131
#endif
132
+ gpRedMR -> ulAllocNextBlock = gpRedCoreVol -> ulFirstAllocableBN ;
155
133
156
- #if REDCONF_API_FSE == 1
157
- /* The FSE API does not support creating or deletes files, so all the
158
- inodes are created during setup .
134
+ /* The branched flag is typically set automatically when bits in the
135
+ imap change. It is set here explicitly because the imap has only
136
+ been initialized, not changed .
159
137
*/
160
- if (ret == 0 )
161
- {
162
- uint32_t ulInodeIdx ;
138
+ gpRedCoreVol -> fBranched = true;
163
139
164
- for (ulInodeIdx = 0U ; ulInodeIdx < gpRedVolConf -> ulInodeCount ; ulInodeIdx ++ )
165
- {
166
- CINODE ino ;
140
+ ret = RedVolTransact ();
141
+ }
167
142
168
- ino .ulInode = INODE_FIRST_FREE + ulInodeIdx ;
169
- ret = RedInodeCreate (& ino , INODE_INVALID , RED_S_IFREG );
143
+ #if REDCONF_API_POSIX == 1
144
+ /* Create the root directory.
145
+ */
146
+ if (ret == 0 )
147
+ {
148
+ CINODE rootdir ;
170
149
171
- if (ret == 0 )
172
- {
173
- RedInodePut (& ino , 0U );
174
- }
175
- }
176
- }
177
- #endif
150
+ rootdir .ulInode = INODE_ROOTDIR ;
151
+ ret = RedInodeCreate (& rootdir , INODE_INVALID , RED_S_IFDIR );
178
152
179
- /* Write the second metaroot.
180
- */
181
153
if (ret == 0 )
182
154
{
183
- ret = RedVolTransact ( );
155
+ RedInodePut ( & rootdir , 0U );
184
156
}
157
+ }
158
+ #endif
185
159
186
- /* Populate and write out the master block.
187
- */
188
- if (ret == 0 )
160
+ #if REDCONF_API_FSE == 1
161
+ /* The FSE API does not support creating or deleting files, so all the
162
+ inodes are created during setup.
163
+ */
164
+ if (ret == 0 )
165
+ {
166
+ uint32_t ulInodeIdx ;
167
+
168
+ for (ulInodeIdx = 0U ; ulInodeIdx < gpRedVolConf -> ulInodeCount ; ulInodeIdx ++ )
189
169
{
190
- MASTERBLOCK * pMB ;
170
+ CINODE ino ;
171
+
172
+ ino .ulInode = INODE_FIRST_FREE + ulInodeIdx ;
173
+ ret = RedInodeCreate (& ino , INODE_INVALID , RED_S_IFREG );
191
174
192
- ret = RedBufferGet (BLOCK_NUM_MASTER , (uint16_t )((uint32_t )BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY ), CAST_VOID_PTR_PTR (& pMB ));
193
175
if (ret == 0 )
194
176
{
195
- pMB -> ulVersion = RED_DISK_LAYOUT_VERSION ;
196
- RedStrNCpy (pMB -> acBuildNum , RED_BUILD_NUMBER , sizeof (pMB -> acBuildNum ));
197
- pMB -> ulFormatTime = RedOsClockGetTime ();
198
- pMB -> ulInodeCount = gpRedVolConf -> ulInodeCount ;
199
- pMB -> ulBlockCount = gpRedVolume -> ulBlockCount ;
200
- pMB -> uMaxNameLen = REDCONF_NAME_MAX ;
201
- pMB -> uDirectPointers = REDCONF_DIRECT_POINTERS ;
202
- pMB -> uIndirectPointers = REDCONF_INDIRECT_POINTERS ;
203
- pMB -> bBlockSizeP2 = BLOCK_SIZE_P2 ;
204
-
205
- #if REDCONF_API_POSIX == 1
206
- pMB -> bFlags |= MBFLAG_API_POSIX ;
207
- #endif
208
- #if REDCONF_INODE_TIMESTAMPS == 1
209
- pMB -> bFlags |= MBFLAG_INODE_TIMESTAMPS ;
210
- #endif
211
- #if REDCONF_INODE_BLOCKS == 1
212
- pMB -> bFlags |= MBFLAG_INODE_BLOCKS ;
213
- #endif
214
- #if (REDCONF_API_POSIX == 1 ) && (REDCONF_API_POSIX_LINK == 1 )
215
- pMB -> bFlags |= MBFLAG_INODE_NLINK ;
216
- #endif
217
-
218
- ret = RedBufferFlush (BLOCK_NUM_MASTER , 1U );
219
-
220
- RedBufferPut (pMB );
177
+ RedInodePut (& ino , 0U );
221
178
}
222
179
}
180
+ }
181
+ #endif
182
+
183
+ /* Write the second metaroot.
184
+ */
185
+ if (ret == 0 )
186
+ {
187
+ ret = RedVolTransact ();
188
+ }
189
+
190
+ /* Populate and write out the master block.
191
+ */
192
+ if (ret == 0 )
193
+ {
194
+ MASTERBLOCK * pMB ;
223
195
196
+ ret = RedBufferGet (BLOCK_NUM_MASTER , (uint16_t )((uint32_t )BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY ), CAST_VOID_PTR_PTR (& pMB ));
224
197
if (ret == 0 )
225
198
{
226
- ret = RedIoFlush (gbRedVolNum );
199
+ pMB -> ulVersion = RED_DISK_LAYOUT_VERSION ;
200
+ RedStrNCpy (pMB -> acBuildNum , RED_BUILD_NUMBER , sizeof (pMB -> acBuildNum ));
201
+ pMB -> ulFormatTime = RedOsClockGetTime ();
202
+ pMB -> ulInodeCount = gpRedVolConf -> ulInodeCount ;
203
+ pMB -> ulBlockCount = gpRedVolume -> ulBlockCount ;
204
+ pMB -> uMaxNameLen = REDCONF_NAME_MAX ;
205
+ pMB -> uDirectPointers = REDCONF_DIRECT_POINTERS ;
206
+ pMB -> uIndirectPointers = REDCONF_INDIRECT_POINTERS ;
207
+ pMB -> bBlockSizeP2 = BLOCK_SIZE_P2 ;
208
+
209
+ #if REDCONF_API_POSIX == 1
210
+ pMB -> bFlags |= MBFLAG_API_POSIX ;
211
+ #endif
212
+ #if REDCONF_INODE_TIMESTAMPS == 1
213
+ pMB -> bFlags |= MBFLAG_INODE_TIMESTAMPS ;
214
+ #endif
215
+ #if REDCONF_INODE_BLOCKS == 1
216
+ pMB -> bFlags |= MBFLAG_INODE_BLOCKS ;
217
+ #endif
218
+ #if (REDCONF_API_POSIX == 1 ) && (REDCONF_API_POSIX_LINK == 1 )
219
+ pMB -> bFlags |= MBFLAG_INODE_NLINK ;
220
+ #endif
221
+
222
+ ret = RedBufferFlush (BLOCK_NUM_MASTER , 1U );
223
+
224
+ RedBufferPut (pMB );
227
225
}
226
+ }
228
227
228
+ if (ret == 0 )
229
+ {
230
+ ret = RedIoFlush (gbRedVolNum );
231
+ }
232
+
233
+ if (fBDevOpen )
234
+ {
229
235
ret2 = RedBDevClose (gbRedVolNum );
230
236
if (ret == 0 )
231
237
{
232
238
ret = ret2 ;
233
239
}
234
240
}
235
241
236
- /* Discard the buffers so a subsequent format will not run into blocks it
237
- does not expect.
238
- */
239
- if (ret == 0 )
242
+ if (fGeoInited )
240
243
{
241
- ret = RedBufferDiscardRange (0U , gpRedVolume -> ulBlockCount );
244
+ /* Discard the buffers so a subsequent format will not run into blocks
245
+ it does not expect.
246
+ */
247
+ ret2 = RedBufferDiscardRange (0U , gpRedVolume -> ulBlockCount );
248
+ if (ret == 0 )
249
+ {
250
+ ret = ret2 ;
251
+ }
242
252
}
243
253
244
254
return ret ;
0 commit comments