Theoretically support sending GetAttr commands to the server
This commit is contained in:
parent
a298b42672
commit
45cbd2d0db
@ -36,4 +36,4 @@ fuser = "0.10.0"
|
||||
libc = "0.2.112"
|
||||
|
||||
# Common
|
||||
olivefs_common = { path = "../olivefs_common" }
|
||||
olivefs_common = { path = "../olivefs_common", features = ["fuser"] }
|
||||
|
@ -4,10 +4,13 @@ use fuser::{
|
||||
ReplyStatfs, ReplyWrite, ReplyXattr, Request, TimeOrNow,
|
||||
};
|
||||
use libc::{ENOSYS, EPERM};
|
||||
use log::{debug, warn};
|
||||
use log::{debug, error, warn};
|
||||
use std::ffi::OsStr;
|
||||
use std::future::Future;
|
||||
|
||||
use crate::Requester;
|
||||
use anyhow::Context;
|
||||
use olivefs_common::messages::{DataResponse, VnodeId};
|
||||
use std::os::raw::c_int;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
@ -31,7 +34,7 @@ impl Filesystem for OliveFilesystem {
|
||||
/// Initialize filesystem.
|
||||
/// Called before any other filesystem method.
|
||||
/// The kernel module connection can be configured using the KernelConfig object
|
||||
fn init(&mut self, req: &Request<'_>, _config: &mut KernelConfig) -> Result<(), c_int> {
|
||||
fn init(&mut self, _req: &Request<'_>, _config: &mut KernelConfig) -> Result<(), c_int> {
|
||||
// TODO config has some interesting values.
|
||||
Ok(())
|
||||
}
|
||||
@ -92,8 +95,30 @@ impl Filesystem for OliveFilesystem {
|
||||
|
||||
/// Get file attributes.
|
||||
fn getattr(&mut self, _req: &Request<'_>, ino: u64, reply: ReplyAttr) {
|
||||
warn!("[Not Implemented] getattr(ino: {:#x?})", ino);
|
||||
reply.error(ENOSYS);
|
||||
let requester = self.requester.clone();
|
||||
|
||||
self.spawn_with_error_handler(
|
||||
async move {
|
||||
let vnode = VnodeId(
|
||||
ino.try_into()
|
||||
.context("Converting u64 inode to u32 VnodeId.")?,
|
||||
);
|
||||
|
||||
match requester.getattr(vnode).await? {
|
||||
DataResponse::Success(file_metadata) => {
|
||||
let file_attr = file_metadata.into();
|
||||
reply.attr(&Duration::from_secs(5), &file_attr);
|
||||
}
|
||||
DataResponse::Error { code, message } => {
|
||||
warn!("getattr(ino: {:#x?}) failed: {:?}", ino, message);
|
||||
reply.error(code as c_int);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
"getattr",
|
||||
);
|
||||
}
|
||||
|
||||
/// Set file attributes.
|
||||
@ -729,3 +754,16 @@ impl Filesystem for OliveFilesystem {
|
||||
reply.error(ENOSYS);
|
||||
}
|
||||
}
|
||||
|
||||
impl OliveFilesystem {
|
||||
pub fn spawn_with_error_handler<Fut>(&self, future: Fut, name: &'static str)
|
||||
where
|
||||
Fut: Future<Output = anyhow::Result<()>> + Send + 'static,
|
||||
{
|
||||
self.tokio_runtime.spawn(async move {
|
||||
if let Err(error) = future.await {
|
||||
error!("Error in {}: {:?}", name, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use olivefs_common::io::read_file;
|
||||
use olivefs_common::messages::{DataCommand, DataResponse, VnodeId};
|
||||
use olivefs_common::messages::{DataCommand, DataResponse, FileMetadata, VnodeId};
|
||||
use olivefs_common::networking::{
|
||||
hello_handshake, read_bare_message, send_bare_message, ALPN_PROTOCOL,
|
||||
};
|
||||
@ -122,7 +122,7 @@ impl RequesterInternal {
|
||||
}
|
||||
|
||||
pub async fn command<R: DeserializeOwned>(
|
||||
&mut self,
|
||||
&self,
|
||||
command: &DataCommand,
|
||||
) -> anyhow::Result<DataResponse<R>> {
|
||||
self.with_stream(|mut tx, mut rx| async {
|
||||
@ -141,7 +141,7 @@ impl Requester {
|
||||
Requester { internal }
|
||||
}
|
||||
|
||||
pub async fn getattr(&mut self, _vnode: VnodeId) -> anyhow::Result<DataResponse<()>> {
|
||||
todo!()
|
||||
pub async fn getattr(&self, vnode: VnodeId) -> anyhow::Result<DataResponse<FileMetadata>> {
|
||||
self.internal.command(&DataCommand::GetAttr { vnode }).await
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::messages::FileKind;
|
||||
use fuser::FileType;
|
||||
use std::fs::FileType;
|
||||
use crate::messages::{FileKind, FileMetadata};
|
||||
use fuser::{FileAttr, FileType};
|
||||
|
||||
impl From<FileType> for FileKind {
|
||||
fn from(filetype: FileType) -> Self {
|
||||
@ -29,3 +28,25 @@ impl Into<FileType> for FileKind {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<FileAttr> for FileMetadata {
|
||||
fn into(self) -> FileAttr {
|
||||
FileAttr {
|
||||
ino: self.ino.0 as u64,
|
||||
size: self.size,
|
||||
blocks: self.blocks,
|
||||
atime: self.atime,
|
||||
mtime: self.mtime,
|
||||
ctime: self.ctime,
|
||||
crtime: self.ctime,
|
||||
kind: self.kind.into(),
|
||||
perm: self.perm,
|
||||
nlink: self.nlink,
|
||||
uid: self.uid,
|
||||
gid: self.gid,
|
||||
rdev: self.rdev,
|
||||
blksize: self.blksize,
|
||||
flags: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user