@@ -1242,6 +1242,92 @@ impl FatVolume {
1242
1242
block_cache. write_back ( ) . map_err ( Error :: DeviceError ) ?;
1243
1243
Ok ( ( ) )
1244
1244
}
1245
+
1246
+ /// Create a new directory.
1247
+ ///
1248
+ /// 1) Creates the directory entry in the parent
1249
+ /// 2) Allocates a new cluster to hold the new directory
1250
+ /// 3) Writes out the `.` and `..` entries in the new directory
1251
+ pub ( crate ) fn make_dir < D , T > (
1252
+ & mut self ,
1253
+ block_cache : & mut BlockCache < D > ,
1254
+ time_source : & T ,
1255
+ parent : ClusterId ,
1256
+ sfn : ShortFileName ,
1257
+ att : Attributes ,
1258
+ ) -> Result < ( ) , Error < D :: Error > >
1259
+ where
1260
+ D : BlockDevice ,
1261
+ T : TimeSource ,
1262
+ {
1263
+ let mut new_dir_entry_in_parent =
1264
+ self . write_new_directory_entry ( block_cache, time_source, parent, sfn, att) ?;
1265
+ if new_dir_entry_in_parent. cluster == ClusterId :: EMPTY {
1266
+ new_dir_entry_in_parent. cluster = self . alloc_cluster ( block_cache, None , false ) ?;
1267
+ // update the parent dir with the cluster of the new dir
1268
+ self . write_entry_to_disk ( block_cache, & new_dir_entry_in_parent) ?;
1269
+ }
1270
+ let new_dir_start_block = self . cluster_to_block ( new_dir_entry_in_parent. cluster ) ;
1271
+ debug ! ( "Made new dir entry {:?}" , new_dir_entry_in_parent) ;
1272
+ let now = time_source. get_timestamp ( ) ;
1273
+ let fat_type = self . get_fat_type ( ) ;
1274
+ // A blank block
1275
+ let block = block_cache. blank_mut ( new_dir_start_block) ;
1276
+ // make the "." entry
1277
+ let dot_entry_in_child = DirEntry {
1278
+ name : crate :: ShortFileName :: this_dir ( ) ,
1279
+ mtime : now,
1280
+ ctime : now,
1281
+ attributes : att,
1282
+ // point at ourselves
1283
+ cluster : new_dir_entry_in_parent. cluster ,
1284
+ size : 0 ,
1285
+ entry_block : new_dir_start_block,
1286
+ entry_offset : 0 ,
1287
+ } ;
1288
+ debug ! ( "New dir has {:?}" , dot_entry_in_child) ;
1289
+ let mut offset = 0 ;
1290
+ block[ offset..offset + OnDiskDirEntry :: LEN ]
1291
+ . copy_from_slice ( & dot_entry_in_child. serialize ( fat_type) [ ..] ) ;
1292
+ offset += OnDiskDirEntry :: LEN ;
1293
+ // make the ".." entry
1294
+ let dot_dot_entry_in_child = DirEntry {
1295
+ name : crate :: ShortFileName :: parent_dir ( ) ,
1296
+ mtime : now,
1297
+ ctime : now,
1298
+ attributes : att,
1299
+ // point at our parent
1300
+ cluster : match fat_type {
1301
+ FatType :: Fat16 => {
1302
+ // On FAT16, indicate parent is root using Cluster(0)
1303
+ if parent == ClusterId :: ROOT_DIR {
1304
+ ClusterId :: EMPTY
1305
+ } else {
1306
+ parent
1307
+ }
1308
+ }
1309
+ FatType :: Fat32 => parent,
1310
+ } ,
1311
+ size : 0 ,
1312
+ entry_block : new_dir_start_block,
1313
+ entry_offset : OnDiskDirEntry :: LEN_U32 ,
1314
+ } ;
1315
+ debug ! ( "New dir has {:?}" , dot_dot_entry_in_child) ;
1316
+ block[ offset..offset + OnDiskDirEntry :: LEN ]
1317
+ . copy_from_slice ( & dot_dot_entry_in_child. serialize ( fat_type) [ ..] ) ;
1318
+
1319
+ block_cache. write_back ( ) ?;
1320
+
1321
+ for block_idx in new_dir_start_block
1322
+ . range ( BlockCount ( u32:: from ( self . blocks_per_cluster ) ) )
1323
+ . skip ( 1 )
1324
+ {
1325
+ let _block = block_cache. blank_mut ( block_idx) ;
1326
+ block_cache. write_back ( ) ?;
1327
+ }
1328
+
1329
+ Ok ( ( ) )
1330
+ }
1245
1331
}
1246
1332
1247
1333
/// Load the boot parameter block from the start of the given partition and
0 commit comments