Add seek function

This commit is contained in:
pjht 2024-09-30 13:33:25 -05:00
parent d756ac19c2
commit 1a2f51a7bb
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A

View File

@ -5,10 +5,18 @@ use std::{
use parking_lot::RwLock; use parking_lot::RwLock;
use tar::Archive; use tar::Archive;
#[derive(Clone)]
struct OpenFile {
mount_id: usize,
file_offset: u64,
len: usize,
pos: u64,
}
#[derive(Clone)] #[derive(Clone)]
struct Serv { struct Serv {
mounts: Arc<RwLock<Vec<(File, Vec<(PathBuf, u64, usize)>)>>>, mounts: Arc<RwLock<Vec<(File, Vec<(PathBuf, u64, usize)>)>>>,
files: Arc<RwLock<Vec<(usize, u64, usize)>>>, files: Arc<RwLock<Vec<OpenFile>>>,
} }
impl fs_rpc::Server for Serv { impl fs_rpc::Server for Serv {
@ -40,48 +48,87 @@ impl fs_rpc::Server for Serv {
.ok_or(())?; .ok_or(())?;
self.files self.files
.write() .write()
.push((mount_id as usize, file_offset, file_size)); .push(OpenFile {
mount_id: mount_id as usize,
file_offset,
len: file_size,
pos: 0,
});
Ok((None, (self.files.read().len() - 1) as u64)) Ok((None, (self.files.read().len() - 1) as u64))
} }
fn open_dir(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option<u64>, u64), ()> { fn open_dir(&self, _path: &std::path::Path, _mount_id: u64) -> Result<(Option<u64>, u64), ()> {
// TODO // TODO
Err(()) Err(())
} }
} }
impl file_rpc::Server for Serv { impl file_rpc::Server for Serv {
fn read(&self, fd: u64, pos: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> { fn read(&self, fd: u64, len: usize) -> Result<Cow<'_, [u8]>, ()> {
let (mount_id, file_offset, size) = self.files.read()[fd as usize]; let files = self.files.read();
let read_len = usize::min(len, size - (pos as usize)); let file = &files[fd as usize];
let read_len = usize::min(len, file.len - (file.pos as usize));
if read_len == 0 { if read_len == 0 {
return Ok(Vec::new().into()); return Ok(Vec::new().into());
}; };
let mounts = self.mounts.read(); let mounts = self.mounts.read();
let mount = &mounts[mount_id]; let mount = &mounts[file.mount_id];
(&mount.0) (&mount.0)
.seek(std::io::SeekFrom::Start(file_offset + pos)) .seek(std::io::SeekFrom::Start(file.file_offset + file.pos))
.unwrap(); .unwrap();
let mut buf = vec![0; read_len]; let mut buf = vec![0; read_len];
let read_bytes = (&mount.0).read(&mut buf).map_err(|_| ())?; let read_bytes = (&mount.0).read(&mut buf).map_err(|_| ())?;
buf.truncate(read_bytes); buf.truncate(read_bytes);
std::mem::drop(files);
self.files.write()[fd as usize].pos += read_bytes as u64;
Ok(buf.into()) Ok(buf.into())
} }
fn write(&self, _fd: u64, _pos: u64, _data: &[u8]) -> Result<(), ()> { fn write(&self, _fd: u64, _data: &[u8]) -> Result<(), ()> {
Err(()) Err(())
} }
fn close(&self, _fd: u64) {} fn close(&self, _fd: u64) {}
fn size(&self, fd: u64) -> Option<u64> { fn size(&self, fd: u64) -> Option<u64> {
let (_mount_id, _file_offset, size) = self.files.read()[fd as usize]; Some(self.files.read()[fd as usize].len as u64)
Some(size as u64)
} }
fn dup(&self, fd: u64) -> Option<u64> { fn dup(&self, fd: u64) -> Option<u64> {
Some(fd) let mut files = self.files.write();
let file = files[fd as usize].clone();
files.push(file);
Some((files.len() - 1) as u64)
} }
fn seek(&self, fd: u64, pos: file_rpc::SeekFrom) -> u64{
let mut files = self.files.write();
let file = &mut files[fd as usize];
match pos {
file_rpc::SeekFrom::Start(offset) => {
file.pos = offset;
},
file_rpc::SeekFrom::End(offset) => {
if offset <= 0 {
file.pos = file.len as u64 - (-offset) as u64;
}
},
file_rpc::SeekFrom::Current(offset) => {
if offset > 0 {
file.pos = u64::min(file.pos + offset as u64, file.len as u64);
} else {
let offset = (-offset) as u64;
if offset > file.pos {
file.pos = 0;
} else {
file.pos -= offset;
}
}
},
};
file.pos
}
} }
fn main() { fn main() {