From 31c422f86ac9a4d3b4e12a6f1a51f86315b47f0c Mon Sep 17 00:00:00 2001 From: edef Date: Sun, 24 Apr 2022 23:40:18 +0000 Subject: ripple/fossil/mount: implement stateful file handles This will primarily allow us to amortise metadata lookups. Change-Id: Ic92781bf1ded5af62f6e955322bb89623afb2061 --- ripple/fossil/src/bin/mount.rs | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'ripple/fossil/src/bin') 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 }, + _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, 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, _flush: bool, reply: fuser::ReplyEmpty, ) { + let _ = unsafe { + let ptr = fh as *mut Handle; + Box::from_raw(ptr) + }; reply.ok(); } -- cgit 1.4.1