Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue 74 #110

Merged
merged 2 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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