summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/passthrough.rs11
-rw-r--r--src/ops/entry.rs27
-rw-r--r--src/ops/mod.rs2
-rw-r--r--src/ops/traits.rs9
-rw-r--r--src/session.rs3
5 files changed, 50 insertions, 2 deletions
diff --git a/examples/passthrough.rs b/examples/passthrough.rs
index 32f50ca..7115fb1 100644
--- a/examples/passthrough.rs
+++ b/examples/passthrough.rs
@@ -161,6 +161,16 @@ 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 = {
@@ -368,6 +378,7 @@ async fn main_loop(session: Start, mut fs: Passthrough) -> FuseResult<()> {
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,
diff --git a/src/ops/entry.rs b/src/ops/entry.rs
index 74072ef..435188a 100644
--- a/src/ops/entry.rs
+++ b/src/ops/entry.rs
@@ -16,12 +16,17 @@ pub enum Getattr {}
pub enum Mkdir {}
pub enum Unlink {}
pub enum Rmdir {}
+pub enum Symlink {}
pub enum Link {}
pub trait RequestForget<'o>: Operation<'o> {
fn forget_list<'a>(request: &'a Request<'o, Self>) -> ForgetList<'a>;
}
+pub trait RequestTarget<'o>: Operation<'o> {
+ fn target<'a>(request: &'a Request<'o, Self>) -> &'a OsStr;
+}
+
pub trait RequestLink<'o>: Operation<'o> {
fn source_ino(request: &Request<'o, Self>) -> Ino;
}
@@ -40,6 +45,7 @@ impl Sealed for Getattr {}
impl Sealed for Mkdir {}
impl Sealed for Unlink {}
impl Sealed for Rmdir {}
+impl Sealed for Symlink {}
impl Sealed for Link {}
impl<'o> Operation<'o> for Forget {
@@ -72,6 +78,11 @@ impl<'o> Operation<'o> for Rmdir {
type ReplyState = ();
}
+impl<'o> Operation<'o> for Symlink {
+ type RequestBody = (&'o CStr, &'o CStr); // name(), target()
+ type ReplyState = ();
+}
+
impl<'o> Operation<'o> for Link {
type RequestBody = (&'o proto::LinkIn, &'o CStr);
type ReplyState = ();
@@ -161,6 +172,22 @@ impl<'o> RequestName<'o> for Rmdir {
impl<'o> ReplyOk<'o> for Rmdir {}
+impl<'o> RequestName<'o> for Symlink {
+ fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
+ let (name, _target) = request.body;
+ c_to_os(name)
+ }
+}
+
+impl<'o> RequestTarget<'o> for Symlink {
+ fn target<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
+ let (_name, target) = request.body;
+ c_to_os(target)
+ }
+}
+
+impl<'o> ReplyKnown<'o> for Symlink {}
+
impl<'o> RequestName<'o> for Link {
fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
let (_header, name) = request.body;
diff --git a/src/ops/mod.rs b/src/ops/mod.rs
index 2970ef8..bc486b1 100644
--- a/src/ops/mod.rs
+++ b/src/ops/mod.rs
@@ -12,7 +12,7 @@ use bytemuck::{bytes_of, Pod};
pub mod traits;
pub use dir::{BufferedReaddir, Lookup, Readdir};
-pub use entry::{Forget, Getattr, Link, Mkdir, Rmdir, Unlink};
+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};
diff --git a/src/ops/traits.rs b/src/ops/traits.rs
index 6a4b1ce..52aaed3 100644
--- a/src/ops/traits.rs
+++ b/src/ops/traits.rs
@@ -5,7 +5,7 @@ use crate::{
pub use super::{
dir::{ReplyEntries, ReplyFound},
- entry::{ReplyStat, RequestForget, RequestLink},
+ entry::{ReplyStat, RequestForget, RequestLink, RequestTarget},
global::ReplyFsInfo,
open::{ReplyOpen, ReplyPermissionDenied},
rw::ReplyAll,
@@ -146,6 +146,13 @@ impl<'o, O: Operation<'o>> Request<'o, O> {
O::forget_list(self)
}
+ pub fn target(&self) -> &OsStr
+ where
+ O: RequestTarget<'o>,
+ {
+ O::target(self)
+ }
+
pub fn source_ino(&self) -> Ino
where
O: RequestLink<'o>,
diff --git a/src/session.rs b/src/session.rs
index 5f6336f..696d97a 100644
--- a/src/session.rs
+++ b/src/session.rs
@@ -62,6 +62,7 @@ pub enum Dispatch<'o> {
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>),
@@ -259,6 +260,7 @@ impl<'o> Dispatch<'o> {
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,
@@ -343,6 +345,7 @@ impl Endpoint<'_> {
Mkdir => dispatch!(Mkdir),
Unlink => dispatch!(Unlink),
Rmdir => dispatch!(Rmdir),
+ Symlink => dispatch!(Symlink),
Link => dispatch!(Link),
Open => dispatch!(Open),
Read => dispatch!(Read),