Skip to content

vfs abstractions and tarfs #1037

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

Draft
wants to merge 29 commits into
base: rust-next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a3fe8d8
xattr: make the xattr array itself const
wedsonaf Sep 29, 2023
484ec70
rust: introduce `InPlaceModule`
wedsonaf Sep 29, 2023
da1a2b6
samples: rust: add in-place initialisation sample
wedsonaf Sep 29, 2023
883e433
rust: add the `container_of` macro
wedsonaf Sep 29, 2023
14513c0
rust: init: introduce `Opaque::try_ffi_init`
wedsonaf Sep 29, 2023
c7d0fb2
rust: time: introduce `time` module
wedsonaf Sep 29, 2023
ca4a93c
rust: types: add little-endian type
wedsonaf Sep 29, 2023
a44bdcc
rust: types: introduce `FromBytes` trait
wedsonaf Sep 29, 2023
caf9b29
rust: mem_cache: introduce `MemCache`
wedsonaf Sep 29, 2023
b0bc357
kbuild: rust: allow modules to allocate memory
wedsonaf Sep 29, 2023
528babd
rust: fs: add registration/unregistration of file systems
wedsonaf Sep 29, 2023
e909f43
rust: fs: introduce the `module_fs` macro
wedsonaf Sep 29, 2023
ad07f4b
samples: rust: add initial ro file system sample
wedsonaf Sep 29, 2023
626056a
rust: fs: introduce `FileSystem::super_params`
wedsonaf Sep 29, 2023
a448dc5
rust: fs: introduce `INode<T>`
wedsonaf Sep 29, 2023
b26f77a
rust: fs: introduce `FileSystem::init_root`
wedsonaf Sep 29, 2023
ac0f637
rust: fs: introduce `FileSystem::read_dir`
wedsonaf Sep 29, 2023
14b32d0
rust: fs: introduce `FileSystem::lookup`
wedsonaf Sep 29, 2023
5e601b9
rust: folio: introduce basic support for folios
wedsonaf Sep 29, 2023
c02d2b9
rust: fs: introduce `FileSystem::read_folio`
wedsonaf Sep 29, 2023
ce0acb6
rust: fs: introduce `FileSystem::read_xattr`
wedsonaf Sep 29, 2023
3f94966
rust: fs: introduce `FileSystem::statfs`
wedsonaf Sep 29, 2023
6032d93
rust: fs: introduce more inode types
wedsonaf Sep 29, 2023
1cf6e5e
rust: fs: add per-superblock data
wedsonaf Sep 29, 2023
516d0e4
rust: fs: add basic support for fs buffer heads
wedsonaf Sep 29, 2023
0605dba
rust: fs: allow file systems backed by a block device
wedsonaf Sep 29, 2023
b40e37b
rust: fs: allow per-inode data
wedsonaf Sep 29, 2023
80fda66
rust: fs: export file type from mode constants
wedsonaf Sep 29, 2023
7189177
tarfs: introduce tar fs
wedsonaf Sep 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rust: fs: introduce FileSystem::lookup
Allow Rust file systems to create inodes that are children of a
directory inode when they're looked up by name.

Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
  • Loading branch information
wedsonaf committed Oct 18, 2023
commit 14b32d0d0a804538bacb570cf1abfb720c56959c
1 change: 0 additions & 1 deletion rust/kernel/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ impl Error {
}

/// Returns the error encoded as a pointer.
#[allow(dead_code)]
pub(crate) fn to_ptr<T>(self) -> *mut T {
// SAFETY: self.0 is a valid error due to its invariant.
unsafe { bindings::ERR_PTR(self.0.into()) as *mut _ }
Expand Down
65 changes: 63 additions & 2 deletions rust/kernel/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ pub trait FileSystem {
///
/// [`DirEmitter::pos`] holds the current position of the directory reader.
fn read_dir(inode: &INode<Self>, emitter: &mut DirEmitter) -> Result;

/// Returns the inode corresponding to the directory entry with the given name.
fn lookup(parent: &INode<Self>, name: &[u8]) -> Result<ARef<INode<Self>>>;
}

/// The types of directory entries reported by [`FileSystem::read_dir`].
Expand Down Expand Up @@ -226,8 +229,7 @@ impl<T: FileSystem + ?Sized> NewINode<T> {
let mode = match params.typ {
INodeType::Dir => {
inode.__bindgen_anon_3.i_fop = &Tables::<T>::DIR_FILE_OPERATIONS;
// SAFETY: `simple_dir_inode_operations` never changes, it's safe to reference it.
inode.i_op = unsafe { &bindings::simple_dir_inode_operations };
inode.i_op = &Tables::<T>::DIR_INODE_OPERATIONS;
bindings::S_IFDIR
}
};
Expand Down Expand Up @@ -530,6 +532,62 @@ impl<T: FileSystem + ?Sized> Tables<T> {
}
})
}

const DIR_INODE_OPERATIONS: bindings::inode_operations = bindings::inode_operations {
lookup: Some(Self::lookup_callback),
get_link: None,
permission: None,
get_inode_acl: None,
readlink: None,
create: None,
link: None,
unlink: None,
symlink: None,
mkdir: None,
rmdir: None,
mknod: None,
rename: None,
setattr: None,
getattr: None,
listxattr: None,
fiemap: None,
update_time: None,
atomic_open: None,
tmpfile: None,
get_acl: None,
set_acl: None,
fileattr_set: None,
fileattr_get: None,
get_offset_ctx: None,
};

extern "C" fn lookup_callback(
parent_ptr: *mut bindings::inode,
dentry: *mut bindings::dentry,
_flags: u32,
) -> *mut bindings::dentry {
// SAFETY: The C API guarantees that `parent_ptr` is a valid inode.
let parent = unsafe { &*parent_ptr.cast::<INode<T>>() };

// SAFETY: The C API guarantees that `dentry` is valid for read. Since the name is
// immutable, it's ok to read its length directly.
let len = unsafe { (*dentry).d_name.__bindgen_anon_1.__bindgen_anon_1.len };
let Ok(name_len) = usize::try_from(len) else {
return ENOENT.to_ptr();
};

// SAFETY: The C API guarantees that `dentry` is valid for read. Since the name is
// immutable, it's ok to read it directly.
let name = unsafe { core::slice::from_raw_parts((*dentry).d_name.name, name_len) };
match T::lookup(parent, name) {
Err(e) => e.to_ptr(),
// SAFETY: The returned inode is valid and referenced (by the type invariants), so
// it is ok to transfer this increment to `d_splice_alias`.
Ok(inode) => unsafe {
bindings::d_splice_alias(ManuallyDrop::new(inode).0.get(), dentry)
},
}
}
}

/// Directory entry emitter.
Expand Down Expand Up @@ -637,6 +695,9 @@ impl<T: FileSystem + ?Sized + Sync + Send> crate::InPlaceModule for Module<T> {
/// fn read_dir(_: &INode<Self>, _: &mut DirEmitter) -> Result {
/// todo!()
/// }
/// fn lookup(_: &INode<Self>, _: &[u8]) -> Result<ARef<INode<Self>>> {
/// todo!()
/// }
/// }
/// # }
/// ```
Expand Down
25 changes: 25 additions & 0 deletions samples/rust/rust_rofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,29 @@ impl fs::FileSystem for RoFs {

Ok(())
}

fn lookup(parent: &INode<Self>, name: &[u8]) -> Result<ARef<INode<Self>>> {
if parent.ino() != 1 {
return Err(ENOENT);
}

match name {
b"subdir" => match parent.super_block().get_or_create_inode(2)? {
Either::Left(existing) => Ok(existing),
Either::Right(new) => new.init(INodeParams {
typ: INodeType::Dir,
mode: 0o555,
size: 0,
blocks: 1,
nlink: 2,
uid: 0,
gid: 0,
atime: UNIX_EPOCH,
ctime: UNIX_EPOCH,
mtime: UNIX_EPOCH,
}),
},
_ => Err(ENOENT),
}
}
}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy