summary refs log tree commit diff
path: root/devices/src/virtio/fs/filesystem.rs
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2019-12-05 19:20:48 +0900
committerCommit Bot <commit-bot@chromium.org>2019-12-10 03:10:57 +0000
commit4f9f5c74791fd13f6930a48232b3327066259b8e (patch)
tree0bbbad8c69a96209fee1b75e6d8f1d6352b6ee16 /devices/src/virtio/fs/filesystem.rs
parentf21572c7187c8beb9c6bfea6446351ae93200d01 (diff)
downloadcrosvm-4f9f5c74791fd13f6930a48232b3327066259b8e.tar
crosvm-4f9f5c74791fd13f6930a48232b3327066259b8e.tar.gz
crosvm-4f9f5c74791fd13f6930a48232b3327066259b8e.tar.bz2
crosvm-4f9f5c74791fd13f6930a48232b3327066259b8e.tar.lz
crosvm-4f9f5c74791fd13f6930a48232b3327066259b8e.tar.xz
crosvm-4f9f5c74791fd13f6930a48232b3327066259b8e.tar.zst
crosvm-4f9f5c74791fd13f6930a48232b3327066259b8e.zip
devices: fs: Support fs crypto ioctls
Add support for FS_IOC_{GET,SET}_ENCRYPTION_POLICY.  Unfortunately,
since the I/O direction is encoded backwards in the ioctl definitions,
these will only work with on a kernel that's compiled with a patch to
mark them as unrestricted FUSE ioctls.

BUG=b:136127632
TEST=Compile and run the vfs_crypto.c program on a virtio-fs mount
     inside a VM

Change-Id: I124c5a943111b453dd44921a079a2baa1036dfd4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1952570
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Tested-by: Chirantan Ekbote <chirantan@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Chirantan Ekbote <chirantan@chromium.org>
Diffstat (limited to 'devices/src/virtio/fs/filesystem.rs')
-rw-r--r--devices/src/virtio/fs/filesystem.rs64
1 files changed, 55 insertions, 9 deletions
diff --git a/devices/src/virtio/fs/filesystem.rs b/devices/src/virtio/fs/filesystem.rs
index 53a3f1e..232ff99 100644
--- a/devices/src/virtio/fs/filesystem.rs
+++ b/devices/src/virtio/fs/filesystem.rs
@@ -13,10 +13,7 @@ use libc;
 
 use crate::virtio::fs::fuse;
 
-pub use fuse::FsOptions;
-pub use fuse::OpenOptions;
-pub use fuse::SetattrValid;
-pub use fuse::ROOT_ID;
+pub use fuse::{FsOptions, IoctlFlags, IoctlIovec, OpenOptions, SetattrValid, ROOT_ID};
 
 /// Information about a path in the filesystem.
 pub struct Entry {
@@ -111,6 +108,26 @@ pub enum ListxattrReply {
     Count(u32),
 }
 
+/// A reply to an `ioctl` method call.
+pub enum IoctlReply {
+    /// Indicates that the ioctl should be retried. This is only a valid reply when the `flags`
+    /// field of the ioctl request contains `IoctlFlags::UNRESTRICTED`. The kernel will read in data
+    /// and prepare output buffers as specified in the `input` and `output` fields before re-sending
+    /// the ioctl message.
+    Retry {
+        /// Data that should be read by the kernel module and sent to the server when the ioctl is
+        /// retried.
+        input: Vec<IoctlIovec>,
+
+        /// Buffer space that should be prepared so that the server can send back the response to
+        /// the ioctl.
+        output: Vec<IoctlIovec>,
+    },
+
+    /// Indicates that the ioctl was processed.
+    Done(io::Result<Vec<u8>>),
+}
+
 /// A trait for directly copying data from the fuse transport into a `File` without first storing it
 /// in an intermediate buffer.
 pub trait ZeroCopyReader {
@@ -1054,23 +1071,52 @@ pub trait FileSystem {
         Err(io::Error::from_raw_os_error(libc::ENOSYS))
     }
 
-    /// TODO: support this
-    fn getlk(&self) -> io::Result<()> {
+    /// Perform an ioctl on a file or directory.
+    ///
+    /// `handle` is the `Handle` returned by the file system from the `open` or `opendir` methods,
+    /// if any. If the file system did not return a `Handle` from then the contents of `handle` are
+    /// undefined.
+    ///
+    /// If `flags` contains `IoctlFlags::UNRESTRICTED` then the file system may retry the ioctl
+    /// after informing the kernel about the input and output areas. If `flags` does not contain
+    /// `IoctlFlags::UNRESTRICTED` then the kernel will prepare the input and output areas according
+    /// to the encoding in the ioctl command. In that case the ioctl cannot be retried.
+    ///
+    /// `cmd` is the ioctl request made by the calling process, truncated to 32 bits.
+    ///
+    /// `arg` is the argument provided by the calling process.
+    ///
+    /// `in_size` is the length of the additional data that accompanies the request. The file system
+    /// may fetch this data from `reader`.
+    ///
+    /// `out_size` is the length of the output area prepared by the kernel to hold the response to
+    /// the ioctl.
+    fn ioctl<R: io::Read>(
+        &self,
+        ctx: Context,
+        handle: Self::Handle,
+        flags: IoctlFlags,
+        cmd: u32,
+        arg: u64,
+        in_size: u32,
+        out_size: u32,
+        reader: R,
+    ) -> io::Result<IoctlReply> {
         Err(io::Error::from_raw_os_error(libc::ENOSYS))
     }
 
     /// TODO: support this
-    fn setlk(&self) -> io::Result<()> {
+    fn getlk(&self) -> io::Result<()> {
         Err(io::Error::from_raw_os_error(libc::ENOSYS))
     }
 
     /// TODO: support this
-    fn setlkw(&self) -> io::Result<()> {
+    fn setlk(&self) -> io::Result<()> {
         Err(io::Error::from_raw_os_error(libc::ENOSYS))
     }
 
     /// TODO: support this
-    fn ioctl(&self) -> io::Result<()> {
+    fn setlkw(&self) -> io::Result<()> {
         Err(io::Error::from_raw_os_error(libc::ENOSYS))
     }