mirror of
https://github.com/OMGeeky/gdriver2.git
synced 2026-02-15 22:14:31 +01:00
Improve implementation & actually mount it for testing
This commit is contained in:
@@ -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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user