-
Notifications
You must be signed in to change notification settings - Fork 191
Add mount_setattr
#1002
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
base: main
Are you sure you want to change the base?
Add mount_setattr
#1002
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
use crate::backend::c; | ||
use crate::fd::BorrowedFd; | ||
use bitflags::bitflags; | ||
|
||
bitflags! { | ||
|
@@ -147,9 +148,10 @@ pub(crate) enum FsConfigCmd { | |
|
||
#[cfg(feature = "mount")] | ||
bitflags! { | ||
/// `MOUNT_ATTR_*` constants for use with [`fsmount`]. | ||
/// `MOUNT_ATTR_*` constants for use with [`fsmount`, `mount_setattr`]. | ||
/// | ||
/// [`fsmount`]: crate::mount::fsmount | ||
/// [`mount_setattr`]: crate::mount::mount_setattr | ||
#[repr(transparent)] | ||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] | ||
pub struct MountAttrFlags: c::c_uint { | ||
|
@@ -330,3 +332,13 @@ bitflags! { | |
|
||
#[repr(transparent)] | ||
pub(crate) struct MountFlagsArg(pub(crate) c::c_uint); | ||
|
||
#[repr(C)] | ||
#[derive(Debug, Copy, Clone)] | ||
#[allow(missing_docs)] | ||
pub struct MountAttr<'a> { | ||
pub attr_set: MountAttrFlags, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to Linux's documentation, |
||
pub attr_clr: MountAttrFlags, | ||
pub propagation: MountPropagationFlags, | ||
pub userns_fd: BorrowedFd<'a>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
#[repr(C)]
pub(crate) struct mount_attr {
pub attr_set: u64,
pub attr_clr: u64,
pub propagation: u64,
pub userns_fd: u64,
} Also, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that the way The usage would be something like this: mount_setattr(
dir_fd,
c"",
MountSetattrFlags::RECURSIVE | MountSetattrFlags::EMPTY_PATH,
MountAttr::new().set_flags(MountAttrFlags::RDONLY),
)?; @sunfishcode Do you want to take the same approach from I can implement the changes if needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is In general, I'm in favor of encapsulating these fields like this, provided we can do so without restricting useful functionality. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It seems that it does not support setting values to
Maybe something like this: pub struct MountAttr {
mount_attr: sys::mount_attr,
userns_fd: Option<OwnedFd>,
}
impl MountAttr {
pub fn set_userns_fd(&mut self, userns_fd: OwnedFd) -> &mut Self {
self.mount_attr.userns_fd = userns_fd.as_raw_fd() as u64;
self.userns_fd = Some(userns_fd);
self
}
// ... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to me like the current We could even imagine specialized cases similar to what is done for other mount APIs (like how the mount syscall is exposed also as mount_remount, or there are many typesafe fsconfig variants). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Well this would mean rustix needs a semver bump or a new function if the kernel adds a new field.
There is one difference, the mount functions you listed have an multiplexed interface that got demultiplexed by rustix. Summarizing my thought, we should first decided whether we want extensibility in the future (w/o breaking) or not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see it as a matter of pragmatism: this would be an easy way to resolve this issue in the short term... Should the API ever change, then there would be a lot of options at that point, including adding a complex API that takes a struct... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
An advantage of using a struct is that it is easier to omit default fields with dedicated builder functions. For example, with the draft in #1002 (comment), an ID-mapped mount could be created with: use MountSetAttrFlags as Flags;
mount_setattr(
dir_fd,
c"",
Flags::RECURSIVE | Flags::EMPTY_PATH,
MountAttr::new_with_idmap(userns),
)?; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
So we are not dealing with a single syscall but also with the design future syscalls in rustix might follow. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//! Miscellaneous mount APIs | ||
|
||
use crate::backend::mount::types::MountAttr; | ||
use crate::fd::BorrowedFd; | ||
use crate::fs::AtFlags; | ||
use crate::{backend, io, path}; | ||
|
||
/// `mount_setattr(dir_fd, path, flags, mount_attr)` | ||
sunfishcode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// # References | ||
/// - [Linux] | ||
/// | ||
/// [Linux]: https://man7.org/linux/man-pages/man2/mount_setattr.2.html | ||
#[inline] | ||
pub fn mount_setattr<Path: path::Arg>( | ||
dir_fd: BorrowedFd<'_>, | ||
path: Path, | ||
flags: AtFlags, | ||
mount_attr: &MountAttr<'_>, | ||
) -> io::Result<()> { | ||
path.into_with_c_str(|path| { | ||
backend::mount::syscalls::mount_setattr(dir_fd, path, flags, mount_attr) | ||
}) | ||
} |
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 struct should be non_exhaustive.