From 69b044737a81c7bfbcf41eec044ec0fd8a5ae321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87a=C4=9Fatay=20Yi=C4=9Fit=20=C5=9Eahin?= Date: Sun, 4 Feb 2024 19:23:13 +0100 Subject: [PATCH] fuse: associate creation functions with structs Turning the Cmd/Rsp creation functions into associated functions for the Op structs allows us to refer to the Op struct in the function signature and body in a more concise manner. --- src/fs/fuse.rs | 490 +++++++++++++++++++++++-------------------------- 1 file changed, 234 insertions(+), 256 deletions(-) diff --git a/src/fs/fuse.rs b/src/fs/fuse.rs index 82ee014e3d..e709b9b296 100644 --- a/src/fs/fuse.rs +++ b/src/fs/fuse.rs @@ -97,6 +97,23 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Init as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Init as u32 }> { + fn create() -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::new_cmd( + fuse_abi::ROOT_ID, + fuse_abi::InitIn { + major: 7, + minor: 31, + max_readahead: 0, + flags: 0, + }, + ); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Create as u32 }> { type InStruct = fuse_abi::CreateIn; type InPayload = CStr; @@ -104,6 +121,27 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Create as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Create as u32 }> { + fn create( + path: &str, + flags: u32, + mode: u32, + ) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::cmd_from_str( + fuse_abi::ROOT_ID, + fuse_abi::CreateIn { + flags, + mode, + ..Default::default() + }, + path, + ); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Open as u32 }> { type InStruct = fuse_abi::OpenIn; type InPayload = (); @@ -111,6 +149,21 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Open as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Open as u32 }> { + fn create(nid: u64, flags: u32) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::new_cmd( + nid, + fuse_abi::OpenIn { + flags, + ..Default::default() + }, + ); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Write as u32 }> { type InStruct = fuse_abi::WriteIn; type InPayload = [u8]; @@ -118,6 +171,29 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Write as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Write as u32 }> { + fn create( + nid: u64, + fh: u64, + buf: &[u8], + offset: u64, + ) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::cmd_from_array( + nid, + fuse_abi::WriteIn { + fh, + offset, + size: buf.len().try_into().unwrap(), + ..Default::default() + }, + buf, + ); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Read as u32 }> { type InStruct = fuse_abi::ReadIn; type InPayload = (); @@ -128,6 +204,32 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Read as u32 }> { type OutPayload = [MaybeUninit]; } +impl Op<{ fuse_abi::Opcode::Read as u32 }> { + fn create( + nid: u64, + fh: u64, + size: u32, + offset: u64, + ) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::new_cmd( + nid, + fuse_abi::ReadIn { + fh, + offset, + size, + ..Default::default() + }, + ); + let rsp = unsafe { + as OpTrait>::Rsp::new_uninit( + size.try_into().unwrap(), + ) + }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Lseek as u32 }> { type InStruct = fuse_abi::LseekIn; type InPayload = (); @@ -135,6 +237,28 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Lseek as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Lseek as u32 }> { + fn create( + nid: u64, + fh: u64, + offset: isize, + whence: SeekWhence, + ) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::new_cmd( + nid, + fuse_abi::LseekIn { + fh, + offset: offset.try_into().unwrap(), + whence: num::ToPrimitive::to_u32(&whence).unwrap(), + ..Default::default() + }, + ); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Readlink as u32 }> { type InStruct = fuse_abi::ReadlinkIn; type InPayload = (); @@ -145,6 +269,19 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Readlink as u32 }> { type OutPayload = [MaybeUninit]; } +impl Op<{ fuse_abi::Opcode::Readlink as u32 }> { + fn create(nid: u64, size: u32) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::new_cmd(nid, fuse_abi::ReadlinkIn {}); + let rsp = unsafe { + as OpTrait>::Rsp::new_uninit( + size.try_into().unwrap(), + ) + }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Release as u32 }> { type InStruct = fuse_abi::ReleaseIn; type InPayload = (); @@ -152,6 +289,21 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Release as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Release as u32 }> { + fn create(nid: u64, fh: u64) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::new_cmd( + nid, + fuse_abi::ReleaseIn { + fh, + ..Default::default() + }, + ); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Mkdir as u32 }> { type InStruct = fuse_abi::MkdirIn; type InPayload = CStr; @@ -159,6 +311,22 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Mkdir as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Mkdir as u32 }> { + fn create(path: &str, mode: u32) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::cmd_from_str( + fuse_abi::ROOT_ID, + fuse_abi::MkdirIn { + mode, + ..Default::default() + }, + path, + ); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Unlink as u32 }> { type InStruct = fuse_abi::UnlinkIn; type InPayload = CStr; @@ -166,6 +334,15 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Unlink as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Unlink as u32 }> { + fn create(name: &str) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::cmd_from_str(fuse_abi::ROOT_ID, fuse_abi::UnlinkIn {}, name); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Rmdir as u32 }> { type InStruct = fuse_abi::RmdirIn; type InPayload = CStr; @@ -173,6 +350,15 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Rmdir as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Rmdir as u32 }> { + fn create(name: &str) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::cmd_from_str(fuse_abi::ROOT_ID, fuse_abi::RmdirIn {}, name); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl OpTrait for Op<{ fuse_abi::Opcode::Lookup as u32 }> { type InStruct = fuse_abi::LookupIn; type InPayload = CStr; @@ -180,6 +366,15 @@ impl OpTrait for Op<{ fuse_abi::Opcode::Lookup as u32 }> { type OutPayload = (); } +impl Op<{ fuse_abi::Opcode::Lookup as u32 }> { + fn create(name: &str) -> (Box<::Cmd>, Box<::Rsp>) { + let cmd = Self::cmd_from_str(fuse_abi::ROOT_ID, fuse_abi::LookupIn {}, name); + let rsp = unsafe { Box::new_uninit().assume_init() }; + + (cmd, rsp) + } +} + impl From for FileAttr { fn from(attr: fuse_abi::Attr) -> FileAttr { FileAttr { @@ -325,246 +520,8 @@ where } } -fn create_init() -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Init as u32 }>::new_cmd( - fuse_abi::ROOT_ID, - fuse_abi::InitIn { - major: 7, - minor: 31, - max_readahead: 0, - flags: 0, - }, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_create( - path: &str, - flags: u32, - mode: u32, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Create as u32 }>::cmd_from_str( - fuse_abi::ROOT_ID, - fuse_abi::CreateIn { - flags, - mode, - ..Default::default() - }, - path, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_open( - nid: u64, - flags: u32, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Open as u32 }>::new_cmd( - nid, - fuse_abi::OpenIn { - flags, - ..Default::default() - }, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -// TODO: do write zerocopy? -fn create_write( - nid: u64, - fh: u64, - buf: &[u8], - offset: u64, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Write as u32 }>::cmd_from_array( - nid, - fuse_abi::WriteIn { - fh, - offset, - size: buf.len().try_into().unwrap(), - ..Default::default() - }, - buf, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_read( - nid: u64, - fh: u64, - size: u32, - offset: u64, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Read as u32 }>::new_cmd( - nid, - fuse_abi::ReadIn { - fh, - offset, - size, - ..Default::default() - }, - ); - let rsp = unsafe { - as OpTrait>::Rsp::new_uninit( - size.try_into().unwrap(), - ) - }; - - (cmd, rsp) -} - -fn create_lseek( - nid: u64, - fh: u64, - offset: isize, - whence: SeekWhence, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Lseek as u32 }>::new_cmd( - nid, - fuse_abi::LseekIn { - fh, - offset: offset.try_into().unwrap(), - whence: num::ToPrimitive::to_u32(&whence).unwrap(), - ..Default::default() - }, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_readlink( - nid: u64, - size: u32, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Readlink as u32 }>::new_cmd(nid, fuse_abi::ReadlinkIn {}); - let rsp = unsafe { - as OpTrait>::Rsp::new_uninit( - size.try_into().unwrap(), - ) - }; - - (cmd, rsp) -} - -fn create_release( - nid: u64, - fh: u64, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Release as u32 }>::new_cmd( - nid, - fuse_abi::ReleaseIn { - fh, - ..Default::default() - }, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_mkdir( - path: &str, - mode: u32, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Mkdir as u32 }>::cmd_from_str( - fuse_abi::ROOT_ID, - fuse_abi::MkdirIn { - mode, - ..Default::default() - }, - path, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_unlink( - name: &str, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Unlink as u32 }>::cmd_from_str( - fuse_abi::ROOT_ID, - fuse_abi::UnlinkIn {}, - name, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_rmdir( - name: &str, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Rmdir as u32 }>::cmd_from_str( - fuse_abi::ROOT_ID, - fuse_abi::RmdirIn {}, - name, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - -fn create_lookup( - name: &str, -) -> ( - Box< as OpTrait>::Cmd>, - Box< as OpTrait>::Rsp>, -) { - let cmd = Op::<{ fuse_abi::Opcode::Lookup as u32 }>::cmd_from_str( - fuse_abi::ROOT_ID, - fuse_abi::LookupIn {}, - name, - ); - let rsp = unsafe { Box::new_uninit().assume_init() }; - - (cmd, rsp) -} - fn lookup(name: &str) -> Option { - let (cmd, mut rsp) = create_lookup(name); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Lookup as u32 }>::create(name); get_filesystem_driver() .unwrap() .lock() @@ -578,7 +535,7 @@ fn lookup(name: &str) -> Option { fn readlink(nid: u64) -> Result { let len = MAX_READ_LEN as u32; - let (cmd, mut rsp) = create_readlink(nid, len); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Readlink as u32 }>::create(nid, len); get_filesystem_driver() .unwrap() .lock() @@ -624,7 +581,12 @@ impl FuseFileHandleInner { len = MAX_READ_LEN; } if let (Some(nid), Some(fh)) = (self.fuse_nid, self.fuse_fh) { - let (cmd, mut rsp) = create_read(nid, fh, len.try_into().unwrap(), self.offset as u64); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Read as u32 }>::create( + nid, + fh, + len.try_into().unwrap(), + self.offset as u64, + ); get_filesystem_driver() .ok_or(IoError::ENOSYS)? .lock() @@ -665,7 +627,12 @@ impl FuseFileHandleInner { len = MAX_WRITE_LEN; } if let (Some(nid), Some(fh)) = (self.fuse_nid, self.fuse_fh) { - let (cmd, mut rsp) = create_write(nid, fh, &buf[..len], self.offset as u64); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Write as u32 }>::create( + nid, + fh, + &buf[..len], + self.offset as u64, + ); get_filesystem_driver() .ok_or(IoError::ENOSYS)? .lock() @@ -693,7 +660,8 @@ impl FuseFileHandleInner { debug!("FUSE lseek"); if let (Some(nid), Some(fh)) = (self.fuse_nid, self.fuse_fh) { - let (cmd, mut rsp) = create_lseek(nid, fh, offset, whence); + let (cmd, mut rsp) = + Op::<{ fuse_abi::Opcode::Lseek as u32 }>::create(nid, fh, offset, whence); get_filesystem_driver() .ok_or(IoError::ENOSYS)? .lock() @@ -715,7 +683,10 @@ impl FuseFileHandleInner { impl Drop for FuseFileHandleInner { fn drop(&mut self) { if self.fuse_nid.is_some() && self.fuse_fh.is_some() { - let (cmd, mut rsp) = create_release(self.fuse_nid.unwrap(), self.fuse_fh.unwrap()); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Release as u32 }>::create( + self.fuse_nid.unwrap(), + self.fuse_fh.unwrap(), + ); get_filesystem_driver() .unwrap() .lock() @@ -786,7 +757,7 @@ impl VfsNode for FuseDirectory { // Opendir // Flag 0x10000 for O_DIRECTORY might not be necessary - let (mut cmd, mut rsp) = create_open(fuse_nid, 0x10000); + let (mut cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Open as u32 }>::create(fuse_nid, 0x10000); cmd.common_header.opcode = fuse_abi::Opcode::Opendir as u32; get_filesystem_driver() .ok_or(IoError::ENOSYS)? @@ -801,7 +772,8 @@ impl VfsNode for FuseDirectory { let mut offset: usize = 0; // read content of the directory - let (mut cmd, mut rsp) = create_read(fuse_nid, fuse_fh, len, 0); + let (mut cmd, mut rsp) = + Op::<{ fuse_abi::Opcode::Read as u32 }>::create(fuse_nid, fuse_fh, len, 0); cmd.common_header.opcode = fuse_abi::Opcode::Readdir as u32; get_filesystem_driver() .ok_or(IoError::ENOSYS)? @@ -845,7 +817,7 @@ impl VfsNode for FuseDirectory { })); } - let (cmd, mut rsp) = create_release(fuse_nid, fuse_fh); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Release as u32 }>::create(fuse_nid, fuse_fh); get_filesystem_driver() .unwrap() .lock() @@ -868,7 +840,7 @@ impl VfsNode for FuseDirectory { debug!("FUSE stat: {}", path); // Is there a better way to implement this? - let (cmd, mut rsp) = create_lookup(&path); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Lookup as u32 }>::create(&path); get_filesystem_driver() .unwrap() .lock() @@ -904,7 +876,7 @@ impl VfsNode for FuseDirectory { debug!("FUSE lstat: {}", path); - let (cmd, mut rsp) = create_lookup(&path); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Lookup as u32 }>::create(&path); get_filesystem_driver() .unwrap() .lock() @@ -949,8 +921,10 @@ impl VfsNode for FuseDirectory { } // 3.FUSE_OPEN(nodeid, O_RDONLY) -> fh - let (cmd, mut rsp) = - create_open(file_guard.fuse_nid.unwrap(), opt.bits().try_into().unwrap()); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Open as u32 }>::create( + file_guard.fuse_nid.unwrap(), + opt.bits().try_into().unwrap(), + ); get_filesystem_driver() .ok_or(IoError::ENOSYS)? .lock() @@ -958,7 +932,11 @@ impl VfsNode for FuseDirectory { file_guard.fuse_fh = Some(unsafe { rsp.op_header.assume_init().fh }); } else { // Create file (opens implicitly, returns results from both lookup and open calls) - let (cmd, mut rsp) = create_create(&path, opt.bits().try_into().unwrap(), mode.bits()); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Create as u32 }>::create( + &path, + opt.bits().try_into().unwrap(), + mode.bits(), + ); get_filesystem_driver() .ok_or(IoError::ENOSYS)? .lock() @@ -985,7 +963,7 @@ impl VfsNode for FuseDirectory { .collect() }; - let (cmd, mut rsp) = create_unlink(&path); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Unlink as u32 }>::create(&path); get_filesystem_driver() .ok_or(IoError::ENOSYS)? .lock() @@ -1006,7 +984,7 @@ impl VfsNode for FuseDirectory { .collect() }; - let (cmd, mut rsp) = create_rmdir(&path); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Rmdir as u32 }>::create(&path); get_filesystem_driver() .ok_or(IoError::ENOSYS)? .lock() @@ -1030,7 +1008,7 @@ impl VfsNode for FuseDirectory { .map(|v| "/".to_owned() + v) .collect() }; - let (cmd, mut rsp) = create_mkdir(&path, mode.bits()); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Mkdir as u32 }>::create(&path, mode.bits()); get_filesystem_driver() .ok_or(IoError::ENOSYS)? @@ -1048,7 +1026,7 @@ pub(crate) fn init() { debug!("Try to initialize fuse filesystem"); if let Some(driver) = get_filesystem_driver() { - let (cmd, mut rsp) = create_init(); + let (cmd, mut rsp) = Op::<{ fuse_abi::Opcode::Init as u32 }>::create(); driver .lock() .send_command::<{ fuse_abi::Opcode::Init as u32 }>(cmd.as_ref(), rsp.as_mut());