Selaa lähdekoodia

Modified LocalFs to keep track of which path owns which handles.

Matthew Carr 2 vuotta sitten
vanhempi
commit
44a6ef6ad4

+ 2 - 2
crates/btfproto/src/client.rs

@@ -147,7 +147,7 @@ impl<T: Transmitter> FsClient<T> {
         &self,
         parent: Inode,
         name: &str,
-        flags: i32,
+        flags: Flags,
         mode: u32,
         umask: u32,
     ) -> Result<CreateReply> {
@@ -161,7 +161,7 @@ impl<T: Transmitter> FsClient<T> {
         self.tx.call(msg, extractor!(Create)).await?
     }
 
-    pub async fn open(&self, inode: Inode, flags: i32) -> Result<OpenReply> {
+    pub async fn open(&self, inode: Inode, flags: Flags) -> Result<OpenReply> {
         let msg = FsMsg::Open(Open { inode, flags });
         self.tx.call(msg, extractor!(Open)).await?
     }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 285 - 300
crates/btfproto/src/local_fs.rs


+ 90 - 3
crates/btfproto/src/msg.rs

@@ -2,7 +2,7 @@ use btlib::{BlockMeta, BlockMetaSecrets, DirEntry};
 use btmsg::CallMsg;
 use core::time::Duration;
 use serde::{Deserialize, Serialize};
-use std::fmt::Display;
+use std::{fmt::Display, io};
 
 pub type Inode = u64;
 pub type Handle = u64;
@@ -64,6 +64,93 @@ impl Display for FsError {
 
 impl std::error::Error for FsError {}
 
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+/// A wrapper type around [i32] with convenience methods for checking if `libc::O_*`
+/// flags have been set.
+pub struct Flags(i32);
+
+impl Copy for Flags {}
+
+impl Flags {
+    pub fn new(value: i32) -> Self {
+        Self(value)
+    }
+
+    pub fn value(self) -> i32 {
+        self.0
+    }
+
+    /// Returns true if and only if the given open flags allow the file to be written to.
+    pub fn writeable(self) -> bool {
+        const MASK: i32 = libc::O_RDWR | libc::O_WRONLY;
+        self.0 & MASK != 0
+    }
+
+    pub fn readable(self) -> bool {
+        // Be careful; because libc::O_RDONLY is 0 you can't use the '&' operator
+        // to test for it, it has to be an equality check.
+        self.0 == libc::O_RDONLY || (self.0 & libc::O_RDWR) != 0
+    }
+
+    pub fn read_only(self) -> bool {
+        self.0 == libc::O_RDONLY
+    }
+
+    pub fn write_only(self) -> bool {
+        self.0 & libc::O_WRONLY != 0
+    }
+
+    pub fn directory(self) -> bool {
+        self.0 & libc::O_DIRECTORY != 0
+    }
+
+    pub fn assert_readable(self) -> Result<(), io::Error> {
+        if !self.readable() {
+            Err(io::Error::from_raw_os_error(libc::EACCES))
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn assert_writeable(self) -> Result<(), io::Error> {
+        if !self.writeable() {
+            Err(io::Error::from_raw_os_error(libc::EACCES))
+        } else {
+            Ok(())
+        }
+    }
+}
+
+impl From<i32> for Flags {
+    fn from(value: i32) -> Self {
+        Self::new(value)
+    }
+}
+
+impl From<Flags> for i32 {
+    fn from(flags: Flags) -> Self {
+        flags.value()
+    }
+}
+
+impl AsRef<i32> for Flags {
+    fn as_ref(&self) -> &i32 {
+        &self.0
+    }
+}
+
+impl Display for Flags {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.value().fmt(f)
+    }
+}
+
+impl Default for Flags {
+    fn default() -> Self {
+        Self::new(0)
+    }
+}
+
 #[derive(Serialize, Deserialize)]
 pub struct Entry {
     pub attr: BlockMetaSecrets,
@@ -88,7 +175,7 @@ pub struct LookupReply {
 pub struct Create<'a> {
     pub parent: Inode,
     pub name: &'a str,
-    pub flags: i32,
+    pub flags: Flags,
     pub mode: u32,
     pub umask: u32,
 }
@@ -103,7 +190,7 @@ pub struct CreateReply {
 #[derive(Serialize, Deserialize)]
 pub struct Open {
     pub inode: Inode,
-    pub flags: i32,
+    pub flags: Flags,
 }
 
 #[derive(Serialize, Deserialize)]

+ 16 - 15
crates/btfproto/src/server.rs

@@ -10,76 +10,77 @@ pub trait FsProvider {
     type LookupFut<'c>: Send + Future<Output = Result<LookupReply>>
     where
         Self: 'c;
-    fn lookup<'c>(&'c self, from: &'c BlockPath, msg: Lookup<'c>) -> Self::LookupFut<'c>;
+    fn lookup<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Lookup<'c>) -> Self::LookupFut<'c>;
 
     type CreateFut<'c>: Send + Future<Output = Result<CreateReply>>
     where
         Self: 'c;
-    fn create<'c>(&'c self, from: &'c BlockPath, msg: Create<'c>) -> Self::CreateFut<'c>;
+    fn create<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Create<'c>) -> Self::CreateFut<'c>;
 
     type OpenFut<'c>: Send + Future<Output = Result<OpenReply>>
     where
         Self: 'c;
-    fn open<'c>(&'c self, from: &'c BlockPath, msg: Open) -> Self::OpenFut<'c>;
+    fn open<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Open) -> Self::OpenFut<'c>;
 
-    fn read<'c, R, F>(&'c self, from: &'c BlockPath, msg: Read, callback: F) -> Result<R>
+    fn read<'c, R, F>(&'c self, from: &'c Arc<BlockPath>, msg: Read, callback: F) -> Result<R>
     where
         F: 'c + Send + FnOnce(&[u8]) -> R;
 
     type WriteFut<'c>: Send + Future<Output = Result<WriteReply>>
     where
         Self: 'c;
-    fn write<'c>(&'c self, from: &'c BlockPath, msg: Write) -> Self::WriteFut<'c>;
+    fn write<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Write) -> Self::WriteFut<'c>;
 
     type FlushFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn flush<'c>(&'c self, from: &'c BlockPath, msg: Flush) -> Self::FlushFut<'c>;
+    fn flush<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Flush) -> Self::FlushFut<'c>;
 
     type ReadDirFut<'c>: Send + Future<Output = Result<ReadDirReply>>
     where
         Self: 'c;
-    fn read_dir<'c>(&'c self, from: &'c BlockPath, msg: ReadDir) -> Self::ReadDirFut<'c>;
+    fn read_dir<'c>(&'c self, from: &'c Arc<BlockPath>, msg: ReadDir) -> Self::ReadDirFut<'c>;
 
     type LinkFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn link<'c>(&'c self, from: &'c BlockPath, msg: Link) -> Self::LinkFut<'c>;
+    fn link<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Link) -> Self::LinkFut<'c>;
 
     type UnlinkFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn unlink<'c>(&'c self, from: &'c BlockPath, msg: Unlink) -> Self::UnlinkFut<'c>;
+    fn unlink<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Unlink) -> Self::UnlinkFut<'c>;
 
     type ReadMetaFut<'c>: Send + Future<Output = Result<BlockMeta>>
     where
         Self: 'c;
-    fn read_meta<'c>(&'c self, from: &'c BlockPath, msg: ReadMeta) -> Self::ReadMetaFut<'c>;
+    fn read_meta<'c>(&'c self, from: &'c Arc<BlockPath>, msg: ReadMeta) -> Self::ReadMetaFut<'c>;
 
     type WriteMetaFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn write_meta<'c>(&'c self, from: &'c BlockPath, msg: WriteMeta) -> Self::WriteMetaFut<'c>;
+    fn write_meta<'c>(&'c self, from: &'c Arc<BlockPath>, msg: WriteMeta)
+        -> Self::WriteMetaFut<'c>;
 
     type CloseFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn close<'c>(&'c self, from: &'c BlockPath, msg: Close) -> Self::CloseFut<'c>;
+    fn close<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Close) -> Self::CloseFut<'c>;
 
     type ForgetFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn forget<'c>(&'c self, from: &'c BlockPath, msg: Forget) -> Self::ForgetFut<'c>;
+    fn forget<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Forget) -> Self::ForgetFut<'c>;
 
     type LockFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn lock<'c>(&'c self, from: &'c BlockPath, msg: Lock) -> Self::LockFut<'c>;
+    fn lock<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Lock) -> Self::LockFut<'c>;
 
     type UnlockFut<'c>: Send + Future<Output = Result<()>>
     where
         Self: 'c;
-    fn unlock<'c>(&'c self, from: &'c BlockPath, msg: Unlock) -> Self::UnlockFut<'c>;
+    fn unlock<'c>(&'c self, from: &'c Arc<BlockPath>, msg: Unlock) -> Self::UnlockFut<'c>;
 }
 
 struct ServerCallback<P> {

+ 1 - 1
crates/btlib/src/accessor.rs

@@ -37,7 +37,7 @@ mod private {
     }
 
     impl<T: Size + ReadAt + AsRef<BlockMeta>> Accessor<T> {
-        pub fn get_buf<'a>(&'a self, offset: u64, size: u64) -> Result<&'a [u8]> {
+        pub fn get_buf(&self, offset: u64, size: u64) -> Result<&[u8]> {
             self.inner.get_buf(offset, size)
         }
     }

+ 1 - 1
crates/btlib/src/sectored_buf.rs

@@ -320,7 +320,7 @@ mod private {
         /// stream, and which is no longer than the given size. Note that this slice may
         /// be shorter than the `size` parameter if the number of bytes in the internal buffer is
         /// less than `size`.
-        pub fn get_buf<'a>(&'a self, offset: u64, size: u64) -> Result<&'a [u8]> {
+        pub fn get_buf(&self, offset: u64, size: u64) -> Result<&[u8]> {
             let offset: usize = offset.try_into().unwrap();
             let size: usize = size.try_into().unwrap();
             let sect_sz = self.sector_sz();

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä