Add seek function

This commit is contained in:
pjht 2024-09-30 13:32:58 -05:00
parent 32a4e71dae
commit beae05db0b
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
2 changed files with 68 additions and 11 deletions

4
Cargo.lock generated
View File

@ -22,6 +22,9 @@ name = "bitflags"
version = "2.6.0" version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "byteorder" name = "byteorder"
@ -107,6 +110,7 @@ checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
name = "file_rpc" name = "file_rpc"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitflags",
"parking_lot", "parking_lot",
"postcard", "postcard",
"serde", "serde",

View File

@ -3,7 +3,7 @@ use std::{
io::{Read, Seek, SeekFrom}, io::{Read, Seek, SeekFrom},
os::mikros::{ipc, syscalls}, os::mikros::{ipc, syscalls},
path::Path, path::Path,
sync::Arc, sync::{atomic::{AtomicU64, Ordering}, Arc},
}; };
use dashmap::DashMap; use dashmap::DashMap;
@ -30,43 +30,96 @@ struct GptEntry {
name: String, name: String,
} }
struct OpenFile {
drive_file: (u64, u64),
offset: u64,
part_len: usize,
pos: AtomicU64,
}
impl Clone for OpenFile {
fn clone(&self) -> Self {
Self {
drive_file: self.drive_file,
offset: self.offset,
part_len: self.part_len,
pos: AtomicU64::new(self.pos.load(Ordering::Relaxed)),
}
}
}
#[derive(Clone)] #[derive(Clone)]
struct Serv { struct Serv {
parts: Arc<DashMap<String, ((u64, u64), u64, usize)>>, parts: Arc<DashMap<String, ((u64, u64), u64, usize)>>,
open_files: Arc<Slab<((u64, u64), u64, usize)>>, open_files: Arc<Slab<OpenFile>>,
} }
impl dev_driver_rpc::Server for Serv { impl dev_driver_rpc::Server for Serv {
fn open(&self, path: &std::path::Path) -> Result<u64, ()> { fn open(&self, path: &std::path::Path) -> Result<u64, ()> {
let part = *(self.parts.get(path.to_str().unwrap()).ok_or(())?); let part = *(self.parts.get(path.to_str().unwrap()).ok_or(())?);
Ok(self.open_files.insert(part).unwrap() as u64) Ok(self.open_files.insert(OpenFile {
drive_file: part.0,
offset: part.1,
part_len: part.2,
pos: AtomicU64::new(0),
}).unwrap() as u64)
} }
} }
impl file_rpc::Server for Serv { impl file_rpc::Server for Serv {
fn read(&self, fd: u64, pos: u64, len: usize) -> Result<std::borrow::Cow<'_, [u8]>, ()> { fn read(&self, fd: u64, len: usize) -> Result<std::borrow::Cow<'_, [u8]>, ()> {
let &(drive_file, offset, part_len) = &*self.open_files.get(fd as usize).ok_or(())?; let file = &*self.open_files.get(fd as usize).ok_or(())?;
if pos.saturating_add(len as u64) > part_len as u64 { if file.pos.load(Ordering::Relaxed).saturating_add(len as u64) > file.part_len as u64 {
return Err(()); return Err(());
} }
Ok(file_rpc::Client::new(drive_file.0) let file_client = file_rpc::Client::new(file.drive_file.0);
.read(drive_file.1, offset + pos, len)? file_client.seek(file.drive_file.1, file_rpc::SeekFrom::Start(file.offset + file.pos.load(Ordering::Relaxed)));
Ok(file_client
.read(file.drive_file.1, len)?
.into()) .into())
} }
fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> { fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> {
todo!() todo!()
} }
fn close(&self, _fd: u64) {} fn close(&self, _fd: u64) {}
fn size(&self, fd: u64) -> Option<u64> { fn size(&self, fd: u64) -> Option<u64> {
Some(self.open_files.get(fd as usize)?.2 as u64) Some(self.open_files.get(fd as usize)?.part_len as u64)
} }
fn dup(&self, fd: u64) -> Option<u64> { fn dup(&self, fd: u64) -> Option<u64> {
Some(fd) let file = self.open_files.get(fd as usize)?.clone();
self.open_files.insert(file).map(|x| x as u64)
}
fn seek(&self, fd: u64, pos: file_rpc::SeekFrom) -> u64 {
let file = &*self.open_files.get(fd as usize).unwrap();
match pos {
file_rpc::SeekFrom::Start(offset) => {
file.pos.store(offset, Ordering::Relaxed);
},
file_rpc::SeekFrom::End(offset) => {
if offset <= 0 {
file.pos.store(file.part_len as u64 - (-offset) as u64, Ordering::Relaxed);
}
},
file_rpc::SeekFrom::Current(offset) => {
if offset > 0 {
file.pos.store(u64::min(file.pos.load(Ordering::Relaxed) + offset as u64, file.part_len as u64), Ordering::Relaxed);
} else {
let offset = (-offset) as u64;
if offset > file.pos.load(Ordering::Relaxed) {
file.pos.store(0, Ordering::Relaxed);
} else {
file.pos.fetch_sub(offset, Ordering::Relaxed);
}
}
},
}
file.pos.load(Ordering::Relaxed)
} }
} }