-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added a NVME FS prototype #192
Merged
Merged
Changes from 6 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
9da517f
Added a nvme fs prototype
CPTforever 4bf27e9
Merge branch 'main' of github.com:CPTforever/twizzler into main
CPTforever 2e108f8
Added fat repo as just code instead of submodule
CPTforever 43d5483
fmted code and added optimizations
CPTforever 139810a
OS Side FS STD integration
CPTforever 8ade52c
Added std fs changes to rust
CPTforever e65912f
Merge branch 'twizzler-operating-system:main' into albert-fs-std
CPTforever 44aa5dd
Fixed bug with build system
CPTforever 38eb2c1
Added error handling, minor design changes
CPTforever 792a887
Merge branch 'twizzler-operating-system:main' into albert-fs-std
CPTforever 927ae89
Added compaction to fd allocator
CPTforever 11bfb4a
Ran cargo fmt
CPTforever f85b9d7
Merge branch 'albert-fs-std' of github.com:CPTforever/twizzler into a…
CPTforever 8cd2702
Formatted and documented the fs runtimme
CPTforever ef6a42a
Merge branch 'albert-fs-std' into main
CPTforever 915f1d0
Booting on QEMU Morello (#197)
PandaZ3D bbedcfa
Merge branch 'main' of github.com:CPTforever/twizzler
CPTforever 798228f
Changed the rust submodule to point to the twizzler branch
CPTforever ee83d9c
Moved back rust submodule to previous commit
CPTforever 32e37f6
Fixed cargo lock because of a typo I made
CPTforever File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[package] | ||
name = "mnemosyne" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
twizzler-abi = { path = "../../lib/twizzler-abi", features = ["runtime"] } | ||
twizzler-net = { path = "../../lib/twizzler-net" } | ||
twizzler-object = { path = "../../lib/twizzler-object" } | ||
twizzler-queue = { path = "../../lib/twizzler-queue" } | ||
twizzler-async = { path = "../../lib/twizzler-async" } | ||
twizzler-driver = { path = "../../lib/twizzler-driver" } | ||
nvme = { path = "../../lib/nvme-rs" } | ||
lethe-gadget-fat = { path = "./fat" } | ||
layout = { path = "./fat/layout" } | ||
tickv = { version = "1.0.0" } | ||
async-trait = "0.1.66" | ||
volatile = "0.5" | ||
pci-ids = "0.2.4" | ||
|
||
[package.metadata] | ||
twizzler-build = "static" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "lethe-gadget-fat" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
layout = { path = "./layout" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "layout" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
array-init = "2.0.1" | ||
layout-derive = { path = "./layout-derive" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "layout-derive" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
proc-macro = true | ||
|
||
[dependencies] | ||
proc-macro2 = "1.0.46" | ||
quote = "1.0.21" | ||
syn = { version = "1.0.102", features = ["full"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
use proc_macro::TokenStream; | ||
use proc_macro2::TokenStream as TokenStream2; | ||
use quote::quote; | ||
use syn::{parse_macro_input, Ident, ItemStruct, Type}; | ||
|
||
enum FieldLayout { | ||
SubLayout, | ||
Primitive, | ||
} | ||
|
||
impl FieldLayout { | ||
fn gen_accessor( | ||
&self, | ||
offset_in_parent: &TokenStream2, | ||
name: &Ident, | ||
ty: &Type, | ||
) -> TokenStream2 { | ||
match self { | ||
FieldLayout::SubLayout => { | ||
let all_name = Ident::new(&format!("all_{name}"), name.span()); | ||
quote! { | ||
pub fn #name (&mut self) -> Result<<#ty as ::layout::ApplyLayout<'_, R>>::Frame, R::Error> { | ||
let offset_in_parent = #offset_in_parent; | ||
<#ty as ::layout::ApplyLayout<'_, R>>::apply_layout(self.stream, self.offset + offset_in_parent) | ||
} | ||
|
||
pub fn #all_name (&mut self) -> Result<#ty, R::Error> { | ||
let offset_in_parent = #offset_in_parent; | ||
self.stream.seek(::layout::io::SeekFrom::Start(self.offset + offset_in_parent))?; | ||
<#ty as ::layout::Decode>::decode(self.stream) | ||
} | ||
} | ||
} | ||
FieldLayout::Primitive => quote! { | ||
pub fn #name (&mut self) -> Result<#ty, R::Error> { | ||
let offset_in_parent = #offset_in_parent; | ||
self.stream.seek(::layout::io::SeekFrom::Start(self.offset + offset_in_parent))?; | ||
<#ty as ::layout::Decode>::decode(self.stream) | ||
} | ||
}, | ||
} | ||
} | ||
|
||
fn gen_setter(&self, offset_in_parent: &TokenStream2, name: &Ident, ty: &Type) -> TokenStream2 { | ||
let setter_name = Ident::new(&format!("set_{name}"), name.span()); | ||
quote! { | ||
pub fn #setter_name (&mut self, data: &#ty) -> Result<(), W::Error> { | ||
let offset_in_parent = #offset_in_parent; | ||
self.stream.seek(::layout::io::SeekFrom::Start(self.offset + offset_in_parent))?; | ||
<#ty as ::layout::Encode>::encode(data, self.stream) | ||
} | ||
} | ||
} | ||
} | ||
|
||
enum Size { | ||
Dynamic, | ||
Fixed, | ||
} | ||
|
||
impl Size { | ||
fn gen_field_size(&self, name: &Ident, ty: &Type) -> [TokenStream2; 3] { | ||
match self { | ||
Size::Dynamic => [ | ||
quote!(::layout::FramedDynamic::framed_size(&mut self.#name()?)?), | ||
quote!(::layout::SourcedDynamic::sourced_size(&#name)), | ||
quote!(::layout::SourcedDynamic::sourced_size(&self.#name)), | ||
], | ||
Size::Fixed => { | ||
let s = quote!(<#ty as ::layout::Fixed>::size()); | ||
[s.clone(), s.clone(), s] | ||
} | ||
} | ||
} | ||
|
||
fn gen_impl_wrapper( | ||
&self, | ||
framed: TokenStream2, | ||
sourced: TokenStream2, | ||
name: &Ident, | ||
frame_name: &Ident, | ||
) -> TokenStream2 { | ||
match self { | ||
Size::Dynamic => quote! { | ||
impl<'a, S> ::layout::FramedDynamic<S> for #frame_name<'a, S> | ||
where | ||
S: ::layout::Read + ::layout::Seek + ::layout::IO | ||
{ | ||
fn framed_size(&mut self) -> Result<u64, S::Error> { | ||
Ok(#framed) | ||
} | ||
|
||
} | ||
|
||
impl ::layout::SourcedDynamic for #name { | ||
fn sourced_size(&self) -> u64 { | ||
#sourced | ||
} | ||
} | ||
}, | ||
Size::Fixed => quote! { | ||
impl ::layout::Fixed for #name { | ||
fn size() -> u64 { | ||
#framed | ||
} | ||
} | ||
}, | ||
} | ||
} | ||
} | ||
|
||
#[proc_macro_attribute] | ||
pub fn layout(_: TokenStream, item: TokenStream) -> TokenStream { | ||
let mut tokens = parse_macro_input!(item as ItemStruct); | ||
|
||
let vis = &tokens.vis; | ||
let source_name = &tokens.ident; | ||
let frame_name = Ident::new(&format!("{}Frame", tokens.ident), tokens.ident.span()); | ||
|
||
let mut accessor_impls = TokenStream2::new(); | ||
let mut setter_impls = TokenStream2::new(); | ||
|
||
let mut encode_impl = TokenStream2::new(); | ||
let mut decode_impl_assigns = TokenStream2::new(); | ||
let mut decode_impl_struct_init = TokenStream2::new(); | ||
|
||
let mut total_framed_offset: TokenStream2 = quote!(0); | ||
let mut total_sourced_offset: TokenStream2 = quote!(0); | ||
let mut total_selfed_offset: TokenStream2 = quote!(0); | ||
|
||
let mut size = Size::Fixed; | ||
|
||
'outer: for field in &mut tokens.fields { | ||
let mut field_layout = FieldLayout::Primitive; | ||
let mut field_size = Size::Fixed; | ||
|
||
for attr in field.attrs.drain(..) { | ||
let p = attr.path; | ||
match quote!(#p).to_string().as_str() { | ||
"sublayout" => field_layout = FieldLayout::SubLayout, | ||
"dynamic" => { | ||
field_size = Size::Dynamic; | ||
size = Size::Dynamic; | ||
field_layout = FieldLayout::SubLayout; | ||
} | ||
"ignore" => continue 'outer, | ||
_ => continue, | ||
} | ||
} | ||
|
||
let field_name = field.ident.as_ref().unwrap(); | ||
let field_ty = &field.ty; | ||
|
||
let accessor = field_layout.gen_accessor(&total_framed_offset, field_name, field_ty); | ||
accessor_impls = quote!(#accessor_impls #accessor); | ||
|
||
let setter = field_layout.gen_setter(&total_framed_offset, field_name, field_ty); | ||
setter_impls = quote!(#setter_impls #setter); | ||
|
||
encode_impl = quote!(#encode_impl self.#field_name.encode(writer)?;); | ||
|
||
decode_impl_assigns = quote!(#decode_impl_assigns let #field_name = <#field_ty>::decode(reader)?;); | ||
decode_impl_struct_init = quote!(#decode_impl_struct_init #field_name,); | ||
|
||
let [framed, sourced, selfed] = field_size.gen_field_size(field_name, field_ty); | ||
total_framed_offset = quote!(#total_framed_offset + #framed); | ||
total_sourced_offset = quote!(#total_sourced_offset + #sourced); | ||
total_selfed_offset = quote!(#total_selfed_offset + #selfed); | ||
} | ||
|
||
let size_impl = size.gen_impl_wrapper( | ||
total_framed_offset, | ||
total_selfed_offset, | ||
source_name, | ||
&frame_name, | ||
); | ||
|
||
// todo: already existent generics | ||
let out = quote! { | ||
#tokens | ||
|
||
impl<'a, R: 'a + ::layout::IO> ::layout::ApplyLayout<'a, R> for #source_name { | ||
type Frame = #frame_name<'a, R>; | ||
|
||
fn apply_layout(stream: &'a mut R, offset: u64) -> Result<Self::Frame, R::Error> { | ||
Ok(#frame_name { | ||
stream, | ||
offset | ||
}) | ||
} | ||
} | ||
|
||
impl ::layout::Encode for #source_name { | ||
fn encode<S: ::layout::Write + ::layout::Seek + ::layout::IO>(&self, writer: &mut S) -> Result<(), S::Error> { | ||
#encode_impl | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl ::layout::Decode for #source_name { | ||
fn decode<S: ::layout::Read + ::layout::Seek + ::layout::IO>(reader: &mut S) -> Result<Self, S::Error> { | ||
#decode_impl_assigns | ||
|
||
Ok(Self { | ||
#decode_impl_struct_init | ||
}) | ||
} | ||
} | ||
|
||
#vis struct #frame_name<'a, R> { | ||
stream: &'a mut R, | ||
offset: u64 | ||
} | ||
|
||
#size_impl | ||
|
||
impl<'a, R> ::layout::Frame<R> for #frame_name<'a, R> { | ||
fn stream(&mut self) -> &mut R { | ||
self.stream | ||
} | ||
|
||
fn offset(&self) -> u64 { | ||
self.offset | ||
} | ||
} | ||
|
||
impl<'a, R: ::layout::Read + ::layout::Seek + ::layout::IO> #frame_name<'a, R> { | ||
#accessor_impls | ||
} | ||
|
||
impl<'a, W: ::layout::Write + ::layout::Read + ::layout::Seek + ::layout::IO> #frame_name<'a, W> { | ||
#setter_impls | ||
} | ||
}; | ||
|
||
// println!("{out}"); | ||
|
||
out.into() | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of extra white space throuhout. Can we tighten this up? Perhaps @dbittman has thoughts on how the code looks as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing we need to do is setup a CI step that ensures that rustfmt is happy. @CPTforever is this code formatted with rustfmt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure I did, I ran cargo fmt in the crate's root but I'll double check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok today I found out it's not recursive, I'll commit the fix soon,