-
Notifications
You must be signed in to change notification settings - Fork 4
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
fs: Two fixes for set_file_contents #55
fs: Two fixes for set_file_contents #55
Conversation
This definitely falls under my oft-repeated "move fast and make broken things" mantra 😅. In fairness, I put a |
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 agree that cap-std
would bring some wins around API usage like this, but it's also probably way more than what we need...
The main thing that needs to be fixed is the fd
variable name and the weird use of .map()
. Maybe also the DRYification, if you like.
src/fs.rs
Outdated
write(&fd, data)?; | ||
fdatasync(&fd)?; | ||
) | ||
.map(std::fs::File::from)?; |
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.
Any reason to not just leave the ?
on the openat()
operation and do let file = File::from(fd);
after? I find that a lot more readable than having to know what .map()
on an Option<>
means.
The variable name here is wrong now. This isn't an fd
anymore.
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.
Also: this is a bit DRY-unfriendly with respect to the block above. I wonder if we should have some kind of a util::write_to_fd()
helper that does this pattern of taking an fd
, creating a File
from it, .write_all()
to it, then calling sync. I know this is only strengthening your argument for cap-std
... :)
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.
Another aside: I've been wondering if we should stop calling fdatasync()
so much. I've noticed that this is making things really slow. I added cache=unsafe
to our VM runs to help a bit, but it's clearly a problem. We probably need to think about this more systematically...
In particular, do we really need to do this with fsverity files? It probably makes sense there to let fsverity do its job, no?
This particular aside isn't actionable for this PR. This code here is used for bootloader resources, so it's probably more valuable here...
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.
Any reason to not just leave the ? on the openat() operation and do let file = File::from(fd); after?
I think that's a style thing that can go either way, will change it in the next push.
I find that a lot more readable than having to know what .map() on an Option<> means.
This however: map
on an Option is a very fundamental Rust thing I think (and it's not a complex API either). You will see nontrivial "combinator" usage out there (and to be fair it's easy to sometimes go too far on combinators) but this isn't at all unusual usage I think.
A basic example is:
let f = File::open("/etc/foo")?;
let f = BufReader::new(f);
vs
let f = File::open("/etc/foo").map(BufReader::new)?;
I use the latter a lot because I think it is just shorter and more readable.
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's like 5 separate things in this one thread so not marking resolved but I changed the map
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.
Thanks. The others were more like drive-bys for discussion points not directly related to anything here...
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.
This however:
map
on an Option is a very fundamental Rust thing I think (and it's not a complex API either). You will see nontrivial "combinator" usage out there (and to be fair it's easy to sometimes go too far on combinators) but this isn't at all unusual usage I think.
Ya. I think this is maybe another case of me not being hip to the jive or whatever the kids these days are doing. I know that I really dislike seeing these.massive.chains().of().linked().operators()...
...
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.
Ya. I think this is maybe another case of me not being hip to the jive or whatever the kids these days are doing. I know that I really dislike seeing these.massive.chains().of().linked().operators()......
There are IMO some things that are super elegant as combinators that are straightforward but verbose in explicit loop form, for example the map()
+ .sum()
as used here:
I was just skimming this code and noticed we were incorrectly using `write`. I'd like to reopen that conversation about using cap-std and especially cap-std-ext, which would have fixed several of these bugs with our nice high level helper API like https://docs.rs/cap-std-ext/latest/cap_std_ext/dirext/trait.CapStdExtDirExt.html#tymethod.atomic_replace_with Anyways for now I just fixed the implementation here. - Add a doc comment - Add O_CLOEXEC - Use `write_all` instead of a single `write` (!) - Add a test (Also a different bug, this function takes a `Stat` but ignores everything except st_mode, but we can fix that later) Signed-off-by: Colin Walters <[email protected]>
dc06d92
to
55367de
Compare
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.
Thanks for the changes!
I was just skimming this code and noticed
we were incorrectly using
write
.I'd like to reopen that conversation about using
cap-std and especially cap-std-ext, which
would have fixed several of these bugs
with our nice high level helper API like
https://docs.rs/cap-std-ext/latest/cap_std_ext/dirext/trait.CapStdExtDirExt.html#tymethod.atomic_replace_with
Anyways for now I just fixed the implementation here.
write_all
instead of a singlewrite
(!)(Also a different bug, this function takes a
Stat
butignores everything except st_mode, but we can fix that later)