aster_forge_cloud_files_linux/
lib.rs1#![cfg_attr(
10 not(test),
11 deny(
12 clippy::unwrap_used,
13 clippy::unreachable,
14 clippy::expect_used,
15 clippy::panic,
16 clippy::unimplemented,
17 clippy::todo
18 )
19)]
20
21mod dispatch;
22mod engine;
23mod error;
24mod inode;
25mod namespace;
26mod remote;
27mod writeback;
28
29#[cfg(target_os = "linux")]
30mod native;
31
32pub use dispatch::{
33 LinuxDispatchMetrics, LinuxDispatchRejection, LinuxDispatchReservation, LinuxRequestDispatcher,
34};
35pub use engine::{
36 LinuxAttributePolicy, LinuxDirectoryEntry, LinuxDirectoryHandle, LinuxDirectorySnapshot,
37 LinuxFileAttributes, LinuxFileHandle, LinuxNode, LinuxNodeKind, LinuxReadOnlyEngine,
38 validate_linux_name,
39};
40pub use error::{
41 LinuxCloudFilesError, LinuxErrorCode, Result, backend_error_code, namespace_store_error_code,
42 writeback_store_error_code,
43};
44pub use inode::{
45 LINUX_ROOT_INODE, LinuxInode, LinuxInodeGeneration, LinuxInodeRecord, LinuxInodeTable,
46};
47pub use namespace::{
48 LinuxCreateDirectoryRequest, LinuxCreateFileAcceptance, LinuxCreateFileRequest,
49 LinuxCreatedFile, LinuxNamespaceItem, LinuxNamespaceMutationStore,
50 LinuxNamespaceMutationStoreError, LinuxNamespaceMutationStoreErrorKind, LinuxNamespaceOverlay,
51 LinuxNamespaceStoreResult, LinuxNamespaceTombstone, LinuxRemoveRequest, LinuxRenameAcceptance,
52 LinuxRenameDestination, LinuxRenameRequest,
53};
54#[cfg(target_os = "linux")]
55pub use native::{
56 LinuxBackgroundSession, LinuxKernelNotifier, LinuxReadOnlyFilesystem, LinuxWritableFilesystem,
57 mount_read_only, mount_writable, spawn_mount_read_only, spawn_mount_writable,
58};
59pub use remote::{
60 LinuxInvalidation, LinuxRemoteChange, LinuxRemoteDelete, LinuxRemoteEntry, LinuxRemoteLocation,
61 LinuxRemoteUpsert,
62};
63pub use writeback::{
64 LinuxFileAccess, LinuxWritableEngine, LinuxWriteCommit, LinuxWriteOpenRequest,
65 LinuxWriteSession, LinuxWriteSessionId, LinuxWritebackStore,
66};
67
68#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct LinuxMountConfig {
71 filesystem_name: String,
72 subtype: Option<String>,
73 kernel_threads: Option<usize>,
74 clone_fd: bool,
75}
76
77impl LinuxMountConfig {
78 pub fn new(filesystem_name: impl Into<String>) -> Result<Self> {
84 let filesystem_name = filesystem_name.into();
85 validate_mount_text(&filesystem_name, "filesystem name")?;
86 Ok(Self {
87 filesystem_name,
88 subtype: None,
89 kernel_threads: None,
90 clone_fd: false,
91 })
92 }
93
94 pub fn with_subtype(mut self, subtype: impl Into<String>) -> Result<Self> {
100 let subtype = subtype.into();
101 validate_mount_text(&subtype, "filesystem subtype")?;
102 self.subtype = Some(subtype);
103 Ok(self)
104 }
105
106 pub fn with_kernel_threads(mut self, threads: usize, clone_fd: bool) -> Result<Self> {
112 if threads == 0 {
113 return Err(LinuxCloudFilesError::InvalidConfiguration {
114 reason: "kernel event-loop thread count must be greater than zero",
115 });
116 }
117 self.kernel_threads = Some(threads);
118 self.clone_fd = clone_fd;
119 Ok(self)
120 }
121
122 #[must_use]
124 pub fn filesystem_name(&self) -> &str {
125 &self.filesystem_name
126 }
127
128 #[must_use]
130 pub fn subtype(&self) -> Option<&str> {
131 self.subtype.as_deref()
132 }
133
134 #[must_use]
136 pub const fn kernel_threads(&self) -> Option<usize> {
137 self.kernel_threads
138 }
139
140 #[must_use]
142 pub const fn clone_fd(&self) -> bool {
143 self.clone_fd
144 }
145}
146
147fn validate_mount_text(value: &str, _field: &'static str) -> Result<()> {
148 if value.is_empty() {
149 return Err(LinuxCloudFilesError::InvalidConfiguration {
150 reason: "mount identity text must not be empty",
151 });
152 }
153 if value.contains('\0') || value.contains(',') {
154 return Err(LinuxCloudFilesError::InvalidConfiguration {
155 reason: "mount identity text must not contain NUL or comma",
156 });
157 }
158 Ok(())
159}