@@ -266,6 +266,47 @@ impl Default for Config {
266
266
}
267
267
}
268
268
269
+ fn insert_root_dir (
270
+ root_dir : & str ,
271
+ inodes : & mut MultikeyBTreeMap < Inode , InodeAltKey , Arc < InodeData > > ,
272
+ ) -> io:: Result < ( ) > {
273
+ let root = CString :: new ( root_dir) . expect ( "CString::new failed" ) ;
274
+
275
+ // Safe because this doesn't modify any memory and we check the return value.
276
+ // We use `O_PATH` because we just want this for traversing the directory tree
277
+ // and not for actually reading the contents.
278
+ let fd = unsafe {
279
+ libc:: openat (
280
+ libc:: AT_FDCWD ,
281
+ root. as_ptr ( ) ,
282
+ libc:: O_PATH | libc:: O_NOFOLLOW | libc:: O_CLOEXEC ,
283
+ )
284
+ } ;
285
+ if fd < 0 {
286
+ return Err ( io:: Error :: last_os_error ( ) ) ;
287
+ }
288
+
289
+ // Safe because we just opened this fd above.
290
+ let f = unsafe { File :: from_raw_fd ( fd) } ;
291
+
292
+ let st = stat ( & f) ?;
293
+
294
+ // Not sure why the root inode gets a refcount of 2 but that's what libfuse does.
295
+ inodes. insert (
296
+ fuse:: ROOT_ID ,
297
+ InodeAltKey {
298
+ ino : st. st_ino ,
299
+ dev : st. st_dev ,
300
+ } ,
301
+ Arc :: new ( InodeData {
302
+ inode : fuse:: ROOT_ID ,
303
+ file : f,
304
+ refcount : AtomicU64 :: new ( 2 ) ,
305
+ } ) ,
306
+ ) ;
307
+ Ok ( ( ) )
308
+ }
309
+
269
310
/// A file system that simply "passes through" all requests it receives to the underlying file
270
311
/// system. To keep the implementation simple it servers the contents of its root directory. Users
271
312
/// that wish to serve only a specific directory should set up the environment so that that
@@ -324,9 +365,11 @@ impl PassthroughFs {
324
365
325
366
// Safe because we just opened this fd or it was provided by our caller.
326
367
let proc_self_fd = unsafe { File :: from_raw_fd ( fd) } ;
368
+ let mut inodes = MultikeyBTreeMap :: new ( ) ;
369
+ insert_root_dir ( & cfg. root_dir , & mut inodes) ?;
327
370
328
371
Ok ( PassthroughFs {
329
- inodes : RwLock :: new ( MultikeyBTreeMap :: new ( ) ) ,
372
+ inodes : RwLock :: new ( inodes ) ,
330
373
next_inode : AtomicU64 :: new ( fuse:: ROOT_ID + 2 ) ,
331
374
init_inode : fuse:: ROOT_ID + 1 ,
332
375
@@ -683,48 +726,11 @@ impl FileSystem for PassthroughFs {
683
726
type Handle = Handle ;
684
727
685
728
fn init ( & self , capable : FsOptions ) -> io:: Result < FsOptions > {
686
- let root = CString :: new ( self . cfg . root_dir . as_str ( ) ) . expect ( "CString::new failed" ) ;
687
-
688
- // Safe because this doesn't modify any memory and we check the return value.
689
- // We use `O_PATH` because we just want this for traversing the directory tree
690
- // and not for actually reading the contents.
691
- let fd = unsafe {
692
- libc:: openat (
693
- libc:: AT_FDCWD ,
694
- root. as_ptr ( ) ,
695
- libc:: O_PATH | libc:: O_NOFOLLOW | libc:: O_CLOEXEC ,
696
- )
697
- } ;
698
- if fd < 0 {
699
- return Err ( io:: Error :: last_os_error ( ) ) ;
700
- }
701
-
702
- // Safe because we just opened this fd above.
703
- let f = unsafe { File :: from_raw_fd ( fd) } ;
704
-
705
- let st = stat ( & f) ?;
706
-
707
729
// Safe because this doesn't modify any memory and there is no need to check the return
708
730
// value because this system call always succeeds. We need to clear the umask here because
709
731
// we want the client to be able to set all the bits in the mode.
710
732
unsafe { libc:: umask ( 0o000 ) } ;
711
733
712
- let mut inodes = self . inodes . write ( ) . unwrap ( ) ;
713
-
714
- // Not sure why the root inode gets a refcount of 2 but that's what libfuse does.
715
- inodes. insert (
716
- fuse:: ROOT_ID ,
717
- InodeAltKey {
718
- ino : st. st_ino ,
719
- dev : st. st_dev ,
720
- } ,
721
- Arc :: new ( InodeData {
722
- inode : fuse:: ROOT_ID ,
723
- file : f,
724
- refcount : AtomicU64 :: new ( 2 ) ,
725
- } ) ,
726
- ) ;
727
-
728
734
let mut opts = FsOptions :: DO_READDIRPLUS | FsOptions :: READDIRPLUS_AUTO ;
729
735
if self . cfg . writeback && capable. contains ( FsOptions :: WRITEBACK_CACHE ) {
730
736
opts |= FsOptions :: WRITEBACK_CACHE ;
0 commit comments