Add seek function
This commit is contained in:
parent
32a4e71dae
commit
beae05db0b
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -22,6 +22,9 @@ name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@ -107,6 +110,7 @@ checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||
name = "file_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"parking_lot",
|
||||
"postcard",
|
||||
"serde",
|
||||
|
75
src/main.rs
75
src/main.rs
@ -3,7 +3,7 @@ use std::{
|
||||
io::{Read, Seek, SeekFrom},
|
||||
os::mikros::{ipc, syscalls},
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
sync::{atomic::{AtomicU64, Ordering}, Arc},
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
@ -30,43 +30,96 @@ struct GptEntry {
|
||||
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)]
|
||||
struct Serv {
|
||||
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 {
|
||||
fn open(&self, path: &std::path::Path) -> Result<u64, ()> {
|
||||
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 {
|
||||
fn read(&self, fd: u64, pos: u64, len: usize) -> Result<std::borrow::Cow<'_, [u8]>, ()> {
|
||||
let &(drive_file, offset, part_len) = &*self.open_files.get(fd as usize).ok_or(())?;
|
||||
if pos.saturating_add(len as u64) > part_len as u64 {
|
||||
fn read(&self, fd: u64, len: usize) -> Result<std::borrow::Cow<'_, [u8]>, ()> {
|
||||
let file = &*self.open_files.get(fd as usize).ok_or(())?;
|
||||
if file.pos.load(Ordering::Relaxed).saturating_add(len as u64) > file.part_len as u64 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Ok(file_rpc::Client::new(drive_file.0)
|
||||
.read(drive_file.1, offset + pos, len)?
|
||||
let file_client = file_rpc::Client::new(file.drive_file.0);
|
||||
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())
|
||||
}
|
||||
|
||||
fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> {
|
||||
fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn close(&self, _fd: 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> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user