Compare commits

...

No commits in common. "5bd839e0229b174a2ac0810c2473522a3b1de405" and "2e4934e986130839a5a2ce58620679404b3389ea" have entirely different histories.

2 changed files with 40 additions and 20 deletions

View File

@ -1,11 +1,18 @@
use std::{ use std::{
cmp::min, collections::HashMap, ffi::{OsStr, OsString}, iter::repeat, time::{Duration, SystemTime} cmp::min,
collections::HashMap,
ffi::{OsStr, OsString},
iter::repeat,
time::{Duration, SystemTime},
}; };
use fuser::{consts::{FOPEN_DIRECT_IO, FOPEN_KEEP_CACHE, FUSE_WRITEBACK_CACHE}, FileAttr, FileType, Filesystem, TimeOrNow}; use fuser::{
consts::{FOPEN_DIRECT_IO, FOPEN_KEEP_CACHE, FUSE_WRITEBACK_CACHE},
FileAttr, FileType, Filesystem, TimeOrNow,
};
use nix::{ use nix::{
libc::{ libc::{
EBADF, EBUSY, EEXIST, EINVAL, EISDIR, ENOENT, ENOTDIR, EPERM, O_DIRECT, O_RDONLY, SEEK_SET EBADF, EBUSY, EEXIST, EINVAL, EISDIR, ENOENT, ENOTDIR, EPERM, O_DIRECT, O_RDONLY, SEEK_SET,
}, },
unistd::{getgid, getuid}, unistd::{getgid, getuid},
}; };
@ -144,7 +151,11 @@ impl CorruptFs {
} }
impl Filesystem for CorruptFs { impl Filesystem for CorruptFs {
fn init(&mut self, _req: &fuser::Request<'_>, config: &mut fuser::KernelConfig) -> Result<(), nix::libc::c_int> { fn init(
&mut self,
_req: &fuser::Request<'_>,
config: &mut fuser::KernelConfig,
) -> Result<(), nix::libc::c_int> {
if let Err(unsup) = config.add_capabilities(FUSE_WRITEBACK_CACHE) { if let Err(unsup) = config.add_capabilities(FUSE_WRITEBACK_CACHE) {
warn!("Unsupported kernel caps: 0x{:08x}", unsup); warn!("Unsupported kernel caps: 0x{:08x}", unsup);
} }
@ -227,9 +238,13 @@ impl Filesystem for CorruptFs {
if req.uid() != getuid().as_raw() { if req.uid() != getuid().as_raw() {
reply.error(EPERM); reply.error(EPERM);
} else if let Some((file, _)) = fh.and_then(|fh| self.open_file_with_file_mut(fh)) { } else if let Some((file, _)) = fh.and_then(|fh| self.open_file_with_file_mut(fh)) {
do_setattr(file, mode, uid, gid, size, atime, mtime, ctime, crtime, reply); do_setattr(
file, mode, uid, gid, size, atime, mtime, ctime, crtime, reply,
);
} else if let Some(file) = self.files.get_mut(&ino) { } else if let Some(file) = self.files.get_mut(&ino) {
do_setattr(file, mode, uid, gid, size, atime, mtime, ctime, crtime, reply); do_setattr(
file, mode, uid, gid, size, atime, mtime, ctime, crtime, reply,
);
} else { } else {
reply.error(ENOENT); reply.error(ENOENT);
} }
@ -245,12 +260,11 @@ impl Filesystem for CorruptFs {
let open_file = OpenFile { ino, flags }; let open_file = OpenFile { ino, flags };
self.open_fds.insert(fh, OpenFd::File(open_file)); self.open_fds.insert(fh, OpenFd::File(open_file));
let o_flags = let o_flags = if (flags & O_DIRECT) != 0 {
if (flags & O_DIRECT) != 0 { FOPEN_DIRECT_IO
FOPEN_DIRECT_IO } else {
} else { FOPEN_KEEP_CACHE
FOPEN_KEEP_CACHE };
};
reply.opened(fh, o_flags); reply.opened(fh, o_flags);
} else { } else {
reply.error(ENOENT); reply.error(ENOENT);
@ -297,12 +311,11 @@ impl Filesystem for CorruptFs {
}; };
self.open_fds.insert(fh, OpenFd::File(open_file)); self.open_fds.insert(fh, OpenFd::File(open_file));
let cr_flags = let cr_flags = if (flags & O_DIRECT) != 0 {
if (flags & O_DIRECT) != 0 { FOPEN_DIRECT_IO
FOPEN_DIRECT_IO } else {
} else { FOPEN_KEEP_CACHE
FOPEN_KEEP_CACHE };
};
reply.created(&TTL, &attr, 0, fh, cr_flags); reply.created(&TTL, &attr, 0, fh, cr_flags);
} }
} }
@ -644,7 +657,9 @@ fn do_setattr(
crtime: Option<SystemTime>, crtime: Option<SystemTime>,
reply: fuser::ReplyAttr, reply: fuser::ReplyAttr,
) { ) {
if uid.filter(|uid| *uid != getuid().as_raw()).is_some() || gid.filter(|gid| *gid != getgid().as_raw()).is_some() { if uid.filter(|uid| *uid != getuid().as_raw()).is_some()
|| gid.filter(|gid| *gid != getgid().as_raw()).is_some()
{
reply.error(EPERM); reply.error(EPERM);
} else { } else {
if let Some(mode) = mode { if let Some(mode) = mode {

View File

@ -41,5 +41,10 @@ fn main() {
.map(|opt| MountOption::CUSTOM(opt.clone())), .map(|opt| MountOption::CUSTOM(opt.clone())),
); );
fuser::mount2(fs::CorruptFs::new(args.allow_direct_io), args.mount_point, &options).unwrap(); fuser::mount2(
fs::CorruptFs::new(args.allow_direct_io),
args.mount_point,
&options,
)
.unwrap();
} }