1 //! Filesystem-oriented `ioctl` functions.
2
3 #![allow(unsafe_code)]
4
5 #[cfg(linux_kernel)]
6 use {
7 crate::fd::AsFd,
8 crate::{backend, io, ioctl},
9 backend::c,
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, 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")]
ioctl_blksszget<Fd: AsFd>(fd: Fd) -> io::Result<u32>25 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 let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::BLKSSZGET }>, c::c_uint>::new();
29 ioctl::ioctl(fd, ctl)
30 }
31 }
32
33 /// `ioctl(fd, BLKPBSZGET)`—Returns the physical block size of a block device.
34 #[cfg(linux_kernel)]
35 #[inline]
36 #[doc(alias = "BLKPBSZGET")]
ioctl_blkpbszget<Fd: AsFd>(fd: Fd) -> io::Result<u32>37 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 let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::BLKPBSZGET }>, c::c_uint>::new();
41 ioctl::ioctl(fd, ctl)
42 }
43 }
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")]
ioctl_ficlone<Fd: AsFd, SrcFd: AsFd>(fd: Fd, src_fd: SrcFd) -> io::Result<()>56 pub fn ioctl_ficlone<Fd: AsFd, SrcFd: AsFd>(fd: Fd, src_fd: SrcFd) -> io::Result<()> {
57 unsafe { ioctl::ioctl(fd, Ficlone(src_fd.as_fd())) }
58 }
59
60 /// `ioctl(fd, EXT4_IOC_RESIZE_FS, blocks)`—Resize ext4 filesystem on fd.
61 #[cfg(feature = "linux-raw-sys")]
62 #[inline]
63 #[doc(alias = "EXT4_IOC_RESIZE_FS")]
ext4_ioc_resize_fs<Fd: AsFd>(fd: Fd, blocks: u64) -> io::Result<()>64 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 let ctl = ioctl::Setter::<ioctl::BadOpcode<{ backend::fs::EXT4_IOC_RESIZE_FS }>, u64>::new(
68 blocks,
69 );
70 ioctl::ioctl(fd, ctl)
71 }
72 }
73
74 #[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
75 struct Ficlone<'a>(BorrowedFd<'a>);
76
77 #[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))]
78 unsafe impl ioctl::Ioctl for Ficlone<'_> {
79 type Output = ();
80
81 const IS_MUTATING: bool = false;
82 const OPCODE: ioctl::Opcode = ioctl::Opcode::old(c::FICLONE as ioctl::RawOpcode);
83
as_ptr(&mut self) -> *mut c::c_void84 fn as_ptr(&mut self) -> *mut c::c_void {
85 self.0.as_raw_fd() as *mut c::c_void
86 }
87
output_from_ptr( _: ioctl::IoctlOutput, _: *mut c::c_void, ) -> io::Result<Self::Output>88 unsafe fn output_from_ptr(
89 _: ioctl::IoctlOutput,
90 _: *mut c::c_void,
91 ) -> io::Result<Self::Output> {
92 Ok(())
93 }
94 }
95
96 #[cfg(feature = "linux-raw-sys")]
97 bitflags! {
98 /// `FS_*` constants for use with [`ioctl_getflags`][crate::io::ioctl::ioctl_getflags].
99 pub struct IFlags: c::c_uint {
100 /// `FS_APPEND_FL`
101 const APPEND = linux_raw_sys::general::FS_APPEND_FL;
102 /// `FS_COMPR_FL`
103 const COMPRESSED = linux_raw_sys::general::FS_COMPR_FL;
104 /// `FS_DIRSYNC_FL`
105 const DIRSYNC = linux_raw_sys::general::FS_DIRSYNC_FL;
106 /// `FS_IMMUTABLE_FL`
107 const IMMUTABLE = linux_raw_sys::general::FS_IMMUTABLE_FL;
108 /// `FS_JOURNAL_DATA_FL`
109 const JOURNALING = linux_raw_sys::general::FS_JOURNAL_DATA_FL;
110 /// `FS_NOATIME_FL`
111 const NOATIME = linux_raw_sys::general::FS_NOATIME_FL;
112 /// `FS_NOCOW_FL`
113 const NOCOW = linux_raw_sys::general::FS_NOCOW_FL;
114 /// `FS_NODUMP_FL`
115 const NODUMP = linux_raw_sys::general::FS_NODUMP_FL;
116 /// `FS_NOTAIL_FL`
117 const NOTAIL = linux_raw_sys::general::FS_NOTAIL_FL;
118 /// `FS_PROJINHERIT_FL`
119 const PROJECT_INHERIT = linux_raw_sys::general::FS_PROJINHERIT_FL;
120 /// `FS_SECRM_FL`
121 const SECURE_REMOVAL = linux_raw_sys::general::FS_SECRM_FL;
122 /// `FS_SYNC_FL`
123 const SYNC = linux_raw_sys::general::FS_SYNC_FL;
124 /// `FS_TOPDIR_FL`
125 const TOPDIR = linux_raw_sys::general::FS_TOPDIR_FL;
126 /// `FS_UNRM_FL`
127 const UNRM = linux_raw_sys::general::FS_UNRM_FL;
128 }
129 }
130
131 /// `ioctl(fd, FS_IOC_GETFLAGS)`—Returns the [inode flags] attributes
132 ///
133 /// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
134 #[cfg(feature = "linux-raw-sys")]
135 #[inline]
136 #[doc(alias = "FS_IOC_GETFLAGS")]
ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags>137 pub fn ioctl_getflags<Fd: AsFd>(fd: Fd) -> io::Result<IFlags> {
138 unsafe {
139 #[cfg(target_pointer_width = "32")]
140 let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::FS_IOC32_GETFLAGS }>, u32>::new();
141 #[cfg(target_pointer_width = "64")]
142 let ctl = ioctl::Getter::<ioctl::BadOpcode<{ c::FS_IOC_GETFLAGS }>, u32>::new();
143
144 ioctl::ioctl(fd, ctl).map(IFlags::from_bits_retain)
145 }
146 }
147
148 /// `ioctl(fd, FS_IOC_SETFLAGS)`—Modify the [inode flags] attributes
149 ///
150 /// [inode flags]: https://man7.org/linux/man-pages/man2/ioctl_iflags.2.html
151 #[cfg(feature = "linux-raw-sys")]
152 #[inline]
153 #[doc(alias = "FS_IOC_SETFLAGS")]
ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()>154 pub fn ioctl_setflags<Fd: AsFd>(fd: Fd, flags: IFlags) -> io::Result<()> {
155 unsafe {
156 #[cfg(target_pointer_width = "32")]
157 let ctl =
158 ioctl::Setter::<ioctl::BadOpcode<{ c::FS_IOC32_SETFLAGS }>, u32>::new(flags.bits());
159
160 #[cfg(target_pointer_width = "64")]
161 let ctl = ioctl::Setter::<ioctl::BadOpcode<{ c::FS_IOC_SETFLAGS }>, u32>::new(flags.bits());
162
163 ioctl::ioctl(fd, ctl)
164 }
165 }
166