@@ -3,6 +3,7 @@ use super::fuse3_sys::{
33 fuse_session_unmount,
44} ;
55use super :: { MountOption , with_fuse_args} ;
6+ use log:: warn;
67use std:: {
78 ffi:: { CString , c_void} ,
89 fs:: File ,
@@ -25,6 +26,7 @@ fn ensure_last_os_error() -> io::Error {
2526#[ derive( Debug ) ]
2627pub struct Mount {
2728 fuse_session : * mut c_void ,
29+ mountpoint : CString ,
2830}
2931impl Mount {
3032 pub fn new ( mnt : & Path , options : & [ MountOption ] ) -> io:: Result < ( Arc < File > , Mount ) > {
@@ -34,7 +36,10 @@ impl Mount {
3436 if fuse_session. is_null ( ) {
3537 return Err ( io:: Error :: last_os_error ( ) ) ;
3638 }
37- let mount = Mount { fuse_session } ;
39+ let mount = Mount {
40+ fuse_session,
41+ mountpoint : mnt. clone ( ) ,
42+ } ;
3843 let result = unsafe { fuse_session_mount ( mount. fuse_session , mnt. as_ptr ( ) ) } ;
3944 if result != 0 {
4045 return Err ( ensure_last_os_error ( ) ) ;
@@ -53,9 +58,20 @@ impl Mount {
5358}
5459impl Drop for Mount {
5560 fn drop ( & mut self ) {
56- unsafe {
57- fuse_session_unmount ( self . fuse_session ) ;
58- fuse_session_destroy ( self . fuse_session ) ;
61+ use std:: io:: ErrorKind :: PermissionDenied ;
62+
63+ if let Err ( err) = super :: libc_umount ( & self . mountpoint ) {
64+ // Linux always returns EPERM for non-root users. We have to let the
65+ // library go through the setuid-root "fusermount -u" to unmount.
66+ if err. kind ( ) == PermissionDenied {
67+ #[ cfg( target_os = "linux" ) ]
68+ unsafe {
69+ fuse_session_unmount ( self . fuse_session ) ;
70+ fuse_session_destroy ( self . fuse_session ) ;
71+ return ;
72+ }
73+ }
74+ warn ! ( "umount failed with {:?}" , err) ;
5975 }
6076 }
6177}
0 commit comments