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: &OpenRequest) -> 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: &[OpenRequest]) -> 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<Metadata> {
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 if pairs.is_empty() => Ok(()),
401 vfsi_core::api::RenameOptions::NoReplace => {
402 Err(VfError::client(0, vfsi_core::VF_ERR_UNSUPPORTED))
403 }
404 }
405 }
406
407 fn vremove_impl(&mut self, files: &[VfFile]) -> VfRes {
408 let _ = (files,);
409 Err(VfError::unsupported(0))
410 }
411
412 fn vmkdir_impl(&mut self, dirs: &[VfAttrs]) -> VfRes {
413 let _ = (dirs,);
414 Err(VfError::unsupported(0))
415 }
416
417 fn unlink_impl(&mut self, pathname: &Path) -> VfResult<()> {
418 crate::backend_helpers::unlink_impl_default(self, pathname)
419 }
420
421 fn vunlink_impl(&mut self, pathnames: &[&Path]) -> VfRes {
422 crate::backend_helpers::vunlink_impl_default(self, pathnames)
423 }
424
425 fn mkdir_raw_impl(&mut self, path: &Path, mode: u32) -> VfResult<()> {
426 crate::backend_helpers::mkdir_raw_impl_default(self, path, mode)
427 }
428
429 fn ensure_dir_impl(&mut self, dir: &Path, mode: u32) -> VfResult<()> {
430 crate::backend_helpers::ensure_dir_impl_default(self, dir, mode)
431 }
432
433 fn remove_impl(&mut self, path: &std::path::Path, recursive: bool) -> VfResult<()> {
434 crate::backend_helpers::native_remove_impl_default(self, path, recursive)
435 }
436
437 fn remove_dir_contents_impl(&mut self, path: &std::path::Path) -> VfResult<()> {
438 crate::backend_helpers::native_remove_dir_contents_impl_default(self, path)
439 }
440
441 fn rename_impl(&mut self, from: &std::path::Path, to: &std::path::Path) -> VfResult<()> {
442 crate::backend_helpers::native_rename_impl_default(self, from, to)
443 }
444
445 fn vsymlink_impl(&mut self, oldpaths: &[&Path], newpaths: &[&Path]) -> VfRes {
447 let _ = (oldpaths, newpaths);
448 Err(VfError::unsupported(0))
449 }
450
451 fn vreadlink_impl(&mut self, paths: &[&Path]) -> VfResult<Vec<Vec<u8>>> {
452 let _ = (paths,);
453 Err(VfError::unsupported(0))
454 }
455
456 fn vhardlink_impl(&mut self, oldpaths: &[&Path], newpaths: &[&Path]) -> VfRes {
457 let _ = (oldpaths, newpaths);
458 Err(VfError::unsupported(0))
459 }
460
461 fn symlink_raw_impl(&mut self, oldpath: &Path, newpath: &Path) -> VfResult<()> {
462 crate::backend_helpers::symlink_raw_impl_default(self, oldpath, newpath)
463 }
464
465 fn readlink_raw_impl(&mut self, path: &Path) -> VfResult<Vec<u8>> {
466 crate::backend_helpers::readlink_raw_impl_default(self, path)
467 }
468
469 fn symlink_impl(&mut self, target: &std::path::Path, link: &std::path::Path) -> VfResult<()> {
470 crate::backend_helpers::native_symlink_impl_default(self, target, link)
471 }
472
473 fn hard_link_impl(&mut self, source: &std::path::Path, link: &std::path::Path) -> VfResult<()> {
474 crate::backend_helpers::native_hard_link_impl_default(self, source, link)
475 }
476
477 fn read_link_impl(&mut self, path: &std::path::Path) -> VfResult<std::path::PathBuf> {
478 crate::backend_helpers::native_read_link_impl_default(self, path)
479 }
480
481 fn vcopy_data_impl(&mut self, pairs: &[ExtentPair]) -> VfRes {
483 let _ = (pairs,);
484 Err(VfError::unsupported(0))
485 }
486
487 fn vcopy_impl(&mut self, pairs: &[ExtentPair], options: CopyOption) -> VfRes {
488 crate::backend_helpers::vcopy_impl_default(self, pairs, options)
489 }
490
491 fn copy_tree_impl(
492 &mut self,
493 src_dir: &Path,
494 dst: &Path,
495 symlinks: bool,
496 use_server_side_copy: bool,
497 ) -> VfRes {
498 let _ = (src_dir, dst, symlinks, use_server_side_copy);
499 Err(VfError::unsupported(0))
500 }
501
502 fn copy_impl(
503 &mut self,
504 source: &std::path::Path,
505 destination: &std::path::Path,
506 ) -> VfResult<()> {
507 crate::backend_helpers::native_copy_impl_default(self, source, destination)
508 }
509
510 fn vread_all_impl(&mut self, files: &[VfFile]) -> VfResult<Vec<Vec<u8>>> {
512 crate::backend_helpers::vread_all_impl_default(self, files)
513 }
514
515 fn vread_all_with_options_impl(
516 &mut self,
517 files: &[VfFile],
518 options: ReadAllOptions,
519 ) -> VfResult<Vec<Vec<u8>>> {
520 crate::backend_helpers::vread_all_with_options_impl_default(self, files, options)
521 }
522
523 fn vstream_impl(
524 &mut self,
525 files: &[VfFile],
526 chunk_size: usize,
527 memory_limit: usize,
528 cb: &mut ReadStreamCallback<'_>,
529 ) -> VfRes {
530 crate::backend_helpers::vstream_impl_default(self, files, chunk_size, memory_limit, cb)
531 }
532
533 fn before_remove_type(&mut self, _index: usize) -> VfResult<()> {
535 crate::backend_helpers::before_remove_type_default(self, _index)
536 }
537
538 fn remove_paths_impl(&mut self, objs: &[&Path], recursive: bool) -> VfRes {
539 crate::backend_helpers::remove_paths_impl_default(self, objs, recursive)
540 }
541
542 fn remove_paths_with_options_impl(
543 &mut self,
544 objs: &[&Path],
545 recursive: bool,
546 options: RemoveOptions,
547 ) -> VfRes {
548 crate::backend_helpers::remove_paths_with_options_impl_default(
549 self, objs, recursive, options,
550 )
551 }
552
553 fn open_dir_impl(&mut self, path: &Path) -> VfResult<VfDir> {
554 crate::backend_helpers::open_dir_impl_default(self, path)
555 }
556
557 fn remove_dir_contents_handle_impl(&mut self, dir: &VfDir) -> VfRes {
558 crate::backend_helpers::remove_dir_contents_handle_impl_default(self, dir)
559 }
560
561 fn remove_dir_contents_handle_with_options_impl(
562 &mut self,
563 dir: &VfDir,
564 options: RemoveOptions,
565 ) -> VfRes {
566 crate::backend_helpers::remove_dir_contents_handle_with_options_impl_default(
567 self, dir, options,
568 )
569 }
570
571 fn close_dir_impl(&mut self, _dir: &VfDir) -> VfResult<()> {
572 crate::backend_helpers::close_dir_impl_default(self, _dir)
573 }
574
575 fn remove_dir_contents_path_impl(&mut self, dir: &Path) -> VfRes {
576 crate::backend_helpers::remove_dir_contents_path_impl_default(self, dir)
577 }
578
579 fn remove_dir_contents_path_with_options_impl(
580 &mut self,
581 dir: &Path,
582 options: RemoveOptions,
583 ) -> VfRes {
584 crate::backend_helpers::remove_dir_contents_path_with_options_impl_default(
585 self, dir, options,
586 )
587 }
588
589 fn ensure_empty_dir_impl(&mut self, dir: &Path) -> VfRes {
590 crate::backend_helpers::ensure_empty_dir_impl_default(self, dir)
591 }
592
593 fn vwrite_adb_impl(&mut self, patterns: &[Adb]) -> VfResult<Vec<usize>> {
595 let _ = (patterns,);
596 Err(VfError::unsupported(0))
597 }
598}
599pub(crate) fn metadata_mask() -> AttrMask {
600 AttrMask::MODE
601 | AttrMask::SIZE
602 | AttrMask::NLINK
603 | AttrMask::FILEID
604 | AttrMask::UID
605 | AttrMask::GID
606 | AttrMask::ATIME
607 | AttrMask::MTIME
608 | AttrMask::CTIME
609 | AttrMask::CHANGE
610}
611
612pub(crate) fn system_time_parts(time: std::time::SystemTime) -> VfResult<(i64, u32)> {
613 match time.duration_since(std::time::UNIX_EPOCH) {
614 Ok(duration) => Ok((
615 i64::try_from(duration.as_secs())
616 .map_err(|_| VfError::client(0, libc::EOVERFLOW as u32))?,
617 duration.subsec_nanos(),
618 )),
619 Err(error) => {
620 let duration = error.duration();
621 let seconds = i64::try_from(duration.as_secs())
622 .map_err(|_| VfError::client(0, libc::EOVERFLOW as u32))?;
623 if duration.subsec_nanos() == 0 {
624 Ok((-seconds, 0))
625 } else {
626 let seconds = seconds
627 .checked_add(1)
628 .ok_or_else(|| VfError::client(0, libc::EOVERFLOW as u32))?;
629 Ok((-seconds, 1_000_000_000 - duration.subsec_nanos()))
630 }
631 }
632 }
633}
634#[cfg(unix)]
635pub(crate) fn bytes_to_path(bytes: Vec<u8>) -> PathBuf {
636 use std::os::unix::ffi::OsStringExt;
637 std::ffi::OsString::from_vec(bytes).into()
638}
639#[cfg(not(unix))]
640pub(crate) fn bytes_to_path(bytes: Vec<u8>) -> PathBuf {
641 String::from_utf8_lossy(&bytes).into_owned().into()
642}
643pub(crate) fn translate_open_flags(requests: &[OpenRequest]) -> VfResult<Vec<i32>> {
644 requests
645 .iter()
646 .enumerate()
647 .map(|(index, request)| {
648 vfsi_core::open_flags_to_libc(request.flags).map_err(|error| error.with_index(index))
649 })
650 .collect()
651}