Skip to content

Commit

Permalink
Merge pull request #1048 from imageworks/fix-fuse-io-error
Browse files Browse the repository at this point in the history
Fix spfs-fuse task panicking on mask entry
  • Loading branch information
jrray authored Jun 16, 2024
2 parents f6c1c8f + 5bde6da commit 10c3112
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/spfs-vfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ libc = "0.2"
miette = { workspace = true, features = ["fancy"] }
prost = { workspace = true, optional = true }
spfs = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.20", features = ["rt", "rt-multi-thread"] }
tracing = { workspace = true }
tonic = { workspace = true, optional = true }
Expand Down
13 changes: 13 additions & 0 deletions crates/spfs-vfs/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Sony Pictures Imageworks, et al.
// SPDX-License-Identifier: Apache-2.0
// https://github.com/imageworks/spk

use thiserror::Error;

/// Errors specific to fuse operations.
#[derive(Debug, Error)]
pub enum Error {
/// An operation was attempted on a mask entry.
#[error("Entry is a mask")]
EntryIsMask,
}
26 changes: 19 additions & 7 deletions crates/spfs-vfs/src/fuse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ use spfs::tracking::{Entry, EntryKind, EnvSpec, Manifest};
use spfs::OsError;
use tokio::io::AsyncReadExt;

use crate::Error;

type Result<T> = std::result::Result<T, Error>;

/// Options to configure the FUSE filesystem and
/// its behavior at runtime
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -157,12 +161,12 @@ impl Filesystem {
}
}

fn attr_from_entry(&self, entry: &Entry<u64>) -> FileAttr {
fn attr_from_entry(&self, entry: &Entry<u64>) -> Result<FileAttr> {
let kind = match entry.kind {
EntryKind::Blob(_) if entry.is_symlink() => FileType::Symlink,
EntryKind::Blob(_) => FileType::RegularFile,
EntryKind::Tree => FileType::Directory,
EntryKind::Mask => unreachable!(),
EntryKind::Mask => return Err(Error::EntryIsMask),
};
let size = if entry.is_dir() {
entry.entries.len() as u64
Expand All @@ -179,7 +183,7 @@ impl Filesystem {
1
};

FileAttr {
Ok(FileAttr {
ino: entry.user_data,
size,
perm: entry.mode as u16, // truncate the non-perm bits
Expand All @@ -197,7 +201,7 @@ impl Filesystem {
rdev: 0,
blksize: Self::BLOCK_SIZE,
flags: 0,
}
})
}
}

Expand Down Expand Up @@ -281,7 +285,10 @@ impl Filesystem {
return;
};

let attr = self.attr_from_entry(entry);
let Ok(attr) = self.attr_from_entry(entry) else {
reply.error(libc::ENOENT);
return;
};
reply.entry(&self.ttl, &attr, 0);
}

Expand All @@ -296,7 +303,10 @@ impl Filesystem {
return;
};

let attr = self.attr_from_entry(inode.value());
let Ok(attr) = self.attr_from_entry(inode.value()) else {
reply.error(libc::ENOENT);
return;
};
reply.attr(&self.ttl, &attr);
}

Expand Down Expand Up @@ -595,7 +605,9 @@ impl Filesystem {
for (name, entry) in remaining {
let ino = entry.user_data;
let next_offset = ino as i64;
let attr = self.attr_from_entry(entry);
let Ok(attr) = self.attr_from_entry(entry) else {
continue;
};
tracing::trace!("readdirplus add {name}");
let buffer_full = reply.add(ino, next_offset, name, &self.ttl, &attr, 0);
if buffer_full {
Expand Down
3 changes: 3 additions & 0 deletions crates/spfs-vfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

#![deny(missing_docs)]

mod error;
pub use error::Error;

#[cfg(all(unix, feature = "fuse-backend"))]
mod fuse;
#[cfg(all(windows, feature = "winfsp-backend"))]
Expand Down

0 comments on commit 10c3112

Please sign in to comment.