summary refs log tree commit diff
path: root/ripple/fossil
diff options
context:
space:
mode:
Diffstat (limited to 'ripple/fossil')
-rw-r--r--ripple/fossil/src/bin/mount.rs36
1 files changed, 22 insertions, 14 deletions
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<u8> },
+enum Handle<'a> {
+	File { contents: RefCell<fossil::Blob<'a>> },
 	_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<u64>,
 		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),
 		}