summaryrefslogtreecommitdiff
path: root/src/fuse/fs.rs
blob: 4cf32820c972161ceef9b3182a9d539fb0baee4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use async_trait::async_trait;
use nix::errno::Errno;

use std::{
    num::NonZeroUsize,
    ops::{Deref, DerefMut},
    sync::Arc,
};

use crate::{Ino, TimeToLive};

use super::{
    io::{Attrs, EntryType},
    ops::*,
    Done, Op, Reply,
};

#[async_trait]
pub trait Fuse: Sized + Send + Sync + 'static {
    type Inode: Inode<Fuse = Self> + ?Sized;
    type Farc: Deref<Target = Self::Inode> + Clone + Send + Sync = Arc<Self::Inode>;

    async fn init<'o>(&self, reply: Reply<'o, Self, Init>) -> Done<'o>;

    async fn statfs<'o>(&self, (_, reply, _): Op<'o, Self, Statfs>) -> Done<'o> {
        reply.not_implemented()
    }

    fn request_buffers(&self) -> NonZeroUsize {
        NonZeroUsize::new(16).unwrap()
    }

    fn request_buffer_pages(&self) -> NonZeroUsize {
        NonZeroUsize::new(4).unwrap()
    }
}

#[async_trait]
pub trait Inode: Send + Sync {
    type Fuse: Fuse<Inode = Self>;

    fn ino(self: &FarcTo<Self>) -> Ino;
    fn attrs(self: &FarcTo<Self>) -> (Attrs, TimeToLive);
    fn inode_type(self: &FarcTo<Self>) -> EntryType;

    fn direct_io<'o>(self: &FarcTo<Self>) -> bool {
        false
    }

    fn access<'o>(self: &FarcTo<Self>, (_, reply, _): Op<'o, Self::Fuse, Access>) -> Done<'o> {
        reply.not_implemented()
    }

    async fn lookup<'o>(self: FarcTo<Self>, (_, reply, _): Op<'o, Self::Fuse, Lookup>) -> Done<'o> {
        reply.not_implemented()
    }

    async fn readlink<'o>(
        self: FarcTo<Self>,
        (_, reply, _): Op<'o, Self::Fuse, Readlink>,
    ) -> Done<'o> {
        reply.not_implemented()
    }

    async fn open<'o>(self: FarcTo<Self>, (_, reply, _): Op<'o, Self::Fuse, Open>) -> Done<'o> {
        // Calling not_implemented() here would ignore direct_io() and similar flags
        reply.ok()
    }

    async fn opendir<'o>(
        self: FarcTo<Self>,
        (_, reply, _): Op<'o, Self::Fuse, Opendir>,
    ) -> Done<'o> {
        reply.not_implemented()
    }

    async fn readdir<'o>(
        self: FarcTo<Self>,
        (_, reply, _): Op<'o, Self::Fuse, Readdir>,
    ) -> Done<'o> {
        reply.not_implemented()
    }
}

#[async_trait]
pub trait Tape: Send + Sync {
    type Fuse: Fuse;

    async fn seek(self: &mut Head<Self>, offset: u64) -> Result<(), Errno>;

    async fn rewind(self: &mut Head<Self>) -> Result<(), Errno> {
        self.seek(0).await
    }

    async fn read<'o>(self: &mut Head<Self>, (_, reply, _): Op<'o, Self::Fuse, Read>) -> Done<'o> {
        reply.not_implemented()
    }

    async fn write<'o>(
        self: &mut Head<Self>,
        (_, reply, _): Op<'o, Self::Fuse, Write>,
    ) -> Done<'o> {
        reply.not_implemented()
    }
}

pub type FarcTo<I> = <<I as Inode>::Fuse as Fuse>::Farc;

pub struct Head<T: Tape + ?Sized> {
    offset: u64,
    inode: <T::Fuse as Fuse>::Farc,
    tape: T,
}

impl<T: Tape + ?Sized> Deref for Head<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.tape
    }
}

impl<T: Tape + ?Sized> DerefMut for Head<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.tape
    }
}