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::{ use std::{
fs::OpenOptions, fs::OpenOptions,
io::{Read, Seek, SeekFrom, Write},
path::{Path, PathBuf}, 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 anyhow::Context;
use crate::{storage::StorageFactoryExt, torrent_state::ManagedTorrentInfo}; use crate::{storage::StorageFactoryExt, torrent_state::ManagedTorrentInfo};
@ -85,25 +90,31 @@ impl FilesystemStorage {
impl TorrentStorage for FilesystemStorage { impl TorrentStorage for FilesystemStorage {
fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> { fn pread_exact(&self, file_id: usize, offset: u64, buf: &mut [u8]) -> anyhow::Result<()> {
let mut g = self let of = self.opened_files.get(file_id).context("no such file")?;
.opened_files #[cfg(target_family = "unix")]
.get(file_id) {
.context("no such file")? Ok(of.file.read().read_exact_at(buf, offset)?)
.file }
.lock(); #[cfg(not(target_family = "unix"))]
g.seek(SeekFrom::Start(offset))?; {
Ok(g.read_exact(buf)?) 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<()> { fn pwrite_all(&self, file_id: usize, offset: u64, buf: &[u8]) -> anyhow::Result<()> {
let mut g = self let of = self.opened_files.get(file_id).context("no such file")?;
.opened_files #[cfg(target_family = "unix")]
.get(file_id) {
.context("no such file")? Ok(of.file.read().write_all_at(buf, offset)?)
.file }
.lock(); #[cfg(not(target_family = "unix"))]
g.seek(SeekFrom::Start(offset))?; {
Ok(g.write_all(buf)?) 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<()> { 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<()> { 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>> { 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 fs_storage = FilesystemStorageFactory::default().init_storage(meta)?;
let mut mmaps = Vec::new(); let mut mmaps = Vec::new();
for file in fs_storage.opened_files.iter() { 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")?; .context("error mapping file")?;
mmaps.push(RwLock::new(mmap)); mmaps.push(RwLock::new(mmap));
} }

View file

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