1use crate::*;
5use std::path::{Path, PathBuf};
6use vfsi_core::internal::ManyResults;
7
8pub trait FileSystem {
12 fn vstatfs_impl(&mut self, files: &[VfFile]) -> VfResult<Vec<FilesystemStats>> {
13 crate::backend_helpers::vstatfs_impl_default(self, files)
14 }
15
16 fn close_deferred(&mut self, file: &VfFile) -> VfResult<()> {
17 crate::backend_helpers::close_deferred_default(self, file)
18 }
19
20 fn take_notifications(&mut self) -> Vec<Box<dyn FnOnce() + Send>> {
21 crate::backend_helpers::take_notifications_default(self)
22 }
23
24 fn capability_bits(&self) -> u64 {
25 crate::backend_helpers::capability_bits_default(self)
26 }
27
28 fn capabilities(&self) -> Capabilities {
29 crate::backend_helpers::typed_capabilities_default(self)
30 }
31
32 fn abs_path(&self, path: &Path) -> PathBuf {
33 crate::backend_helpers::abs_path_default(self, path)
34 }
35
36 fn open_path_impl(
37 &mut self,
38 base: VfPathBase,
39 pathname: &Path,
40 flags: i32,
41 mode: u32,
42 ) -> VfResult<VfFile> {
43 crate::backend_helpers::open_path_impl_default(self, base, pathname, flags, mode)
44 }
45
46 fn sync_data(&mut self, tcf: &VfFile) -> VfResult<()>;
47
48 fn sync_all(&mut self, tcf: &VfFile) -> VfResult<()> {
49 crate::backend_helpers::sync_all_default(self, tcf)
50 }
51
52 fn chdir(&mut self, path: &Path) -> VfResult<()> {
53 crate::backend_helpers::chdir_default(self, path)
54 }
55
56 fn getcwd(&self) -> PathBuf {
57 crate::backend_helpers::getcwd_default(self)
58 }
59
60 fn seek_raw_impl(&mut self, tcf: &VfFile, offset: i64, whence: SeekFrom) -> VfResult<i64> {
61 crate::backend_helpers::seek_raw_impl_default(self, tcf, offset, whence)
62 }
63
64 fn vf_path(&self, file: &VfFile) -> VfResult<PathBuf> {
65 crate::backend_helpers::vf_path_default(self, file)
66 }
67
68 fn open_raw_impl(&mut self, pathname: &Path, flags: i32, mode: u32) -> VfResult<VfFile> {
69 crate::backend_helpers::open_raw_impl_default(self, pathname, flags, mode)
70 }
71
72 fn read_raw_impl(&mut self, file: &VfFile, offset: u64, length: usize) -> VfResult<Vec<u8>> {
73 crate::backend_helpers::read_raw_impl_default(self, file, offset, length)
74 }
75
76 fn write_raw_impl(&mut self, file: &VfFile, offset: u64, data: &[u8]) -> VfResult<usize> {
77 crate::backend_helpers::write_raw_impl_default(self, file, offset, data)
78 }
79
80 fn read_file_impl(&mut self, file: &VfFile, max_bytes: usize) -> VfResult<Vec<u8>> {
81 crate::backend_helpers::read_file_impl_default(self, file, max_bytes)
82 }
83
84 fn open_impl(&mut self, request: &OpenOp) -> VfResult<VfFile>;
85
86 fn close_impl(&mut self, file: &VfFile) -> VfResult<()>;
87
88 fn read_impl(&mut self, request: &ReadOp) -> VfResult<ReadResult>;
89
90 fn read_into_impl(&mut self, request: &ReadOp, buffer: &mut [u8]) -> VfResult<ReadIntoResult> {
91 crate::backend_helpers::read_into_impl_default(self, request, buffer)
92 }
93
94 fn write_impl(&mut self, request: WriteOpRef<'_>) -> VfResult<WriteResult>;
95
96 fn seek_impl(&mut self, file: &VfFile, position: std::io::SeekFrom) -> VfResult<u64>;
97
98 fn metadata_impl(&mut self, query: MetadataQuery) -> VfResult<VfAttrs>;
99
100 fn set_attributes_impl(&mut self, update: SetAttributes) -> VfResult<()>;
101
102 fn vsetattrs_impl(&mut self, updates: Vec<SetAttributes>, follow: bool) -> VfResult<()> {
103 crate::backend_helpers::vsetattrs_impl_default(self, updates, follow)
104 }
105}
106
107pub trait Backend: FileSystem {
118 fn vread_impl(&mut self, reads: &[ReadOp]) -> VfResult<Vec<ReadResult>>;
120
121 fn vread_into_impl(
122 &mut self,
123 reads: &[ReadOp],
124 buffers: &mut [&mut [u8]],
125 ) -> VfResult<Vec<ReadIntoResult>> {
126 crate::backend_helpers::vread_into_impl_default(self, reads, buffers)
127 }
128
129 fn vwrite_owned_impl(&mut self, writes: &[WriteOp]) -> VfResult<Vec<WriteResult>> {
130 let _ = writes;
131 Err(VfError::unsupported(0))
132 }
133
134 fn vwrite_impl(&mut self, writes: &[WriteOpRef<'_>]) -> VfResult<Vec<WriteResult>> {
135 crate::backend_helpers::vwrite_impl_default(self, writes)
136 }
137
138 #[doc(hidden)]
141 fn vopen_outcomes_impl(
142 &mut self,
143 paths: &[&Path],
144 flags: &[i32],
145 modes: &[u32],
146 ) -> VfResult<ManyResults<VfFile>> {
147 crate::backend_helpers::vopen_outcomes_impl_default(self, paths, flags, modes)
148 }
149
150 fn before_open_cleanup(&mut self, _index: usize, _file: &VfFile) -> VfResult<()> {
151 crate::backend_helpers::before_open_cleanup_default(self, _index, _file)
152 }
153
154 fn vopen_raw_impl(
155 &mut self,
156 paths: &[&Path],
157 flags: &[i32],
158 modes: &[u32],
159 ) -> VfResult<Vec<VfFile>> {
160 crate::backend_helpers::vopen_raw_impl_default(self, paths, flags, modes)
161 }
162
163 fn vopen_raw_simple_impl(
164 &mut self,
165 paths: &[&Path],
166 flags: i32,
167 mode: u32,
168 ) -> VfResult<Vec<VfFile>> {
169 crate::backend_helpers::vopen_raw_simple_impl_default(self, paths, flags, mode)
170 }
171
172 fn vclose_impl(&mut self, files: &[VfFile]) -> VfRes {
173 crate::backend_helpers::vclose_impl_default(self, files)
174 }
175
176 fn vopen_impl(&mut self, requests: &[OpenOp]) -> VfResult<Vec<VfFile>> {
179 crate::backend_helpers::vopen_typed_default(self, requests)
180 }
181
182 fn vgetattrs_impl(&mut self, attrs: &mut [VfAttrs]) -> VfRes {
184 let _ = (attrs,);
185 Err(VfError::unsupported(0))
186 }
187
188 fn vgetattrs_nofollow_impl(&mut self, attrs: &mut [VfAttrs]) -> VfRes {
189 let _ = (attrs,);
190 Err(VfError::unsupported(0))
191 }
192
193 fn vsetattrs_raw_impl(&mut self, attrs: &[VfAttrs]) -> VfRes {
194 let _ = (attrs,);
195 Err(VfError::unsupported(0))
196 }
197
198 fn vsetattrs_raw_nofollow_impl(&mut self, attrs: &[VfAttrs]) -> VfRes {
199 let _ = (attrs,);
200 Err(VfError::unsupported(0))
201 }
202
203 fn stat_impl(&mut self, path: &Path) -> VfResult<VfAttrs> {
204 crate::backend_helpers::stat_impl_default(self, path)
205 }
206
207 fn lstat_impl(&mut self, path: &Path) -> VfResult<VfAttrs> {
208 crate::backend_helpers::lstat_impl_default(self, path)
209 }
210
211 fn fstat_impl(&mut self, tcf: &VfFile) -> VfResult<VfAttrs> {
212 crate::backend_helpers::fstat_impl_default(self, tcf)
213 }
214
215 fn exists_impl(&mut self, path: &Path) -> VfResult<bool> {
216 crate::backend_helpers::exists_impl_default(self, path)
217 }
218
219 fn file_type_impl(&mut self, path: &Path) -> VfResult<VfType> {
220 crate::backend_helpers::file_type_impl_default(self, path)
221 }
222
223 fn metadata_path_impl(&mut self, path: &std::path::Path, follow: bool) -> VfResult<Attrs> {
224 crate::backend_helpers::native_metadata_path_impl_default(self, path, follow)
225 }
226
227 fn set_metadata_path_impl(
228 &mut self,
229 path: &std::path::Path,
230 update: MetadataUpdate,
231 follow: bool,
232 ) -> VfResult<()> {
233 crate::backend_helpers::native_set_metadata_path_impl_default(self, path, update, follow)
234 }
235
236 fn listdir_impl(
238 &mut self,
239 dir: &Path,
240 masks: AttrMask,
241 max_count: usize,
242 recursive: bool,
243 ) -> VfResult<Vec<VfAttrs>> {
244 let _ = (dir, masks, max_count, recursive);
245 Err(VfError::unsupported(0))
246 }
247
248 fn listdir_page_impl(
249 &mut self,
250 dir: &Path,
251 masks: AttrMask,
252 cursor: Option<DirPageCursor>,
253 page_size: usize,
254 max_entries: usize,
255 ) -> VfResult<(Vec<VfAttrs>, Option<DirPageCursor>)> {
256 crate::backend_helpers::listdir_page_impl_default(
257 self,
258 dir,
259 masks,
260 cursor,
261 page_size,
262 max_entries,
263 )
264 }
265
266 fn directory_page_batch_size(&self) -> usize {
267 crate::backend_helpers::directory_page_batch_size_default(self)
268 }
269
270 fn vlistdir_pages_impl(
271 &mut self,
272 dirs: &[&Path],
273 masks: AttrMask,
274 cursors: Vec<Option<DirPageCursor>>,
275 page_size: usize,
276 max_entries: usize,
277 ) -> VfResult<Vec<BackendDirectoryPage>> {
278 crate::backend_helpers::vlistdir_pages_impl_default(
279 self,
280 dirs,
281 masks,
282 cursors,
283 page_size,
284 max_entries,
285 )
286 }
287
288 fn create_dir_impl(&mut self, path: &std::path::Path, mode: u32) -> VfResult<()> {
289 crate::backend_helpers::native_create_dir_impl_default(self, path, mode)
290 }
291
292 fn read_dir_impl(
293 &mut self,
294 path: &std::path::Path,
295 options: ReadDirOptions,
296 ) -> VfResult<Vec<DirEntry>> {
297 crate::backend_helpers::native_read_dir_impl_default(self, path, options)
298 }
299
300 fn read_dir_page_impl(
302 &mut self,
303 path: &std::path::Path,
304 cursor: Option<DirPageCursor>,
305 page_size: usize,
306 max_entries: usize,
307 ) -> VfResult<(Vec<DirEntry>, Option<DirPageCursor>)> {
308 crate::backend_helpers::native_read_dir_page_impl_default(
309 self,
310 path,
311 cursor,
312 page_size,
313 max_entries,
314 )
315 }
316
317 fn read_dir_page_with_fields_impl(
321 &mut self,
322 path: &std::path::Path,
323 fields: AttrMask,
324 cursor: Option<DirPageCursor>,
325 page_size: usize,
326 max_entries: usize,
327 ) -> VfResult<(Vec<DirEntry>, Option<DirPageCursor>)> {
328 crate::backend_helpers::native_read_dir_page_with_fields_impl_default(
329 self,
330 path,
331 fields,
332 cursor,
333 page_size,
334 max_entries,
335 )
336 }
337
338 fn walk_impl(
340 &mut self,
341 root: &Path,
342 masks: AttrMask,
343 sort: &mut dyn FnMut(&Path, &mut Vec<VfAttrs>),
344 ) -> VfResult<Vec<WalkEntry>> {
345 crate::backend_helpers::walk_impl_default(self, root, masks, sort)
346 }
347
348 fn walk_with_options_impl(
349 &mut self,
350 root: &Path,
351 masks: AttrMask,
352 options: WalkOptions,
353 sort: &mut dyn FnMut(&Path, &mut Vec<VfAttrs>),
354 ) -> VfResult<Vec<WalkEntry>> {
355 crate::backend_helpers::walk_with_options_impl_default(self, root, masks, options, sort)
356 }
357
358 fn vlistdirs_impl(
359 &mut self,
360 dirs: &[&Path],
361 masks: AttrMask,
362 max_entries: usize,
363 recursive: bool,
364 cb: &mut dyn FnMut(&VfAttrs, &Path) -> bool,
365 ) -> VfRes {
366 crate::backend_helpers::vlistdirs_impl_default(
367 self,
368 dirs,
369 masks,
370 max_entries,
371 recursive,
372 cb,
373 )
374 }
375
376 fn visit_dir_impl(
377 &mut self,
378 dir: &Path,
379 masks: AttrMask,
380 max_entries: usize,
381 cb: &mut dyn FnMut(&VfAttrs) -> bool,
382 ) -> VfRes {
383 crate::backend_helpers::visit_dir_impl_default(self, dir, masks, max_entries, cb)
384 }
385
386 fn vrename_impl(&mut self, pairs: &[(VfFile, VfFile)]) -> VfRes {
388 let _ = (pairs,);
389 Err(VfError::unsupported(0))
390 }
391
392 fn vrename_with_options_impl(
394 &mut self,
395 pairs: &[(VfFile, VfFile)],
396 options: vfsi_core::api::RenameOptions,
397 ) -> VfRes {
398 match options {
399 vfsi_core::api::RenameOptions::Replace => self.vrename_impl(pairs),
400 vfsi_core::api::RenameOptions::NoReplace | vfsi_core::api::RenameOptions::Exchange
401 if pairs.is_empty() =>
402 {
403 Ok(())
404 }
405 vfsi_core::api::RenameOptions::NoReplace | vfsi_core::api::RenameOptions::Exchange => {
406 Err(VfError::client(0, vfsi_core::VF_ERR_UNSUPPORTED))
407 }
408 }
409 }
410
411 fn vremove_impl(&mut self, files: &[VfFile]) -> VfRes {
412 let _ = (files,);
413 Err(VfError::unsupported(0))
414 }
415
416 fn vmkdir_impl(&mut self, dirs: &[VfAttrs]) -> VfRes {
417 let _ = (dirs,);
418 Err(VfError::unsupported(0))
419 }
420
421 fn unlink_impl(&mut self, pathname: &Path) -> VfResult<()> {
422 crate::backend_helpers::unlink_impl_default(self, pathname)
423 }
424
425 fn vunlink_impl(&mut self, pathnames: &[&Path]) -> VfRes {
426 crate::backend_helpers::vunlink_impl_default(self, pathnames)
427 }
428
429 fn mkdir_raw_impl(&mut self, path: &Path, mode: u32) -> VfResult<()> {
430 crate::backend_helpers::mkdir_raw_impl_default(self, path, mode)
431 }
432
433 fn ensure_dir_impl(&mut self, dir: &Path, mode: u32) -> VfResult<()> {
434 crate::backend_helpers::ensure_dir_impl_default(self, dir, mode)
435 }
436
437 fn remove_impl(&mut self, path: &std::path::Path, recursive: bool) -> VfResult<()> {
438 crate::backend_helpers::native_remove_impl_default(self, path, recursive)
439 }
440
441 fn remove_dir_contents_impl(&mut self, path: &std::path::Path) -> VfResult<()> {
442 crate::backend_helpers::native_remove_dir_contents_impl_default(self, path)
443 }
444
445 fn rename_impl(&mut self, from: &std::path::Path, to: &std::path::Path) -> VfResult<()> {
446 crate::backend_helpers::native_rename_impl_default(self, from, to)
447 }
448
449 fn vsymlink_impl(&mut self, oldpaths: &[&Path], newpaths: &[&Path]) -> VfRes {
451 let _ = (oldpaths, newpaths);
452 Err(VfError::unsupported(0))
453 }
454
455 fn vreadlink_impl(&mut self, paths: &[&Path]) -> VfResult<Vec<Vec<u8>>> {
456 let _ = (paths,);
457 Err(VfError::unsupported(0))
458 }
459
460 fn vhardlink_impl(&mut self, oldpaths: &[&Path], newpaths: &[&Path]) -> VfRes {
461 let _ = (oldpaths, newpaths);
462 Err(VfError::unsupported(0))
463 }
464
465 fn symlink_raw_impl(&mut self, oldpath: &Path, newpath: &Path) -> VfResult<()> {
466 crate::backend_helpers::symlink_raw_impl_default(self, oldpath, newpath)
467 }
468
469 fn readlink_raw_impl(&mut self, path: &Path) -> VfResult<Vec<u8>> {
470 crate::backend_helpers::readlink_raw_impl_default(self, path)
471 }
472
473 fn symlink_impl(&mut self, target: &std::path::Path, link: &std::path::Path) -> VfResult<()> {
474 crate::backend_helpers::native_symlink_impl_default(self, target, link)
475 }
476
477 fn hard_link_impl(&mut self, source: &std::path::Path, link: &std::path::Path) -> VfResult<()> {
478 crate::backend_helpers::native_hard_link_impl_default(self, source, link)
479 }
480
481 fn read_link_impl(&mut self, path: &std::path::Path) -> VfResult<std::path::PathBuf> {
482 crate::backend_helpers::native_read_link_impl_default(self, path)
483 }
484
485 fn vcopy_data_impl(&mut self, pairs: &[ExtentPair]) -> VfRes {
487 let _ = (pairs,);
488 Err(VfError::unsupported(0))
489 }
490
491 fn vcopy_impl(&mut self, pairs: &[ExtentPair], options: CopyOption) -> VfRes {
492 crate::backend_helpers::vcopy_impl_default(self, pairs, options)
493 }
494
495 fn copy_tree_impl(
496 &mut self,
497 src_dir: &Path,
498 dst: &Path,
499 symlinks: bool,
500 use_server_side_copy: bool,
501 ) -> VfRes {
502 let _ = (src_dir, dst, symlinks, use_server_side_copy);
503 Err(VfError::unsupported(0))
504 }
505
506 fn vread_all_impl(&mut self, files: &[VfFile]) -> VfResult<Vec<Vec<u8>>> {
508 crate::backend_helpers::vread_all_impl_default(self, files)
509 }
510
511 fn vread_all_with_options_impl(
512 &mut self,
513 files: &[VfFile],
514 options: ReadAllOptions,
515 ) -> VfResult<Vec<Vec<u8>>> {
516 crate::backend_helpers::vread_all_with_options_impl_default(self, files, options)
517 }
518
519 fn vstream_impl(
520 &mut self,
521 files: &[VfFile],
522 chunk_size: usize,
523 memory_limit: usize,
524 cb: &mut ReadStreamCallback<'_>,
525 ) -> VfRes {
526 crate::backend_helpers::vstream_impl_default(self, files, chunk_size, memory_limit, cb)
527 }
528
529 fn before_remove_type(&mut self, _index: usize) -> VfResult<()> {
531 crate::backend_helpers::before_remove_type_default(self, _index)
532 }
533
534 fn remove_paths_impl(&mut self, objs: &[&Path], recursive: bool) -> VfRes {
535 crate::backend_helpers::remove_paths_impl_default(self, objs, recursive)
536 }
537
538 fn remove_paths_with_options_impl(
539 &mut self,
540 objs: &[&Path],
541 recursive: bool,
542 options: RemoveOptions,
543 ) -> VfRes {
544 crate::backend_helpers::remove_paths_with_options_impl_default(
545 self, objs, recursive, options,
546 )
547 }
548
549 fn open_dir_impl(&mut self, path: &Path) -> VfResult<VfDir> {
550 crate::backend_helpers::open_dir_impl_default(self, path)
551 }
552
553 fn remove_dir_contents_handle_impl(&mut self, dir: &VfDir) -> VfRes {
554 crate::backend_helpers::remove_dir_contents_handle_impl_default(self, dir)
555 }
556
557 fn remove_dir_contents_handle_with_options_impl(
558 &mut self,
559 dir: &VfDir,
560 options: RemoveOptions,
561 ) -> VfRes {
562 crate::backend_helpers::remove_dir_contents_handle_with_options_impl_default(
563 self, dir, options,
564 )
565 }
566
567 fn close_dir_impl(&mut self, _dir: &VfDir) -> VfResult<()> {
568 crate::backend_helpers::close_dir_impl_default(self, _dir)
569 }
570
571 fn remove_dir_contents_path_impl(&mut self, dir: &Path) -> VfRes {
572 crate::backend_helpers::remove_dir_contents_path_impl_default(self, dir)
573 }
574
575 fn remove_dir_contents_path_with_options_impl(
576 &mut self,
577 dir: &Path,
578 options: RemoveOptions,
579 ) -> VfRes {
580 crate::backend_helpers::remove_dir_contents_path_with_options_impl_default(
581 self, dir, options,
582 )
583 }
584
585 fn ensure_empty_dir_impl(&mut self, dir: &Path) -> VfRes {
586 crate::backend_helpers::ensure_empty_dir_impl_default(self, dir)
587 }
588
589 fn vwrite_adb_impl(&mut self, patterns: &[Adb]) -> VfResult<Vec<usize>> {
591 let _ = (patterns,);
592 Err(VfError::unsupported(0))
593 }
594}
595pub(crate) fn metadata_mask() -> AttrMask {
596 AttrMask::MODE
597 | AttrMask::SIZE
598 | AttrMask::NLINK
599 | AttrMask::FILEID
600 | AttrMask::UID
601 | AttrMask::GID
602 | AttrMask::ATIME
603 | AttrMask::MTIME
604 | AttrMask::CTIME
605 | AttrMask::CHANGE
606}
607
608pub(crate) fn system_time_parts(time: std::time::SystemTime) -> VfResult<(i64, u32)> {
609 match time.duration_since(std::time::UNIX_EPOCH) {
610 Ok(duration) => Ok((
611 i64::try_from(duration.as_secs())
612 .map_err(|_| VfError::client(0, libc::EOVERFLOW as u32))?,
613 duration.subsec_nanos(),
614 )),
615 Err(error) => {
616 let duration = error.duration();
617 let seconds = i64::try_from(duration.as_secs())
618 .map_err(|_| VfError::client(0, libc::EOVERFLOW as u32))?;
619 if duration.subsec_nanos() == 0 {
620 Ok((-seconds, 0))
621 } else {
622 let seconds = seconds
623 .checked_add(1)
624 .ok_or_else(|| VfError::client(0, libc::EOVERFLOW as u32))?;
625 Ok((-seconds, 1_000_000_000 - duration.subsec_nanos()))
626 }
627 }
628 }
629}
630#[cfg(unix)]
631pub(crate) fn bytes_to_path(bytes: Vec<u8>) -> PathBuf {
632 use std::os::unix::ffi::OsStringExt;
633 std::ffi::OsString::from_vec(bytes).into()
634}
635#[cfg(not(unix))]
636pub(crate) fn bytes_to_path(bytes: Vec<u8>) -> PathBuf {
637 String::from_utf8_lossy(&bytes).into_owned().into()
638}
639pub(crate) fn translate_open_flags(requests: &[OpenOp]) -> VfResult<Vec<i32>> {
640 requests
641 .iter()
642 .enumerate()
643 .map(|(index, request)| {
644 vfsi_core::open_flags_to_libc(request.flags).map_err(|error| error.with_index(index))
645 })
646 .collect()
647}