Skip to content

Commit 5c94303

Browse files
authored
fix(libfuse): fix flags in ReplyOpen & fix set_creds logic (#250)
1 parent 44799b9 commit 5c94303

File tree

4 files changed

+52
-11
lines changed

4 files changed

+52
-11
lines changed

project/libfuse-fs/examples/overlay.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,17 @@ async fn main() -> Result<(), std::io::Error> {
111111

112112
set_log(&args);
113113

114+
let file = std::fs::OpenOptions::new()
115+
.create(true)
116+
.write(true)
117+
.truncate(true)
118+
.open("/tmp/overlayfs.log")?;
119+
use std::os::unix::io::AsRawFd;
120+
unsafe {
121+
libc::dup2(file.as_raw_fd(), libc::STDOUT_FILENO);
122+
libc::dup2(file.as_raw_fd(), libc::STDERR_FILENO);
123+
}
124+
114125
let mut mount_handle = libfuse_fs::overlayfs::mount_fs(OverlayArgs {
115126
name: Some(args.name),
116127
mountpoint: args.mountpoint,

project/libfuse-fs/examples/overlayfs_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct Args {
2121
#[arg(long)]
2222
lowerdir: Vec<String>,
2323
/// Use privileged mount instead of unprivileged (default false)
24-
#[arg(long, default_value_t = true)]
24+
#[arg(long, default_value_t = false)]
2525
privileged: bool,
2626
/// Options, currently contains uid/gid mapping info
2727
#[arg(long, short)]

project/libfuse-fs/src/overlayfs/async_io.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,18 @@ impl Filesystem for OverlayFs {
366366

367367
self.handles.lock().await.insert(hd, Arc::new(handle_data));
368368

369+
let mut opts = OpenOptions::empty();
370+
match self.config.cache_policy {
371+
CachePolicy::Never => opts |= OpenOptions::DIRECT_IO,
372+
CachePolicy::Always => opts |= OpenOptions::KEEP_CACHE,
373+
_ => {}
374+
}
375+
369376
trace!("OPEN: returning handle: {hd}");
370377

371378
Ok(ReplyOpen {
372379
fh: hd,
373-
flags: flags as u32,
380+
flags: opts.bits(),
374381
})
375382
}
376383

@@ -837,8 +844,8 @@ impl Filesystem for OverlayFs {
837844
let mut opts = OpenOptions::empty();
838845
match self.config.cache_policy {
839846
CachePolicy::Never => opts |= OpenOptions::DIRECT_IO,
840-
CachePolicy::Auto => opts |= OpenOptions::DIRECT_IO,
841847
CachePolicy::Always => opts |= OpenOptions::KEEP_CACHE,
848+
_ => {}
842849
}
843850

844851
Ok(ReplyCreated {

project/libfuse-fs/src/passthrough/async_io.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
491491
uid.unwrap_or(self.cfg.mapping.get_uid(req.uid)),
492492
gid.unwrap_or(self.cfg.mapping.get_gid(req.gid)),
493493
)?;
494+
// Maybe buggy because `open_file` may call `open_by_handle_at`, which requires CAP_DAC_READ_SEARCH.
494495
data.open_file(final_flags, &self.proc_self_fd)?
495496
}
496497
}
@@ -560,14 +561,14 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
560561
self.validate_path_component(name)?;
561562

562563
let data = self.inode_map.get(parent).await?;
564+
let file = data.get_file()?;
563565

564566
let res = {
565567
let _guard = set_creds(
566568
uid.unwrap_or(self.cfg.mapping.get_uid(req.uid)),
567569
gid.unwrap_or(self.cfg.mapping.get_gid(req.gid)),
568570
)?;
569571

570-
let file = data.get_file()?;
571572
// Safe because this doesn't modify any memory and we check the return value.
572573
unsafe { libc::mkdirat(file.as_raw_fd(), name.as_ptr(), mode & !umask) }
573574
};
@@ -617,14 +618,14 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
617618
self.validate_path_component(name)?;
618619

619620
let data = self.inode_map.get(parent).await?;
621+
let file = data.get_file()?;
620622

621623
let res = {
622624
let _guard = set_creds(
623625
uid.unwrap_or(self.cfg.mapping.get_uid(req.uid)),
624626
gid.unwrap_or(self.cfg.mapping.get_gid(req.gid)),
625627
)?;
626628

627-
let file = data.get_file()?;
628629
// Safe because this doesn't modify any memory and we check the return value.
629630
unsafe { libc::symlinkat(link.as_ptr(), file.as_raw_fd(), name.as_ptr()) }
630631
};
@@ -1097,8 +1098,14 @@ impl Filesystem for PassthroughFs {
10971098
buf.truncate(bytes_read); // Adjust the buffer size
10981099
}
10991100
} else {
1100-
error!("read error: {ret}");
1101-
return Err(Errno::from(ret as i32));
1101+
let e = io::Error::last_os_error();
1102+
// if e.raw_os_error() == Some(libc::EINVAL) {
1103+
// // Handle EINVAL for sparse files by returning zeroed data
1104+
// buf.clear();
1105+
// } else {
1106+
error!("read error: {e:?}");
1107+
return Err(Errno::from(e.raw_os_error().unwrap_or(-1)));
1108+
// }
11021109
}
11031110
}
11041111
}
@@ -1145,6 +1152,17 @@ impl Filesystem for PassthroughFs {
11451152
let size = data.len();
11461153

11471154
self.check_fd_flags(&handle_data, raw_fd, flags).await?;
1155+
// // Debug for O_DIRECT alignment issues
1156+
// if (flags & libc::O_DIRECT as u32) != 0 {
1157+
// let block_size = 512;
1158+
// debug!(
1159+
// "Alignment check (block_size={}): offset_ok={}, len_ok={}, addr_ok={}",
1160+
// block_size,
1161+
// offset % block_size as u64 == 0,
1162+
// size % block_size == 0,
1163+
// (data.as_ptr() as usize) % block_size == 0
1164+
// );
1165+
// }
11481166
let ret = unsafe {
11491167
libc::pwrite(
11501168
raw_fd as c_int,
@@ -1156,8 +1174,9 @@ impl Filesystem for PassthroughFs {
11561174
if ret >= 0 {
11571175
ret
11581176
} else {
1159-
error!("write error: {ret}");
1160-
return Err(Errno::from(ret as i32));
1177+
let e = io::Error::last_os_error();
1178+
error!("write error: {e:?}");
1179+
return Err(Errno::from(e.raw_os_error().unwrap_or(-1)));
11611180
}
11621181
}
11631182
};
@@ -1313,7 +1332,9 @@ impl Filesystem for PassthroughFs {
13131332
)
13141333
};
13151334
if res < 0 {
1316-
return Err(io::Error::last_os_error().into());
1335+
let e = io::Error::last_os_error();
1336+
// error!("getxattr error: {e:?}");
1337+
return Err(e.into());
13171338
}
13181339

13191340
if size == 0 {
@@ -1351,7 +1372,9 @@ impl Filesystem for PassthroughFs {
13511372
)
13521373
};
13531374
if res < 0 {
1354-
return Err(io::Error::last_os_error().into());
1375+
let e = io::Error::last_os_error();
1376+
// error!("listxattr error: {e:?}");
1377+
return Err(e.into());
13551378
}
13561379

13571380
if size == 0 {

0 commit comments

Comments
 (0)