pread/pwrite
This commit is contained in:
parent
b3cb194700
commit
0431584b19
3 changed files with 35 additions and 24 deletions
|
|
@ -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>> {
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue