mbox series

[RFC,0/3] bcachefs: add framework for internal Rust code

Message ID 20240207055558.611606-1-tahbertschinger@gmail.com (mailing list archive)
Headers show
Series bcachefs: add framework for internal Rust code | expand

Message

Thomas Bertschinger Feb. 7, 2024, 5:55 a.m. UTC
This series adds support for Rust code into bcachefs. This only enables
using Rust internally within bcachefs; there are no public Rust APIs
added. Rust support is hidden behind a new config option,
CONFIG_BCACHEFS_RUST. It is optional and bcachefs can still be built
with full functionality without rust.

I wasn't sure if this needed to be an RFC based on the current status
of accepting Rust code outside of the rust/ tree, so I designated it as
such to be safe. However, Kent plans to merge rust+bcachefs code in the
6.9 merge window, so I hope at least the first 2 patches in this series,
the ones that actually enable Rust for bcachefs, can be accepted.

#1 is a prerequisite in KBuild. In order to call bindgen commands in the
fs/bcachefs tree, the bindgen commands need to be defined in the
top-level scripts/Makefile.build along with the rustc commands, instead
of in rust/Makefile. This is the only patch outside of fs/bcachefs/ in
this series.

#2 creates the framework to use rust-bindgen in fs/bcachefs and
introduces the new config option to enable this. This patch does not
actually generate any Rust bindings; it just lays the foundation for
future patches to create bindings.

#3 demonstrates the new Rust functionality by implementing the module
entry and exit functions for bcachefs in Rust. The current C entry
and exit are retained so that bcachefs can still be built without Rust.
Given Kent's goal to use Rust more in bcachefs, the C functions will
presumably be dropped in the future.


Thomas Bertschinger (3):
  kbuild: rust: move bindgen commands to top-level
  bcachefs: create framework for Rust bindings
  bcachefs: introduce Rust module implementation

 fs/bcachefs/.gitignore                 |  3 ++
 fs/bcachefs/Kconfig                    |  6 +++
 fs/bcachefs/Makefile                   | 12 +++++
 fs/bcachefs/bcachefs.h                 |  5 ++
 fs/bcachefs/bcachefs_module.rs         | 66 ++++++++++++++++++++++++
 fs/bcachefs/bindgen_parameters         | 16 ++++++
 fs/bcachefs/bindings/bindings_helper.h |  7 +++
 fs/bcachefs/bindings/mod.rs            |  5 ++
 fs/bcachefs/super.c                    | 31 +++++++++--
 rust/Makefile                          | 67 ------------------------
 scripts/Makefile.build                 | 71 ++++++++++++++++++++++++++
 11 files changed, 219 insertions(+), 70 deletions(-)
 create mode 100644 fs/bcachefs/.gitignore
 create mode 100644 fs/bcachefs/bcachefs_module.rs
 create mode 100644 fs/bcachefs/bindgen_parameters
 create mode 100644 fs/bcachefs/bindings/bindings_helper.h
 create mode 100644 fs/bcachefs/bindings/mod.rs

Comments

Miguel Ojeda Feb. 7, 2024, 11:06 a.m. UTC | #1
On Wed, Feb 7, 2024 at 6:57 AM Thomas Bertschinger
<tahbertschinger@gmail.com> wrote:
>
> This series adds support for Rust code into bcachefs. This only enables
> using Rust internally within bcachefs; there are no public Rust APIs
> added. Rust support is hidden behind a new config option,
> CONFIG_BCACHEFS_RUST. It is optional and bcachefs can still be built
> with full functionality without rust.

But is it the goal to make it use Rust always? If not, do you mean you
are you going to have 2 "modes" in bcachefs? i.e. one with all C, and
one with some parts replaced (i.e. duplicated) in Rust?

If it is the former (dropping C), then please note that it will limit
where bcachefs can be built for, i.e. architectures and configurations
(at least for the time being, i.e. we want to relax all that, but it
will take time).

If it is the latter (duplication), then please note that the kernel
has only gone the "duplication" route for "Rust reference drivers" as
an exceptional case that we requested to bootstrap their subsystems
and give Rust a try.

Could you please explain more about what is the intention here?

Either way, the approach you are taking in this patch series seems to
be about calling C code directly, rather than writing and using
abstractions in general. For instance, in one of the patches you
mention in a comment "If/when a Rust API is provided" to justify the
functions, but it is the other way around, i.e. you need to first
write the abstractions for that C code, upstream them through the
relevant tree/maintainers, and then you use them from your Rust code.

Instead, to bootstrap things, what about writing a bcachefs module in
Rust that uses e.g. the VFS abstractions posted by Wedson, and
perhaps, to experiment/prototype, fill it with calls to the relevant C
parts of bcachefs? That way you can start working on the abstractions
and code you will eventually need for a Rust bcachefs module, without
limiting what C bcachefs can do/build for. And that way it would also
help to justify the upstreaming of the VFS abstractions too, since you
would be another expected user of them, and so on.

> I wasn't sure if this needed to be an RFC based on the current status
> of accepting Rust code outside of the rust/ tree, so I designated it as
> such to be safe. However, Kent plans to merge rust+bcachefs code in the
> 6.9 merge window, so I hope at least the first 2 patches in this series,
> the ones that actually enable Rust for bcachefs, can be accepted.

This is worrying -- there has been no discussion about mixing C and
Rust like this, but you say it is targeted for 6.9. I feel there is a
disconnect somewhere. Perhaps it would be a good idea to have a quick
meeting about this.

Cheers,
Miguel
Kent Overstreet Feb. 7, 2024, 8:57 p.m. UTC | #2
On Wed, Feb 07, 2024 at 12:06:05PM +0100, Miguel Ojeda wrote:
> On Wed, Feb 7, 2024 at 6:57 AM Thomas Bertschinger
> <tahbertschinger@gmail.com> wrote:
> >
> > This series adds support for Rust code into bcachefs. This only enables
> > using Rust internally within bcachefs; there are no public Rust APIs
> > added. Rust support is hidden behind a new config option,
> > CONFIG_BCACHEFS_RUST. It is optional and bcachefs can still be built
> > with full functionality without rust.
> 
> But is it the goal to make it use Rust always? If not, do you mean you
> are you going to have 2 "modes" in bcachefs? i.e. one with all C, and
> one with some parts replaced (i.e. duplicated) in Rust?
> 
> If it is the former (dropping C), then please note that it will limit
> where bcachefs can be built for, i.e. architectures and configurations
> (at least for the time being, i.e. we want to relax all that, but it
> will take time).
> 
> If it is the latter (duplication), then please note that the kernel
> has only gone the "duplication" route for "Rust reference drivers" as
> an exceptional case that we requested to bootstrap their subsystems
> and give Rust a try.
> 
> Could you please explain more about what is the intention here?

I think we're still at the "making sure everything works" stage.

I'll try to keep Rust optional a release or two, more so that we can
iron out any toolchain hiccups, and in that period we'll be looking for
non critical stuff to transition to Rust (the debugfs code, most
likely).

When we make Rust a hard dependency kernel side will have to be a topic
of discussion - but Rust is already a hard dependency on the userspace
side, in -tools, so the lack of full architecture support is definitely
something I'm hoping get addressed sooner rather than later, but it's
probably not the blocker here.

As soon as we're ok with making Rust a hard dependency kernel side,
we'll be looking at switching a lot of stuff to Rust (e.g. fsck).

> Either way, the approach you are taking in this patch series seems to
> be about calling C code directly, rather than writing and using
> abstractions in general. For instance, in one of the patches you
> mention in a comment "If/when a Rust API is provided" to justify the
> functions, but it is the other way around, i.e. you need to first
> write the abstractions for that C code, upstream them through the
> relevant tree/maintainers, and then you use them from your Rust code.

I didn't see that comment, but we're mainly looking at what we can do
inside fs/bcachefs/, and I've already got Rust bindings for the btree
interface (that I talked about in a meeting with you guys, actually)
that we'll be pulling in soon.

> Instead, to bootstrap things, what about writing a bcachefs module in
> Rust that uses e.g. the VFS abstractions posted by Wedson, and
> perhaps, to experiment/prototype, fill it with calls to the relevant C
> parts of bcachefs? That way you can start working on the abstractions
> and code you will eventually need for a Rust bcachefs module, without
> limiting what C bcachefs can do/build for. And that way it would also
> help to justify the upstreaming of the VFS abstractions too, since you
> would be another expected user of them, and so on.

You mean a new, from scratch bcachefs module? Sorry, but that would not
be practical :)

Wedson's work is on my radar too - that opens up a lot of possibilities.
But right now my goal is just to get /some/ Rust code into bcachefs,
and make sure we can incrementally bring in more Rust code within the same
module.

> 
> > I wasn't sure if this needed to be an RFC based on the current status
> > of accepting Rust code outside of the rust/ tree, so I designated it as
> > such to be safe. However, Kent plans to merge rust+bcachefs code in the
> > 6.9 merge window, so I hope at least the first 2 patches in this series,
> > the ones that actually enable Rust for bcachefs, can be accepted.
> 
> This is worrying -- there has been no discussion about mixing C and
> Rust like this, but you say it is targeted for 6.9. I feel there is a
> disconnect somewhere. Perhaps it would be a good idea to have a quick
> meeting about this.

Oh? This is exactly what I said we were going to do at the conference :)

Happy to meet though, let's figure out a time that works for Thomas too.

Cheers,
Kent
Trevor Gross Feb. 7, 2024, 9:33 p.m. UTC | #3
On Wed, Feb 7, 2024 at 2:57 PM Kent Overstreet
<kent.overstreet@linux.dev> wrote:
> [...]
> I didn't see that comment, but we're mainly looking at what we can do
> inside fs/bcachefs/, and I've already got Rust bindings for the btree
> interface (that I talked about in a meeting with you guys, actually)
> that we'll be pulling in soon.

Is there a branch with the bcachefs rust rewrite or WIP, whatever is
intended for upstreaming? I checked at [1] but nothing there jumped
out to me.

- Trevor

[1]: https://evilpiepirate.org/git/bcachefs.git/refs/
Darrick J. Wong Feb. 7, 2024, 10:39 p.m. UTC | #4
On Wed, Feb 07, 2024 at 03:57:35PM -0500, Kent Overstreet wrote:
> On Wed, Feb 07, 2024 at 12:06:05PM +0100, Miguel Ojeda wrote:
> > On Wed, Feb 7, 2024 at 6:57 AM Thomas Bertschinger
> > <tahbertschinger@gmail.com> wrote:
> > >
> > > This series adds support for Rust code into bcachefs. This only enables
> > > using Rust internally within bcachefs; there are no public Rust APIs
> > > added. Rust support is hidden behind a new config option,
> > > CONFIG_BCACHEFS_RUST. It is optional and bcachefs can still be built
> > > with full functionality without rust.
> > 
> > But is it the goal to make it use Rust always? If not, do you mean you
> > are you going to have 2 "modes" in bcachefs? i.e. one with all C, and
> > one with some parts replaced (i.e. duplicated) in Rust?
> > 
> > If it is the former (dropping C), then please note that it will limit
> > where bcachefs can be built for, i.e. architectures and configurations
> > (at least for the time being, i.e. we want to relax all that, but it
> > will take time).

Which architectures are supported by RoL at this point?

I can't speak for kmo, but bcachefs is new(ish) to the kernel, and
restricting support to the five major 64-bit arches (x64, arm64, ppc64,
s390x, riscv64) might be quite a load off him and his team.

Just speaking for myself, where xfs gets occasional weird bug reports of
strange behavior on platforms that none of us can test (csky) or OOM
reports with multi-TB filesystems on m68k.

> > If it is the latter (duplication), then please note that the kernel
> > has only gone the "duplication" route for "Rust reference drivers" as
> > an exceptional case that we requested to bootstrap their subsystems
> > and give Rust a try.
> > 
> > Could you please explain more about what is the intention here?
> 
> I think we're still at the "making sure everything works" stage.
> 
> I'll try to keep Rust optional a release or two, more so that we can
> iron out any toolchain hiccups, and in that period we'll be looking for
> non critical stuff to transition to Rust (the debugfs code, most
> likely).
> 
> When we make Rust a hard dependency kernel side will have to be a topic
> of discussion - but Rust is already a hard dependency on the userspace
> side, in -tools, so the lack of full architecture support is definitely
> something I'm hoping get addressed sooner rather than later, but it's
> probably not the blocker here.

> As soon as we're ok with making Rust a hard dependency kernel side,
> we'll be looking at switching a lot of stuff to Rust (e.g. fsck).
> 
> > Either way, the approach you are taking in this patch series seems to
> > be about calling C code directly, rather than writing and using
> > abstractions in general. For instance, in one of the patches you
> > mention in a comment "If/when a Rust API is provided" to justify the
> > functions, but it is the other way around, i.e. you need to first
> > write the abstractions for that C code, upstream them through the
> > relevant tree/maintainers, and then you use them from your Rust code.
> 
> I didn't see that comment, but we're mainly looking at what we can do
> inside fs/bcachefs/, and I've already got Rust bindings for the btree
> interface (that I talked about in a meeting with you guys, actually)
> that we'll be pulling in soon.

Personally, I suspect that converting the existing big-glob-of-C fs
implementations is going to be a long slow task of rewriting the C code
piece by testable piece, starting with the outer rings and moving in
towards the core.  Until the core is done, there's probably going to be
a lot of FFI'ing going on.

I think that's what Kent is getting at when he talks about rewriting
online fsck before moving on to the guts of bcachefs.  Or at least,
that's the approach I would take if I were to start converting XFS.

Messing around with core structures like xfs_inode and xfs_mount will
come muuuuch later.

> > Instead, to bootstrap things, what about writing a bcachefs module in
> > Rust that uses e.g. the VFS abstractions posted by Wedson, and
> > perhaps, to experiment/prototype, fill it with calls to the relevant C
> > parts of bcachefs? That way you can start working on the abstractions
> > and code you will eventually need for a Rust bcachefs module, without
> > limiting what C bcachefs can do/build for. And that way it would also
> > help to justify the upstreaming of the VFS abstractions too, since you
> > would be another expected user of them, and so on.
> 
> You mean a new, from scratch bcachefs module? Sorry, but that would not
> be practical :)
> 
> Wedson's work is on my radar too - that opens up a lot of possibilities.
> But right now my goal is just to get /some/ Rust code into bcachefs,
> and make sure we can incrementally bring in more Rust code within the same
> module.

Is the ultimate goal of the RoL project to build Rust wrappers around
the C filesystem objects?  Or to design something more Rustic(?) and
present the interfaces that the VFS wants to the VFS only as needed?

I might be talking nonsense here, I've only started learning Rust.  But
I /can/ speculate about what a Rust fs will need based on all the stuff
I've learned over the past 20y of wrangling the C filesystems.

> > > I wasn't sure if this needed to be an RFC based on the current status
> > > of accepting Rust code outside of the rust/ tree, so I designated it as
> > > such to be safe. However, Kent plans to merge rust+bcachefs code in the
> > > 6.9 merge window, so I hope at least the first 2 patches in this series,
> > > the ones that actually enable Rust for bcachefs, can be accepted.
> > 
> > This is worrying -- there has been no discussion about mixing C and
> > Rust like this, but you say it is targeted for 6.9. I feel there is a
> > disconnect somewhere. Perhaps it would be a good idea to have a quick
> > meeting about this.
> 
> Oh? This is exactly what I said we were going to do at the conference :)
> 
> Happy to meet though, let's figure out a time that works for Thomas too.

Honestly, these three patches seem to me like the barest stub to be able
to plant a flag and say "Hey look, Rust in a merged linux fs driver!"
Even if the only progress anyone makes on that this year is to wrap the
bcachefs btree iterators in Rust and reimplement a bunch of ioctls.

--D

> Cheers,
> Kent
>
Thomas Bertschinger Feb. 8, 2024, 1:14 a.m. UTC | #5
On Wed, Feb 07, 2024 at 12:06:05PM +0100, Miguel Ojeda wrote:
> On Wed, Feb 7, 2024 at 6:57 AM Thomas Bertschinger
> <tahbertschinger@gmail.com> wrote:
> > I wasn't sure if this needed to be an RFC based on the current status
> > of accepting Rust code outside of the rust/ tree, so I designated it as
> > such to be safe. However, Kent plans to merge rust+bcachefs code in the
> > 6.9 merge window, so I hope at least the first 2 patches in this series,
> > the ones that actually enable Rust for bcachefs, can be accepted.
> 
> This is worrying -- there has been no discussion about mixing C and
> Rust like this, but you say it is targeted for 6.9. I feel there is a
> disconnect somewhere. Perhaps it would be a good idea to have a quick
> meeting about this.
> 
> Cheers,
> Miguel

That could be a good idea; what format do you suggest?

One question that I would like clarity on is if in general work to add
Rust into something like fs/bcachefs/ can be accepted at this point.
That is, is it realistic to expect that an upcoming kernel release could
include Rust code in fs/bcachefs/ at all (even if not in the form in
this patch series)?

Kent has been suggesting his plan to do this for a while, I think, but I
haven't yet seen many explicit statements about what would, and would
not be accepted into an upstream kernel for rust+bcachefs. (If I missed
any conversations where this was laid out, please let me know.)

Actually, the previous paragraphs in your email are helpful in terms
of laying out concrete expectations, so thank you.

You talk about using the broader kernel Rust APIs like the proposed VFS
layer. What about bindings for internal bcachefs APIs, like the btree
interface [1] that Kent mentioned in another response?

Would a v2 of this series, that removes the current 3rd patch and replaces
it with a patch to add in the bcachefs btree bindings, be more suitable
for acceptance upstream?

I think testing the VFS abstractions for bcachefs sounds like a very
worthwhile project--but it also sounds like a distinct project from
Kent's goals for integrating Rust into bcachefs in the near term.

[1] https://evilpiepirate.org/git/bcachefs-tools.git/tree/bch_bindgen/src/btree.rs

- Thomas Bertschinger
Trevor Gross Feb. 8, 2024, 4:19 a.m. UTC | #6
On Wed, Feb 7, 2024 at 5:39 PM Darrick J. Wong <djwong@kernel.org> wrote:
> [..]
> Which architectures are supported by RoL at this point?
>
> I can't speak for kmo, but bcachefs is new(ish) to the kernel, and
> restricting support to the five major 64-bit arches (x64, arm64, ppc64,
> s390x, riscv64) might be quite a load off him and his team.
>
> Just speaking for myself, where xfs gets occasional weird bug reports of
> strange behavior on platforms that none of us can test (csky) or OOM
> reports with multi-TB filesystems on m68k.

6.7 only has x86. Loongarch is in for 6.8, aarch64 [1] and riscv [2]
shouldn't be too far away, and there has been some interest in the IBM
targets but they haven't sent anything yet.

Any of Rust's tier 2 targets [3] should be reasonably feasible to
support at some point if the maintainers are interested. csky and m68k
are both tier 3 targets so less likely anytime soon, anything more
niche than tier 3 will need GCC support. Which isn't terribly far
off...

[1]: https://lore.kernel.org/rust-for-linux/20231020155056.3495121-1-Jamie.Cunliffe@arm.com/
[2]: https://lore.kernel.org/rust-for-linux/20230307102441.94417-1-conor.dooley@microchip.com/
[3]: https://doc.rust-lang.org/beta/rustc/platform-support.html

> > > Instead, to bootstrap things, what about writing a bcachefs module in
> > > Rust that uses e.g. the VFS abstractions posted by Wedson, and
> > > perhaps, to experiment/prototype, fill it with calls to the relevant C
> > > parts of bcachefs? That way you can start working on the abstractions
> > > and code you will eventually need for a Rust bcachefs module, without
> > > limiting what C bcachefs can do/build for. And that way it would also
> > > help to justify the upstreaming of the VFS abstractions too, since you
> > > would be another expected user of them, and so on.
> >
> > You mean a new, from scratch bcachefs module? Sorry, but that would not
> > be practical :)
> >
> > Wedson's work is on my radar too - that opens up a lot of possibilities.
> > But right now my goal is just to get /some/ Rust code into bcachefs,
> > and make sure we can incrementally bring in more Rust code within the same
> > module.
>
> Is the ultimate goal of the RoL project to build Rust wrappers around
> the C filesystem objects?  Or to design something more Rustic(?) and
> present the interfaces that the VFS wants to the VFS only as needed?
>
> I might be talking nonsense here, I've only started learning Rust.  But
> I /can/ speculate about what a Rust fs will need based on all the stuff
> I've learned over the past 20y of wrangling the C filesystems.
> [..]

The current approach is:

1. Raw bindings to needed APIs are autogenerated with bindgen
2. Abstractions are written on top of the bindings. These should
provide a safe interface where, as much as possible, you can't
accidentally misuse them to do something "wrong" (no UB by Rust's
definitions, plus a fair bit of functional safety).
3. Modules use abstractions, no C bindings directly

So Rust code is currently strictly a consumer of public core APIs,
which cuts off at the module boundary. No reason there couldn't also
be some core functionality, but there is a pretty strong goal of not
keeping duplicate logic between Rust and C. Just not much of a use
case yet.

It works out best if bcachefs uses the same model, so future code can
make use of whatever abstractions come along - at least for the core
APIs, I can imagine bcache-c to bcache-rust will look different. There
is a reasonably complete VFS abstraction available [4] (looks like you
know of this already). I keep a loose list of what is being worked on,
for any other interfaces needed [5].

- Trevor

[4]: https://lore.kernel.org/rust-for-linux/20231018122518.128049-1-wedsonaf@gmail.com/#t
[5]: https://github.com/tgross35/RFL-patch-registry/