axfs/
dev.rs

1use axdriver::prelude::*;
2
3const BLOCK_SIZE: usize = 512;
4
5/// A disk device with a cursor.
6pub struct Disk {
7    block_id: u64,
8    offset: usize,
9    dev: AxBlockDevice,
10}
11
12impl Disk {
13    /// Create a new disk.
14    pub fn new(dev: AxBlockDevice) -> Self {
15        assert_eq!(BLOCK_SIZE, dev.block_size());
16        Self {
17            block_id: 0,
18            offset: 0,
19            dev,
20        }
21    }
22
23    /// Get the size of the disk.
24    pub fn size(&self) -> u64 {
25        self.dev.num_blocks() * BLOCK_SIZE as u64
26    }
27
28    /// Get the position of the cursor.
29    pub fn position(&self) -> u64 {
30        self.block_id * BLOCK_SIZE as u64 + self.offset as u64
31    }
32
33    /// Set the position of the cursor.
34    pub fn set_position(&mut self, pos: u64) {
35        self.block_id = pos / BLOCK_SIZE as u64;
36        self.offset = pos as usize % BLOCK_SIZE;
37    }
38
39    /// Read within one block, returns the number of bytes read.
40    pub fn read_one(&mut self, buf: &mut [u8]) -> DevResult<usize> {
41        let read_size = if self.offset == 0 && buf.len() >= BLOCK_SIZE {
42            // whole block
43            self.dev
44                .read_block(self.block_id, &mut buf[0..BLOCK_SIZE])?;
45            self.block_id += 1;
46            BLOCK_SIZE
47        } else {
48            // partial block
49            let mut data = [0u8; BLOCK_SIZE];
50            let start = self.offset;
51            let count = buf.len().min(BLOCK_SIZE - self.offset);
52
53            self.dev.read_block(self.block_id, &mut data)?;
54            buf[..count].copy_from_slice(&data[start..start + count]);
55
56            self.offset += count;
57            if self.offset >= BLOCK_SIZE {
58                self.block_id += 1;
59                self.offset -= BLOCK_SIZE;
60            }
61            count
62        };
63        Ok(read_size)
64    }
65
66    /// Write within one block, returns the number of bytes written.
67    pub fn write_one(&mut self, buf: &[u8]) -> DevResult<usize> {
68        let write_size = if self.offset == 0 && buf.len() >= BLOCK_SIZE {
69            // whole block
70            self.dev.write_block(self.block_id, &buf[0..BLOCK_SIZE])?;
71            self.block_id += 1;
72            BLOCK_SIZE
73        } else {
74            // partial block
75            let mut data = [0u8; BLOCK_SIZE];
76            let start = self.offset;
77            let count = buf.len().min(BLOCK_SIZE - self.offset);
78
79            self.dev.read_block(self.block_id, &mut data)?;
80            data[start..start + count].copy_from_slice(&buf[..count]);
81            self.dev.write_block(self.block_id, &data)?;
82
83            self.offset += count;
84            if self.offset >= BLOCK_SIZE {
85                self.block_id += 1;
86                self.offset -= BLOCK_SIZE;
87            }
88            count
89        };
90        Ok(write_size)
91    }
92}