Merge pull request #27 from trussed-dev/fs-info

Add filesystem info extension and backend implementation
This commit is contained in:
sosthene-nitrokey
2024-08-01 14:56:52 +02:00
committed by GitHub
6 changed files with 170 additions and 1 deletions
+4 -1
View File
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: CC0-1.0
[workspace]
members = ["extensions/chunked", "extensions/hkdf", "extensions/manage", "extensions/wrap-key-to-file"]
members = ["extensions/chunked", "extensions/fs-info", "extensions/hkdf", "extensions/manage", "extensions/wrap-key-to-file"]
[workspace.package]
authors = ["Nitrokey GmbH <info@nitrokey.com>"]
@@ -40,6 +40,7 @@ trussed-chunked = { version = "0.1.0", optional = true }
trussed-hkdf = { version = "0.2.0", optional = true }
trussed-manage = { version = "0.1.0", optional = true }
trussed-wrap-key-to-file = { version = "0.1.0", optional = true }
trussed-fs-info = { version = "0.1.0", optional = true }
[dev-dependencies]
hex-literal = "0.3.4"
@@ -53,6 +54,7 @@ chunked = ["trussed-chunked", "chacha20poly1305/stream"]
hkdf = ["trussed-hkdf", "dep:hkdf", "dep:sha2"]
manage = ["trussed-manage"]
wrap-key-to-file = ["chacha20poly1305", "trussed-wrap-key-to-file"]
fs-info = ["trussed-fs-info"]
virt = ["std", "trussed/virt"]
std = []
@@ -73,3 +75,4 @@ trussed-chunked = { path = "extensions/chunked" }
trussed-hkdf = { path = "extensions/hkdf" }
trussed-manage = { path = "extensions/manage" }
trussed-wrap-key-to-file = { path = "extensions/wrap-key-to-file" }
trussed-fs-info= { path = "extensions/fs-info" }
+15
View File
@@ -0,0 +1,15 @@
# Copyright (C) Nitrokey GmbH
# SPDX-License-Identifier: CC0-1.0
[package]
name = "trussed-fs-info"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
repository.workspace = true
license.workspace = true
[dependencies]
serde.workspace = true
serde-byte-array.workspace = true
trussed.workspace = true
+89
View File
@@ -0,0 +1,89 @@
// Copyright (C) Nitrokey GmbH
// SPDX-License-Identifier: CC0-1.0
#![no_std]
#![warn(non_ascii_idents, trivial_casts, unused, unused_qualifications)]
#![deny(unsafe_code)]
use serde::{Deserialize, Serialize};
use trussed::{
serde_extensions::{Extension, ExtensionClient, ExtensionResult},
types::Location,
Error,
};
pub struct FsInfoExtension;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub enum FsInfoExtensionRequest {
FsInfo(FsInfoRequest),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct FsInfoRequest {
pub location: Location,
}
impl From<FsInfoRequest> for FsInfoExtensionRequest {
fn from(value: FsInfoRequest) -> Self {
Self::FsInfo(value)
}
}
impl TryFrom<FsInfoExtensionRequest> for FsInfoRequest {
type Error = Error;
fn try_from(value: FsInfoExtensionRequest) -> Result<Self, Self::Error> {
match value {
FsInfoExtensionRequest::FsInfo(v) => Ok(v),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub enum FsInfoExtensionReply {
FsInfo(FsInfoReply),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct FsInfoReply {
pub block_info: Option<BlockInfo>,
pub available_space: usize,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct BlockInfo {
pub size: usize,
pub total: usize,
pub available: usize,
}
impl From<FsInfoReply> for FsInfoExtensionReply {
fn from(value: FsInfoReply) -> Self {
Self::FsInfo(value)
}
}
impl TryFrom<FsInfoExtensionReply> for FsInfoReply {
type Error = Error;
fn try_from(value: FsInfoExtensionReply) -> Result<Self, Self::Error> {
match value {
FsInfoExtensionReply::FsInfo(v) => Ok(v),
}
}
}
impl Extension for FsInfoExtension {
type Request = FsInfoExtensionRequest;
type Reply = FsInfoExtensionReply;
}
pub type FsInfoResult<'a, R, C> = ExtensionResult<'a, FsInfoExtension, R, C>;
pub trait FsInfoClient: ExtensionClient<FsInfoExtension> {
fn fs_info(&mut self, location: Location) -> FsInfoResult<'_, FsInfoReply, Self> {
self.extension(FsInfoRequest { location })
}
}
impl<C: ExtensionClient<FsInfoExtension>> FsInfoClient for C {}
+37
View File
@@ -0,0 +1,37 @@
// Copyright (C) Nitrokey GmbH
// SPDX-License-Identifier: CC0-1.0
use trussed::{
platform::Store, serde_extensions::ExtensionImpl, service::ServiceResources,
types::CoreContext, Error, Platform,
};
use trussed_fs_info::{
BlockInfo, FsInfoExtension, FsInfoExtensionReply, FsInfoExtensionRequest, FsInfoReply,
};
impl ExtensionImpl<FsInfoExtension> for super::StagingBackend {
fn extension_request<P: Platform>(
&mut self,
_core_ctx: &mut CoreContext,
_backend_ctx: &mut Self::Context,
request: &FsInfoExtensionRequest,
resources: &mut ServiceResources<P>,
) -> Result<FsInfoExtensionReply, Error> {
match request {
FsInfoExtensionRequest::FsInfo(req) => {
let platform = resources.platform();
let store = platform.store();
let fs = store.fs(req.location);
Ok(FsInfoReply {
block_info: Some(BlockInfo {
total: fs.total_blocks(),
available: fs.available_blocks().map_err(|_| Error::InternalError)?,
size: fs.total_space() / fs.total_blocks(),
}),
available_space: fs.available_space().map_err(|_| Error::InternalError)?,
}
.into())
}
}
}
}
+3
View File
@@ -15,6 +15,9 @@ pub mod virt;
#[cfg(feature = "wrap-key-to-file")]
mod wrap_key_to_file;
#[cfg(feature = "fs-info")]
mod fs_info;
#[cfg(feature = "chunked")]
mod chunked;
+22
View File
@@ -8,6 +8,8 @@ use trussed::types::{Location, Path};
#[cfg(feature = "chunked")]
use trussed_chunked::ChunkedExtension;
#[cfg(feature = "fs-info")]
use trussed_fs_info::FsInfoExtension;
#[cfg(feature = "hkdf")]
use trussed_hkdf::HkdfExtension;
#[cfg(feature = "manage")]
@@ -37,6 +39,8 @@ pub enum ExtensionIds {
Manage,
#[cfg(feature = "wrap-key-to-file")]
WrapKeyToFile,
#[cfg(feature = "fs-info")]
FsInfo,
}
#[cfg(feature = "chunked")]
@@ -63,6 +67,12 @@ impl ExtensionId<WrapKeyToFileExtension> for Dispatcher {
const ID: ExtensionIds = ExtensionIds::WrapKeyToFile;
}
#[cfg(feature = "fs-info")]
impl ExtensionId<FsInfoExtension> for Dispatcher {
type Id = ExtensionIds;
const ID: ExtensionIds = ExtensionIds::FsInfo;
}
impl From<ExtensionIds> for u8 {
fn from(value: ExtensionIds) -> Self {
match value {
@@ -74,6 +84,8 @@ impl From<ExtensionIds> for u8 {
ExtensionIds::Manage => 2,
#[cfg(feature = "wrap-key-to-file")]
ExtensionIds::WrapKeyToFile => 3,
#[cfg(feature = "fs-info")]
ExtensionIds::FsInfo => 4,
}
}
}
@@ -90,6 +102,8 @@ impl TryFrom<u8> for ExtensionIds {
2 => Ok(Self::Manage),
#[cfg(feature = "wrap-key-to-file")]
3 => Ok(Self::WrapKeyToFile),
#[cfg(feature = "fs-info")]
4 => Ok(Self::FsInfo),
_ => Err(Error::FunctionNotSupported),
}
}
@@ -164,6 +178,14 @@ impl ExtensionDispatch for Dispatcher {
request,
resources,
),
#[cfg(feature = "fs-info")]
ExtensionIds::FsInfo => ExtensionImpl::<FsInfoExtension>::extension_request_serialized(
&mut self.backend,
&mut ctx.core,
&mut ctx.backends,
request,
resources,
),
}
}
}