Coverage Report

Created: 2025-11-24 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.2/src/fs/ioctl.rs
Line
Count
Source
1
//! Filesystem-oriented `ioctl` functions.
2
3
#![allow(unsafe_code)]
4
5
#[cfg(linux_kernel)]
6
use {
7
    crate::backend::c,
8
    crate::fd::AsFd,
9
    crate::{backend, ffi, io, ioctl},
10
};
11
12
use bitflags::bitflags;
13
14
#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
15
use crate::fd::{AsRawFd as _, BorrowedFd};
16
17
/// `ioctl(fd, BLKSSZGET)`—Returns the logical block size of a block device.
18
///
19
/// This is mentioned in the [Linux `openat` manual page].
20
///
21
/// [Linux `openat` manual page]: https://man7.org/linux/man-pages/man2/openat.2.html
22
#[cfg(linux_kernel)]
23
#[inline]
24
#[doc(alias = "BLKSSZGET")]
25
0
pub fn ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
26
    // SAFETY: `BLZSSZGET` is a getter opcode that gets a `u32`.
27
    unsafe {
28
0
        let ctl = ioctl::Getter::<{ c::BLKSSZGET }, c::c_uint>::new();
29
0
        ioctl::ioctl(fd, ctl)
30
    }
31
0
}
32
33
/// `ioctl(fd, BLKPBSZGET)`—Returns the physical block size of a block device.
34
#[cfg(linux_kernel)]
35
#[inline]
36
#[doc(alias = "BLKPBSZGET")]
37
0
pub fn ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
38
    // SAFETY: `BLKPBSZGET` is a getter opcode that gets a `u32`.
39
    unsafe {
40
0
        let ctl = ioctl::Getter::<{ c::BLKPBSZGET }, c::c_uint>::new();
41
0
        ioctl::ioctl(fd, ctl)
42
    }
43
0
}
44
45
/// `ioctl(fd, FICLONE, src_fd)`—Share data between open files.
46
///
47
/// This ioctl is not available on SPARC platforms.
48
///
49
/// # References
50
///  - [Linux]
51
///
52
/// [Linux]: https://man7.org/linux/man-pages/man2/ioctl_ficlone.2.html
53
#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
54
#[inline]
55
#[doc(alias = "FICLONE")]
56
0
pub fn ioctl_ficlone<Fd: AsFd, SrcFd: AsFd>(fd: Fd, src_fd: SrcFd) -> io::Result<()> {
57
0
    unsafe { ioctl::ioctl(fd, Ficlone(src_fd.as_fd())) }
58
0
}
59
60
/// `ioctl(fd, EXT4_IOC_RESIZE_FS, blocks)`—Resize ext4 filesystem on fd.
61
#[cfg(linux_raw_dep)]
62
#[inline]
63
#[doc(alias = "EXT4_IOC_RESIZE_FS")]
64
0
pub fn ext4_ioc_resize_fs<Fd: AsFd>(fd: Fd, blocks: u64) -> io::Result<()> {
65
    // SAFETY: `EXT4_IOC_RESIZE_FS` is a pointer setter opcode.
66
    unsafe {
67
0
        let ctl = ioctl::Setter::<{ backend::fs::EXT4_IOC_RESIZE_FS }, u64>::new(blocks);
68
0
        ioctl::ioctl(fd, ctl)
69
    }
70
0
}
71
72
#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
73
struct Ficlone<'a>(BorrowedFd<'a>);
74
75
#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
76
unsafe impl ioctl::Ioctl for Ficlone<'_> {
77
    type Output = ();
78
79
    const IS_MUTATING: bool = false;
80
81
0
    fn opcode(&self) -> ioctl::Opcode {
82
0
        c::FICLONE as ioctl::Opcode
83
0
    }
84
85
0
    fn as_ptr(&mut self) -> *mut c::c_void {
86
0
        self.0.as_raw_fd() as *mut c::c_void
87
0
    }
88
89
0
    unsafe fn output_from_ptr(
90
0
        _: ioctl::IoctlOutput,
91
0
        _: *mut c::c_void,
92
0
    ) -> io::Result<Self::Output> {
93
0
        Ok(())
94
0
    }
95
}
96
97
#[cfg(linux_raw_dep)]
98
bitflags! {
99
    /// `FS_*` constants for use with [`ioctl_getflags`].
100
    ///
101
    /// [`ioctl_getflags`]: crate::fs::ioctl::ioctl_getflags
102
    #[repr(transparent)]
103
    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
104
    pub struct IFlags: ffi::c_uint {
105
        /// `FS_APPEND_FL`
106
        const APPEND = linux_raw_sys::general::FS_APPEND_FL;
107
        /// `FS_COMPR_FL`
108
        const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL;
109
        /// `FS_DIRSYNC_FL`
110
        const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL;
111
        /// `FS_IMMUTABLE_FL`
112
        const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL;
113
        /// `FS_JOURNAL_DATA_FL`
114
        const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL;
115
        /// `FS_NOATIME_FL`
116
        const NOATIME = linux_raw_sys::general::FS_NOATIME_FL;
117
        /// `FS_NOCOW_FL`
118
        const NOCOW = linux_raw_sys::general::FS_NOCOW_FL;
119
        /// `FS_NODUMP_FL`
120
        const NODUMP = linux_raw_sys::general::FS_NODUMP_FL;
121
        /// `FS_NOTAIL_FL`
122
        const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL;
123
        /// `FS_PROJINHERIT_FL`
124
        const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL;
125
        /// `FS_SECRM_FL`
126
        const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL;
127
        /// `FS_SYNC_FL`
128
        const SYNC = linux_raw_sys::general::FS_SYNC_FL;
129
        /// `FS_TOPDIR_FL`
130
        const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL;
131
        /// `FS_UNRM_FL`
132
        const UNRM = linux_raw_sys::general::FS_UNRM_FL;
133
    }
134
}
135
136
/// `ioctl(fd, FS_IOC_GETFLAGS)`—Returns the [inode flags] attributes
137
///
138
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
139
#[cfg(linux_raw_dep)]
140
#[inline]
141
#[doc(alias = "FS_IOC_GETFLAGS")]
142
0
pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> {
143
    unsafe {
144
        #[cfg(target_pointer_width = "32")]
145
        let ctl = ioctl::Getter::<{ c::FS_IOC32_GETFLAGS }, u32>::new();
146
        #[cfg(target_pointer_width = "64")]
147
0
        let ctl = ioctl::Getter::<{ c::FS_IOC_GETFLAGS }, u32>::new();
148
149
0
        ioctl::ioctl(fd, ctl).map(IFlags::from_bits_retain)
150
    }
151
0
}
152
153
/// `ioctl(fd, FS_IOC_SETFLAGS)`—Modify the [inode flags] attributes
154
///
155
/// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
156
#[cfg(linux_raw_dep)]
157
#[inline]
158
#[doc(alias = "FS_IOC_SETFLAGS")]
159
0
pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()> {
160
    unsafe {
161
        #[cfg(target_pointer_width = "32")]
162
        let ctl = ioctl::Setter::<{ c::FS_IOC32_SETFLAGS }, u32>::new(flags.bits());
163
164
        #[cfg(target_pointer_width = "64")]
165
0
        let ctl = ioctl::Setter::<{ c::FS_IOC_SETFLAGS }, u32>::new(flags.bits());
166
167
0
        ioctl::ioctl(fd, ctl)
168
    }
169
0
}