Skip to content

Commit 8a8d52c

Browse files
authored
Merge pull request #158 from rust-embedded-community/move-make-dir-code
Move FAT-specific code in make_dir_in_dir (and fix .. entries)
2 parents 2c08eac + f497cc2 commit 8a8d52c

File tree

4 files changed

+102
-66
lines changed

4 files changed

+102
-66
lines changed

src/fat/volume.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,87 @@ impl FatVolume {
12421242
block_cache.write_back().map_err(Error::DeviceError)?;
12431243
Ok(())
12441244
}
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: if parent == ClusterId::ROOT_DIR {
1301+
// indicate parent is root using Cluster(0)
1302+
ClusterId::EMPTY
1303+
} else {
1304+
parent
1305+
},
1306+
size: 0,
1307+
entry_block: new_dir_start_block,
1308+
entry_offset: OnDiskDirEntry::LEN_U32,
1309+
};
1310+
debug!("New dir has {:?}", dot_dot_entry_in_child);
1311+
block[offset..offset + OnDiskDirEntry::LEN]
1312+
.copy_from_slice(&dot_dot_entry_in_child.serialize(fat_type)[..]);
1313+
1314+
block_cache.write_back()?;
1315+
1316+
for block_idx in new_dir_start_block
1317+
.range(BlockCount(u32::from(self.blocks_per_cluster)))
1318+
.skip(1)
1319+
{
1320+
let _block = block_cache.blank_mut(block_idx);
1321+
block_cache.write_back()?;
1322+
}
1323+
1324+
Ok(())
1325+
}
12451326
}
12461327

12471328
/// Load the boot parameter block from the start of the given partition and

src/volume_mgr.rs

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,79 +1070,14 @@ where
10701070
// Need mutable access for this
10711071
match &mut data.open_volumes[volume_idx].volume_type {
10721072
VolumeType::Fat(fat) => {
1073-
// TODO: Move this into the FAT volume code
10741073
debug!("Making dir entry");
1075-
let mut new_dir_entry_in_parent = fat.write_new_directory_entry(
1074+
fat.make_dir(
10761075
&mut data.block_cache,
10771076
&self.time_source,
10781077
parent_directory_info.cluster,
10791078
sfn,
10801079
att,
10811080
)?;
1082-
if new_dir_entry_in_parent.cluster == ClusterId::EMPTY {
1083-
new_dir_entry_in_parent.cluster =
1084-
fat.alloc_cluster(&mut data.block_cache, None, false)?;
1085-
// update the parent dir with the cluster of the new dir
1086-
fat.write_entry_to_disk(&mut data.block_cache, &new_dir_entry_in_parent)?;
1087-
}
1088-
let new_dir_start_block = fat.cluster_to_block(new_dir_entry_in_parent.cluster);
1089-
debug!("Made new dir entry {:?}", new_dir_entry_in_parent);
1090-
let now = self.time_source.get_timestamp();
1091-
let fat_type = fat.get_fat_type();
1092-
// A blank block
1093-
let block = data.block_cache.blank_mut(new_dir_start_block);
1094-
// make the "." entry
1095-
let dot_entry_in_child = DirEntry {
1096-
name: crate::ShortFileName::this_dir(),
1097-
mtime: now,
1098-
ctime: now,
1099-
attributes: att,
1100-
// point at ourselves
1101-
cluster: new_dir_entry_in_parent.cluster,
1102-
size: 0,
1103-
entry_block: new_dir_start_block,
1104-
entry_offset: 0,
1105-
};
1106-
debug!("New dir has {:?}", dot_entry_in_child);
1107-
let mut offset = 0;
1108-
block[offset..offset + fat::OnDiskDirEntry::LEN]
1109-
.copy_from_slice(&dot_entry_in_child.serialize(fat_type)[..]);
1110-
offset += fat::OnDiskDirEntry::LEN;
1111-
// make the ".." entry
1112-
let dot_dot_entry_in_child = DirEntry {
1113-
name: crate::ShortFileName::parent_dir(),
1114-
mtime: now,
1115-
ctime: now,
1116-
attributes: att,
1117-
// point at our parent
1118-
cluster: match fat_type {
1119-
fat::FatType::Fat16 => {
1120-
// On FAT16, indicate parent is root using Cluster(0)
1121-
if parent_directory_info.cluster == ClusterId::ROOT_DIR {
1122-
ClusterId::EMPTY
1123-
} else {
1124-
parent_directory_info.cluster
1125-
}
1126-
}
1127-
fat::FatType::Fat32 => parent_directory_info.cluster,
1128-
},
1129-
size: 0,
1130-
entry_block: new_dir_start_block,
1131-
entry_offset: fat::OnDiskDirEntry::LEN_U32,
1132-
};
1133-
debug!("New dir has {:?}", dot_dot_entry_in_child);
1134-
block[offset..offset + fat::OnDiskDirEntry::LEN]
1135-
.copy_from_slice(&dot_dot_entry_in_child.serialize(fat_type)[..]);
1136-
1137-
data.block_cache.write_back()?;
1138-
1139-
for block_idx in new_dir_start_block
1140-
.range(BlockCount(u32::from(fat.blocks_per_cluster)))
1141-
.skip(1)
1142-
{
1143-
let _block = data.block_cache.blank_mut(block_idx);
1144-
data.block_cache.write_back()?;
1145-
}
11461081
}
11471082
};
11481083

tests/directories.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ fn fat16_root_directory_listing() {
9898
},
9999
Some(String::from(".fseventsd")),
100100
),
101+
(
102+
ExpectedDirEntry {
103+
name: String::from("P-FAT16"),
104+
mtime: String::from("2024-10-30 18:43:12"),
105+
ctime: String::from("2024-10-30 18:43:12"),
106+
size: 0,
107+
is_dir: false,
108+
},
109+
None,
110+
),
101111
];
102112

103113
let mut listing = Vec::new();
@@ -266,6 +276,16 @@ fn fat32_root_directory_listing() {
266276
},
267277
Some(String::from(".fseventsd")),
268278
),
279+
(
280+
ExpectedDirEntry {
281+
name: String::from("P-FAT32"),
282+
mtime: String::from("2024-10-30 18:43:16"),
283+
ctime: String::from("2024-10-30 18:43:16"),
284+
size: 0,
285+
is_dir: false,
286+
},
287+
None,
288+
),
269289
(
270290
ExpectedDirEntry {
271291
name: String::from("THISIS~9"),

tests/disk.img.gz

4.46 KB
Binary file not shown.

0 commit comments

Comments
 (0)