1pub mod drivers;
7pub mod ext;
8
9use crate::io_buffers::{IoBuffer, IoVector, IoVectorMut};
10use drivers::CommonStorageHelper;
11use maybe_async::maybe_async;
12use std::any::Any;
13use std::fmt::{Debug, Display};
14#[cfg(feature = "async")]
15use std::future::Future;
16use std::path::{Path, PathBuf};
17#[cfg(feature = "async")]
18use std::pin::Pin;
19use std::sync::Arc;
20use std::{cmp, io};
21
22#[derive(Clone, Debug, Default)]
24pub struct StorageOpenOptions {
25 pub(crate) filename: Option<PathBuf>,
27
28 pub(crate) writable: bool,
30
31 pub(crate) direct: bool,
33
34 #[cfg(target_os = "macos")]
36 pub(crate) relaxed_sync: bool,
37}
38
39#[derive(Clone, Debug)]
41pub struct StorageCreateOptions {
42 pub(crate) open_opts: StorageOpenOptions,
46
47 pub(crate) size: u64,
49
50 pub(crate) prealloc_mode: PreallocateMode,
52
53 pub(crate) overwrite: bool,
55}
56
57#[maybe_async(AFIT)]
59pub trait Storage: Debug + Display + Send + Sized + Sync {
60 #[allow(async_fn_in_trait)] async fn open(_opts: StorageOpenOptions) -> io::Result<Self> {
65 Err(io::Error::new(
66 io::ErrorKind::Unsupported,
67 format!(
68 "Cannot open storage objects of type {}",
69 std::any::type_name::<Self>()
70 ),
71 ))
72 }
73
74 #[cfg(feature = "sync-wrappers")]
76 fn open_sync(opts: StorageOpenOptions) -> io::Result<Self> {
77 tokio::runtime::Builder::new_current_thread()
78 .build()?
79 .block_on(Self::open(opts))
80 }
81
82 #[allow(async_fn_in_trait)] async fn create_open(_opts: StorageCreateOptions) -> io::Result<Self> {
89 Err(io::Error::new(
90 io::ErrorKind::Unsupported,
91 format!(
92 "Cannot create storage objects of type {}",
93 std::any::type_name::<Self>()
94 ),
95 ))
96 }
97
98 #[allow(async_fn_in_trait)] async fn create(opts: StorageCreateOptions) -> io::Result<()> {
103 Self::create_open(opts).await?;
104 Ok(())
105 }
106
107 fn mem_align(&self) -> usize {
109 1
110 }
111
112 fn req_align(&self) -> usize {
114 1
115 }
116
117 fn zero_align(&self) -> usize {
121 self.req_align()
122 }
123
124 fn discard_align(&self) -> usize {
128 self.req_align()
129 }
130
131 fn size(&self) -> io::Result<u64>;
133
134 fn resolve_relative_path<P: AsRef<Path>>(&self, _relative: P) -> io::Result<PathBuf> {
144 Err(io::ErrorKind::Unsupported.into())
145 }
146
147 fn get_filename(&self) -> Option<PathBuf> {
152 None
153 }
154
155 #[allow(async_fn_in_trait)] async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()>;
168
169 #[allow(async_fn_in_trait)] async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()>;
185
186 #[allow(async_fn_in_trait)] async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
204 unsafe { pure_write_full_zeroes(self, offset, length).await }
205 }
206
207 #[allow(async_fn_in_trait)] async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
226 unsafe { pure_write_full_zeroes(self, offset, length).await }
227 }
228
229 #[allow(async_fn_in_trait)] async unsafe fn pure_discard(&self, _offset: u64, _length: u64) -> io::Result<()> {
244 Ok(())
245 }
246
247 #[allow(async_fn_in_trait)] async fn flush(&self) -> io::Result<()>;
256
257 #[allow(async_fn_in_trait)] async fn sync(&self) -> io::Result<()>;
263
264 #[allow(async_fn_in_trait)] async fn settle_writes(&self) -> io::Result<()> {
281 Ok(())
282 }
283
284 #[allow(async_fn_in_trait)] async unsafe fn invalidate_cache(&self) -> io::Result<()>;
294
295 fn get_storage_helper(&self) -> &CommonStorageHelper;
298
299 #[allow(async_fn_in_trait)] async fn resize(&self, _new_size: u64, _prealloc_mode: PreallocateMode) -> io::Result<()> {
309 Err(io::ErrorKind::Unsupported.into())
310 }
311}
312
313pub trait DynStorage: Any + Debug + Display + Send + Sync {
329 fn dyn_mem_align(&self) -> usize;
331
332 fn dyn_req_align(&self) -> usize;
334
335 fn dyn_zero_align(&self) -> usize;
337
338 fn dyn_discard_align(&self) -> usize;
340
341 fn dyn_size(&self) -> io::Result<u64>;
343
344 fn dyn_resolve_relative_path(&self, relative: &Path) -> io::Result<PathBuf>;
346
347 fn dyn_get_filename(&self) -> Option<PathBuf>;
349
350 #[cfg(feature = "async")]
355 unsafe fn dyn_pure_readv<'a>(
356 &'a self,
357 bufv: IoVectorMut<'a>,
358 offset: u64,
359 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>>;
360
361 #[cfg(feature = "sync")]
366 unsafe fn dyn_pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()>;
367
368 #[cfg(feature = "async")]
373 unsafe fn dyn_pure_writev<'a>(
374 &'a self,
375 bufv: IoVector<'a>,
376 offset: u64,
377 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>>;
378
379 #[cfg(feature = "sync")]
384 unsafe fn dyn_pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()>;
385
386 #[cfg(feature = "async")]
391 unsafe fn dyn_pure_write_zeroes(
392 &self,
393 offset: u64,
394 length: u64,
395 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
396
397 #[cfg(feature = "sync")]
402 unsafe fn dyn_pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()>;
403
404 #[cfg(feature = "async")]
409 unsafe fn dyn_pure_write_allocated_zeroes(
410 &self,
411 offset: u64,
412 length: u64,
413 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
414
415 #[cfg(feature = "sync")]
420 unsafe fn dyn_pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()>;
421
422 #[cfg(feature = "async")]
427 unsafe fn dyn_pure_discard(
428 &self,
429 offset: u64,
430 length: u64,
431 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
432
433 #[cfg(feature = "sync")]
438 unsafe fn dyn_pure_discard(&self, offset: u64, length: u64) -> io::Result<()>;
439
440 #[cfg(feature = "async")]
442 fn dyn_flush(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
443
444 #[cfg(feature = "sync")]
446 fn dyn_flush(&self) -> io::Result<()>;
447
448 #[cfg(feature = "async")]
450 fn dyn_sync(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
451
452 #[cfg(feature = "sync")]
454 fn dyn_sync(&self) -> io::Result<()>;
455
456 #[cfg(feature = "async")]
458 fn dyn_settle_writes(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
459
460 #[cfg(feature = "sync")]
462 fn dyn_settle_writes(&self) -> io::Result<()>;
463
464 #[cfg(feature = "async")]
469 unsafe fn dyn_invalidate_cache(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
470
471 #[cfg(feature = "sync")]
476 unsafe fn dyn_invalidate_cache(&self) -> io::Result<()>;
477
478 fn dyn_get_storage_helper(&self) -> &CommonStorageHelper;
480
481 #[cfg(feature = "async")]
483 fn dyn_resize(
484 &self,
485 new_size: u64,
486 prealloc_mode: PreallocateMode,
487 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
488
489 #[cfg(feature = "sync")]
491 fn dyn_resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()>;
492}
493
494#[derive(Clone, Copy, Debug, Eq, PartialEq)]
499#[non_exhaustive]
500pub enum PreallocateMode {
501 None,
505
506 Zero,
511
512 Allocate,
516
517 WriteData,
521}
522
523#[maybe_async(AFIT)]
524impl<S: Storage> Storage for &S {
525 fn mem_align(&self) -> usize {
526 (*self).mem_align()
527 }
528
529 fn req_align(&self) -> usize {
530 (*self).req_align()
531 }
532
533 fn zero_align(&self) -> usize {
534 (*self).zero_align()
535 }
536
537 fn discard_align(&self) -> usize {
538 (*self).discard_align()
539 }
540
541 fn size(&self) -> io::Result<u64> {
542 (*self).size()
543 }
544
545 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
546 (*self).resolve_relative_path(relative)
547 }
548
549 fn get_filename(&self) -> Option<PathBuf> {
550 (*self).get_filename()
551 }
552
553 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
554 unsafe { (*self).pure_readv(bufv, offset).await }
555 }
556
557 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
558 unsafe { (*self).pure_writev(bufv, offset).await }
559 }
560
561 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
562 unsafe { (*self).pure_write_zeroes(offset, length).await }
563 }
564
565 async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
566 unsafe { (*self).pure_write_allocated_zeroes(offset, length).await }
567 }
568
569 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
570 unsafe { (*self).pure_discard(offset, length).await }
571 }
572
573 async fn flush(&self) -> io::Result<()> {
574 (*self).flush().await
575 }
576
577 async fn sync(&self) -> io::Result<()> {
578 (*self).sync().await
579 }
580
581 async fn settle_writes(&self) -> io::Result<()> {
582 (*self).settle_writes().await
583 }
584
585 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
586 unsafe { (*self).invalidate_cache().await }
587 }
588
589 fn get_storage_helper(&self) -> &CommonStorageHelper {
590 (*self).get_storage_helper()
591 }
592
593 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
594 (*self).resize(new_size, prealloc_mode).await
595 }
596}
597
598impl<S: Storage + 'static> DynStorage for S {
599 fn dyn_mem_align(&self) -> usize {
600 <S as Storage>::mem_align(self)
601 }
602
603 fn dyn_req_align(&self) -> usize {
604 <S as Storage>::req_align(self)
605 }
606
607 fn dyn_zero_align(&self) -> usize {
608 <S as Storage>::zero_align(self)
609 }
610
611 fn dyn_discard_align(&self) -> usize {
612 <S as Storage>::discard_align(self)
613 }
614
615 fn dyn_size(&self) -> io::Result<u64> {
616 <S as Storage>::size(self)
617 }
618
619 fn dyn_resolve_relative_path(&self, relative: &Path) -> io::Result<PathBuf> {
620 <S as Storage>::resolve_relative_path(self, relative)
621 }
622
623 fn dyn_get_filename(&self) -> Option<PathBuf> {
624 <S as Storage>::get_filename(self)
625 }
626
627 #[cfg(feature = "async")]
628 unsafe fn dyn_pure_readv<'a>(
629 &'a self,
630 bufv: IoVectorMut<'a>,
631 offset: u64,
632 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>> {
633 Box::pin(unsafe { <S as Storage>::pure_readv(self, bufv, offset) })
634 }
635
636 #[cfg(feature = "sync")]
637 unsafe fn dyn_pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
638 unsafe { <S as Storage>::pure_readv(self, bufv, offset) }
639 }
640
641 #[cfg(feature = "async")]
642 unsafe fn dyn_pure_writev<'a>(
643 &'a self,
644 bufv: IoVector<'a>,
645 offset: u64,
646 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>> {
647 Box::pin(unsafe { <S as Storage>::pure_writev(self, bufv, offset) })
648 }
649
650 #[cfg(feature = "sync")]
651 unsafe fn dyn_pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
652 unsafe { <S as Storage>::pure_writev(self, bufv, offset) }
653 }
654
655 #[cfg(feature = "async")]
656 unsafe fn dyn_pure_write_zeroes(
657 &self,
658 offset: u64,
659 length: u64,
660 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
661 Box::pin(unsafe { <S as Storage>::pure_write_zeroes(self, offset, length) })
662 }
663
664 #[cfg(feature = "sync")]
665 unsafe fn dyn_pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
666 unsafe { <S as Storage>::pure_write_zeroes(self, offset, length) }
667 }
668
669 #[cfg(feature = "async")]
670 unsafe fn dyn_pure_write_allocated_zeroes(
671 &self,
672 offset: u64,
673 length: u64,
674 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
675 Box::pin(unsafe { <S as Storage>::pure_write_allocated_zeroes(self, offset, length) })
676 }
677
678 #[cfg(feature = "sync")]
679 unsafe fn dyn_pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
680 unsafe { <S as Storage>::pure_write_allocated_zeroes(self, offset, length) }
681 }
682
683 #[cfg(feature = "async")]
684 unsafe fn dyn_pure_discard(
685 &self,
686 offset: u64,
687 length: u64,
688 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
689 Box::pin(unsafe { <S as Storage>::pure_discard(self, offset, length) })
690 }
691
692 #[cfg(feature = "sync")]
693 unsafe fn dyn_pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
694 unsafe { <S as Storage>::pure_discard(self, offset, length) }
695 }
696
697 #[cfg(feature = "async")]
698 fn dyn_flush(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
699 Box::pin(<S as Storage>::flush(self))
700 }
701
702 #[cfg(feature = "sync")]
703 fn dyn_flush(&self) -> io::Result<()> {
704 <S as Storage>::flush(self)
705 }
706
707 #[cfg(feature = "async")]
708 fn dyn_sync(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
709 Box::pin(<S as Storage>::sync(self))
710 }
711
712 #[cfg(feature = "sync")]
713 fn dyn_sync(&self) -> io::Result<()> {
714 <S as Storage>::sync(self)
715 }
716
717 #[cfg(feature = "async")]
718 fn dyn_settle_writes(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
719 Box::pin(<S as Storage>::settle_writes(self))
720 }
721
722 #[cfg(feature = "sync")]
723 fn dyn_settle_writes(&self) -> io::Result<()> {
724 <S as Storage>::settle_writes(self)
725 }
726
727 #[cfg(feature = "async")]
728 unsafe fn dyn_invalidate_cache(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
729 Box::pin(unsafe { <S as Storage>::invalidate_cache(self) })
730 }
731
732 #[cfg(feature = "sync")]
733 unsafe fn dyn_invalidate_cache(&self) -> io::Result<()> {
734 unsafe { <S as Storage>::invalidate_cache(self) }
735 }
736
737 fn dyn_get_storage_helper(&self) -> &CommonStorageHelper {
738 <S as Storage>::get_storage_helper(self)
739 }
740
741 #[cfg(feature = "async")]
742 fn dyn_resize(
743 &self,
744 new_size: u64,
745 prealloc_mode: PreallocateMode,
746 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
747 Box::pin(<S as Storage>::resize(self, new_size, prealloc_mode))
748 }
749
750 #[cfg(feature = "sync")]
751 fn dyn_resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
752 <S as Storage>::resize(self, new_size, prealloc_mode)
753 }
754}
755
756#[maybe_async(AFIT)]
757impl Storage for Box<dyn DynStorage> {
758 async fn open(opts: StorageOpenOptions) -> io::Result<Self> {
759 Ok(Box::new(crate::file::File::open(opts).await?))
763 }
764
765 async fn create_open(opts: StorageCreateOptions) -> io::Result<Self> {
766 Ok(Box::new(crate::file::File::create_open(opts).await?))
768 }
769
770 fn mem_align(&self) -> usize {
771 self.as_ref().dyn_mem_align()
772 }
773
774 fn req_align(&self) -> usize {
775 self.as_ref().dyn_req_align()
776 }
777
778 fn zero_align(&self) -> usize {
779 self.as_ref().dyn_zero_align()
780 }
781
782 fn discard_align(&self) -> usize {
783 self.as_ref().dyn_discard_align()
784 }
785
786 fn size(&self) -> io::Result<u64> {
787 self.as_ref().dyn_size()
788 }
789
790 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
791 self.as_ref().dyn_resolve_relative_path(relative.as_ref())
792 }
793
794 fn get_filename(&self) -> Option<PathBuf> {
795 self.as_ref().dyn_get_filename()
796 }
797
798 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
799 unsafe { self.as_ref().dyn_pure_readv(bufv, offset).await }
800 }
801
802 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
803 unsafe { self.as_ref().dyn_pure_writev(bufv, offset).await }
804 }
805
806 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
807 unsafe { self.as_ref().dyn_pure_write_zeroes(offset, length).await }
808 }
809
810 async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
811 unsafe {
812 self.as_ref()
813 .dyn_pure_write_allocated_zeroes(offset, length)
814 .await
815 }
816 }
817
818 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
819 unsafe { self.as_ref().dyn_pure_discard(offset, length).await }
820 }
821
822 async fn flush(&self) -> io::Result<()> {
823 self.as_ref().dyn_flush().await
824 }
825
826 async fn sync(&self) -> io::Result<()> {
827 self.as_ref().dyn_sync().await
828 }
829
830 async fn settle_writes(&self) -> io::Result<()> {
831 self.as_ref().dyn_settle_writes().await
832 }
833
834 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
835 unsafe { self.as_ref().dyn_invalidate_cache().await }
836 }
837
838 fn get_storage_helper(&self) -> &CommonStorageHelper {
839 self.as_ref().dyn_get_storage_helper()
840 }
841
842 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
843 self.as_ref().dyn_resize(new_size, prealloc_mode).await
844 }
845}
846
847#[maybe_async(AFIT)]
848impl Storage for Arc<dyn DynStorage> {
849 async fn open(opts: StorageOpenOptions) -> io::Result<Self> {
850 Box::<dyn DynStorage>::open(opts).await.map(Into::into)
851 }
852
853 async fn create_open(opts: StorageCreateOptions) -> io::Result<Self> {
854 Box::<dyn DynStorage>::create_open(opts)
855 .await
856 .map(Into::into)
857 }
858
859 fn mem_align(&self) -> usize {
860 self.as_ref().dyn_mem_align()
861 }
862
863 fn req_align(&self) -> usize {
864 self.as_ref().dyn_req_align()
865 }
866
867 fn zero_align(&self) -> usize {
868 self.as_ref().dyn_zero_align()
869 }
870
871 fn discard_align(&self) -> usize {
872 self.as_ref().dyn_discard_align()
873 }
874
875 fn size(&self) -> io::Result<u64> {
876 self.as_ref().dyn_size()
877 }
878
879 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
880 self.as_ref().dyn_resolve_relative_path(relative.as_ref())
881 }
882
883 fn get_filename(&self) -> Option<PathBuf> {
884 self.as_ref().dyn_get_filename()
885 }
886
887 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
888 unsafe { self.as_ref().dyn_pure_readv(bufv, offset) }.await
889 }
890
891 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
892 unsafe { self.as_ref().dyn_pure_writev(bufv, offset) }.await
893 }
894
895 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
896 unsafe { self.as_ref().dyn_pure_write_zeroes(offset, length) }.await
897 }
898
899 async unsafe fn pure_write_allocated_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
900 unsafe {
901 self.as_ref()
902 .dyn_pure_write_allocated_zeroes(offset, length)
903 }
904 .await
905 }
906
907 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
908 unsafe { self.as_ref().dyn_pure_discard(offset, length) }.await
909 }
910
911 async fn flush(&self) -> io::Result<()> {
912 self.as_ref().dyn_flush().await
913 }
914
915 async fn sync(&self) -> io::Result<()> {
916 self.as_ref().dyn_sync().await
917 }
918
919 async fn settle_writes(&self) -> io::Result<()> {
920 self.as_ref().dyn_settle_writes().await
921 }
922
923 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
924 unsafe { self.as_ref().dyn_invalidate_cache().await }
925 }
926
927 fn get_storage_helper(&self) -> &CommonStorageHelper {
928 self.as_ref().dyn_get_storage_helper()
929 }
930
931 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
932 self.as_ref().dyn_resize(new_size, prealloc_mode).await
933 }
934}
935
936impl StorageOpenOptions {
937 pub fn new() -> Self {
939 StorageOpenOptions::default()
940 }
941
942 pub fn filename<P: AsRef<Path>>(mut self, filename: P) -> Self {
944 self.filename = Some(filename.as_ref().to_owned());
945 self
946 }
947
948 pub fn write(mut self, write: bool) -> Self {
950 self.writable = write;
951 self
952 }
953
954 pub fn direct(mut self, direct: bool) -> Self {
956 self.direct = direct;
957 self
958 }
959
960 #[cfg(target_os = "macos")]
967 pub fn relaxed_sync(mut self, relaxed_sync: bool) -> Self {
968 self.relaxed_sync = relaxed_sync;
969 self
970 }
971
972 pub fn get_filename(&self) -> Option<&Path> {
974 self.filename.as_deref()
975 }
976
977 pub fn get_writable(&self) -> bool {
979 self.writable
980 }
981
982 pub fn get_direct(&self) -> bool {
984 self.direct
985 }
986
987 #[cfg(target_os = "macos")]
989 pub fn get_relaxed_sync(&self) -> bool {
990 self.relaxed_sync
991 }
992}
993
994impl StorageCreateOptions {
995 pub fn new() -> Self {
997 StorageCreateOptions::default()
998 }
999
1000 pub fn filename<P: AsRef<Path>>(self, filename: P) -> Self {
1002 self.modify_open_opts(|o| o.filename(filename))
1003 }
1004
1005 pub fn size(mut self, size: u64) -> Self {
1007 self.size = size;
1008 self
1009 }
1010
1011 pub fn preallocate(mut self, prealloc_mode: PreallocateMode) -> Self {
1013 self.prealloc_mode = prealloc_mode;
1014 self
1015 }
1016
1017 pub fn overwrite(mut self, overwrite: bool) -> Self {
1019 self.overwrite = overwrite;
1020 self
1021 }
1022
1023 pub fn modify_open_opts<F: FnOnce(StorageOpenOptions) -> StorageOpenOptions>(
1025 mut self,
1026 f: F,
1027 ) -> Self {
1028 self.open_opts = f(self.open_opts);
1029 self
1030 }
1031
1032 pub fn get_filename(&self) -> Option<&Path> {
1034 self.open_opts.filename.as_deref()
1035 }
1036
1037 pub fn get_size(&self) -> u64 {
1039 self.size
1040 }
1041
1042 pub fn get_preallocate(&self) -> PreallocateMode {
1044 self.prealloc_mode
1045 }
1046
1047 pub fn get_overwrite(&self) -> bool {
1049 self.overwrite
1050 }
1051
1052 pub fn get_open_options(self) -> StorageOpenOptions {
1054 self.open_opts
1055 }
1056}
1057
1058impl Default for StorageCreateOptions {
1059 fn default() -> Self {
1060 StorageCreateOptions {
1061 open_opts: Default::default(),
1062 size: 0,
1063 prealloc_mode: PreallocateMode::None,
1064 overwrite: false,
1065 }
1066 }
1067}
1068
1069#[maybe_async]
1081async unsafe fn pure_write_full_zeroes<S: Storage>(
1082 storage: S,
1083 mut offset: u64,
1084 mut length: u64,
1085) -> io::Result<()> {
1086 let req_align = storage.req_align() as u64;
1087 if !(offset | length).is_multiple_of(req_align) {
1088 return Err(io::Error::new(
1089 io::ErrorKind::InvalidInput,
1090 "write_zeroes fallback: offset/length not aligned to request alignment",
1091 ));
1092 }
1093
1094 let mem_align = storage.mem_align() as u64;
1095 let max_chunk_len = cmp::max(cmp::max(req_align, mem_align), 1048576);
1096 let buflen = cmp::min(length, max_chunk_len) as usize;
1097 let mut buf = IoBuffer::new(buflen, storage.mem_align())?;
1098 buf.as_mut().into_slice().fill(0);
1099
1100 while length > 0 {
1101 let chunk_len = cmp::min(length, max_chunk_len) as usize;
1102 unsafe {
1103 storage
1104 .pure_writev(buf.as_ref_range(0..chunk_len).into(), offset)
1105 .await
1106 }?;
1107 offset += chunk_len as u64;
1108 length -= chunk_len as u64;
1109 }
1110
1111 Ok(())
1112}