Skip to content

Commit 916d9e1

Browse files
committed
rust: fs: add basic support for fs buffer heads
This is just the basics to support read-only file systems. All dead-code annotations will be removed in the next commit in the series. Signed-off-by: Wedson Almeida Filho <[email protected]>
1 parent 1ae1641 commit 916d9e1

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

rust/bindings/bindings_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <kunit/test.h>
10+
#include <linux/buffer_head.h>
1011
#include <linux/errname.h>
1112
#include <linux/fs.h>
1213
#include <linux/fs_context.h>

rust/helpers.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*/
2222

2323
#include <kunit/test-bug.h>
24+
#include <linux/buffer_head.h>
2425
#include <linux/bug.h>
2526
#include <linux/build_bug.h>
2627
#include <linux/cacheflush.h>
@@ -233,6 +234,18 @@ unsigned int rust_helper_MKDEV(unsigned int major, unsigned int minor)
233234
}
234235
EXPORT_SYMBOL_GPL(rust_helper_MKDEV);
235236

237+
void rust_helper_get_bh(struct buffer_head *bh)
238+
{
239+
get_bh(bh);
240+
}
241+
EXPORT_SYMBOL_GPL(rust_helper_get_bh);
242+
243+
void rust_helper_put_bh(struct buffer_head *bh)
244+
{
245+
put_bh(bh);
246+
}
247+
EXPORT_SYMBOL_GPL(rust_helper_put_bh);
248+
236249
/*
237250
* `bindgen` binds the C `size_t` type as the Rust `usize` type, so we can
238251
* use it in contexts where Rust expects a `usize` like slice (array) indices.

rust/kernel/fs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//!
77
//! C headers: [`include/linux/fs.h`](../../include/linux/fs.h)
88
9+
pub mod buffer;
10+
911
/// Maximum size of an inode.
1012
pub const MAX_LFS_FILESIZE: i64 = bindings::MAX_LFS_FILESIZE;
1113

rust/kernel/fs/buffer.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! File system buffers.
4+
//!
5+
//! C headers: [`include/linux/buffer_head.h`](../../../include/linux/buffer_head.h)
6+
7+
use crate::types::{ARef, AlwaysRefCounted, Opaque};
8+
use core::ptr;
9+
10+
/// Wraps the kernel's `struct buffer_head`.
11+
///
12+
/// # Invariants
13+
///
14+
/// Instances of this type are always ref-counted, that is, a call to `get_bh` ensures that the
15+
/// allocation remains valid at least until the matching call to `put_bh`.
16+
#[repr(transparent)]
17+
pub struct Head(Opaque<bindings::buffer_head>);
18+
19+
// SAFETY: The type invariants guarantee that `INode` is always ref-counted.
20+
unsafe impl AlwaysRefCounted for Head {
21+
fn inc_ref(&self) {
22+
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
23+
unsafe { bindings::get_bh(self.0.get()) };
24+
}
25+
26+
unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
27+
// SAFETY: The safety requirements guarantee that the refcount is nonzero.
28+
unsafe { bindings::put_bh(obj.cast().as_ptr()) }
29+
}
30+
}
31+
32+
impl Head {
33+
/// Returns the block data associated with the given buffer head.
34+
pub fn data(&self) -> &[u8] {
35+
let h = self.0.get();
36+
// SAFETY: The existence of a shared reference guarantees that the buffer head is
37+
// available and so we can access its contents.
38+
unsafe { core::slice::from_raw_parts((*h).b_data.cast(), (*h).b_size) }
39+
}
40+
}
41+
42+
/// A view of a buffer.
43+
///
44+
/// It may contain just a contiguous subset of the buffer.
45+
pub struct View {
46+
head: ARef<Head>,
47+
offset: usize,
48+
size: usize,
49+
}
50+
51+
impl View {
52+
#[allow(dead_code)]
53+
pub(crate) fn new(head: ARef<Head>, offset: usize, size: usize) -> Self {
54+
Self { head, size, offset }
55+
}
56+
57+
/// Returns the view of the buffer head.
58+
pub fn data(&self) -> &[u8] {
59+
&self.head.data()[self.offset..][..self.size]
60+
}
61+
}

0 commit comments

Comments
 (0)