1use crate::umount::{unmount_, Unmount, UnmountDrop};
5use crate::{MountBuilder, UnmountFlags};
6use std::{
7 ffi::{CString, OsStr},
8 io,
9 os::unix::ffi::OsStrExt,
10 path::Path,
11};
12
13#[derive(Debug)]
15pub struct Mount {
16 pub(crate) target: CString,
17 pub(crate) fstype: String,
18 #[cfg(feature = "loop")]
19 pub(crate) loopback: Option<loopdev::LoopDevice>,
20 pub(crate) loop_path: Option<std::path::PathBuf>,
21}
22
23impl Unmount for Mount {
24 fn unmount(&self, flags: UnmountFlags) -> io::Result<()> {
25 unsafe {
26 unmount_(self.target.as_ptr(), flags)?;
27 }
28
29 #[cfg(feature = "loop")]
30 if let Some(ref loopback) = self.loopback {
31 loopback.detach()?;
32 }
33
34 Ok(())
35 }
36}
37
38impl Mount {
39 #[inline]
53 #[must_use]
54 pub fn builder<'a>() -> MountBuilder<'a> {
55 MountBuilder::default()
56 }
57
58 #[inline]
68 pub fn new(source: impl AsRef<Path>, target: impl AsRef<Path>) -> io::Result<Mount> {
69 let supported = crate::SupportedFilesystems::new()?;
70 MountBuilder::default()
71 .fstype(&supported)
72 .mount(source, target)
73 }
74
75 #[inline]
78 #[must_use]
79 pub fn backing_loop_device(&self) -> Option<&Path> {
80 self.loop_path.as_deref()
81 }
82
83 #[inline]
87 #[must_use]
88 pub fn get_fstype(&self) -> &str {
89 &self.fstype
90 }
91
92 #[inline]
94 #[must_use]
95 pub fn target_path(&self) -> &Path {
96 Path::new(OsStr::from_bytes(self.target.as_bytes()))
97 }
98
99 #[inline]
100 pub(crate) fn from_target_and_fstype(target: CString, fstype: String) -> Self {
101 Mount {
102 target,
103 fstype,
104 #[cfg(feature = "loop")]
105 loopback: None,
106 loop_path: None,
107 }
108 }
109}
110
111pub struct Mounts(pub Vec<UnmountDrop<Mount>>);
113
114impl Mounts {
115 pub fn unmount(&mut self, lazy: bool) -> io::Result<()> {
121 let flags = if lazy {
122 UnmountFlags::DETACH
123 } else {
124 UnmountFlags::empty()
125 };
126 self.0
127 .iter_mut()
128 .rev()
129 .try_for_each(|mount| mount.unmount(flags))
130 }
131}
132
133impl Drop for Mounts {
134 fn drop(&mut self) {
135 for mount in self.0.drain(..).rev() {
136 drop(mount);
137 }
138 }
139}