From 2f7756278e3b49d6f366a73ab6fd64adb17f0564 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Wed, 24 Jan 2024 12:32:50 +0800 Subject: [PATCH] Add `mount_setattr` --- src/backend/libc/mount/syscalls.rs | 28 +++++++++++++++++++++++++ src/backend/libc/mount/types.rs | 14 ++++++++++++- src/backend/linux_raw/mount/syscalls.rs | 20 ++++++++++++++++++ src/backend/linux_raw/mount/types.rs | 14 ++++++++++++- src/mount/misc.rs | 24 +++++++++++++++++++++ src/mount/mod.rs | 2 ++ 6 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/mount/misc.rs diff --git a/src/backend/libc/mount/syscalls.rs b/src/backend/libc/mount/syscalls.rs index 724511480..cd7926b66 100644 --- a/src/backend/libc/mount/syscalls.rs +++ b/src/backend/libc/mount/syscalls.rs @@ -270,3 +270,31 @@ pub(crate) fn fsconfig_reconfigure(fs_fd: BorrowedFd<'_>) -> io::Result<()> { )) } } + +#[cfg(linux_kernel)] +#[cfg(feature = "mount")] +pub(crate) fn mount_setattr( + dir_fd: BorrowedFd<'_>, + path: &CStr, + flags: crate::fs::AtFlags, + mount_attr: &crate::mount::MountAttr<'_>, +) -> io::Result<()> { + syscall! { + fn mount_setattr( + dir_fd: c::c_int, + fs_name: *const c::c_char, + flags: c::c_uint, + mount_attr: *const crate::mount::MountAttr<'_>, + size: usize + ) via SYS_mount_setattr -> c::c_int + } + unsafe { + ret(mount_setattr( + borrowed_fd(dir_fd), + c_str(path), + flags.bits(), + mount_attr as *const _, + core::mem::size_of::>(), + )) + } +} diff --git a/src/backend/libc/mount/types.rs b/src/backend/libc/mount/types.rs index 10236866c..6bc2c40c7 100644 --- a/src/backend/libc/mount/types.rs +++ b/src/backend/libc/mount/types.rs @@ -1,4 +1,5 @@ use crate::backend::c; +use crate::fd::BorrowedFd; use bitflags::bitflags; #[cfg(linux_kernel)] @@ -150,9 +151,10 @@ pub(crate) enum FsConfigCmd { #[cfg(feature = "mount")] #[cfg(linux_kernel)] 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 { @@ -338,3 +340,13 @@ bitflags! { #[cfg(linux_kernel)] pub(crate) struct MountFlagsArg(pub(crate) c::c_ulong); + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +#[allow(missing_docs)] +pub struct MountAttr<'a> { + pub attr_set: MountAttrFlags, + pub attr_clr: MountAttrFlags, + pub propagation: MountPropagationFlags, + pub userns_fd: BorrowedFd<'a>, +} diff --git a/src/backend/linux_raw/mount/syscalls.rs b/src/backend/linux_raw/mount/syscalls.rs index 5cb80cc09..b4b7ae47c 100644 --- a/src/backend/linux_raw/mount/syscalls.rs +++ b/src/backend/linux_raw/mount/syscalls.rs @@ -237,3 +237,23 @@ pub(crate) fn fsconfig_reconfigure(fs_fd: BorrowedFd<'_>) -> io::Result<()> { )) } } + +#[cfg(feature = "mount")] +#[inline] +pub(crate) fn mount_setattr( + dir_fd: BorrowedFd<'_>, + path: &CStr, + flags: crate::fs::AtFlags, + mount_attr: &crate::mount::MountAttr<'_>, +) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_mount_setattr, + dir_fd, + path, + flags, + mount_attr as *const crate::mount::MountAttr<'_>, + crate::backend::conv::size_of::, _>() + )) + } +} diff --git a/src/backend/linux_raw/mount/types.rs b/src/backend/linux_raw/mount/types.rs index 43cb8c0d5..b26c34e07 100644 --- a/src/backend/linux_raw/mount/types.rs +++ b/src/backend/linux_raw/mount/types.rs @@ -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, + pub attr_clr: MountAttrFlags, + pub propagation: MountPropagationFlags, + pub userns_fd: BorrowedFd<'a>, +} diff --git a/src/mount/misc.rs b/src/mount/misc.rs new file mode 100644 index 000000000..26b1b5cb3 --- /dev/null +++ b/src/mount/misc.rs @@ -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)` +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/mount_setattr.2.html +#[inline] +pub fn mount_setattr( + 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) + }) +} diff --git a/src/mount/mod.rs b/src/mount/mod.rs index 9b4f6da51..ace49476f 100644 --- a/src/mount/mod.rs +++ b/src/mount/mod.rs @@ -10,10 +10,12 @@ #[cfg(feature = "mount")] mod fsopen; +mod misc; mod mount_unmount; mod types; #[cfg(feature = "mount")] pub use fsopen::*; +pub use misc::*; pub use mount_unmount::*; pub use types::*;