pread/pwrite

This commit is contained in:
Igor Katson 2024-05-03 12:00:02 +01:00
parent b3cb194700
commit 0431584b19
3 changed files with 35 additions and 24 deletions

View file

@ -1,9 +1,14 @@
use std::{
fs::OpenOptions,
io::{Read, Seek, SeekFrom, Write},
path::{Path, PathBuf},
};
#[cfg(not(target_family = "unix"))]
use std::io::{Read, Seek, SeekFrom, Write};
#[cfg(target_family = "unix")]
use std::os::unix::fs::FileExt;
use anyhow::Context;
use crate::{storage::StorageFactoryExt, torrent_state::ManagedTorrentInfo};
@ -85,25 +90,31 @@ impl FilesystemStorage {
impl TorrentStorage for FilesystemStorage {
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> {
let mut g = self
.opened_files
.get(file_id)
.context("no such file")?
.file
.lock();
g.seek(SeekFrom::Start(offset))?;
Ok(g.read_exact(buf)?)
let of = self.opened_files.get(file_id).context("no such file")?;
#[cfg(target_family = "unix")]
{
Ok(of.file.read().read_exact_at(buf, offset)?)
}
#[cfg(not(target_family = "unix"))]
{
let mut g = of.file.write();
g.seek(SeekFrom::Start(offset))?;
Ok(g.read_exact(buf)?)
}
}
fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> {
let mut g = self
.opened_files
.get(file_id)
.context("no such file")?
.file
.lock();
g.seek(SeekFrom::Start(offset))?;
Ok(g.write_all(buf)?)
let of = self.opened_files.get(file_id).context("no such file")?;
#[cfg(target_family = "unix")]
{
Ok(of.file.read().write_all_at(buf, offset)?)
}
#[cfg(not(target_family = "unix"))]
{
let mut g = of.file.write();
g.seek(SeekFrom::Start(offset))?;
Ok(g.write_all(buf)?)
}
}
fn remove_file(&self, _file_id: usize, filename: &Path) -> anyhow::Result<()> {
@ -111,7 +122,7 @@ impl TorrentStorage for FilesystemStorage {
}
fn ensure_file_length(&self, file_id: usize, len: u64) -> anyhow::Result<()> {
Ok(self.opened_files[file_id].file.lock().set_len(len)?)
Ok(self.opened_files[file_id].file.write().set_len(len)?)
}
fn take(&self) -> anyhow::Result<Box<dyn TorrentStorage>> {

View file

@ -26,7 +26,7 @@ impl StorageFactory for MmapFilesystemStorageFactory {
let fs_storage = FilesystemStorageFactory::default().init_storage(meta)?;
let mut mmaps = Vec::new();
for file in fs_storage.opened_files.iter() {
let mmap = unsafe { MmapOptions::new().map_mut(&*file.file.lock()) }
let mmap = unsafe { MmapOptions::new().map_mut(&*file.file.read()) }
.context("error mapping file")?;
mmaps.push(RwLock::new(mmap));
}

View file

@ -1,11 +1,11 @@
use std::fs::File;
use anyhow::Context;
use parking_lot::Mutex;
use parking_lot::RwLock;
#[derive(Debug)]
pub(crate) struct OpenedFile {
pub file: Mutex<File>,
pub file: RwLock<File>,
}
pub(crate) fn dummy_file() -> anyhow::Result<std::fs::File> {
@ -23,12 +23,12 @@ pub(crate) fn dummy_file() -> anyhow::Result<std::fs::File> {
impl OpenedFile {
pub fn new(f: File) -> Self {
Self {
file: Mutex::new(f),
file: RwLock::new(f),
}
}
pub fn take(&self) -> anyhow::Result<File> {
let mut f = self.file.lock();
let mut f = self.file.write();
let dummy = dummy_file()?;
let f = std::mem::replace(&mut *f, dummy);
Ok(f)
@ -37,7 +37,7 @@ impl OpenedFile {
pub fn take_clone(&self) -> anyhow::Result<Self> {
let f = self.take()?;
Ok(Self {
file: Mutex::new(f),
file: RwLock::new(f),
})
}
}