Skip to content

Commit

Permalink
Merge pull request #110 from rust-embedded-community/fix-issue-74
Browse files Browse the repository at this point in the history
Fix issue 74
  • Loading branch information
thejpster authored Dec 17, 2023
2 parents 3a459d7 + 819a624 commit 85d32e6
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
39 changes: 39 additions & 0 deletions examples/big_dir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
extern crate embedded_sdmmc;

mod linux;
use linux::*;

use embedded_sdmmc::{Error, VolumeManager};

fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
env_logger::init();
let mut args = std::env::args().skip(1);
let filename = args.next().unwrap_or_else(|| "/dev/mmcblk0".into());
let print_blocks = args.find(|x| x == "-v").map(|_| true).unwrap_or(false);
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
let mut volume = volume_mgr
.open_volume(embedded_sdmmc::VolumeIdx(1))
.unwrap();
println!("Volume: {:?}", volume);
let mut root_dir = volume.open_root_dir().unwrap();

let mut file_num = 0;
loop {
file_num += 1;
let file_name = format!("{}.da", file_num);
println!("opening file {file_name} for writing");
let mut file = root_dir
.open_file_in_dir(
file_name.as_str(),
embedded_sdmmc::Mode::ReadWriteCreateOrTruncate,
)
.unwrap();
let buf = b"hello world, from rust";
println!("writing to file");
file.write(&buf[..]).unwrap();
println!("closing file");
drop(file);
}
}
20 changes: 16 additions & 4 deletions src/fat/volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ impl FatVolume {
where
D: BlockDevice,
{
if cluster.0 > (u32::MAX / 4) {
panic!("next_cluster called on invalid cluster {:x?}", cluster);
}
match &self.fat_specific_info {
FatSpecificInfo::Fat16(_fat16_info) => {
let fat_offset = cluster.0 * 2;
Expand Down Expand Up @@ -360,19 +363,24 @@ impl FatVolume {
FatSpecificInfo::Fat32(fat32_info) => {
// All directories on FAT32 have a cluster chain but the root
// dir starts in a specified cluster.
let mut first_dir_block_num = match dir.cluster {
ClusterId::ROOT_DIR => self.cluster_to_block(fat32_info.first_root_dir_cluster),
_ => self.cluster_to_block(dir.cluster),
let mut current_cluster = match dir.cluster {
ClusterId::ROOT_DIR => Some(fat32_info.first_root_dir_cluster),
_ => Some(dir.cluster),
};
let mut current_cluster = Some(dir.cluster);
let mut first_dir_block_num = self.cluster_to_block(dir.cluster);
let mut blocks = [Block::new()];

let dir_size = BlockCount(u32::from(self.blocks_per_cluster));
// Walk the cluster chain until we run out of clusters
while let Some(cluster) = current_cluster {
// Loop through the blocks in the cluster
for block in first_dir_block_num.range(dir_size) {
// Read a block of directory entries
block_device
.read(&mut blocks, block, "read_dir")
.map_err(Error::DeviceError)?;
// Are any entries in the block we just loaded blank? If so
// we can use them.
for entry in 0..Block::LEN / OnDiskDirEntry::LEN {
let start = entry * OnDiskDirEntry::LEN;
let end = (entry + 1) * OnDiskDirEntry::LEN;
Expand All @@ -397,6 +405,8 @@ impl FatVolume {
}
}
}
// Well none of the blocks in that cluster had any space in
// them, let's fetch another one.
let mut block_cache = BlockCache::empty();
current_cluster =
match self.next_cluster(block_device, cluster, &mut block_cache) {
Expand All @@ -412,6 +422,8 @@ impl FatVolume {
_ => None,
};
}
// We ran out of clusters in the chain, and apparently we weren't
// able to make the chain longer, so the disk must be full.
Err(Error::NotEnoughSpace)
}
}
Expand Down

0 comments on commit 85d32e6

Please sign in to comment.