1pub mod drivers;
7pub mod ext;
8
9use crate::io_buffers::{IoVector, IoVectorMut};
10use drivers::CommonStorageHelper;
11use std::any::Any;
12use std::fmt::{Debug, Display};
13use std::future::Future;
14use std::io;
15use std::path::{Path, PathBuf};
16use std::pin::Pin;
17use std::sync::Arc;
18
19#[derive(Clone, Debug, Default)]
21pub struct StorageOpenOptions {
22 pub(crate) filename: Option<PathBuf>,
24
25 pub(crate) writable: bool,
27
28 pub(crate) direct: bool,
30}
31
32#[derive(Clone, Debug)]
34pub struct StorageCreateOptions {
35 pub(crate) open_opts: StorageOpenOptions,
39
40 pub(crate) size: u64,
42
43 pub(crate) prealloc_mode: PreallocateMode,
45
46 pub(crate) overwrite: bool,
48}
49
50pub trait Storage: Debug + Display + Send + Sized + Sync {
52 #[allow(async_fn_in_trait)] async fn open(_opts: StorageOpenOptions) -> io::Result<Self> {
57 Err(io::Error::new(
58 io::ErrorKind::Unsupported,
59 format!(
60 "Cannot open storage objects of type {}",
61 std::any::type_name::<Self>()
62 ),
63 ))
64 }
65
66 #[cfg(feature = "sync-wrappers")]
68 fn open_sync(opts: StorageOpenOptions) -> io::Result<Self> {
69 tokio::runtime::Builder::new_current_thread()
70 .build()?
71 .block_on(Self::open(opts))
72 }
73
74 #[allow(async_fn_in_trait)] async fn create_open(_opts: StorageCreateOptions) -> io::Result<Self> {
81 Err(io::Error::new(
82 io::ErrorKind::Unsupported,
83 format!(
84 "Cannot create storage objects of type {}",
85 std::any::type_name::<Self>()
86 ),
87 ))
88 }
89
90 #[allow(async_fn_in_trait)] async fn create(opts: StorageCreateOptions) -> io::Result<()> {
95 Self::create_open(opts).await?;
96 Ok(())
97 }
98
99 fn mem_align(&self) -> usize {
101 1
102 }
103
104 fn req_align(&self) -> usize {
106 1
107 }
108
109 fn zero_align(&self) -> usize {
111 1
112 }
113
114 fn discard_align(&self) -> usize {
116 1
117 }
118
119 fn size(&self) -> io::Result<u64>;
121
122 fn resolve_relative_path<P: AsRef<Path>>(&self, _relative: P) -> io::Result<PathBuf> {
132 Err(io::ErrorKind::Unsupported.into())
133 }
134
135 fn get_filename(&self) -> Option<PathBuf> {
140 None
141 }
142
143 #[allow(async_fn_in_trait)] async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()>;
156
157 #[allow(async_fn_in_trait)] async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()>;
173
174 #[allow(async_fn_in_trait)] async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
187 ext::write_full_zeroes(self, offset, length).await
188 }
189
190 #[allow(async_fn_in_trait)] async unsafe fn pure_discard(&self, _offset: u64, _length: u64) -> io::Result<()> {
205 Ok(())
206 }
207
208 #[allow(async_fn_in_trait)] async fn flush(&self) -> io::Result<()>;
217
218 #[allow(async_fn_in_trait)] async fn sync(&self) -> io::Result<()>;
224
225 #[allow(async_fn_in_trait)] async unsafe fn invalidate_cache(&self) -> io::Result<()>;
235
236 fn get_storage_helper(&self) -> &CommonStorageHelper;
239
240 #[allow(async_fn_in_trait)] async fn resize(&self, _new_size: u64, _prealloc_mode: PreallocateMode) -> io::Result<()> {
250 Err(io::ErrorKind::Unsupported.into())
251 }
252}
253
254pub trait DynStorage: Any + Debug + Display + Send + Sync {
268 fn dyn_mem_align(&self) -> usize;
270
271 fn dyn_req_align(&self) -> usize;
273
274 fn dyn_zero_align(&self) -> usize;
276
277 fn dyn_discard_align(&self) -> usize;
279
280 fn dyn_size(&self) -> io::Result<u64>;
282
283 fn dyn_resolve_relative_path(&self, relative: &Path) -> io::Result<PathBuf>;
285
286 fn dyn_get_filename(&self) -> Option<PathBuf>;
288
289 unsafe fn dyn_pure_readv<'a>(
294 &'a self,
295 bufv: IoVectorMut<'a>,
296 offset: u64,
297 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>>;
298
299 unsafe fn dyn_pure_writev<'a>(
304 &'a self,
305 bufv: IoVector<'a>,
306 offset: u64,
307 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>>;
308
309 unsafe fn dyn_pure_write_zeroes(
314 &self,
315 offset: u64,
316 length: u64,
317 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
318
319 unsafe fn dyn_pure_discard(
324 &self,
325 offset: u64,
326 length: u64,
327 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
328
329 fn dyn_flush(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
331
332 fn dyn_sync(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
334
335 unsafe fn dyn_invalidate_cache(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
340
341 fn dyn_get_storage_helper(&self) -> &CommonStorageHelper;
343
344 fn dyn_resize(
346 &self,
347 new_size: u64,
348 prealloc_mode: PreallocateMode,
349 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>>;
350}
351
352#[derive(Clone, Copy, Debug, Eq, PartialEq)]
357#[non_exhaustive]
358pub enum PreallocateMode {
359 None,
363
364 Zero,
369
370 Allocate,
374
375 WriteData,
379}
380
381impl<S: Storage> Storage for &S {
382 fn mem_align(&self) -> usize {
383 (*self).mem_align()
384 }
385
386 fn req_align(&self) -> usize {
387 (*self).req_align()
388 }
389
390 fn zero_align(&self) -> usize {
391 (*self).zero_align()
392 }
393
394 fn discard_align(&self) -> usize {
395 (*self).discard_align()
396 }
397
398 fn size(&self) -> io::Result<u64> {
399 (*self).size()
400 }
401
402 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
403 (*self).resolve_relative_path(relative)
404 }
405
406 fn get_filename(&self) -> Option<PathBuf> {
407 (*self).get_filename()
408 }
409
410 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
411 unsafe { (*self).pure_readv(bufv, offset).await }
412 }
413
414 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
415 unsafe { (*self).pure_writev(bufv, offset).await }
416 }
417
418 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
419 unsafe { (*self).pure_write_zeroes(offset, length).await }
420 }
421
422 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
423 unsafe { (*self).pure_discard(offset, length).await }
424 }
425
426 async fn flush(&self) -> io::Result<()> {
427 (*self).flush().await
428 }
429
430 async fn sync(&self) -> io::Result<()> {
431 (*self).sync().await
432 }
433
434 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
435 unsafe { (*self).invalidate_cache().await }
436 }
437
438 fn get_storage_helper(&self) -> &CommonStorageHelper {
439 (*self).get_storage_helper()
440 }
441
442 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
443 (*self).resize(new_size, prealloc_mode).await
444 }
445}
446
447impl<S: Storage + 'static> DynStorage for S {
448 fn dyn_mem_align(&self) -> usize {
449 <S as Storage>::mem_align(self)
450 }
451
452 fn dyn_req_align(&self) -> usize {
453 <S as Storage>::req_align(self)
454 }
455
456 fn dyn_zero_align(&self) -> usize {
457 <S as Storage>::zero_align(self)
458 }
459
460 fn dyn_discard_align(&self) -> usize {
461 <S as Storage>::discard_align(self)
462 }
463
464 fn dyn_size(&self) -> io::Result<u64> {
465 <S as Storage>::size(self)
466 }
467
468 fn dyn_resolve_relative_path(&self, relative: &Path) -> io::Result<PathBuf> {
469 <S as Storage>::resolve_relative_path(self, relative)
470 }
471
472 fn dyn_get_filename(&self) -> Option<PathBuf> {
473 <S as Storage>::get_filename(self)
474 }
475
476 unsafe fn dyn_pure_readv<'a>(
477 &'a self,
478 bufv: IoVectorMut<'a>,
479 offset: u64,
480 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>> {
481 Box::pin(unsafe { <S as Storage>::pure_readv(self, bufv, offset) })
482 }
483
484 unsafe fn dyn_pure_writev<'a>(
485 &'a self,
486 bufv: IoVector<'a>,
487 offset: u64,
488 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>> {
489 Box::pin(unsafe { <S as Storage>::pure_writev(self, bufv, offset) })
490 }
491
492 unsafe fn dyn_pure_write_zeroes(
493 &self,
494 offset: u64,
495 length: u64,
496 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
497 Box::pin(unsafe { <S as Storage>::pure_write_zeroes(self, offset, length) })
498 }
499
500 unsafe fn dyn_pure_discard(
501 &self,
502 offset: u64,
503 length: u64,
504 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
505 Box::pin(unsafe { <S as Storage>::pure_discard(self, offset, length) })
506 }
507
508 fn dyn_flush(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
509 Box::pin(<S as Storage>::flush(self))
510 }
511
512 fn dyn_sync(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
513 Box::pin(<S as Storage>::sync(self))
514 }
515
516 unsafe fn dyn_invalidate_cache(&self) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
517 Box::pin(unsafe { <S as Storage>::invalidate_cache(self) })
518 }
519
520 fn dyn_get_storage_helper(&self) -> &CommonStorageHelper {
521 <S as Storage>::get_storage_helper(self)
522 }
523
524 fn dyn_resize(
525 &self,
526 new_size: u64,
527 prealloc_mode: PreallocateMode,
528 ) -> Pin<Box<dyn Future<Output = io::Result<()>> + '_>> {
529 Box::pin(<S as Storage>::resize(self, new_size, prealloc_mode))
530 }
531}
532
533impl Storage for Box<dyn DynStorage> {
534 async fn open(opts: StorageOpenOptions) -> io::Result<Self> {
535 Ok(Box::new(crate::file::File::open(opts).await?))
539 }
540
541 async fn create_open(opts: StorageCreateOptions) -> io::Result<Self> {
542 Ok(Box::new(crate::file::File::create_open(opts).await?))
544 }
545
546 fn mem_align(&self) -> usize {
547 self.as_ref().dyn_mem_align()
548 }
549
550 fn req_align(&self) -> usize {
551 self.as_ref().dyn_req_align()
552 }
553
554 fn zero_align(&self) -> usize {
555 self.as_ref().dyn_zero_align()
556 }
557
558 fn discard_align(&self) -> usize {
559 self.as_ref().dyn_discard_align()
560 }
561
562 fn size(&self) -> io::Result<u64> {
563 self.as_ref().dyn_size()
564 }
565
566 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
567 self.as_ref().dyn_resolve_relative_path(relative.as_ref())
568 }
569
570 fn get_filename(&self) -> Option<PathBuf> {
571 self.as_ref().dyn_get_filename()
572 }
573
574 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
575 unsafe { self.as_ref().dyn_pure_readv(bufv, offset).await }
576 }
577
578 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
579 unsafe { self.as_ref().dyn_pure_writev(bufv, offset).await }
580 }
581
582 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
583 unsafe { self.as_ref().dyn_pure_write_zeroes(offset, length).await }
584 }
585
586 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
587 unsafe { self.as_ref().dyn_pure_discard(offset, length).await }
588 }
589
590 async fn flush(&self) -> io::Result<()> {
591 self.as_ref().dyn_flush().await
592 }
593
594 async fn sync(&self) -> io::Result<()> {
595 self.as_ref().dyn_sync().await
596 }
597
598 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
599 unsafe { self.as_ref().dyn_invalidate_cache().await }
600 }
601
602 fn get_storage_helper(&self) -> &CommonStorageHelper {
603 self.as_ref().dyn_get_storage_helper()
604 }
605
606 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
607 self.as_ref().dyn_resize(new_size, prealloc_mode).await
608 }
609}
610
611impl Storage for Arc<dyn DynStorage> {
612 async fn open(opts: StorageOpenOptions) -> io::Result<Self> {
613 Box::<dyn DynStorage>::open(opts).await.map(Into::into)
614 }
615
616 async fn create_open(opts: StorageCreateOptions) -> io::Result<Self> {
617 Box::<dyn DynStorage>::create_open(opts)
618 .await
619 .map(Into::into)
620 }
621
622 fn mem_align(&self) -> usize {
623 self.as_ref().dyn_mem_align()
624 }
625
626 fn req_align(&self) -> usize {
627 self.as_ref().dyn_req_align()
628 }
629
630 fn zero_align(&self) -> usize {
631 self.as_ref().dyn_zero_align()
632 }
633
634 fn discard_align(&self) -> usize {
635 self.as_ref().dyn_discard_align()
636 }
637
638 fn size(&self) -> io::Result<u64> {
639 self.as_ref().dyn_size()
640 }
641
642 fn resolve_relative_path<P: AsRef<Path>>(&self, relative: P) -> io::Result<PathBuf> {
643 self.as_ref().dyn_resolve_relative_path(relative.as_ref())
644 }
645
646 fn get_filename(&self) -> Option<PathBuf> {
647 self.as_ref().dyn_get_filename()
648 }
649
650 async unsafe fn pure_readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> io::Result<()> {
651 unsafe { self.as_ref().dyn_pure_readv(bufv, offset) }.await
652 }
653
654 async unsafe fn pure_writev(&self, bufv: IoVector<'_>, offset: u64) -> io::Result<()> {
655 unsafe { self.as_ref().dyn_pure_writev(bufv, offset) }.await
656 }
657
658 async unsafe fn pure_write_zeroes(&self, offset: u64, length: u64) -> io::Result<()> {
659 unsafe { self.as_ref().dyn_pure_write_zeroes(offset, length) }.await
660 }
661
662 async unsafe fn pure_discard(&self, offset: u64, length: u64) -> io::Result<()> {
663 unsafe { self.as_ref().dyn_pure_discard(offset, length) }.await
664 }
665
666 async fn flush(&self) -> io::Result<()> {
667 self.as_ref().dyn_flush().await
668 }
669
670 async fn sync(&self) -> io::Result<()> {
671 self.as_ref().dyn_sync().await
672 }
673
674 async unsafe fn invalidate_cache(&self) -> io::Result<()> {
675 unsafe { self.as_ref().dyn_invalidate_cache().await }
676 }
677
678 fn get_storage_helper(&self) -> &CommonStorageHelper {
679 self.as_ref().dyn_get_storage_helper()
680 }
681
682 async fn resize(&self, new_size: u64, prealloc_mode: PreallocateMode) -> io::Result<()> {
683 self.as_ref().dyn_resize(new_size, prealloc_mode).await
684 }
685}
686
687impl StorageOpenOptions {
688 pub fn new() -> Self {
690 StorageOpenOptions::default()
691 }
692
693 pub fn filename<P: AsRef<Path>>(mut self, filename: P) -> Self {
695 self.filename = Some(filename.as_ref().to_owned());
696 self
697 }
698
699 pub fn write(mut self, write: bool) -> Self {
701 self.writable = write;
702 self
703 }
704
705 pub fn direct(mut self, direct: bool) -> Self {
707 self.direct = direct;
708 self
709 }
710
711 pub fn get_filename(&self) -> Option<&Path> {
713 self.filename.as_deref()
714 }
715
716 pub fn get_writable(&self) -> bool {
718 self.writable
719 }
720
721 pub fn get_direct(&self) -> bool {
723 self.direct
724 }
725}
726
727impl StorageCreateOptions {
728 pub fn new() -> Self {
730 StorageCreateOptions::default()
731 }
732
733 pub fn filename<P: AsRef<Path>>(self, filename: P) -> Self {
735 self.modify_open_opts(|o| o.filename(filename))
736 }
737
738 pub fn size(mut self, size: u64) -> Self {
740 self.size = size;
741 self
742 }
743
744 pub fn preallocate(mut self, prealloc_mode: PreallocateMode) -> Self {
746 self.prealloc_mode = prealloc_mode;
747 self
748 }
749
750 pub fn overwrite(mut self, overwrite: bool) -> Self {
752 self.overwrite = overwrite;
753 self
754 }
755
756 pub fn modify_open_opts<F: FnOnce(StorageOpenOptions) -> StorageOpenOptions>(
758 mut self,
759 f: F,
760 ) -> Self {
761 self.open_opts = f(self.open_opts);
762 self
763 }
764
765 pub fn get_filename(&self) -> Option<&Path> {
767 self.open_opts.filename.as_deref()
768 }
769
770 pub fn get_size(&self) -> u64 {
772 self.size
773 }
774
775 pub fn get_preallocate(&self) -> PreallocateMode {
777 self.prealloc_mode
778 }
779
780 pub fn get_overwrite(&self) -> bool {
782 self.overwrite
783 }
784
785 pub fn get_open_options(self) -> StorageOpenOptions {
787 self.open_opts
788 }
789}
790
791impl Default for StorageCreateOptions {
792 fn default() -> Self {
793 StorageCreateOptions {
794 open_opts: Default::default(),
795 size: 0,
796 prealloc_mode: PreallocateMode::None,
797 overwrite: false,
798 }
799 }
800}