1use crate::config::VIRTIO_BLK_SECTOR_SIZE;
6use crate::device::block::BlockDriver;
7use alloc::sync::Arc;
8use alloc::vec::Vec;
9
10pub struct BlockDeviceAdapter {
11 inner: Arc<dyn BlockDriver>,
12 block_size: usize,
14 sector_size: usize,
16}
17
18impl BlockDeviceAdapter {
19 pub fn new(device: Arc<dyn BlockDriver>, block_size: usize) -> Self {
20 let sector_size = VIRTIO_BLK_SECTOR_SIZE;
21 crate::pr_info!(
22 "[Ext4Adapter] Created adapter: ext4_block_size={}, sector_size={}",
23 block_size,
24 sector_size
25 );
26
27 assert!(
29 block_size % sector_size == 0,
30 "Block size must be a multiple of sector size"
31 );
32
33 Self {
34 inner: device,
35 block_size,
36 sector_size,
37 }
38 }
39}
40
41impl ext4_rs::BlockDevice for BlockDeviceAdapter {
42 fn read_offset(&self, offset: usize) -> Vec<u8> {
43 let start_sector = offset / self.sector_size;
48 let sector_offset = offset % self.sector_size;
49
50 let bytes_needed = self.block_size;
52 let sectors_needed =
53 (sector_offset + bytes_needed + self.sector_size - 1) / self.sector_size;
54
55 let mut buffer = alloc::vec![0u8; sectors_needed * self.sector_size];
57 for i in 0..sectors_needed {
58 let sector_id = start_sector + i;
59 let buf_offset = i * self.sector_size;
60 let sector_buf = &mut buffer[buf_offset..buf_offset + self.sector_size];
61
62 if !self.inner.read_block(sector_id, sector_buf) {
63 crate::pr_err!(
64 "[Ext4Adapter] Read error at sector {} (offset {})",
65 sector_id,
66 offset
67 );
68 return alloc::vec![0u8; self.block_size];
69 }
70 }
71
72 buffer[sector_offset..sector_offset + self.block_size].to_vec()
74 }
75
76 fn write_offset(&self, offset: usize, data: &[u8]) {
77 let start_sector = offset / self.sector_size;
82 let sector_offset = offset % self.sector_size;
83
84 let bytes_to_write = data.len();
86 let sectors_needed =
87 (sector_offset + bytes_to_write + self.sector_size - 1) / self.sector_size;
88
89 let mut buffer = alloc::vec![0u8; sectors_needed * self.sector_size];
91
92 for i in 0..sectors_needed {
94 let sector_id = start_sector + i;
95 let buf_offset = i * self.sector_size;
96 let sector_buf = &mut buffer[buf_offset..buf_offset + self.sector_size];
97
98 if !self.inner.read_block(sector_id, sector_buf) {
99 crate::pr_err!(
100 "[Ext4Adapter] Read error at sector {} (for write, offset {})",
101 sector_id,
102 offset
103 );
104 return;
105 }
106 }
107
108 buffer[sector_offset..sector_offset + bytes_to_write].copy_from_slice(data);
110
111 for i in 0..sectors_needed {
113 let sector_id = start_sector + i;
114 let buf_offset = i * self.sector_size;
115 let sector_data = &buffer[buf_offset..buf_offset + self.sector_size];
116
117 if !self.inner.write_block(sector_id, sector_data) {
118 crate::pr_err!(
119 "[Ext4Adapter] Write error at sector {} (offset {})",
120 sector_id,
121 offset
122 );
123 }
124 }
125 }
126}