Skip to content

Commit b6b5bd5

Browse files
committed
Fixed resource leak reading volume labels.
1 parent 870ed18 commit b6b5bd5

File tree

1 file changed

+38
-15
lines changed

1 file changed

+38
-15
lines changed

src/volume_mgr.rs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,9 @@ where
218218
/// You can then read the directory entries with `iterate_dir`, or you can
219219
/// use `open_file_in_dir`.
220220
pub fn open_root_dir(&self, volume: RawVolume) -> Result<RawDirectory, Error<D::Error>> {
221-
// Opening a root directory twice is OK
221+
debug!("Opening root on {:?}", volume);
222222

223+
// Opening a root directory twice is OK
223224
let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?;
224225

225226
let directory_id = RawDirectory(data.id_generator.generate());
@@ -233,6 +234,8 @@ where
233234
.push(dir_info)
234235
.map_err(|_| Error::TooManyOpenDirs)?;
235236

237+
debug!("Opened root on {:?}, got {:?}", volume, directory_id);
238+
236239
Ok(directory_id)
237240
}
238241

@@ -312,6 +315,7 @@ where
312315
/// Close a directory. You cannot perform operations on an open directory
313316
/// and so must close it if you want to do something with it.
314317
pub fn close_dir(&self, directory: RawDirectory) -> Result<(), Error<D::Error>> {
318+
debug!("Closing {:?}", directory);
315319
let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?;
316320

317321
for (idx, info) in data.open_dirs.iter().enumerate() {
@@ -600,28 +604,47 @@ where
600604
Ok(())
601605
}
602606

603-
/// Search the root directory for a volume label
607+
/// Get the volume label
608+
///
609+
/// Will look in the BPB for a volume label, and if nothing is found, will
610+
/// search the root directory for a volume label.
604611
pub fn get_root_volume_label(
605612
&self,
606-
volume: RawVolume,
613+
raw_volume: RawVolume,
607614
) -> Result<Option<crate::VolumeName>, Error<D::Error>> {
608-
let directory = self.open_root_dir(volume)?;
615+
debug!("Reading volume label for {:?}", raw_volume);
616+
// prefer the one in the BPB - it's easier to get
609617
let data = self.data.borrow();
610-
// this can't fail - we literally just opened it
611-
let directory_idx = data
612-
.get_dir_by_id::<D::Error>(directory)
613-
.expect("Dir ID error");
614-
let volume_idx = data.get_volume_by_id(data.open_dirs[directory_idx].raw_volume)?;
615-
let mut maybe_volume_name = None;
618+
let volume_idx = data.get_volume_by_id(raw_volume)?;
616619
match &data.open_volumes[volume_idx].volume_type {
617620
VolumeType::Fat(fat) => {
618-
fat.iterate_dir(&self.block_device, &data.open_dirs[directory_idx], |de| {
619-
if de.attributes == Attributes::create_from_fat(Attributes::VOLUME) {
620-
maybe_volume_name = Some(unsafe { de.name.clone().to_volume_label() })
621-
}
622-
})?;
621+
if !fat.name.name().is_empty() {
622+
debug!(
623+
"Got volume label {:?} for {:?} from BPB",
624+
fat.name, raw_volume
625+
);
626+
return Ok(Some(fat.name.clone()));
627+
}
623628
}
624629
}
630+
drop(data);
631+
632+
// Nothing in the BPB, let's do it the slow way
633+
let root_dir = self.open_root_dir(raw_volume)?.to_directory(self);
634+
let mut maybe_volume_name = None;
635+
root_dir.iterate_dir(|de| {
636+
if maybe_volume_name.is_none()
637+
&& de.attributes == Attributes::create_from_fat(Attributes::VOLUME)
638+
{
639+
maybe_volume_name = Some(unsafe { de.name.clone().to_volume_label() })
640+
}
641+
})?;
642+
643+
debug!(
644+
"Got volume label {:?} for {:?} from root",
645+
maybe_volume_name, raw_volume
646+
);
647+
625648
Ok(maybe_volume_name)
626649
}
627650

0 commit comments

Comments
 (0)