1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#[cfg(unix)]
use super::super::Error;
#[cfg(unix)]
use std::path::{Path, PathBuf};
#[cfg(unix)]
pub fn find_mountpoint_pre_canonicalized(path: &Path) -> Result<&Path, Error> {
use std::fs::symlink_metadata;
use std::os::unix::fs::MetadataExt;
let mut lstats = symlink_metadata(path)?;
let start_dev = lstats.dev();
let mut mountpoint = path;
loop {
let current = match mountpoint.parent() {
Some(p) => p,
None => return Ok(mountpoint),
};
lstats = symlink_metadata(current)?;
if lstats.dev() != start_dev {
break;
}
mountpoint = current;
}
assert!(path.starts_with(mountpoint));
assert!(!mountpoint.as_os_str().is_empty());
Ok(mountpoint)
}
#[cfg(unix)]
pub fn find_mountpoint(path: &Path) -> Result<PathBuf, Error> {
let canonicalized = path.canonicalize()?;
let found = find_mountpoint_pre_canonicalized(canonicalized.as_path())?;
Ok(found.to_path_buf())
}