Skip to content

Commit dc73be5

Browse files
committed
[rfuse3]: refactor dependencies and improve example unmount logic
- Moved `clap` and `tracing-subscriber` to dev-dependencies in `Cargo.toml`. - Updated the minimal filesystem example to unmount the filesystem after the select completes, preventing overlapping borrows. - Enhanced the test script to implement platform-specific unmount logic for better reliability. Signed-off-by: LangQi99 <[email protected]>
1 parent 4dd7815 commit dc73be5

File tree

6 files changed

+42
-15
lines changed

6 files changed

+42
-15
lines changed

project/rfuse3/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ async-io = { version = "2.3.1", optional = true }
3838
async-process = { version = "2.1.0", optional = true }
3939
bincode = "1.3.3"
4040
bytes = "1.10.1"
41-
clap = { version = "4.4", features = ["derive"] }
4241
futures-channel = { version = "0.3.30", features = ["sink"] }
4342
futures-util = { version = "0.3.30", features = ["sink"] }
4443
libc = "0.2.171"
@@ -59,7 +58,6 @@ nix = { version = "0.29.0", features = [
5958
serde = { version = "1.0", features = ["derive"] }
6059
slab = "0.4.9"
6160
tracing = { version = "0.1.41", features = ["attributes"] }
62-
tracing-subscriber = "0.3"
6361
trait-make = "0.1"
6462
which = { version = "4.4.2", optional = true }
6563

@@ -68,6 +66,10 @@ version = "1.36"
6866
features = ["full"]
6967
optional = true
7068

69+
[dev-dependencies]
70+
clap = { version = "4.4", features = ["derive"] }
71+
tracing-subscriber = "0.3"
72+
7173
[package.metadata.docs.rs]
7274
rustdoc-args = ["--cfg", "docsrs"]
7375
features = ["file-lock", "unprivileged", "tokio-runtime"]

project/rfuse3/examples/minimal_filesystem_example.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,8 @@ async fn main() -> Result<()> {
391391
info!(" - ls {} # List directory contents", args.mountpoint);
392392
info!(" - cat {}/hello.txt # Read file", args.mountpoint);
393393
info!("Press Ctrl+C to unmount the filesystem");
394-
let handle = &mut mount_handle;
395394
tokio::select! {
396-
res = handle => {
395+
res = &mut mount_handle => {
397396
match res {
398397
Ok(_) => info!("Filesystem exited normally"),
399398
Err(e) => {
@@ -404,13 +403,15 @@ async fn main() -> Result<()> {
404403
},
405404
_ = signal::ctrl_c() => {
406405
info!("Received exit signal, unmounting filesystem...");
407-
mount_handle.unmount().await.map_err(|e| {
408-
eprintln!("Unmount failed: {}", e);
409-
e
410-
})?;
411-
info!("Filesystem unmounted");
412406
}
413407
}
414408

409+
// Unmount after the select completes to avoid overlapping borrows
410+
mount_handle.unmount().await.map_err(|e| {
411+
eprintln!("Unmount failed: {}", e);
412+
e
413+
})?;
414+
info!("Filesystem unmounted");
415+
415416
Ok(())
416417
}

project/rfuse3/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
all(target_os = "linux", feature = "unprivileged"),
2525
target_os = "macos"
2626
))]
27-
use std::io::{self, ErrorKind};
27+
use std::io;
2828
#[cfg(target_os = "macos")]
2929
use std::path::Path;
3030
#[cfg(any(
@@ -243,6 +243,7 @@ fn find_fusermount3() -> io::Result<PathBuf> {
243243

244244
#[cfg(target_os = "macos")]
245245
fn find_macfuse_mount() -> io::Result<PathBuf> {
246+
use std::io::ErrorKind;
246247
if Path::new("/Library/Filesystems/macfuse.fs/Contents/Resources/mount_macfuse").exists() {
247248
Ok(PathBuf::from(
248249
"/Library/Filesystems/macfuse.fs/Contents/Resources/mount_macfuse",

project/rfuse3/src/raw/connection/tokio.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use std::env;
33
#[cfg(any(target_os = "linux", target_os = "macos"))]
44
use std::fs::File;
55
use std::fs::OpenOptions;
6+
use std::io;
67
#[cfg(any(target_os = "linux", target_os = "macos"))]
78
use std::io::Write;
8-
use std::io::{self, ErrorKind};
99
use std::io::{IoSlice, IoSliceMut};
1010
use std::ops::{Deref, DerefMut};
1111
#[cfg(any(
@@ -234,6 +234,7 @@ impl BlockFuseConnection {
234234
mount_options: MountOptions,
235235
mount_path: impl AsRef<Path>,
236236
) -> io::Result<Self> {
237+
use std::io::ErrorKind;
237238
use std::{thread, time::Duration};
238239

239240
use tokio::time::sleep;
@@ -416,6 +417,8 @@ struct NonBlockFuseConnection {
416417
impl NonBlockFuseConnection {
417418
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
418419
fn new() -> io::Result<Self> {
420+
use std::io::ErrorKind;
421+
419422
#[cfg(target_os = "freebsd")]
420423
const DEV_FUSE: &str = "/dev/fuse";
421424

project/rfuse3/src/raw/session.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::ffi::OsString;
44
use std::fmt::{Debug, Formatter};
55
use std::future::Future;
66
use std::io::Error as IoError;
7-
use std::io::ErrorKind;
87
use std::io::Result as IoResult;
98
use std::num::NonZeroU32;
109
#[allow(unused_imports)]
@@ -151,6 +150,7 @@ impl MountHandleInner {
151150
{
152151
#[cfg(all(target_os = "linux", feature = "unprivileged"))]
153152
if self.unprivileged {
153+
use std::io::ErrorKind;
154154
let binary_path = find_fusermount3()?;
155155
let mut child = Command::new(binary_path)
156156
.args([OsStr::new("-u"), self.mount_path.as_os_str()])
@@ -3009,6 +3009,8 @@ impl<FS: Filesystem + Send + Sync + 'static> Session<FS> {
30093009
#[cfg(any(feature = "async-io-runtime", feature = "tokio-runtime"))]
30103010
impl<FS: Filesystem + Send + Sync + 'static> Session<FS> {
30113011
async fn mount_empty_check(&self, mount_path: &Path) -> IoResult<()> {
3012+
use std::io::ErrorKind;
3013+
30123014
#[cfg(all(not(feature = "async-io-runtime"), feature = "tokio-runtime"))]
30133015
if !self.mount_options.nonempty
30143016
&& matches!(read_dir(mount_path).await?.next_entry().await, Ok(Some(_)))
@@ -3252,6 +3254,7 @@ impl<FS: Filesystem + Send + Sync + 'static> Session<FS> {
32523254
Either::Right((data, extend_data)) => (data, Some(extend_data)),
32533255
};
32543256
if let Err(err) = fuse_connection.write_vectored(data, extend_data).await.1 {
3257+
use std::io::ErrorKind;
32553258
if err.kind() == ErrorKind::NotFound {
32563259
warn!(
32573260
"may reply interrupted fuse request, ignore this error {}",
@@ -3276,6 +3279,8 @@ impl<FS: Filesystem + Send + Sync + 'static> Session<FS> {
32763279
fs: &FS,
32773280
fuse_connection: &FuseConnection,
32783281
) -> IoResult<NonZeroU32> {
3282+
use std::io::ErrorKind;
3283+
32793284
let header_buffer = vec![0; FUSE_IN_HEADER_SIZE];
32803285
let data_buffer = vec![0; FUSE_MIN_READ_BUFFER_SIZE];
32813286

project/rfuse3/tests/minimal_filesystem_test.sh

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ echo "Testing minimal filesystem example..."
1313
# Clean up any existing mount point
1414
if mount | grep -q " on $MOUNTPOINT "; then
1515
echo "Unmounting existing mount point..."
16-
umount "$MOUNTPOINT" || true
16+
# Use platform-specific unmount logic
17+
if command -v fusermount3 >/dev/null 2>&1; then
18+
fusermount3 -u "$MOUNTPOINT" || fusermount -u "$MOUNTPOINT" || umount "$MOUNTPOINT" || true
19+
elif command -v fusermount >/dev/null 2>&1; then
20+
fusermount -u "$MOUNTPOINT" || umount "$MOUNTPOINT" || true
21+
else
22+
umount "$MOUNTPOINT" || true
23+
fi
1724
fi
1825

1926
# Create mount point
@@ -28,8 +35,16 @@ echo "Starting filesystem at $MOUNTPOINT..."
2835
cargo run --example minimal_filesystem_example -- --mountpoint "$MOUNTPOINT" &
2936
FS_PID=$!
3037

31-
# Set up cleanup trap
32-
trap "kill $FS_PID 2>/dev/null || true; umount $MOUNTPOINT 2>/dev/null || true; rmdir $MOUNTPOINT 2>/dev/null || true" EXIT
38+
# Set up cleanup trap with platform-specific unmount logic
39+
trap "kill $FS_PID 2>/dev/null || true; \
40+
if command -v fusermount3 >/dev/null 2>&1; then \
41+
fusermount3 -u $MOUNTPOINT 2>/dev/null || fusermount -u $MOUNTPOINT 2>/dev/null || umount $MOUNTPOINT 2>/dev/null || true; \
42+
elif command -v fusermount >/dev/null 2>&1; then \
43+
fusermount -u $MOUNTPOINT 2>/dev/null || umount $MOUNTPOINT 2>/dev/null || true; \
44+
else \
45+
umount $MOUNTPOINT 2>/dev/null || true; \
46+
fi; \
47+
rmdir $MOUNTPOINT 2>/dev/null || true" EXIT
3348

3449
# Wait for filesystem to be ready
3550
sleep 2

0 commit comments

Comments
 (0)