5
0
mirror of git://git.proxmox.com/git/pxar.git synced 2024-12-21 17:33:52 +03:00

don't hold temp buffer mutex across await point

the type system guarantees that this can only be accessed by
a single mutable instance, but it's still a bad idea

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2022-07-28 14:36:46 +02:00
parent a50514a920
commit ddc08ebb8b

View File

@ -382,6 +382,31 @@ impl<'a, T: SeqWrite + 'a> EncoderImpl<'a, T> {
})
}
fn take_file_copy_buffer(&self) -> Vec<u8> {
let buf: Vec<_> = take(
&mut self
.file_copy_buffer
.lock()
.expect("failed to lock temporary buffer mutex"),
);
if buf.len() < 1024 * 1024 {
drop(buf);
unsafe { crate::util::vec_new_uninitialized(1024 * 1024) }
} else {
buf
}
}
fn put_file_copy_buffer(&self, buf: Vec<u8>) {
let mut lock = self
.file_copy_buffer
.lock()
.expect("failed to lock temporary buffer mutex");
if lock.len() < buf.len() {
*lock = buf;
}
}
/// Return a file offset usable with `add_hardlink`.
pub async fn add_file(
&mut self,
@ -390,9 +415,8 @@ impl<'a, T: SeqWrite + 'a> EncoderImpl<'a, T> {
file_size: u64,
content: &mut dyn SeqRead,
) -> io::Result<LinkOffset> {
let buf = Arc::clone(&self.file_copy_buffer);
let mut buf = self.take_file_copy_buffer();
let mut file = self.create_file(metadata, file_name, file_size).await?;
let mut buf = buf.lock().expect("failed to lock temporary buffer mutex");
loop {
let got = decoder::seq_read(&mut *content, &mut buf[..]).await?;
if got == 0 {
@ -401,7 +425,10 @@ impl<'a, T: SeqWrite + 'a> EncoderImpl<'a, T> {
file.write_all(&buf[..got]).await?;
}
}
Ok(file.file_offset())
let offset = file.file_offset();
drop(file);
self.put_file_copy_buffer(buf);
Ok(offset)
}
/// Return a file offset usable with `add_hardlink`.