Theoretically support sending GetAttr commands to the server

This commit is contained in:
Olivier 'reivilibre' 2022-01-20 18:33:22 +00:00
parent a298b42672
commit 45cbd2d0db
4 changed files with 71 additions and 12 deletions

View File

@ -36,4 +36,4 @@ fuser = "0.10.0"
libc = "0.2.112" libc = "0.2.112"
# Common # Common
olivefs_common = { path = "../olivefs_common" } olivefs_common = { path = "../olivefs_common", features = ["fuser"] }

View File

@ -4,10 +4,13 @@ use fuser::{
ReplyStatfs, ReplyWrite, ReplyXattr, Request, TimeOrNow, ReplyStatfs, ReplyWrite, ReplyXattr, Request, TimeOrNow,
}; };
use libc::{ENOSYS, EPERM}; use libc::{ENOSYS, EPERM};
use log::{debug, warn}; use log::{debug, error, warn};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::future::Future;
use crate::Requester; use crate::Requester;
use anyhow::Context;
use olivefs_common::messages::{DataResponse, VnodeId};
use std::os::raw::c_int; use std::os::raw::c_int;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
@ -31,7 +34,7 @@ impl Filesystem for OliveFilesystem {
/// Initialize filesystem. /// Initialize filesystem.
/// Called before any other filesystem method. /// Called before any other filesystem method.
/// The kernel module connection can be configured using the KernelConfig object /// 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. // TODO config has some interesting values.
Ok(()) Ok(())
} }
@ -92,8 +95,30 @@ impl Filesystem for OliveFilesystem {
/// Get file attributes. /// Get file attributes.
fn getattr(&mut self, _req: &Request<'_>, ino: u64, reply: ReplyAttr) { fn getattr(&mut self, _req: &Request<'_>, ino: u64, reply: ReplyAttr) {
warn!("[Not Implemented] getattr(ino: {:#x?})", ino); let requester = self.requester.clone();
reply.error(ENOSYS);
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. /// Set file attributes.
@ -729,3 +754,16 @@ impl Filesystem for OliveFilesystem {
reply.error(ENOSYS); 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);
}
});
}
}

View File

@ -12,7 +12,7 @@ use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use olivefs_common::io::read_file; 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::{ use olivefs_common::networking::{
hello_handshake, read_bare_message, send_bare_message, ALPN_PROTOCOL, hello_handshake, read_bare_message, send_bare_message, ALPN_PROTOCOL,
}; };
@ -122,7 +122,7 @@ impl RequesterInternal {
} }
pub async fn command<R: DeserializeOwned>( pub async fn command<R: DeserializeOwned>(
&mut self, &self,
command: &DataCommand, command: &DataCommand,
) -> anyhow::Result<DataResponse<R>> { ) -> anyhow::Result<DataResponse<R>> {
self.with_stream(|mut tx, mut rx| async { self.with_stream(|mut tx, mut rx| async {
@ -141,7 +141,7 @@ impl Requester {
Requester { internal } Requester { internal }
} }
pub async fn getattr(&mut self, _vnode: VnodeId) -> anyhow::Result<DataResponse<()>> { pub async fn getattr(&self, vnode: VnodeId) -> anyhow::Result<DataResponse<FileMetadata>> {
todo!() self.internal.command(&DataCommand::GetAttr { vnode }).await
} }
} }

View File

@ -1,6 +1,5 @@
use crate::messages::FileKind; use crate::messages::{FileKind, FileMetadata};
use fuser::FileType; use fuser::{FileAttr, FileType};
use std::fs::FileType;
impl From<FileType> for FileKind { impl From<FileType> for FileKind {
fn from(filetype: FileType) -> Self { 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,
}
}
}