summary refs log tree commit diff
path: root/ripple/fossil
diff options
context:
space:
mode:
authoredef <edef@unfathomable.blue>2022-04-24 23:40:18 +0000
committeredef <edef@unfathomable.blue>2022-04-24 23:40:18 +0000
commit31c422f86ac9a4d3b4e12a6f1a51f86315b47f0c (patch)
tree4c22d754ba912dccec207c4aaa6e0495263097e4 /ripple/fossil
parentb43c0bb3efaad67259ce077ee89ef152b47a5d5f (diff)
ripple/fossil/mount: implement stateful file handles
This will primarily allow us to amortise metadata lookups.

Change-Id: Ic92781bf1ded5af62f6e955322bb89623afb2061
Diffstat (limited to 'ripple/fossil')
-rw-r--r--ripple/fossil/src/bin/mount.rs42
1 files changed, 31 insertions, 11 deletions
diff --git a/ripple/fossil/src/bin/mount.rs b/ripple/fossil/src/bin/mount.rs
index de03a4b..aead582 100644
--- a/ripple/fossil/src/bin/mount.rs
+++ b/ripple/fossil/src/bin/mount.rs
@@ -109,6 +109,11 @@ impl Filesystem {
 	}
 }
 
+enum Handle {
+	File { contents: Vec<u8> },
+	_NonExhaustive,
+}
+
 impl fuser::Filesystem for Filesystem {
 	fn init(
 		&mut self,
@@ -167,35 +172,46 @@ impl fuser::Filesystem for Filesystem {
 		}
 	}
 
-	fn open(&mut self, _req: &fuser::Request<'_>, _ino: u64, _flags: i32, reply: fuser::ReplyOpen) {
-		reply.opened(0, 0);
+	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 });
+				reply.opened(Box::into_raw(fh) as u64, 0);
+			}
+			Some(_) => reply.error(EINVAL),
+			None => reply.error(ENOENT),
+		}
 	}
 
 	fn read(
 		&mut self,
 		_req: &fuser::Request<'_>,
-		ino: u64,
-		_fh: u64,
+		_ino: u64,
+		fh: u64,
 		offset: i64,
 		size: u32,
 		_flags: i32,
 		_lock_owner: Option<u64>,
 		reply: fuser::ReplyData,
 	) {
-		match self.find(ino) {
-			Some(memtree::Node::File(f)) => {
+		let fh = unsafe {
+			let ptr = fh as *mut Handle;
+			&*ptr
+		};
+
+		match fh {
+			Handle::File { contents } => {
 				let offset = offset as usize;
 				let size = size as usize;
 
-				let content = self.store.read_blob(f.ident);
-				let mut buffer = content.get(offset..).unwrap_or_default();
+				let mut buffer = contents.get(offset..).unwrap_or_default();
 				if buffer.len() > size {
 					buffer = &buffer[..size];
 				}
 				reply.data(buffer);
 			}
-			Some(_) => reply.error(EINVAL),
-			None => reply.error(ENOENT),
+			_ => reply.error(EINVAL),
 		}
 	}
 
@@ -218,12 +234,16 @@ impl fuser::Filesystem for Filesystem {
 		&mut self,
 		_req: &fuser::Request<'_>,
 		_ino: u64,
-		_fh: u64,
+		fh: u64,
 		_flags: i32,
 		_lock_owner: Option<u64>,
 		_flush: bool,
 		reply: fuser::ReplyEmpty,
 	) {
+		let _ = unsafe {
+			let ptr = fh as *mut Handle;
+			Box::from_raw(ptr)
+		};
 		reply.ok();
 	}