Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
|
|

Rust for filesystems

By Jake Edge
June 21, 2024
LSFMM+BPF

At the 2024 Linux Storage, Filesystem, Memory Management, and BPF Summit, Wedson Almeida Filho and Kent Overstreet led a combined storage and filesystem session on using Rust for Linux filesystems. Back in December 2023, Almeida had posted an RFC patch set with some Rust abstractions for filesystems, which resulted in some disagreement over the approach. On the same mid-May day as the session, he posted a second version of the RFC patches, which he wanted to discuss along with other Rust-related topics.

Goals

After updating attendees on the status of his patches, Almeida listed some of the goals of the Rust-for-Linux project, which are embodied in the filesystem abstractions that he is proposing. The first is to express more of the requirements using Rust's type system in order to catch more mistakes at compile time. In addition, the project's developers want to automate some tasks, such as cleaning up resources, in ways that are not easily available to C code. The overall idea is to have a more productive filesystem-development experience, with less time spent on debugging problems that the compiler could find, and with fewer memory-related vulnerabilities overall.

[Wedson Almeida Filho]

Overstreet said that he had been a part of too many two-week bug hunts and has been trying to find ways to avoid those kinds of problems for bcachefs. The Rust language provides a lot more than what he can do in C; it eliminates undefined behavior and provides facilities to see what is happening inside the code. "You can't debug, if you can't see what's going on." He believes that kernel development "will get a whole lot easier over the coming decades" due to using Rust. It will be possible to prove the correctness of code written in Rust, which will mean that bugs that can derail feature development will be much less common.

From his slides, Almeida showed an example of how the Rust type system can eliminate certain kinds of errors. He noted that the iget_locked() function in current kernels has a complicated set of requirements. Callers must check to see if the return value is null and, if it is not, then the contents of the returned struct inode need to be checked to see if it is a new or existing inode. If it is new, it needs to be initialized before it can be used; if that fails, iget_failed() needs to be called, he said.

There was some discussion of the finer points of what callers of iget_locked() need to do, with Al Viro disagreeing with some of what Almeida had on his slide. That went back and forth, with Overstreet observing that it was exactly that kind of discussion/argument that could be avoided by encapsulating the rules into the Rust types and abstractions; the compiler will know the right thing to do.

Overstreet noted that Christian Brauner and Alice Ryhl have helped to improve the abstractions a great deal since the first posting; in particular, there are things he has learned about reference counts based on how they are being handled by the Rust code. "This is going to make all our lives so much easier", Overstreet said.

Almeida put up a slide with the equivalent of iget_locked() in Rust, which was called get_or_create_inode(). The important part is the return type, he said; as with C, callers must check for failure, but the success case is much different. If it is successful, the caller either receives a regular reference-counted inode to use (which has its reference count automatically decremented when the inode object is no longer referenced) or it receives a new inode, which will automatically call the equivalent of iget_failed() if it is never initialized. If it is ever initialized (which can only be done once), it becomes a regular inode with the automatic reference-count decrement. All of that is enforced through the type system.

Viro seemed somewhat skeptical of how that would work in practice. He wondered where in the source code those constraints would be defined. Almeida said that the whole idea is to determine what the constraints are from Viro and other filesystem developers, then to create types and abstractions that can enforce them.

Disconnect

Dave Chinner asked about the disconnect between the names in the C API and the Rust API, which means that developers cannot look at the C code and know what the equivalent Rust call would be. He said that the same names should be used or it would all be completely unfamiliar to the existing development community. In addition, when the C code changes, the Rust code needs to follow along, but who is going to do that work? Almeida agreed that it was something that needs to be discussed.

As far as the renamed functions goes, he is not opposed to switching the names to match the C API, but does not think iget_locked() is a particularly good name. It might make sense to take the opportunity to create better names.

There was some more discussion of the example, with Viro saying that it was not a good choice because iget_locked() is a library function, rather than a member function of the superblock object. Almeida said that there was no reason get_or_create_inode() could not be turned into a library function; his example was simply meant to show how the constraints could be encoded in the types.

Brauner said that there needs to be a decision on whether the Rust abstractions are going to be general-purpose, intended for all kernel filesystems, or if they will only be focused on the functionality needed for the simpler filesystems that have been written in Rust. There is also a longer-term problem in handling situations where functions like get_or_create_inode() encode a lot more of the constraints than iget_locked() does. As the C code evolves, which will happen more quickly than with the Rust code, at least initially, there will be a need to keep the two APIs in sync.

It comes down to a question of whether refactoring and cleanup will be done as part of adding the Rust abstractions, Overstreet said; he strongly believes that is required. But there is more to it than just that, James Bottomley said. The object lifecycles are being encoded into the Rust API, but there is no equivalent of that in C; if someone changes the lifecycle of the object on one side, the other will have bugs.

There are also problems because the lifecycle of inode objects is sometimes filesystem-specific, Chinner said. Encoding a single lifecycle understanding into the API means that its functions will not work for some filesystems. Overstreet said that filesystems which are not using the VFS API would simply not benefit, but Chinner said that a VFS inode is just a structure and it is up to filesystems to manage its lifetime. Almeida said that the example would only be used by filesystems that currently call iget_locked() and could benefit. The Rust developers are not trying to force filesystems to change how they are doing things.

Allocating pain

Part of the problem, Ted Ts'o said, is that there is an effort to get "everyone to switch over to the religion" of Rust; that will not happen, he said, because there are 50+ different filesystems in Linux that will not be instantaneously converted. The C code will continue to be improved and if that breaks the Rust bindings, it will break the filesystems that depend on them. For the foreseeable future, the Rust bindings are a second-class citizen, he said; broken Rust bindings are a problem for the Rust-for-Linux developers and not the filesystem community at large.

He suggested that the development of the Rust bindings continue, while the C code continues to evolve. As those changes occur, "we will find out whether or not this concept of encoding huge amounts of semantics into the type system is a good thing or a bad thing". In a year or two, he thinks the answer to that will become clear; really, though, it will come down to a question of "where does the pain get allocated". In his mind, large-scale changes like this almost always come down to a "pain-allocation question".

Almeida said that he is not trying to keep the C API static; his goal is to get the filesystem developers to explain the semantics of the API so that they can be encoded into Rust. Bottomley said that as more of those semantics get encoded into the bindings, they will become more fragile from a synchronization standpoint. Several disagreed with that, in the form of a jumble of "no" replies and the like. Almeida said that it was the same with any user of an API; if the API changes, the users need to be updated. But Ts'o pointedly said that not everyone will learn Rust; if he makes a change, he will fix all of the affected C code, but, "because I don't know Rust, I am not going to fix the Rust bindings, sorry".

Viro came back to his objections about the proposed replacement for iget_locked(). The underlying problem that he sees is the reliance on methods versus functions; using methods is not the proper way forward because the arguments are not specified explicitly. But Overstreet said that the complaints about methods come from languages like C++ that rely too heavily on inheritance, which is "a crap idea". Rust does not do so; methods in Rust are largely just a syntactical element.

There was some discussion of what exactly is being encoded in the types. Jan Kara said that there is some behavior that goes with the inode, such as its reference count and its handling, but there is other behavior that is inherent in the iget_locked() function. Overstreet and Almeida said that those two pieces were both encoded into the types, but separately; other functions using the inode type could have return values with different properties.

Viro went through some of his reasoning about why inodes work the way they do in the VFS. He agreed with the idea of starting small to see where things lead. Overstreet suggested that maybe the example used was not a good starting point, "because this is the complicated case". "Oh, no it isn't", Viro replied to laughter as the session concluded.


Index entries for this article
KernelDevelopment tools/Rust
KernelFilesystems/Internal API
ConferenceStorage, Filesystem, Memory-Management and BPF Summit/2024


to post comments

Capturing complex requirements in Rust helps evolution

Posted Jun 21, 2024 22:26 UTC (Fri) by roc (subscriber, #30627) [Link] (6 responses)

Capturing complex API requirements in the Rust type system is actually a huge *win* when those requirements change. The compiler tells you what needs to be fixed, and whether your fix satisfies the new requirements. It is much easier and safer to make these kinds of sweeping changes than with C or C++, and it is easier to review those changes.

So, fixing users of Rust abstractions will probably turn out to be less work per user than fixing the C users of the underlying C APIs that have changed. But it does sound like coordinating that work with kernel devs who simply refuse to interact with Rust code in any way is going to be painful.

Capturing complex requirements in Rust helps evolution

Posted Jun 22, 2024 1:00 UTC (Sat) by python (guest, #171317) [Link] (5 responses)

I'm excited to see what they come up with. More discipline and scrutiny (which is required when inter-operating multiple languages) will probably reveal a lot of hidden and unintended behaviors. I sincerely hope they find a way to bury some of the really horrible crufty APIs (epoll in userspace come to mind, I am sure something analogous exists in the kernel API) and replace them with something a little more sane.

It will be interesting to see if the rust bindings (making full use of the type system) could be more secure (or less secure?), despite being a thin wallpaper over raw C calls to an ever changing kernel API. Also will be interesting if it impacts performance, particularly since Rust favors doing/structuring things certain ways that are uncommon in plain C.

I would be inclined to think that any sort of simple wrapper would be at least minusculely slower, but perhaps it might enable more complex and efficient ways of doing things? (automatically handled in the background by the wrappers)

Capturing complex requirements in Rust helps evolution

Posted Jun 22, 2024 9:11 UTC (Sat) by Wol (subscriber, #4433) [Link] (4 responses)

If the Rust compiler is capable of emitting a C .h file, that would make it even better! Unfortunately, it probably can't ingest a .h file because different C compilers could lay things out differently, all C cares about is consistency during the compile so unless the programmer has taken special care a .h can have an ambiguous layout. The Rust compiler could take that care.

In which case, it's then hopefully (crossed fingers and toes!) a drop-in swap of .h files.

Cheers,
Wol

Capturing complex requirements in Rust helps evolution

Posted Jun 22, 2024 9:43 UTC (Sat) by atnot (subscriber, #124910) [Link] (1 responses)

the rust compiler is not, but bindgen is (c headers->rust) and cbindgen does the reverse (rust->c headers)

Capturing complex requirements in Rust helps evolution

Posted Jun 22, 2024 13:52 UTC (Sat) by atnot (subscriber, #124910) [Link]

The thing that doesn't solve though, is how much information you lose going from Rust to C. That's somewhat improving with things like counted_by, but it's a long way off.

However, even that ultimately doesn't really matter, because the barriers to calling Rust from C aren't primarily technical. It's more the attitude among some people that Rust for Linux is just a temporary blip that is bound to fail, or a hope that it does so you don't have to deal with it. Which becomes significantly harder if C code is allowed to call Rust.

There will realistically be a pretty long tail of people who need a few more years to be convinced Rust is not going away, and probably not everyone will be. However I think writing C APIs in Rust will be a lot more palatable when, say, the GPU driver you are currently using being removed seems unwelcome enough that Rust is de facto necessary anyway. But it'll be a bit until that happens.

Capturing complex requirements in Rust helps evolution

Posted Jul 20, 2024 15:13 UTC (Sat) by kevincox (guest, #93938) [Link] (1 responses)

> different C compilers could lay things out differently

I don't think this is true. I don't think the C standard cares (other than some basic restrictions on possible layouts) but platform ABIs will strictly define how structs are laid out, just like they define how arguments are laid out, what object files look like and everything else.

For example if you compile code with Clang and GCC on x86_64 Linux they will be binary compatible as they all follow the same ABI specification (IIRC it is the System V AMD64 ABI). There is no reason why the Rust compiler couldn't follow the same rules for structures that are shared with C (even if it uses a more efficient and unstable layout for internal structures).

Rust supports platform C ABI

Posted Jul 20, 2024 15:51 UTC (Sat) by farnz (subscriber, #17727) [Link]

Just FYI, Rust has #[repr(C)] to tell the compiler to lay out a data structure in a fashion compatible with the platform's C ABI. cbindgen (where the source of truth is Rust code) and bindgen (where the source of truth is C code) make use of this to produce matching representations in C and Rust for the same data structure.

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 22, 2024 10:41 UTC (Sat) by gray_-_wolf (subscriber, #131074) [Link] (10 responses)

This part has cought my eye:

> But Ts'o pointedly said that not everyone will learn Rust; if he makes a change, he will fix all of the affected C code, but, "because I don't know Rust, I am not going to fix the Rust bindings, sorry".

I understand the view point, but I wonder how will this work with regards to the "do not break user space" policy. Let us say that Ts'o does some change, and updates all C users. But the Rust binding will break (either compilation, or runtime behavior). What now? In ideal world someone from rust-on-linux will step up and promptly resolve the issue. However we do not live in the ideal world and everyone has full plate already. What now? Will Ts'o's change be prevented from being merged? Will it be merged and the rust part just be broken (with user-space visible effects) until someone finds the time?

On similar note, will contributors with less weight behind them have the same priviledge of saying "I am not touching rust code"?

Regardless of my opinion on rust, this whole thing is really interesting experiment, so I am wondering what is current thinking in the community regarding this.

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 22, 2024 12:33 UTC (Sat) by pbonzini (subscriber, #60935) [Link] (7 responses)

What will _actually_ happen is a mix of three things:

1) APIs are changed in backwards-incompatible ways (e.g. https://www.spinics.net/lists/intel-gfx/msg349025.html) but they're generally not complicated and you handle them with topic branches as usual.

2) new APIs are introduced but updating 50 filesystems (or hundreds of anonymous file_operations) does not happen at ones, therefore in practice fallbacks are left in place and Rust bindings can be updated separately. The typical example here is read_iter/write_iter.

3) most subsystems that have Rust bindings will have no problem adjusting, at which point who's left will have to acknowledge the reality.

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 25, 2024 8:42 UTC (Tue) by b7j0c (subscriber, #27559) [Link] (6 responses)

> What will _actually_ happen is a mix of three things:

treating the migration to Rust as inevitable feels like magical thinking, same as Mozilla experienced with Servo

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 25, 2024 10:42 UTC (Tue) by pbonzini (subscriber, #60935) [Link] (5 responses)

I'm not talking of a full-scale migration; a non-trivial or undeniable level of adoption is enough.

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 25, 2024 11:57 UTC (Tue) by pizza (subscriber, #46) [Link] (2 responses)

> I'm not talking of a full-scale migration; a non-trivial or undeniable level of adoption is enough.

In other words, "The inevitability of Rust becoming a requirement to build a usable/useful kernel."

...All it takes is one driver (not even subsystem), and *BAM* you're now a Rust system with a (substantial) pile of C.

(Or rather, "kernel-Rust" with a pile of "kernel-C")

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 25, 2024 12:13 UTC (Tue) by Wol (subscriber, #4433) [Link] (1 responses)

> > I'm not talking of a full-scale migration; a non-trivial or undeniable level of adoption is enough.

> In other words, "The inevitability of Rust becoming a requirement to build a usable/useful kernel."

Which, if the claims of the speed with which good solid drivers can be written in Rust are true, is inevitable sooner rather than later ...

I remember reading somewhere, that the speed at which a good programmer could produce good code was measured in LoC, REGARDLESS OF THE LANGUAGE USED. In other words, measured in terms an end user could understand - what a system could do - the choice of language has a major impact on productivity.

Cheers,
Wol

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 25, 2024 17:20 UTC (Tue) by NYKevin (subscriber, #129325) [Link]

> I remember reading somewhere, that the speed at which a good programmer could produce good code was measured in LoC, REGARDLESS OF THE LANGUAGE USED.

This is less surprising than it sounds. It basically amounts to "higher level languages allow programmers to write code that does more elaborate things in the same amount of development time," which had darned well better be true considering all of the performance cost of e.g. Python. If Python didn't give you a development speed advantage, there would be no (or at least much less) reason to use it for serious purposes (outside of the classroom).

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 25, 2024 15:23 UTC (Tue) by b7j0c (subscriber, #27559) [Link] (1 responses)

both Microsoft and Google appear to be able to introduce Rust into existing codebases - but they also have the power to promote, deliver bonuses, or alternatively, fire people who aren't aligned with the strategy

open source projects are different...volunteers can just move on if they are unhappy, and if you don't have suitable replacement volunteers, things stop happening

How will fixing only C part work with the "do not break user space" policy?

Posted Jul 4, 2024 2:13 UTC (Thu) by mrugiero (guest, #153040) [Link]

That won't be a problem. Most kernel development is made by employees of companies with the ability to promote, deliver bonuses and firing, and they'd rather have their kernel maintained, be it in C, Rust or Pascal. You are right for the general case though, most open source projects are driven by volunteers. Linux is an exception to that rule.

How will fixing only C part work with the "do not break user space" policy?

Posted Jun 24, 2024 6:27 UTC (Mon) by LtWorf (subscriber, #124958) [Link] (1 responses)

"do not break user space" only applies to syscalls basically.

If a filesystem stops working, that has never counted as "userspace is now broken".

How will fixing only C part work with the "do not break user space" policy?

Posted Jul 4, 2024 2:16 UTC (Thu) by mrugiero (guest, #153040) [Link]

OTOH, isn't fixing what you break the general etiquette? I don't think "I don't know this" works as an excuse in other cases. You don't get to leave XFS broken if you touch VFS because you don't know XFS. Rust is not even that hard to learn when you come from C (also knowing C++ helps a lot as well, since Rust is pretty much C++ best practices enforced by the compiler), it's not frontend programmers we're dealing with.

Just wait

Posted Jun 22, 2024 10:54 UTC (Sat) by wsy (subscriber, #121706) [Link] (17 responses)

Sometimes it's just easier to wait until older guys retire than to convince them to adapt to new way of doing things.

Just wait

Posted Jun 22, 2024 11:41 UTC (Sat) by pizza (subscriber, #46) [Link]

> Sometimes it's just easier to wait until older guys retire than to convince them to adapt to new way of doing things.

Change, real change, has _always_ operated on a generational cycle.

(And this isn't "adapt to the new way", it's "double your congnitive workload maintaining a mission-critical working system before its nominal replacement is ready to be deployed.")

Just wait

Posted Jun 22, 2024 12:08 UTC (Sat) by willy (subscriber, #9762) [Link] (15 responses)

https://en.wikipedia.org/wiki/Planck%27s_principle

"Science advances one funeral at a time"

I'm disappointed by how resistant some fellow hackers are to Rust. It's the first language in 50 years to be enough of an advantage over C to be worth switching to.

Just wait

Posted Jun 22, 2024 12:37 UTC (Sat) by liw (subscriber, #6379) [Link] (12 responses)

If it were only a matter of teaching kernel hackers the Rust language, that'd be a solvable problem. (I say, as someone who does Rust training for free and for money.) But I fear there's usually more resistance to change than just having to learn a new language or a new tool.

Just wait

Posted Jun 23, 2024 8:52 UTC (Sun) by Wol (subscriber, #4433) [Link] (3 responses)

> But I fear there's usually more resistance to change than just having to learn a new language or a new tool.

It usually involves changing your entire way of thinking.

Look at that post a few days back over P4 - where the comment was "someone comes along thinking they can rewrite it in C", and several man-years of effort later, they realise that actually, someone using a domain specific language can do double the work in half the time, if not even better.

Going back even further, someone commented people who've learnt Rust usually make far better C programmers because, even though C doesn't enforce memory safety etc, because Rust insists that you code in memory-safe ways, they code memory-safe in C anyways.

It's like me and databases - 4th normal form is the best for a whole bunch of reasons, but because my experience is with a database where 4th normal form was the OBVIOUS way to do it, when I'm forced to work with relational I do it without thinking. Unfortunately I'm usually working with stuff designed by others where I'm thinking "what the hell were they thinking?".

Cheers,
Wol

Just wait

Posted Jun 23, 2024 17:48 UTC (Sun) by Kaligule (subscriber, #167650) [Link] (2 responses)

Please, what is P4?

Just wait

Posted Jun 23, 2024 19:37 UTC (Sun) by softball (subscriber, #160655) [Link]

They are possibly referring to: https://lwn.net/Articles/977310/

P4

Posted Jun 24, 2024 22:04 UTC (Mon) by riking (subscriber, #95706) [Link]

https://p4.org/ is a programmable packet processing specification language. You use it to write firewall or routing rules, or queue dropping priorities, or whatever the hardware of the router you bought allows you to load a P4 program to do.

Just wait

Posted Jun 25, 2024 13:36 UTC (Tue) by zuki (subscriber, #41808) [Link] (7 responses)

I find the attitude of "I don't care about Rust, I'll not learn Rust" annoying and destructive.

There's also the distinction that there are different levels of "knowing" a language. It's quite easy to get to the level where one can do small modifications to existing code, or to copy existing functionality and extend it to cover additional cases. It's much harder to know which of the many possible ways of structuring code and which abstractions to use for a new problem. But fortunately, for ongoing maintenance, this first easier level is all that is needed. The second higher level is only necessary e.g. to implement or review new Rust abstractions in the kernel or new drivers, but a different set of people can handle that.

I think it's entirely reasonable to ask maintainers to also care about the Rust code.

Just wait

Posted Jun 25, 2024 14:36 UTC (Tue) by pizza (subscriber, #46) [Link]

> I think it's entirely reasonable to ask maintainers to also care about the Rust code.

I agree in principle -- but we're a long, long way from the "ongoing maintenance" phase.

The current status quo is that, in order to meaningfully contribute to kernel-Rust, you have to essentially be an expert in all-things-Rust, including living on the bleeding edge of Rust language/feature development.

> I find the attitude of "I don't care about Rust, I'll not learn Rust" annoying and destructive.

You may find it annoying but it is an entirely rational (and reasonable!) attitude to take given that hyper-unstable nature of kernel-Rust and the already-overwhelming "just maintaining existing stuff" workload.

After all, "Let those who care about X do the work" has been the kernel development philosophy since approximately forever.

Just wait

Posted Jun 25, 2024 14:51 UTC (Tue) by somlo (subscriber, #92421) [Link]

Having never used the Go language, I managed to "cut'n'paste" my way into writing a useful (and also stylistically and functionally correct) patch against Docker. So in principle you *should* be right about your first level of "knowing" a language concept.

However, unlike Go, I find Rust hard to skim over -- for the lack of a better word, it's too "syntax-y" for my brain :) So your "anyone should be able to deal with it" statement is actually a much bigger ask than you think, depending on the actual language's legibility to newcomers.

I then tried working my way through "The Rust Programming Language", and was mostly able to follow along and understand what's going on, and even managed to write ok-ish small programs in the process.

But without being a real, $DAYJOB Rust programmer, when I look at production code a few months later, it's back to a wall-of-syntax "foo::bar => <blah:::xyz>" incomprehensible gibberish... :D
This may be just an undiagnosed learning disability on my part, or it might be that Rust syntax is simply less legible to a large swath of the otherwise OK programmer population.

I'm also constantly high-key annoyed at how compiling a program involves downloading crap off the Internet, as part of the compilation process (this is the part where I might just be old and grumpy, and the whole download-crap-from-the-Internet thing is interfering with my lawn care routine).

Anyhow, if kernel maintainers' experience is anything like mine, I can't blame them for putting a "low pass filter" on this thing: maybe it goes away if they ignore it long enough, and they won't have to waste time on it.

Now, if based on the description of my pain points above there's a more targeted way of learning Rust in a way that sticks, I'm happy to take hints and advice...

Changing code when you barely understand the language

Posted Jun 25, 2024 15:40 UTC (Tue) by farnz (subscriber, #17727) [Link]

The other thing to bear in mind is that different languages have different challenge levels when you're not very good at them. At one extreme, you have languages where just about everything you could reasonably consider "language source code" is accepted by implementations as "valid" code, and if you barely understand the language, it's really hard to avoid making mistakes.

At the other extreme, you have languages where the compiler will definitely complain if you make a change that won't work, and thus it's a lot easier to avoid making mistakes because the compiler tells you that what you've implemented is not going to work.

And in the middle of those two extremes, we have real languages, where some things that won't work cause the compiler to complain (such as including a file that doesn't exist like #include <linus/asm.h>), while other things that won't work compile and fail later.

The interesting question is whether Rust is strict enough that someone with good C skills and minimal Rust skills can be confident that the Rust toolchain will complain if they make the "obvious" fix, but it's wrong, or whether they have to learn more Rust so that they can do the checks themselves (or ask someone else to check their work).

Just wait

Posted Jul 4, 2024 2:23 UTC (Thu) by mrugiero (guest, #153040) [Link]

> I think it's entirely reasonable to ask maintainers to also care about the Rust code.

I'm not sure if I'm inventing this, but I believe the deal was that maintainers got to decide whether Rust made it into in their subsystems? If that's the case, it's only reasonable to expect them to either reject the patches or commit to keep them working. Otherwise we're in a kind of Seinfeld's car reservation situation.

Just wait

Posted Jul 17, 2024 12:19 UTC (Wed) by that_kca (guest, #172467) [Link] (2 responses)

> I find the attitude of "I don't care about Rust, I'll not learn Rust" annoying and destructive.

I mean is it any more annoying or destructive than the "Everything must be written in rust" evangelism that many of the rust fans parrot?

I imagine if rust spent less of the design/engineering points in being hard to learn the language might find more people willing to pick it up.

But then the majority of the rust internet community would probably run to something else.

Just wait

Posted Jul 17, 2024 13:40 UTC (Wed) by Wol (subscriber, #4433) [Link] (1 responses)

> I mean is it any more annoying or destructive than the "Everything must be written in rust" evangelism that many of the rust fans parrot?

Rust FANS, or Rust PROGRAMMERS.

Generally you'll find the people who make the most noise, are the people who do the least work. That's not always a bad thing, you need your evangelists (after all, I make a heck of a lot of noise about Pick/MV), but there are too many people who think it's a silver bullet when they've never really used it.

It DOES sound great. And given that all the evidence says it's not vulnerable to a huge class of errors that regularly bite C/C++, there's good reason to - as a minimum - try it out. But it's noticeable that a lot of people are too busy using it to evangelise it. That to me is a good sign.

Cheers,
Wol

Just wait

Posted Jul 17, 2024 16:55 UTC (Wed) by andresfreund (subscriber, #69562) [Link]

Wol. You regularly post close to half of the comments here. I'd appreciate if you could try to appreciate the perspective of the readers of the comment section into consideration a bit more. Nobody writes *that* much interesting stuff.

Just wait

Posted Jun 22, 2024 14:05 UTC (Sat) by khim (subscriber, #9252) [Link] (1 responses)

> It's the first language in 50 years to be enough of an advantage over C to be worth switching to.

Sure, but the flip side is that it is the first language in 50 years that offers genuine advantage large enough to switch.

The only way to convince people to switch is to write more good Rust code, ultimately.

Just wait

Posted Jun 22, 2024 14:21 UTC (Sat) by adobriyan (subscriber, #30858) [Link]

> The only way to convince people to switch is to write more good Rust code, ultimately.

Just imagine what bug-for-bug compatible Linux.rs kernel could do...

test suite for complicated cases

Posted Jun 22, 2024 15:17 UTC (Sat) by aszs (subscriber, #50252) [Link] (5 responses)

I'm a little surprised there's no mention here about building a test suite for these "complicated cases" -- that's the obvious way to make sure two independent implementations conform. And it has some benefits:
* the grunt work doesn't have to be done by time-constrained core developers
* getting a nice test suite out of this effort could be a good sweetener to motivate Rust-resistant maintainers

test suite for complicated cases

Posted Jun 22, 2024 18:41 UTC (Sat) by willy (subscriber, #9762) [Link] (3 responses)

How would you write a test suite that verifies that every filesystem conforms to the current VFS locking rules? Particularly when those locking rules are mostly not written down.

To take an example that I do know...

When you call folio_mark_dirty(), you must guarantee that the folio will not be concurrently truncated from the file (for values of truncate that include operations like hole-punch).

Holding the folio lock is one way to do that. But this is a sleeping lock, so you can't always do that. If the folio is currently mapped by a page table, holding that page table lock guarantees truncation will not complete, and some callers rely on this.

If you have buffer heads attached to the folio, and you have a buffer head locked, then that is also sufficient to prevent truncation. Some callers rely on this.

Now, encode all that information into a type system? Not sure it can be done. And you certainly can't write a test suite for it. Or any reasonable assertion.

I'm a huge fan of test suites. But saying "just write a test suite" without understanding the problem space is not helpful.

test suite for complicated cases

Posted Jun 22, 2024 20:06 UTC (Sat) by mathstuf (subscriber, #69389) [Link]

One way would be to have some "token" ZST (zero-size type) that one could retrieve from any of these locking mechanisms. `folio_mark_dirty()` would then require that as one of its parameters. Something like:

```
let folio_lock = folio.lock();
let mark_dirty_allowed = folio_lock.i_want_to_mark_dirty();

// …

let buffer_head_lock = buffer_head.lock();
let mark_dirty_allowed = buffer_head_lock.i_want_to_mark_folio_dirty(&folio)?; // better error handling, but checks that it is attached

// ….

let page_table_lock = page_table.lock();
let mark_dirty_allowed = page_table_lock.i_want_to_mark_folio_dirty(&folio); // similar to above; make sure this page table maps the folio
```

Techniques from ghost_cell[1] can likely be used to ensure that the "mark_dirty_allowed" proof token is associated with the folio in question and not any folio that might also exist.

[1] https://docs.rs/ghost-cell/latest/ghost_cell/

test suite for complicated cases

Posted Jun 23, 2024 3:53 UTC (Sun) by aszs (subscriber, #50252) [Link]

Maybe I missed something but it didn't seem that the problem being discussed here was how to "verify that every filesystem conforms to the current VFS locking rules" but rather how to make sure the semantics of the Rust APIs for writing file systems match the semantics for the C APIs for writing file systems -- even as those semantics are changed developers that might ignore the Rust bindings. And if it's unrealistic to test all the ways a surface API might impact some internal invariant, well that's what fuzz testing is for. To be clear, I wasn't saying "just" write a test suite, I was saying I'm surprised tests aren't being discussed as part of a solution to a fairly hard problem.

test suite for complicated cases

Posted Jul 4, 2024 2:34 UTC (Thu) by mrugiero (guest, #153040) [Link]

> Now, encode all that information into a type system? Not sure it can be done.

There's the option to not do that in Rust, too. The type system is quite useful most of the time, but there is a point of diminishing returns and at that point you rely on runtime checks and discipline just like in any other language.

test suite for complicated cases

Posted Jul 15, 2024 2:49 UTC (Mon) by ssokolow (guest, #94568) [Link]

...but do also keep this quote in mind:
Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence. -- Edsger W. Dijkstra, "The Humble Programmer" (1972)


Copyright © 2024, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds