diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-01-06 08:18:58 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-01-06 08:18:58 -0600 |
| commit | b3a9082a8b81c28ef81dbaaffe171f646b1f2777 (patch) | |
| tree | d878ad0185657eff76426888d46420b48e47725b | |
| parent | a65325e15844f880132a69b447e4aec983cb30ab (diff) | |
Implement Fsync/Fsyncdir
Diffstat (limited to '')
| -rw-r--r-- | examples/passthrough.rs | 40 | ||||
| -rw-r--r-- | src/io.rs | 2 | ||||
| -rw-r--r-- | src/ops/mod.rs | 2 | ||||
| -rw-r--r-- | src/ops/rw.rs | 52 | ||||
| -rw-r--r-- | src/proto.rs | 6 | ||||
| -rw-r--r-- | src/session.rs | 12 |
6 files changed, 96 insertions, 18 deletions
diff --git a/examples/passthrough.rs b/examples/passthrough.rs index 7115fb1..2837d81 100644 --- a/examples/passthrough.rs +++ b/examples/passthrough.rs @@ -12,7 +12,7 @@ use std::{ }; use blown_fuse::{ - io::{Attrs, Entry, EntryType, Gid, Known, Mode, OpenFlags, Stat, Uid}, + io::{Attrs, Entry, EntryType, FsyncFlags, Gid, Known, Mode, OpenFlags, Stat, Uid}, mount::mount_sync, ops, session::{Dispatch, Start}, @@ -135,6 +135,16 @@ impl Passthrough { reply.blob(&target) } + async fn symlink<'o>(&mut self, (request, reply): Op<'o, ops::Symlink>) -> Done<'o> { + let (reply, inode) = reply.and_then(self.known(request.ino()))?; + let path = inode.path.join(request.name()); + + let (reply, ()) = reply.and_then(fs::symlink(request.target(), &path).await)?; + let (reply, metadata) = reply.and_then(fs::symlink_metadata(&path).await)?; + + reply.known(New(&mut self.known, Inode::new(path, metadata)), Ttl::MAX) + } + async fn mkdir<'o>(&mut self, (request, reply): Op<'o, ops::Mkdir>) -> Done<'o> { let (reply, inode) = reply.and_then(self.known(request.ino()))?; let path = inode.path.join(request.name()); @@ -161,16 +171,6 @@ impl Passthrough { reply.ok() } - async fn symlink<'o>(&mut self, (request, reply): Op<'o, ops::Symlink>) -> Done<'o> { - let (reply, inode) = reply.and_then(self.known(request.ino()))?; - let path = inode.path.join(request.name()); - - let (reply, ()) = reply.and_then(fs::symlink(request.target(), &path).await)?; - let (reply, metadata) = reply.and_then(fs::symlink_metadata(&path).await)?; - - reply.known(New(&mut self.known, Inode::new(path, metadata)), Ttl::MAX) - } - async fn open<'o>(&mut self, (request, reply): Op<'o, ops::Open>) -> Done<'o> { let (reply, inode) = reply.and_then(self.known(request.ino()))?; let options = { @@ -230,6 +230,21 @@ impl Passthrough { reply.ok() } + async fn fsync<'o>(&mut self, (request, reply): Op<'o, ops::Fsync>) -> Done<'o> { + let (reply, file) = reply.and_then(self.open_files.get(request.handle()))?; + let (reply, ()) = { + let result = if request.flags().contains(FsyncFlags::FDATASYNC) { + file.handle.sync_data().await + } else { + file.handle.sync_all().await + }; + + reply.and_then(result)? + }; + + reply.ok() + } + async fn opendir<'o>(&mut self, (request, reply): Op<'o, ops::Opendir>) -> Done<'o> { let (reply, inode) = reply.and_then(self.known(request.ino()))?; let (mut reply, mut stream) = reply.and_then(fs::read_dir(&inode.path).await)?; @@ -375,15 +390,16 @@ async fn main_loop(session: Start, mut fs: Passthrough) -> FuseResult<()> { Forget(forget) => fs.forget(forget.op()?), Getattr(getattr) => fs.getattr(getattr.op()?), Readlink(readlink) => fs.readlink(readlink.op()?).await, + Symlink(symlink) => fs.symlink(symlink.op()?).await, Mkdir(mkdir) => fs.mkdir(mkdir.op()?).await, Unlink(unlink) => fs.unlink(unlink.op()?).await, Rmdir(rmdir) => fs.rmdir(rmdir.op()?).await, - Symlink(symlink) => fs.symlink(symlink.op()?).await, //TODO: Link Open(open) => fs.open(open.op()?).await, Read(read) => fs.read(read.op()?).await, Write(write) => fs.write(write.op()?).await, Release(release) => fs.release(release.op()?), + Fsync(fsync) => fs.fsync(fsync.op()?).await, Opendir(opendir) => fs.opendir(opendir.op()?).await, Readdir(readdir) => fs.readdir(readdir.op()?).await, Releasedir(releasedir) => fs.releasedir(releasedir.op()?), @@ -19,6 +19,8 @@ pub use nix::{ unistd::{AccessFlags, Gid, Pid, Uid}, }; +pub use proto::FsyncFlags; + pub enum Interruptible<'o, O: Operation<'o>, T> { Completed(Reply<'o, O>, T), Interrupted(Done<'o>), diff --git a/src/ops/mod.rs b/src/ops/mod.rs index bc486b1..de13ac6 100644 --- a/src/ops/mod.rs +++ b/src/ops/mod.rs @@ -15,7 +15,7 @@ pub use dir::{BufferedReaddir, Lookup, Readdir}; pub use entry::{Forget, Getattr, Link, Mkdir, Rmdir, Symlink, Unlink}; pub use global::{Init, Statfs}; pub use open::{Access, Open, Opendir, Release, Releasedir}; -pub use rw::{Flush, Read, Readlink, Write}; +pub use rw::{Flush, Fsync, Fsyncdir, Read, Readlink, Write}; pub use xattr::{Getxattr, Listxattr, Removexattr, Setxattr}; mod dir; diff --git a/src/ops/rw.rs b/src/ops/rw.rs index cf2e286..4f5bad4 100644 --- a/src/ops/rw.rs +++ b/src/ops/rw.rs @@ -1,14 +1,18 @@ use super::{ - traits::{ReplyGather, ReplyOk, RequestData, RequestHandle, RequestOffset, RequestSize}, + traits::{ + ReplyGather, ReplyOk, RequestData, RequestFlags, RequestHandle, RequestOffset, RequestSize, + }, FromRequest, }; -use crate::{private_trait::Sealed, proto, Done, Operation, Reply, Request}; +use crate::{io::FsyncFlags, private_trait::Sealed, proto, Done, Operation, Reply, Request}; pub enum Readlink {} pub enum Read {} pub enum Write {} +pub enum Fsync {} pub enum Flush {} +pub enum Fsyncdir {} pub struct WriteState { size: u32, @@ -21,7 +25,9 @@ pub trait ReplyAll<'o>: Operation<'o> { impl Sealed for Readlink {} impl Sealed for Read {} impl Sealed for Write {} +impl Sealed for Fsync {} impl Sealed for Flush {} +impl Sealed for Fsyncdir {} impl<'o> Operation<'o> for Readlink { type RequestBody = (); @@ -38,11 +44,21 @@ impl<'o> Operation<'o> for Write { type ReplyState = WriteState; } +impl<'o> Operation<'o> for Fsync { + type RequestBody = &'o proto::FsyncIn; + type ReplyState = (); +} + impl<'o> Operation<'o> for Flush { type RequestBody = &'o proto::FlushIn; type ReplyState = (); } +impl<'o> Operation<'o> for Fsyncdir { + type RequestBody = &'o proto::FsyncdirIn; + type ReplyState = (); +} + impl<'o> ReplyGather<'o> for Readlink {} impl<'o> RequestHandle<'o> for Read { @@ -93,6 +109,22 @@ impl<'o> ReplyAll<'o> for Write { } } +impl<'o> RequestHandle<'o> for Fsync { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.fh + } +} + +impl<'o> RequestFlags<'o> for Fsync { + type Flags = FsyncFlags; + + fn flags(request: &Request<'o, Self>) -> Self::Flags { + FsyncFlags::from_bits_truncate(request.body.fsync_flags) + } +} + +impl<'o> ReplyOk<'o> for Fsync {} + impl<'o> RequestHandle<'o> for Flush { fn handle(request: &Request<'o, Self>) -> u64 { request.body.fh @@ -101,6 +133,22 @@ impl<'o> RequestHandle<'o> for Flush { impl<'o> ReplyOk<'o> for Flush {} +impl<'o> RequestHandle<'o> for Fsyncdir { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.fsync_in.fh + } +} + +impl<'o> RequestFlags<'o> for Fsyncdir { + type Flags = FsyncFlags; + + fn flags(request: &Request<'o, Self>) -> Self::Flags { + FsyncFlags::from_bits_truncate(request.body.fsync_in.fsync_flags) + } +} + +impl<'o> ReplyOk<'o> for Fsyncdir {} + impl<'o> FromRequest<'o, Write> for WriteState { fn from_request(request: &Request<'o, Write>) -> Self { let (body, data) = request.body; diff --git a/src/proto.rs b/src/proto.rs index 2d53fe6..7e81201 100644 --- a/src/proto.rs +++ b/src/proto.rs @@ -332,6 +332,12 @@ pub struct FsyncIn { pub padding: u32, } +bitflags! { + pub struct FsyncFlags: u32 { + const FDATASYNC = 1 << 0; + } +} + #[derive(Pod, Zeroable, Copy, Clone)] #[repr(C)] pub struct SetxattrIn { diff --git a/src/session.rs b/src/session.rs index 696d97a..7c4172b 100644 --- a/src/session.rs +++ b/src/session.rs @@ -59,16 +59,17 @@ pub enum Dispatch<'o> { Forget(Incoming<'o, ops::Forget>), Getattr(Incoming<'o, ops::Getattr>), Readlink(Incoming<'o, ops::Readlink>), + Symlink(Incoming<'o, ops::Symlink>), Mkdir(Incoming<'o, ops::Mkdir>), Unlink(Incoming<'o, ops::Unlink>), Rmdir(Incoming<'o, ops::Rmdir>), - Symlink(Incoming<'o, ops::Symlink>), Link(Incoming<'o, ops::Link>), Open(Incoming<'o, ops::Open>), Read(Incoming<'o, ops::Read>), Write(Incoming<'o, ops::Write>), Statfs(Incoming<'o, ops::Statfs>), Release(Incoming<'o, ops::Release>), + Fsync(Incoming<'o, ops::Fsync>), Setxattr(Incoming<'o, ops::Setxattr>), Getxattr(Incoming<'o, ops::Getxattr>), Listxattr(Incoming<'o, ops::Listxattr>), @@ -77,6 +78,7 @@ pub enum Dispatch<'o> { Opendir(Incoming<'o, ops::Opendir>), Readdir(Incoming<'o, ops::Readdir>), Releasedir(Incoming<'o, ops::Releasedir>), + Fsyncdir(Incoming<'o, ops::Fsyncdir>), Access(Incoming<'o, ops::Access>), } @@ -257,16 +259,17 @@ impl<'o> Dispatch<'o> { Forget(incoming) => incoming.common, Getattr(incoming) => incoming.common, Readlink(incoming) => incoming.common, + Symlink(incoming) => incoming.common, Mkdir(incoming) => incoming.common, Unlink(incoming) => incoming.common, Rmdir(incoming) => incoming.common, - Symlink(incoming) => incoming.common, Link(incoming) => incoming.common, Open(incoming) => incoming.common, Read(incoming) => incoming.common, Write(incoming) => incoming.common, Statfs(incoming) => incoming.common, Release(incoming) => incoming.common, + Fsync(incoming) => incoming.common, Setxattr(incoming) => incoming.common, Getxattr(incoming) => incoming.common, Listxattr(incoming) => incoming.common, @@ -275,6 +278,7 @@ impl<'o> Dispatch<'o> { Opendir(incoming) => incoming.common, Readdir(incoming) => incoming.common, Releasedir(incoming) => incoming.common, + Fsyncdir(incoming) => incoming.common, Access(incoming) => incoming.common, }; @@ -342,16 +346,17 @@ impl Endpoint<'_> { Forget => dispatch!(Forget), Getattr => dispatch!(Getattr), Readlink => dispatch!(Readlink), + Symlink => dispatch!(Symlink), Mkdir => dispatch!(Mkdir), Unlink => dispatch!(Unlink), Rmdir => dispatch!(Rmdir), - Symlink => dispatch!(Symlink), Link => dispatch!(Link), Open => dispatch!(Open), Read => dispatch!(Read), Write => dispatch!(Write), Statfs => dispatch!(Statfs), Release => dispatch!(Release), + Fsync => dispatch!(Fsync), Setxattr => dispatch!(Setxattr), Getxattr => dispatch!(Getxattr), Listxattr => dispatch!(Listxattr), @@ -360,6 +365,7 @@ impl Endpoint<'_> { Opendir => dispatch!(Opendir), Readdir => dispatch!(Readdir), Releasedir => dispatch!(Releasedir), + Fsyncdir => dispatch!(Fsyncdir), Access => dispatch!(Access), BatchForget => dispatch!(Forget), ReaddirPlus => dispatch!(Readdir), |
