From b6e4073f445dc35225df58e0f1e33c8da485b0f6 Mon Sep 17 00:00:00 2001 From: edef Date: Mon, 25 Apr 2022 00:33:04 +0000 Subject: ripple/fossil/mount: implement incremental file reads Change-Id: Iae189c3107a6841bcbdd75bb57dde785f9548130 --- ripple/fossil/src/bin/mount.rs | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'ripple/fossil/src') diff --git a/ripple/fossil/src/bin/mount.rs b/ripple/fossil/src/bin/mount.rs index aead582..3335c1f 100644 --- a/ripple/fossil/src/bin/mount.rs +++ b/ripple/fossil/src/bin/mount.rs @@ -8,7 +8,8 @@ use { log::debug, prost::Message, std::{ - io::{self, Read}, + cell::RefCell, + io::{self, Read, Seek}, time::{Duration, SystemTime, UNIX_EPOCH}, }, }; @@ -107,10 +108,14 @@ impl Filesystem { fn find(&self, ino: u64) -> Option<&memtree::Node> { self.root.find(ino.checked_sub(1)?.try_into().ok()?) } + + unsafe fn from_fh<'a>(&'a self, fh: u64) -> *mut Handle<'a> { + fh as *mut Handle<'a> + } } -enum Handle { - File { contents: Vec }, +enum Handle<'a> { + File { contents: RefCell> }, _NonExhaustive, } @@ -175,8 +180,10 @@ impl fuser::Filesystem for Filesystem { fn open(&mut self, _req: &fuser::Request<'_>, ino: u64, _flags: i32, reply: fuser::ReplyOpen) { match self.find(ino) { Some(memtree::Node::File(f)) => { - let contents = self.store.read_blob(f.ident); - let fh = Box::new(Handle::File { contents }); + let contents = self.store.open_blob(f.ident); + let fh = Box::new(Handle::File { + contents: RefCell::new(contents), + }); reply.opened(Box::into_raw(fh) as u64, 0); } Some(_) => reply.error(EINVAL), @@ -195,21 +202,22 @@ impl fuser::Filesystem for Filesystem { _lock_owner: Option, reply: fuser::ReplyData, ) { - let fh = unsafe { - let ptr = fh as *mut Handle; - &*ptr - }; + let fh = unsafe { &*self.from_fh(fh) }; match fh { Handle::File { contents } => { + let mut contents = contents.borrow_mut(); let offset = offset as usize; let size = size as usize; - let mut buffer = contents.get(offset..).unwrap_or_default(); - if buffer.len() > size { - buffer = &buffer[..size]; - } - reply.data(buffer); + assert_eq!( + contents.seek(io::SeekFrom::Start(offset as u64)).unwrap(), + offset as u64 + ); + + let mut buffer = vec![0; size]; + let n = contents.read(&mut buffer).unwrap(); + reply.data(&buffer[..n]); } _ => reply.error(EINVAL), } -- cgit 1.4.1