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"
|
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",
|
||||||
|
75
src/main.rs
75
src/main.rs
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user