fuse_backend_rs/passthrough/
config.rs

1// Copyright (C) 2020-2022 Alibaba Cloud. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::str::FromStr;
5use std::time::Duration;
6
7/// The caching policy that the file system should report to the FUSE client. By default the FUSE
8/// protocol uses close-to-open consistency. This means that any cached contents of the file are
9/// invalidated the next time that file is opened.
10#[derive(Debug, Default, Clone, Eq, PartialEq)]
11pub enum CachePolicy {
12    /// The client should never cache file data and all I/O should be directly forwarded to the
13    /// server. This policy must be selected when file contents may change without the knowledge of
14    /// the FUSE client (i.e., the file system does not have exclusive access to the directory).
15    Never,
16
17    /// This is almost same as Never, but it allows page cache of directories, dentries and attr
18    /// cache in guest. In other words, it acts like cache=never for normal files, and like
19    /// cache=always for directories, besides, metadata like dentries and attrs are kept as well.
20    /// This policy can be used if:
21    /// 1. the client wants to use Never policy but it's performance in I/O is not good enough
22    /// 2. the file system has exclusive access to the directory
23    /// 3. cache directory content and other fs metadata can make a difference on performance.
24    Metadata,
25
26    /// The client is free to choose when and how to cache file data. This is the default policy and
27    /// uses close-to-open consistency as described in the enum documentation.
28    #[default]
29    Auto,
30
31    /// The client should always cache file data. This means that the FUSE client will not
32    /// invalidate any cached data that was returned by the file system the last time the file was
33    /// opened. This policy should only be selected when the file system has exclusive access to the
34    /// directory.
35    Always,
36}
37
38impl FromStr for CachePolicy {
39    type Err = &'static str;
40
41    fn from_str(s: &str) -> Result<Self, Self::Err> {
42        match s {
43            "never" | "Never" | "NEVER" | "none" | "None" | "NONE" => Ok(CachePolicy::Never),
44            "metadata" => Ok(CachePolicy::Metadata),
45            "auto" | "Auto" | "AUTO" => Ok(CachePolicy::Auto),
46            "always" | "Always" | "ALWAYS" => Ok(CachePolicy::Always),
47            _ => Err("invalid cache policy"),
48        }
49    }
50}
51
52/// Options that configure the behavior of the passthrough fuse file system.
53#[derive(Debug, Clone, Eq, PartialEq)]
54pub struct Config {
55    /// How long the FUSE client should consider file and directory attributes to be valid. If the
56    /// attributes of a file or directory can only be modified by the FUSE client (i.e., the file
57    /// system has exclusive access), then this should be set to a large value.
58    ///
59    /// The default value for this option is 5 seconds.
60    pub attr_timeout: Duration,
61
62    /// How long the FUSE client should consider directory entries to be valid. If the contents of a
63    /// directory can only be modified by the FUSE client (i.e., the file system has exclusive
64    /// access), then this should be a large value.
65    ///
66    /// The default value for this option is 5 seconds.
67    pub entry_timeout: Duration,
68
69    /// Same as `attr_timeout`, override `attr_timeout` config, but only take effect on directories
70    /// when specified. This is useful to set different timeouts for directories and regular files.
71    pub dir_attr_timeout: Option<Duration>,
72
73    /// Same as `entry_timeout`, override `entry_timeout` config, but only take effect on
74    /// directories when specified. This is useful to set different timeouts for directories and
75    /// regular files.
76    pub dir_entry_timeout: Option<Duration>,
77
78    /// The caching policy the file system should use. See the documentation of `CachePolicy` for
79    /// more details.
80    pub cache_policy: CachePolicy,
81
82    /// Whether the file system should enable writeback caching. This can improve performance as it
83    /// allows the FUSE client to cache and coalesce multiple writes before sending them to the file
84    /// system. However, enabling this option can increase the risk of data corruption if the file
85    /// contents can change without the knowledge of the FUSE client (i.e., the server does **NOT**
86    /// have exclusive access). Additionally, the file system should have read access to all files
87    /// in the directory it is serving as the FUSE client may send read requests even for files
88    /// opened with `O_WRONLY`.
89    ///
90    /// Therefore callers should only enable this option when they can guarantee that: 1) the file
91    /// system has exclusive access to the directory and 2) the file system has read permissions for
92    /// all files in that directory.
93    ///
94    /// The default value for this option is `false`.
95    pub writeback: bool,
96
97    /// The path of the root directory.
98    ///
99    /// The default is `/`.
100    pub root_dir: String,
101
102    /// Whether the file system should support Extended Attributes (xattr). Enabling this feature may
103    /// have a significant impact on performance, especially on write parallelism. This is the result
104    /// of FUSE attempting to remove the special file privileges after each write request.
105    ///
106    /// The default value for this options is `false`.
107    pub xattr: bool,
108
109    /// To be compatible with Vfs and PseudoFs, PassthroughFs needs to prepare
110    /// root inode before accepting INIT request.
111    ///
112    /// The default value for this option is `true`.
113    pub do_import: bool,
114
115    /// Control whether no_open is allowed.
116    ///
117    /// The default value for this option is `false`.
118    pub no_open: bool,
119
120    /// Control whether no_opendir is allowed.
121    ///
122    /// The default value for this option is `false`.
123    pub no_opendir: bool,
124
125    /// Control whether kill_priv_v2 is enabled.
126    ///
127    /// The default value for this option is `false`.
128    pub killpriv_v2: bool,
129
130    /// Whether to use file handles to reference inodes.  We need to be able to open file
131    /// descriptors for arbitrary inodes, and by default that is done by storing an `O_PATH` FD in
132    /// `InodeData`.  Not least because there is a maximum number of FDs a process can have open
133    /// users may find it preferable to store a file handle instead, which we can use to open an FD
134    /// when necessary.
135    /// So this switch allows to choose between the alternatives: When set to `false`, `InodeData`
136    /// will store `O_PATH` FDs.  Otherwise, we will attempt to generate and store a file handle
137    /// instead.
138    ///
139    /// The default is `false`.
140    pub inode_file_handles: bool,
141
142    /// Control whether readdir/readdirplus requests return zero dirent to client, as if the
143    /// directory is empty even if it has children.
144    pub no_readdir: bool,
145
146    /// Control whether to refuse operations which modify the size of the file. For a share memory
147    /// file mounted from host, seal_size can prohibit guest to increase the size of
148    /// share memory file to attack the host.
149    pub seal_size: bool,
150
151    /// Whether count mount ID or not when comparing two inodes. By default we think two inodes
152    /// are same if their inode number and st_dev are the same. When `enable_mntid` is set as
153    /// 'true', inode's mount ID will be taken into account as well. For example, bindmount the
154    /// same file into virtiofs' source dir, the two bindmounted files will be identified as two
155    /// different inodes when this option is true, so the don't share pagecache.
156    ///
157    /// The default value for this option is `false`.
158    pub enable_mntid: bool,
159
160    /// What size file supports dax
161    /// * If dax_file_size == None, DAX will disable to all files.
162    /// * If dax_file_size == 0, DAX will enable all files.
163    /// * If dax_file_size == N, DAX will enable only when the file size is greater than or equal
164    /// to N Bytes.
165    pub dax_file_size: Option<u64>,
166
167    /// Reduce memory consumption by directly use host inode when possible.
168    ///
169    /// When set to false, a virtual inode number will be allocated for each file managed by
170    /// the passthroughfs driver. A map is used to maintain the relationship between virtual
171    /// inode numbers and host file objects.
172    /// When set to true, the host inode number will be directly used as virtual inode number
173    /// if it's less than the threshold (1 << 47), so reduce memory consumed by the map.
174    /// A virtual inode number will still be allocated and maintained if the host inode number
175    /// is bigger than the threshold.
176    /// The default value for this option is `false`.
177    pub use_host_ino: bool,
178}
179
180impl Default for Config {
181    fn default() -> Self {
182        Config {
183            entry_timeout: Duration::from_secs(5),
184            attr_timeout: Duration::from_secs(5),
185            cache_policy: Default::default(),
186            writeback: false,
187            root_dir: String::from("/"),
188            xattr: false,
189            do_import: true,
190            no_open: false,
191            no_opendir: false,
192            killpriv_v2: false,
193            inode_file_handles: false,
194            no_readdir: false,
195            seal_size: false,
196            enable_mntid: false,
197            dax_file_size: None,
198            dir_entry_timeout: None,
199            dir_attr_timeout: None,
200            use_host_ino: false,
201        }
202    }
203}