mirror of
https://github.com/sgmarz/osblog.git
synced 2024-11-24 02:16:19 +04:00
Reading up to indirect pointers
This commit is contained in:
parent
c2fb6cf90d
commit
080a529f01
@ -5,8 +5,7 @@
|
||||
|
||||
use crate::{kmem::{kfree, kmalloc, talloc, tfree},
|
||||
page::{zalloc, PAGE_SIZE},
|
||||
process::{add_kernel_process_args, set_running, set_waiting},
|
||||
syscall::syscall_exit,
|
||||
process::{add_kernel_process_args, set_running, set_waiting, get_by_pid},
|
||||
virtio,
|
||||
virtio::{Descriptor, MmioOffsets, Queue, StatusField, VIRTIO_RING_SIZE}};
|
||||
use core::mem::size_of;
|
||||
@ -365,6 +364,8 @@ pub fn pending(bd: &mut BlockDevice) {
|
||||
// A PID of 0 means that we don't have a watcher.
|
||||
if pid_of_watcher > 0 {
|
||||
set_running(pid_of_watcher);
|
||||
let proc = get_by_pid(pid_of_watcher);
|
||||
(*(*proc).get_frame()).regs[10] = (*rq).status.status as usize;
|
||||
// TODO: Set GpA0 to the value of the return status.
|
||||
}
|
||||
kfree(rq as *mut u8);
|
||||
|
@ -122,7 +122,7 @@ impl MinixFileSystem {
|
||||
// top portion of our buffer. Since we won't be using the super block and inode
|
||||
// simultaneously, we can overlap the memory regions.
|
||||
let super_block = unsafe { &*(buffer.get_mut() as *mut SuperBlock) };
|
||||
let inode = unsafe { &*(buffer.get_mut() as *mut Inode) };
|
||||
let inode = buffer.get_mut() as *mut Inode;
|
||||
// Read from the block device. The size is 1 sector (512 bytes) and our offset is past
|
||||
// the boot block (first 1024 bytes). This is where the superblock sits.
|
||||
syc_read(desc, buffer.get_mut(), 512, 1024);
|
||||
@ -132,12 +132,22 @@ impl MinixFileSystem {
|
||||
// have to skip the bitmaps blocks. We have a certain number of inode map blocks (imap)
|
||||
// and zone map blocks (zmap).
|
||||
// The inode comes to us as a NUMBER, not an index. So, we need to subtract 1.
|
||||
let inode_offset = (2 + super_block.imap_blocks + super_block.zmap_blocks) as usize
|
||||
* BLOCK_SIZE as usize + (inode_num as usize - 1) * size_of::<Inode>();
|
||||
let inode_offset =
|
||||
(2 + super_block.imap_blocks + super_block.zmap_blocks) as usize * BLOCK_SIZE as usize;
|
||||
|
||||
// Now, we read the inode itself.
|
||||
// The block driver requires that our offset be a multiple of 512. We do that with the
|
||||
// inode_offset. However, we're going to be reading a group of inodes.
|
||||
syc_read(desc, buffer.get_mut(), 512, inode_offset as u32);
|
||||
return Some(*inode);
|
||||
|
||||
// There are 512 / size_of<Inode>() inodes in each read that we can do. However, we
|
||||
// need to figure out which inode in that group we need to read. We just take
|
||||
// the % of this to find out.
|
||||
let read_this_node = (inode_num as usize - 1) % (512 / size_of::<Inode>());
|
||||
|
||||
// We copy the inode over. This might not be the best thing since the Inode will
|
||||
// eventually have to change after writing.
|
||||
return unsafe { Some(*(inode.add(read_this_node))) };
|
||||
}
|
||||
// If we get here, some result wasn't OK. Either the super block
|
||||
// or the inode itself.
|
||||
@ -174,9 +184,11 @@ impl FileSystem for MinixFileSystem {
|
||||
else {
|
||||
size
|
||||
};
|
||||
println!("Bytes left = {}", bytes_left);
|
||||
let mut bytes_read = 0u32;
|
||||
let mut block_buffer = BlockBuffer::new(BLOCK_SIZE);
|
||||
// ////////////////////////////////////////////
|
||||
// // DIRECT ZONES
|
||||
// ////////////////////////////////////////////
|
||||
// In Rust, our for loop automatically "declares" i from 0 to < 7. The syntax
|
||||
// 0..7 means 0 through to 7 but not including 7. If we want to include 7, we
|
||||
// would use the syntax 0..=7.
|
||||
@ -206,7 +218,6 @@ impl FileSystem for MinixFileSystem {
|
||||
else {
|
||||
BLOCK_SIZE - offset_byte
|
||||
};
|
||||
println!("Copy {} bytes", read_this_many);
|
||||
unsafe {
|
||||
memcpy(
|
||||
buffer.add(bytes_read as usize,),
|
||||
@ -220,9 +231,60 @@ impl FileSystem for MinixFileSystem {
|
||||
if bytes_left == 0 {
|
||||
return bytes_read;
|
||||
}
|
||||
println!("Bytes left = {}", bytes_left);
|
||||
}
|
||||
blocks_seen += 1;
|
||||
}
|
||||
// ////////////////////////////////////////////
|
||||
// // SINGLY INDIRECT ZONES
|
||||
// ////////////////////////////////////////////
|
||||
// Each indirect zone is a list of pointers, each 4 bytes. These then
|
||||
// point to zones where the data can be found.
|
||||
if inode.zones[7] != 0 {
|
||||
let mut indirect_buffer = BlockBuffer::new(BLOCK_SIZE);
|
||||
syc_read(desc, indirect_buffer.get_mut(), BLOCK_SIZE, BLOCK_SIZE * inode.zones[7]);
|
||||
let num_indirect_pointers = BLOCK_SIZE as usize / 4;
|
||||
let izones = indirect_buffer.get() as *const u32;
|
||||
for i in 0..num_indirect_pointers {
|
||||
unsafe {
|
||||
if izones.add(i).read() != 0 {
|
||||
if offset_block <= blocks_seen {
|
||||
syc_read(
|
||||
desc,
|
||||
block_buffer.get_mut(),
|
||||
BLOCK_SIZE,
|
||||
BLOCK_SIZE * izones.add(i,).read(),
|
||||
);
|
||||
let read_this_many = if BLOCK_SIZE - offset_byte > bytes_left {
|
||||
bytes_left
|
||||
}
|
||||
else {
|
||||
BLOCK_SIZE - offset_byte
|
||||
};
|
||||
memcpy(
|
||||
buffer.add(bytes_read as usize,),
|
||||
block_buffer.get().add(offset_byte as usize,),
|
||||
read_this_many as usize,
|
||||
);
|
||||
bytes_read += read_this_many;
|
||||
bytes_left -= read_this_many;
|
||||
println!("Bytes left = {}", bytes_left);
|
||||
offset_byte = 0;
|
||||
if bytes_left == 0 {
|
||||
return bytes_read;
|
||||
}
|
||||
}
|
||||
blocks_seen += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ////////////////////////////////////////////
|
||||
// // DOUBLY INDIRECT ZONES
|
||||
// ////////////////////////////////////////////
|
||||
// ////////////////////////////////////////////
|
||||
// // TRIPLY INDIRECT ZONES
|
||||
// ////////////////////////////////////////////
|
||||
bytes_read
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
use crate::{block::block_op,
|
||||
cpu::TrapFrame,
|
||||
minixfs,
|
||||
process::{delete_process, set_sleeping}};
|
||||
process::{delete_process, set_sleeping, set_waiting}};
|
||||
|
||||
pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
||||
let syscall_number;
|
||||
@ -62,6 +62,7 @@ pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
||||
// (*frame).regs[12],
|
||||
// (*frame).regs[13]
|
||||
// );
|
||||
set_waiting((*frame).pid as u16);
|
||||
let _ = block_op((*frame).regs[10],
|
||||
(*frame).regs[11] as *mut u8,
|
||||
(*frame).regs[12] as u32,
|
||||
|
@ -4,11 +4,12 @@ use crate::syscall::syscall_fs_read;
|
||||
|
||||
pub fn test_block() {
|
||||
// Let's test the block driver!
|
||||
let buffer = crate::kmem::kmalloc(1024);
|
||||
let bytes_to_read = 1024 * 14;
|
||||
let buffer = crate::kmem::kmalloc(bytes_to_read);
|
||||
println!("Started test block process, buffer is at {:p}.", buffer);
|
||||
unsafe {
|
||||
syscall_fs_read(8, 12, buffer, 1024, 0);
|
||||
for i in 0..32 {
|
||||
syscall_fs_read(8, 5, buffer, bytes_to_read as u32, 0);
|
||||
for i in 0..16*4 {
|
||||
print!("{:02x} ", buffer.add(i).read());
|
||||
if (i+1) % 16 == 0 {
|
||||
println!();
|
||||
|
Loading…
Reference in New Issue
Block a user