From 4cf0ced950e3381f996dc36ea9505561ed7f0049 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Tue, 23 Jun 2020 12:09:49 +0200 Subject: [PATCH] add LocalDynamicReadAt mostly copied from BufferedDynamicReadAt from proxmox-backup-client but the reader is wrapped in an Arc in addition to the Mutex we will use this for local access to a pxar behind a didx file Signed-off-by: Dominik Csapak --- src/backup/dynamic_index.rs | 42 +++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/backup/dynamic_index.rs b/src/backup/dynamic_index.rs index 9dcf3fc2..4cf52c20 100644 --- a/src/backup/dynamic_index.rs +++ b/src/backup/dynamic_index.rs @@ -1,9 +1,11 @@ use std::fs::File; -use std::io::{BufWriter, Seek, SeekFrom, Write}; +use std::io::{self, BufWriter, Seek, SeekFrom, Write}; use std::ops::Range; use std::os::unix::io::AsRawFd; use std::path::{Path, PathBuf}; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use std::pin::Pin; use anyhow::{bail, format_err, Error}; @@ -395,6 +397,42 @@ impl std::io::Seek for BufferedDynamicReader { } } +/// This is a workaround until we have cleaned up the chunk/reader/... infrastructure for better +/// async use! +/// +/// Ideally BufferedDynamicReader gets replaced so the LruCache maps to `BroadcastFuture`, +/// so that we can properly access it from multiple threads simultaneously while not issuing +/// duplicate simultaneous reads over http. +#[derive(Clone)] +pub struct LocalDynamicReadAt { + inner: Arc>>, +} + +impl LocalDynamicReadAt { + pub fn new(inner: BufferedDynamicReader) -> Self { + Self { + inner: Arc::new(Mutex::new(inner)), + } + } +} + +impl pxar::accessor::ReadAt for LocalDynamicReadAt { + fn poll_read_at( + self: Pin<&Self>, + _cx: &mut Context, + buf: &mut [u8], + offset: u64, + ) -> Poll> { + use std::io::Read; + tokio::task::block_in_place(move || { + let mut reader = self.inner.lock().unwrap(); + reader.seek(SeekFrom::Start(offset))?; + Poll::Ready(Ok(reader.read(buf)?)) + }) + } +} + + /// Create dynamic index files (`.dixd`) pub struct DynamicIndexWriter { store: Arc,