@@ -9,6 +9,7 @@ use libc::{EAGAIN, EINTR, ENODEV, ENOENT};
9
9
use log:: { info, warn} ;
10
10
use nix:: unistd:: geteuid;
11
11
use std:: fmt;
12
+ use std:: os:: fd:: { AsFd , BorrowedFd , OwnedFd } ;
12
13
use std:: path:: { Path , PathBuf } ;
13
14
use std:: sync:: { Arc , Mutex } ;
14
15
use std:: thread:: { self , JoinHandle } ;
@@ -31,10 +32,15 @@ pub const MAX_WRITE_SIZE: usize = 16 * 1024 * 1024;
31
32
/// up to MAX_WRITE_SIZE bytes in a write request, we use that value plus some extra space.
32
33
const BUFFER_SIZE : usize = MAX_WRITE_SIZE + 4096 ;
33
34
34
- #[ derive( Debug , Eq , PartialEq ) ]
35
- pub ( crate ) enum SessionACL {
35
+ #[ derive( Default , Debug , Eq , PartialEq ) ]
36
+ /// How requests should be filtered based on the calling UID.
37
+ pub enum SessionACL {
38
+ /// Allow requests from any user. Corresponds to the `allow_other` mount option.
36
39
All ,
40
+ /// Allow requests from root. Corresponds to the `allow_root` mount option.
37
41
RootAndOwner ,
42
+ /// Allow requests from the owning UID. This is FUSE's default mode of operation.
43
+ #[ default]
38
44
Owner ,
39
45
}
40
46
@@ -46,9 +52,7 @@ pub struct Session<FS: Filesystem> {
46
52
/// Communication channel to the kernel driver
47
53
ch : Channel ,
48
54
/// Handle to the mount. Dropping this unmounts.
49
- mount : Arc < Mutex < Option < Mount > > > ,
50
- /// Mount point
51
- mountpoint : PathBuf ,
55
+ mount : Arc < Mutex < Option < ( PathBuf , Mount ) > > > ,
52
56
/// Whether to restrict access to owner, root + owner, or unrestricted
53
57
/// Used to implement allow_root and auto_unmount
54
58
pub ( crate ) allowed : SessionACL ,
@@ -64,6 +68,12 @@ pub struct Session<FS: Filesystem> {
64
68
pub ( crate ) destroyed : bool ,
65
69
}
66
70
71
+ impl < FS : Filesystem > AsFd for Session < FS > {
72
+ fn as_fd ( & self ) -> BorrowedFd < ' _ > {
73
+ self . ch . as_fd ( )
74
+ }
75
+ }
76
+
67
77
impl < FS : Filesystem > Session < FS > {
68
78
/// Create a new session by mounting the given filesystem to the given mountpoint
69
79
pub fn new < P : AsRef < Path > > (
@@ -100,8 +110,7 @@ impl<FS: Filesystem> Session<FS> {
100
110
Ok ( Session {
101
111
filesystem,
102
112
ch,
103
- mount : Arc :: new ( Mutex :: new ( Some ( mount) ) ) ,
104
- mountpoint : mountpoint. to_owned ( ) ,
113
+ mount : Arc :: new ( Mutex :: new ( Some ( ( mountpoint. to_owned ( ) , mount) ) ) ) ,
105
114
allowed,
106
115
session_owner : geteuid ( ) . as_raw ( ) ,
107
116
proto_major : 0 ,
@@ -111,9 +120,21 @@ impl<FS: Filesystem> Session<FS> {
111
120
} )
112
121
}
113
122
114
- /// Return path of the mounted filesystem
115
- pub fn mountpoint ( & self ) -> & Path {
116
- & self . mountpoint
123
+ /// Wrap an existing /dev/fuse file descriptor. This doesn't mount the
124
+ /// filesystem anywhere; that must be done separately.
125
+ pub fn from_fd ( filesystem : FS , fd : OwnedFd , acl : SessionACL ) -> Self {
126
+ let ch = Channel :: new ( Arc :: new ( fd. into ( ) ) ) ;
127
+ Session {
128
+ filesystem,
129
+ ch,
130
+ mount : Arc :: new ( Mutex :: new ( None ) ) ,
131
+ allowed : acl,
132
+ session_owner : geteuid ( ) . as_raw ( ) ,
133
+ proto_major : 0 ,
134
+ proto_minor : 0 ,
135
+ initialized : false ,
136
+ destroyed : false ,
137
+ }
117
138
}
118
139
119
140
/// Run the session loop that receives kernel requests and dispatches them to method
@@ -177,7 +198,7 @@ impl<FS: Filesystem> Session<FS> {
177
198
#[ derive( Debug ) ]
178
199
/// A thread-safe object that can be used to unmount a Filesystem
179
200
pub struct SessionUnmounter {
180
- mount : Arc < Mutex < Option < Mount > > > ,
201
+ mount : Arc < Mutex < Option < ( PathBuf , Mount ) > > > ,
181
202
}
182
203
183
204
impl SessionUnmounter {
@@ -210,40 +231,38 @@ impl<FS: Filesystem> Drop for Session<FS> {
210
231
self . filesystem . destroy ( ) ;
211
232
self . destroyed = true ;
212
233
}
213
- info ! ( "Unmounted {}" , self . mountpoint( ) . display( ) ) ;
234
+
235
+ if let Some ( ( mountpoint, _mount) ) = std:: mem:: take ( & mut * self . mount . lock ( ) . unwrap ( ) ) {
236
+ info ! ( "unmounting session at {}" , mountpoint. display( ) ) ;
237
+ }
214
238
}
215
239
}
216
240
217
241
/// The background session data structure
218
242
pub struct BackgroundSession {
219
- /// Path of the mounted filesystem
220
- pub mountpoint : PathBuf ,
221
243
/// Thread guard of the background session
222
244
pub guard : JoinHandle < io:: Result < ( ) > > ,
223
245
/// Object for creating Notifiers for client use
224
246
#[ cfg( feature = "abi-7-11" ) ]
225
247
sender : ChannelSender ,
226
248
/// Ensures the filesystem is unmounted when the session ends
227
- _mount : Mount ,
249
+ _mount : Option < Mount > ,
228
250
}
229
251
230
252
impl BackgroundSession {
231
253
/// Create a new background session for the given session by running its
232
254
/// session loop in a background thread. If the returned handle is dropped,
233
255
/// the filesystem is unmounted and the given session ends.
234
256
pub fn new < FS : Filesystem + Send + ' static > ( se : Session < FS > ) -> io:: Result < BackgroundSession > {
235
- let mountpoint = se. mountpoint ( ) . to_path_buf ( ) ;
236
257
#[ cfg( feature = "abi-7-11" ) ]
237
258
let sender = se. ch . sender ( ) ;
238
259
// Take the fuse_session, so that we can unmount it
239
- let mount = std:: mem:: take ( & mut * se. mount . lock ( ) . unwrap ( ) ) ;
240
- let mount = mount. ok_or_else ( || io:: Error :: from_raw_os_error ( libc:: ENODEV ) ) ?;
260
+ let mount = std:: mem:: take ( & mut * se. mount . lock ( ) . unwrap ( ) ) . map ( |( _, mount) | mount) ;
241
261
let guard = thread:: spawn ( move || {
242
262
let mut se = se;
243
263
se. run ( )
244
264
} ) ;
245
265
Ok ( BackgroundSession {
246
- mountpoint,
247
266
guard,
248
267
#[ cfg( feature = "abi-7-11" ) ]
249
268
sender,
@@ -253,7 +272,6 @@ impl BackgroundSession {
253
272
/// Unmount the filesystem and join the background thread.
254
273
pub fn join ( self ) {
255
274
let Self {
256
- mountpoint : _,
257
275
guard,
258
276
#[ cfg( feature = "abi-7-11" ) ]
259
277
sender: _,
@@ -274,10 +292,6 @@ impl BackgroundSession {
274
292
// thread_scoped::JoinGuard
275
293
impl fmt:: Debug for BackgroundSession {
276
294
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> Result < ( ) , fmt:: Error > {
277
- write ! (
278
- f,
279
- "BackgroundSession {{ mountpoint: {:?}, guard: JoinGuard<()> }}" ,
280
- self . mountpoint
281
- )
295
+ write ! ( f, "BackgroundSession {{ guard: JoinGuard<()> }}" , )
282
296
}
283
297
}
0 commit comments