Improve implementation & actually mount it for testing

This commit is contained in:
OMGeeky
2024-02-18 18:33:42 +01:00
parent e498ec3f94
commit 267167e276
11 changed files with 249 additions and 17 deletions

View File

@@ -5,11 +5,13 @@ use std::time::Duration;
use anyhow::anyhow;
use bimap::BiMap;
use fuser::{KernelConfig, ReplyEntry, Request};
use fuser::{KernelConfig, ReplyEntry, ReplyOpen, Request};
use tarpc::context::current as current_context;
use tracing::*;
use gdriver_common::drive_structure::drive_id::{DriveId, ROOT_ID};
use gdriver_common::drive_structure::meta::read_metadata_file;
use gdriver_common::drive_structure::file_handle_flags::HandleFlags;
use gdriver_common::ipc::gdriver_service::{
errors::GDriverServiceError, GDriverServiceClient, GDriverSettings,
};
@@ -18,7 +20,6 @@ use crate::filesystem::attributes::read_inode_attributes_from_meta_file;
use crate::filesystem::errors::FilesystemError;
use crate::prelude::macros::*;
use crate::prelude::*;
use tarpc::context::current as current_context;
mod macros;
@@ -26,24 +27,25 @@ mod macros;
const TTL: Duration = Duration::from_secs(2);
type Inode = u64;
type FileHandle = u64;
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
struct FileIdentifier {
parent: Inode,
name: OsString,
}
pub struct Filesystem {
#[derive(Debug)]
pub struct DriveFilesystem {
gdriver_client: GDriverServiceClient,
entry_ids: BiMap<Inode, DriveId>,
ino_to_file_handles: HashMap<Inode, Vec<u64>>,
ino_to_file_handles: HashMap<Inode, Vec<FileHandle>>,
next_ino: u64,
gdriver_settings: GDriverSettings,
entry_name_parent_to_ino: BiMap<FileIdentifier, Inode>,
}
impl Filesystem {
impl DriveFilesystem {
pub fn new(gdriver_client: GDriverServiceClient) -> Self {
Self {
gdriver_client,
@@ -62,7 +64,7 @@ impl Filesystem {
}
//region DriveFilesystem ino_to_id
impl Filesystem {
impl DriveFilesystem {
fn get_id_from_ino(&self, ino: Inode) -> Option<&DriveId> {
self.entry_ids.get_by_left(&ino)
}
@@ -91,7 +93,7 @@ impl Filesystem {
//endregion
mod attributes;
impl fuser::Filesystem for Filesystem {
impl fuser::Filesystem for DriveFilesystem {
//region init
fn init(&mut self, _req: &Request<'_>, _config: &mut KernelConfig) -> StdResult<(), c_int> {
self.entry_ids.insert(1, ROOT_ID.clone());
@@ -111,6 +113,9 @@ impl fuser::Filesystem for Filesystem {
//endregion
//region lookup
fn lookup(&mut self, _req: &Request<'_>, parent: u64, name: &OsStr, reply: ReplyEntry) {
if name.to_str().unwrap().contains('/') {
todo!("The name in lookup can contain multiple path segments, not just a single name, directly under the parent")
}
let metadata = utils::lookup::lookup(self, parent, name.to_os_string());
match metadata {
Ok(metadata) => {
@@ -133,12 +138,37 @@ impl fuser::Filesystem for Filesystem {
}
}
//endregion
//region open
fn open(&mut self, _req: &Request<'_>, ino: u64, flags: i32, reply: ReplyOpen) {
let data = utils::lookup::open(self, ino, HandleFlags::from(flags));
match data {
Ok((file_header, flags)) => {
reply.opened(file_header, flags.into());
}
Err(e) => {
error!("Got an error during open: {e:?}");
match e {
FilesystemError::Rpc(_) => reply.error(libc::EREMOTEIO),
FilesystemError::NotFound => reply.error(libc::ENOENT),
FilesystemError::IO(_) => reply.error(libc::EIO),
e => {
dbg!(e);
todo!("Handle other errors and decide what error code should be used here")
}
}
}
}
}
//endregion
}
mod errors {
use gdriver_common::ipc::gdriver_service::errors::GDriverServiceError;
use std::error::Error;
use tarpc::client::RpcError;
use gdriver_common::ipc::gdriver_service::errors::GDriverServiceError;
#[derive(Debug, thiserror::Error)]
pub enum FilesystemError {
#[error("Error while executing RPC: {0}")]
@@ -153,17 +183,22 @@ mod errors {
Other(#[source] Box<dyn Error>),
}
}
mod utils {
use super::*;
pub mod lookup {
use super::*;
use crate::filesystem::attributes::InodeAttributes;
use crate::filesystem::errors::FilesystemError;
use futures::TryFutureExt;
use gdriver_common::ipc::gdriver_service::errors::GetFileByPathError;
use crate::filesystem::attributes::InodeAttributes;
use crate::filesystem::errors::FilesystemError;
use super::*;
pub fn lookup(
fs: &mut Filesystem,
fs: &mut DriveFilesystem,
parent: Inode,
name: OsString,
) -> StdResult<InodeAttributes, FilesystemError> {
@@ -216,5 +251,14 @@ mod utils {
.map_err(FilesystemError::IO)?;
Ok(metadata)
}
pub(crate) fn open(
fs: &mut DriveFilesystem,
inode: Inode,
flags: HandleFlags,
) -> StdResult<(FileHandle, HandleFlags), FilesystemError> {
dbg!(&fs, inode, flags);
todo!()
}
}
}

View File

@@ -1,5 +1,10 @@
use fuser::{mount2, MountOption};
use std::path::Path;
use std::{error::Error, net::IpAddr, result::Result as StdResult};
use crate::filesystem::DriveFilesystem;
use crate::service::create_client;
use gdriver_common::ipc::gdriver_service::GDriverServiceClient;
use gdriver_common::{ipc::sample::*, prelude::*};
use tarpc::{client, tokio_serde::formats::Json};
@@ -7,7 +12,14 @@ type Result<T> = StdResult<T, Box<dyn Error>>;
#[tokio::main]
async fn main() -> Result<()> {
service::start().await?;
println!("Hello, world!");
let config = &CONFIGURATION;
println!("Config: {:?}", **config);
let client: GDriverServiceClient = create_client(config.ip, config.port).await?;
let fs = DriveFilesystem::new(client);
mount2(fs, Path::new("/tmp/gdriver"), &[MountOption::RW])?;
// service::start().await?;
Ok(())
}
pub mod prelude;