fxcp_core/consistency/
exchange.rs1use std::path::Path;
7use std::fs::File;
8use std::os::unix::io::AsRawFd;
9use std::io;
10use libc;
11
12const XFS_IOC_EXCHANGE_RANGE: u64 = 0xC0385828;
13const XFS_EXCHANGE_RANGE_TO_EOF: u64 = 1 << 0;
14
15#[repr(C)]
16struct xfs_exchange_range {
17 file1_fd: i32,
18 pad: i32,
19 file1_offset: u64,
20 file2_offset: u64,
21 length: u64,
22 flags: u64,
23 pad2: [u64; 2],
24}
25
26pub fn atomic_exchange(temp: &Path, target: &Path) -> io::Result<()> {
29 let temp_file = File::open(temp)?;
30 let target_file = File::open(target)?;
31
32 let args = xfs_exchange_range {
33 file1_fd: temp_file.as_raw_fd(),
34 pad: 0,
35 file1_offset: 0,
36 file2_offset: 0,
37 length: 0, flags: XFS_EXCHANGE_RANGE_TO_EOF,
39 pad2: [0; 2],
40 };
41
42 let ret = unsafe {
46 libc::ioctl(target_file.as_raw_fd(), XFS_IOC_EXCHANGE_RANGE, &args)
47 };
48
49 if ret == 0 {
50 Ok(())
51 } else {
52 Err(io::Error::last_os_error())
53 }
54}