storage/driver-block: Make Disk::block_length infallible
It should be read when creating the struct implementing Disk and every disk needs to have some block length.
This commit is contained in:
@@ -178,7 +178,7 @@ impl Disk for DiskATA {
|
||||
}
|
||||
}
|
||||
|
||||
fn block_length(&mut self) -> Result<u32> {
|
||||
Ok(512)
|
||||
fn block_length(&mut self) -> u32 {
|
||||
512
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ pub struct DiskATAPI {
|
||||
// Just using the same buffer size as DiskATA
|
||||
// Although the sector size is different (and varies)
|
||||
buf: Dma<[u8; 256 * 512]>,
|
||||
blk_count: u32,
|
||||
blk_size: u32,
|
||||
}
|
||||
|
||||
impl DiskATAPI {
|
||||
@@ -38,12 +40,20 @@ impl DiskATAPI {
|
||||
.unwrap_or_else(|_| unreachable!());
|
||||
|
||||
let mut fb = unsafe { Dma::zeroed()?.assume_init() };
|
||||
let buf = unsafe { Dma::zeroed()?.assume_init() };
|
||||
let mut buf = unsafe { Dma::zeroed()?.assume_init() };
|
||||
|
||||
port.init(&mut clb, &mut ctbas, &mut fb);
|
||||
|
||||
let size = unsafe { port.identify_packet(&mut clb, &mut ctbas).unwrap_or(0) };
|
||||
|
||||
let mut cmd = [0; 16];
|
||||
cmd[0] = SCSI_READ_CAPACITY;
|
||||
port.atapi_dma(&cmd, 8, &mut clb, &mut ctbas, &mut buf)?;
|
||||
|
||||
// Instead of a count, contains number of last LBA, so add 1
|
||||
let blk_count = BigEndian::read_u32(&buf[0..4]) + 1;
|
||||
let blk_size = BigEndian::read_u32(&buf[4..8]);
|
||||
|
||||
Ok(DiskATAPI {
|
||||
id,
|
||||
port,
|
||||
@@ -52,37 +62,25 @@ impl DiskATAPI {
|
||||
ctbas,
|
||||
_fb: fb,
|
||||
buf,
|
||||
blk_count,
|
||||
blk_size,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_capacity(&mut self) -> Result<(u32, u32)> {
|
||||
// TODO: only query when needed (disk changed)
|
||||
|
||||
let mut cmd = [0; 16];
|
||||
cmd[0] = SCSI_READ_CAPACITY;
|
||||
self.port
|
||||
.atapi_dma(&cmd, 8, &mut self.clb, &mut self.ctbas, &mut self.buf)?;
|
||||
|
||||
// Instead of a count, contains number of last LBA, so add 1
|
||||
let blk_count = BigEndian::read_u32(&self.buf[0..4]) + 1;
|
||||
let blk_size = BigEndian::read_u32(&self.buf[4..8]);
|
||||
|
||||
Ok((blk_count, blk_size))
|
||||
}
|
||||
}
|
||||
|
||||
impl Disk for DiskATAPI {
|
||||
fn block_length(&mut self) -> u32 {
|
||||
self.blk_size
|
||||
}
|
||||
|
||||
fn size(&mut self) -> u64 {
|
||||
match self.read_capacity() {
|
||||
Ok((blk_count, blk_size)) => (blk_count as u64) * (blk_size as u64),
|
||||
Err(_) => 0, // XXX
|
||||
}
|
||||
u64::from(self.blk_count) * u64::from(self.blk_size)
|
||||
}
|
||||
|
||||
fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result<Option<usize>> {
|
||||
// TODO: Handle audio CDs, which use special READ CD command
|
||||
|
||||
let blk_len = self.block_length()?;
|
||||
let blk_len = self.blk_size;
|
||||
let sectors = buffer.len() as u32 / blk_len;
|
||||
|
||||
fn read10_cmd(block: u32, count: u16) -> [u8; 16] {
|
||||
@@ -147,8 +145,4 @@ impl Disk for DiskATAPI {
|
||||
fn write(&mut self, _block: u64, _buffer: &[u8]) -> Result<Option<usize>> {
|
||||
Err(Error::new(EBADF)) // TODO: Implement writing
|
||||
}
|
||||
|
||||
fn block_length(&mut self) -> Result<u32> {
|
||||
Ok(self.read_capacity()?.1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ impl SchemeBlock for DiskScheme {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
stat.st_mode = MODE_FILE;
|
||||
stat.st_size = disk.size();
|
||||
stat.st_blksize = disk.block_length()?;
|
||||
stat.st_blksize = disk.block_length();
|
||||
Ok(Some(0))
|
||||
}
|
||||
Handle::Partition(disk_id, part_num) => {
|
||||
@@ -190,8 +190,8 @@ impl SchemeBlock for DiskScheme {
|
||||
};
|
||||
|
||||
stat.st_mode = MODE_FILE; // TODO: Block device?
|
||||
stat.st_size = size * u64::from(disk.block_length()?);
|
||||
stat.st_blksize = disk.block_length()?;
|
||||
stat.st_size = size * u64::from(disk.block_length());
|
||||
stat.st_blksize = disk.block_length();
|
||||
stat.st_blocks = size;
|
||||
Ok(Some(0))
|
||||
}
|
||||
@@ -263,12 +263,12 @@ impl SchemeBlock for DiskScheme {
|
||||
}
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
let blk_len = disk.block_length();
|
||||
disk.read(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
let blksize = disk.block_length();
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = offset / u64::from(blksize);
|
||||
@@ -304,12 +304,12 @@ impl SchemeBlock for DiskScheme {
|
||||
Handle::List(_) => Err(Error::new(EBADF)),
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
let blk_len = disk.block_length();
|
||||
disk.write(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
let blksize = disk.block_length();
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = offset / u64::from(blksize);
|
||||
@@ -351,7 +351,7 @@ impl SchemeBlock for DiskScheme {
|
||||
.get(part_num as usize)
|
||||
.ok_or(Error::new(EBADF))?
|
||||
.size;
|
||||
u64::from(disk.block_length()?) * block_count
|
||||
u64::from(disk.block_length()) * block_count
|
||||
}
|
||||
},
|
||||
))
|
||||
|
||||
@@ -164,7 +164,7 @@ impl SchemeBlock for DiskScheme {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
stat.st_mode = MODE_FILE;
|
||||
stat.st_size = disk.size();
|
||||
stat.st_blksize = disk.block_length()?;
|
||||
stat.st_blksize = disk.block_length();
|
||||
Ok(Some(0))
|
||||
}
|
||||
Handle::Partition(disk_id, part_num) => {
|
||||
@@ -179,8 +179,8 @@ impl SchemeBlock for DiskScheme {
|
||||
};
|
||||
|
||||
stat.st_mode = MODE_FILE; // TODO: Block device?
|
||||
stat.st_size = size * u64::from(disk.block_length()?);
|
||||
stat.st_blksize = disk.block_length()?;
|
||||
stat.st_size = size * u64::from(disk.block_length());
|
||||
stat.st_blksize = disk.block_length();
|
||||
stat.st_blocks = size;
|
||||
Ok(Some(0))
|
||||
}
|
||||
@@ -251,12 +251,12 @@ impl SchemeBlock for DiskScheme {
|
||||
}
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
let blk_len = disk.block_length();
|
||||
disk.read(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
let blksize = disk.block_length();
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = offset / u64::from(blksize);
|
||||
@@ -285,12 +285,12 @@ impl SchemeBlock for DiskScheme {
|
||||
Handle::List(_) => Err(Error::new(EBADF)),
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
let blk_len = disk.block_length();
|
||||
disk.write(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
let blksize = disk.block_length();
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = offset / u64::from(blksize as u64);
|
||||
@@ -331,7 +331,7 @@ impl SchemeBlock for DiskScheme {
|
||||
.get(part_num as usize)
|
||||
.ok_or(Error::new(EBADF))?
|
||||
.size;
|
||||
Ok(Some(u64::from(disk.block_length()?) * block_count))
|
||||
Ok(Some(u64::from(disk.block_length()) * block_count))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,7 +774,7 @@ impl Disk for SdHostCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
fn block_length(&mut self) -> Result<u32> {
|
||||
Ok(512)
|
||||
fn block_length(&mut self) -> u32 {
|
||||
512
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ fn block_read(
|
||||
}
|
||||
|
||||
pub trait Disk {
|
||||
fn block_length(&mut self) -> syscall::error::Result<u32>;
|
||||
fn block_length(&mut self) -> u32;
|
||||
fn size(&mut self) -> u64;
|
||||
|
||||
fn read(&mut self, block: u64, buffer: &mut [u8]) -> syscall::Result<Option<usize>>;
|
||||
@@ -68,8 +68,8 @@ pub struct DiskWrapper {
|
||||
impl DiskWrapper {
|
||||
pub fn pt(disk: &mut dyn Disk) -> Option<PartitionTable> {
|
||||
let bs = match disk.block_length() {
|
||||
Ok(512) => LogicalBlockSize::Lb512,
|
||||
Ok(4096) => LogicalBlockSize::Lb4096,
|
||||
512 => LogicalBlockSize::Lb512,
|
||||
4096 => LogicalBlockSize::Lb4096,
|
||||
_ => return None,
|
||||
};
|
||||
struct Device<'a> {
|
||||
@@ -98,10 +98,7 @@ impl DiskWrapper {
|
||||
// TODO: Perhaps this impl should be used in the rest of the scheme.
|
||||
impl<'a> Read for Device<'a> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let blksize = self
|
||||
.disk
|
||||
.block_length()
|
||||
.map_err(|err| io::Error::from_raw_os_error(err.errno))?;
|
||||
let blksize = self.disk.block_length();
|
||||
let size_in_blocks = self.disk.size() / u64::from(blksize);
|
||||
|
||||
let disk = &mut self.disk;
|
||||
|
||||
@@ -461,7 +461,7 @@ impl Disk for AtaDisk {
|
||||
Ok(Some(count))
|
||||
}
|
||||
|
||||
fn block_length(&mut self) -> Result<u32> {
|
||||
Ok(512)
|
||||
fn block_length(&mut self) -> u32 {
|
||||
512
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ impl SchemeBlock for DiskScheme {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
stat.st_mode = MODE_FILE;
|
||||
stat.st_size = disk.size();
|
||||
stat.st_blksize = disk.block_length()?;
|
||||
stat.st_blksize = disk.block_length();
|
||||
Ok(Some(0))
|
||||
}
|
||||
Handle::Partition(disk_id, part_num) => {
|
||||
@@ -193,8 +193,8 @@ impl SchemeBlock for DiskScheme {
|
||||
};
|
||||
|
||||
stat.st_mode = MODE_FILE; // TODO: Block device?
|
||||
stat.st_size = size * u64::from(disk.block_length()?);
|
||||
stat.st_blksize = disk.block_length()?;
|
||||
stat.st_size = size * u64::from(disk.block_length());
|
||||
stat.st_blksize = disk.block_length();
|
||||
stat.st_blocks = size;
|
||||
Ok(Some(0))
|
||||
}
|
||||
@@ -265,12 +265,12 @@ impl SchemeBlock for DiskScheme {
|
||||
}
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
let blk_len = disk.block_length();
|
||||
disk.read(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
let blksize = disk.block_length();
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = offset / u64::from(blksize);
|
||||
@@ -299,12 +299,12 @@ impl SchemeBlock for DiskScheme {
|
||||
Handle::List(_) => Err(Error::new(EBADF)),
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
let blk_len = disk.block_length();
|
||||
disk.write(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
let blksize = disk.block_length();
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = offset / u64::from(blksize as u64);
|
||||
@@ -345,7 +345,7 @@ impl SchemeBlock for DiskScheme {
|
||||
.get(part_num as usize)
|
||||
.ok_or(Error::new(EBADF))?
|
||||
.size;
|
||||
Ok(Some(u64::from(disk.block_length()?) * block_count))
|
||||
Ok(Some(u64::from(disk.block_length()) * block_count))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ enum Handle {
|
||||
struct NamespaceAndNvme<'a>(&'a Nvme, NvmeNamespace);
|
||||
|
||||
impl Disk for NamespaceAndNvme<'_> {
|
||||
fn block_length(&mut self) -> syscall::error::Result<u32> {
|
||||
Ok(self.1.block_size.try_into().unwrap())
|
||||
fn block_length(&mut self) -> u32 {
|
||||
self.1.block_size.try_into().unwrap()
|
||||
}
|
||||
|
||||
fn size(&mut self) -> u64 {
|
||||
|
||||
@@ -124,8 +124,8 @@ impl<'a> DiskScheme<'a> {
|
||||
}
|
||||
|
||||
impl driver_block::Disk for DiskScheme<'_> {
|
||||
fn block_length(&mut self) -> syscall::error::Result<u32> {
|
||||
Ok(self.cfg.block_size())
|
||||
fn block_length(&mut self) -> u32 {
|
||||
self.cfg.block_size()
|
||||
}
|
||||
|
||||
fn size(&mut self) -> u64 {
|
||||
|
||||
Reference in New Issue
Block a user