Skip to content

Commit

Permalink
Add synchronization for closing blobs to keep them in stable state in…
Browse files Browse the repository at this point in the history
… case of future disk faults (#85)

* Add sync of blob on closing and either add sync for indices during transition to another state

* Fix 'Bad descriptor' issue
  • Loading branch information
Justarone authored Mar 24, 2021
1 parent ce89014 commit 1f63b6e
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/blob/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl Blob {
}

pub(crate) async fn dump(&mut self) -> Result<usize> {
self.file.fsyncdata().await?;
self.index
.dump()
.await
Expand Down
7 changes: 3 additions & 4 deletions src/blob/file.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{io::Write, os::unix::prelude::FileExt};
use std::os::unix::prelude::FileExt;

use super::prelude::*;

Expand Down Expand Up @@ -166,11 +166,10 @@ impl File {

pub(crate) async fn fsyncdata(&self) -> IOResult<()> {
if let Some(ref ioring) = self.ioring {
let compl = ioring.fdatasync(&*self.no_lock_fd);
let compl = ioring.fsync(&*self.no_lock_fd);
compl.await
} else {
let file = self.no_lock_fd.clone();
Self::blocking_call(move || file.as_ref().flush()).await
self.write_fd.read().await.sync_all().await
}
}

Expand Down
1 change: 1 addition & 0 deletions src/blob/index/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ impl Simple {
.with_context(|| format!("file open failed {:?}", self.name.to_path()))?;
let size = file.write_append(&buf).await?;
self.apply_written_byte(&file).await?;
file.fsyncdata().await?;
self.inner = State::OnDisk(file);
self.mem = None;
Ok(size)
Expand Down
11 changes: 3 additions & 8 deletions src/storage/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,14 +727,9 @@ impl Safe {
Ok(Box::pin(async move {
let mut blobs = blobs.write().await;
blobs.push(*old_active);
// FIXME: seems, like in case of disk error indices won't dump on disk and we won't
// know about it (the state will be okay, they will be InMemory, but there won't be any
// further task to dump them)
// Possible solution: in case of disk issues during the next write in new active blob
// we will receive error AND after solving it in some time we can start another job
// (seems like we should add one more method to public API for that)
// which will start dump tasks for all blobs from old_blobs array (or for the last one;
// seems that it's either okay; in case of OnDisk state dump works very fast)
// Notice: if dump of blob or indices fails, it's likely a problem with disk appeared, so
// all descriptors of the storage become invalid and unusable
// Possible solution: recreate instance of storage, when disk will be available
if let Err(e) = blobs.last_mut().unwrap().dump().await {
error!("Error dumping blob: {}", e);
}
Expand Down

0 comments on commit 1f63b6e

Please sign in to comment.