diff --git a/core/io/io_uring.rs b/core/io/io_uring.rs index 14a6bd83c..4f6001cdf 100644 --- a/core/io/io_uring.rs +++ b/core/io/io_uring.rs @@ -1,13 +1,11 @@ use super::{common, Completion, File, OpenFlags, IO}; use crate::{LimboError, Result}; +use libc::{c_short, fcntl, flock, iovec, F_SETLK}; use log::{debug, trace}; -use rustix::fs::{self, FlockOperation, OFlags}; -use rustix::io_uring::iovec; +use nix::fcntl::{FcntlArg, OFlag}; use std::cell::RefCell; use std::collections::HashMap; use std::fmt; -use std::io::ErrorKind; -use std::os::fd::AsFd; use std::os::unix::io::AsRawFd; use std::rc::Rc; use thiserror::Error; @@ -138,12 +136,12 @@ impl IO for UringIO { .open(path)?; // Let's attempt to enable direct I/O. Not all filesystems support it // so ignore any errors. - let fd = file.as_fd(); + let fd = file.as_raw_fd(); if direct { - match fs::fcntl_setfl(fd, OFlags::DIRECT) { - Ok(_) => {} + match nix::fcntl::fcntl(fd, FcntlArg::F_SETFL(OFlag::O_DIRECT)) { + Ok(_) => {}, Err(error) => debug!("Error {error:?} returned when setting O_DIRECT flag to read file. The performance of the system may be affected"), - } + }; } let uring_file = Rc::new(UringFile { io: self.inner.clone(), @@ -201,39 +199,52 @@ pub struct UringFile { impl File for UringFile { fn lock_file(&self, exclusive: bool) -> Result<()> { - let fd = self.file.as_fd(); + let fd = self.file.as_raw_fd(); + let flock = flock { + l_type: if exclusive { + libc::F_WRLCK as c_short + } else { + libc::F_RDLCK as c_short + }, + l_whence: libc::SEEK_SET as c_short, + l_start: 0, + l_len: 0, // Lock entire file + l_pid: 0, + }; + // F_SETLK is a non-blocking lock. The lock will be released when the file is closed // or the process exits or after an explicit unlock. - fs::fcntl_lock( - fd, - if exclusive { - FlockOperation::LockExclusive + let lock_result = unsafe { fcntl(fd, F_SETLK, &flock) }; + if lock_result == -1 { + let err = std::io::Error::last_os_error(); + if err.kind() == std::io::ErrorKind::WouldBlock { + return Err(LimboError::LockingError( + "File is locked by another process".into(), + )); } else { - FlockOperation::LockShared - }, - ) - .map_err(|e| { - let io_error = std::io::Error::from(e); - let message = match io_error.kind() { - ErrorKind::WouldBlock => { - "Failed locking file. File is locked by another process".to_string() - } - _ => format!("Failed locking file, {}", io_error), - }; - LimboError::LockingError(message) - })?; - + return Err(LimboError::IOError(err)); + } + } Ok(()) } fn unlock_file(&self) -> Result<()> { - let fd = self.file.as_fd(); - fs::fcntl_lock(fd, FlockOperation::Unlock).map_err(|e| { - LimboError::LockingError(format!( + let fd = self.file.as_raw_fd(); + let flock = flock { + l_type: libc::F_UNLCK as c_short, + l_whence: libc::SEEK_SET as c_short, + l_start: 0, + l_len: 0, + l_pid: 0, + }; + + let unlock_result = unsafe { fcntl(fd, F_SETLK, &flock) }; + if unlock_result == -1 { + return Err(LimboError::LockingError(format!( "Failed to release file lock: {}", - std::io::Error::from(e) - )) - })?; + std::io::Error::last_os_error() + ))); + } Ok(()) } @@ -250,7 +261,7 @@ impl File for UringFile { let len = buf.len(); let buf = buf.as_mut_ptr(); let iovec = io.get_iovec(buf, len); - io_uring::opcode::Readv::new(fd, iovec as *const iovec as *const libc::iovec, 1) + io_uring::opcode::Readv::new(fd, iovec, 1) .offset(pos as u64) .build() .user_data(io.ring.get_key()) @@ -271,7 +282,7 @@ impl File for UringFile { let buf = buffer.borrow(); trace!("pwrite(pos = {}, length = {})", pos, buf.len()); let iovec = io.get_iovec(buf.as_ptr(), buf.len()); - io_uring::opcode::Writev::new(fd, iovec as *const iovec as *const libc::iovec, 1) + io_uring::opcode::Writev::new(fd, iovec, 1) .offset(pos as u64) .build() .user_data(io.ring.get_key())