From 39bd8cedaccde54781fc107d2fb61c994a3701c4 Mon Sep 17 00:00:00 2001 From: pigeonmoelleux <pigeonmoelleux@crans.org> Date: Sat, 20 May 2023 22:18:24 +0200 Subject: [PATCH] fix: some devices could be found several times --- src/fs/ext2/inode.rs | 22 +++++++++++----------- src/kernel/device/ata.rs | 4 ++++ src/kernel/device/mod.rs | 26 +++++++++++++++++++++++--- src/kernel/device/storage.rs | 8 ++++++++ 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/fs/ext2/inode.rs b/src/fs/ext2/inode.rs index 4673a65..073d348 100644 --- a/src/fs/ext2/inode.rs +++ b/src/fs/ext2/inode.rs @@ -182,36 +182,36 @@ bitflags! { /// Inode Flags pub struct Flags: u32 { /// Secure deletion (not used) - const SECURE_DELETION = 0x00000001; + const SECURE_DELETION = 0x0000_0001; /// Keep a copy of data when deleted (not used) - const DELETION_KEEP_DATA_COPY = 0x00000002; + const DELETION_KEEP_DATA_COPY = 0x0000_0002; /// File compression (not used) - const FILE_COMPRESSION = 0x00000004; + const FILE_COMPRESSION = 0x0000_0004; /// Synchronous updates—new data is written immediately to disk - const SYNCHRONOUS_UPDATES = 0x00000008; + const SYNCHRONOUS_UPDATES = 0x0000_0008; /// Immutable file (content cannot be changed) - const IMMUTABLE_FILE = 0x00000010; + const IMMUTABLE_FILE = 0x0000_0010; /// Append only - const APPEND_ONLY = 0x00000020; + const APPEND_ONLY = 0x0000_0020; /// File is not included in `dump` command - const DUMP_EXCLUDED = 0x00000040; + const DUMP_EXCLUDED = 0x0000_0040; /// Last accessed time should not updated - const LAST_ACCESSED_TIME_UPDATE_DISABLE = 0x00000080; + const LAST_ACCESSED_TIME_UPDATE_DISABLE = 0x0000_0080; /// Hash indexed directory - const HASHED_INDEXED_DIR = 0x00010000; + const HASHED_INDEXED_DIR = 0x0001_0000; /// AFS directory - const AFS_DIR = 0x00020000; + const AFS_DIR = 0x0002_0000; /// Journal file data - const JOURNAL_FILE_DATA = 0x000400000; + const JOURNAL_FILE_DATA = 0x0004_0000; } } diff --git a/src/kernel/device/ata.rs b/src/kernel/device/ata.rs index 9ed8312..1088fc8 100644 --- a/src/kernel/device/ata.rs +++ b/src/kernel/device/ata.rs @@ -1176,6 +1176,10 @@ impl Device for Drive { self.identify_data.user_addressable_sectors as usize } } + + fn uuid(&self) -> [u8; 20] { + self.identify_data.serial_number + } } impl Drive { diff --git a/src/kernel/device/mod.rs b/src/kernel/device/mod.rs index b5238fd..082fb9e 100644 --- a/src/kernel/device/mod.rs +++ b/src/kernel/device/mod.rs @@ -1,13 +1,15 @@ //! Device interface +use alloc::collections::BTreeMap; use alloc::sync::Arc; use alloc::vec::Vec; use conquer_once::spin::OnceCell; -use log::info; +use log::{info, warn}; use spin::Mutex; -use crate::kernel::device::ata::IdeController; +use self::ata::IdeController; +use self::storage::Uuid; #[allow(clippy::same_name_method)] mod ata; @@ -26,13 +28,31 @@ pub fn init() { info!("{} devices found during PCI scan", devices.len()); let storage_controllers = STORAGE_CONTROLLERS.get_or_init(|| { + let mut controllers = BTreeMap::<Vec<Uuid>, Arc<Mutex<dyn storage::Controller + Send>>>::new(); + + // To ensure each storage controller is only found once devices .values() .flatten() .filter_map(|device| { Some(Arc::new(Mutex::new(IdeController::new(device)?)) as Arc<Mutex<dyn storage::Controller + Send>>) }) - .collect::<Vec<Arc<Mutex<dyn storage::Controller + Send>>>>() + .for_each(|controller| { + let uuids = controller.lock().devices().iter().map(|device| device.lock().uuid()).collect(); + if let Some(controller) = controllers.insert(uuids, controller) { + warn!( + "The storage device controller {:?} has been found several times", + controller + .lock() + .devices() + .iter() + .map(|device| device.lock().uuid()) + .collect::<Vec<Uuid>>() + ); + } + }); + + controllers.into_values().collect() }); info!( diff --git a/src/kernel/device/storage.rs b/src/kernel/device/storage.rs index 4f138a4..95029ed 100644 --- a/src/kernel/device/storage.rs +++ b/src/kernel/device/storage.rs @@ -7,10 +7,18 @@ use spin::Mutex; use super::block::Manipulation; +/// Type alias representing a device UUID +pub type Uuid = [u8; 20]; + /// Represents storage devices such as hard drive, SSDs, etc. pub trait Device: Manipulation { /// Returns the size of the device in blocks fn size_in_blocks(&self) -> usize; + + /// Returns a unique identifier for the device + /// + /// This allows to be sure a same device will not be found several times. + fn uuid(&self) -> Uuid; } /// Represents a storage controller -- GitLab