mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
fix(fuse): a folder whose mkdir is queued is listed from the database (B125)
This commit is contained in:
1 parent
f9b1638603
commit
e743cd60cf
5 files changed
+72
-6
No files matched your search
@@ -2521,6 +2521,17 @@ impl Core {
|
||||
Ok(None) => {}
|
||||
Err(e) => warn!(%folder_uid, error = %e, "db children_if_listed failed"),
|
||||
}
|
||||
// Drive knows nothing by a stand-in. Until its mkdir lands the folder
|
||||
// is only here, and once it has, the DB holds what Drive does. A
|
||||
// listing dropped meanwhile was asked of Drive, and every lookup in
|
||||
// the folder failed with EIO (`docs/BUGS.md` B125).
|
||||
if is_local_uid(&folder_uid) {
|
||||
let nodes = self.db.known_children(&folder_uid).map_err(|e| {
|
||||
warn!(%folder_uid, error = %e, "db known_children failed");
|
||||
Errno::EIO
|
||||
})?;
|
||||
return self.adopt_db_listing(ino, &folder_uid, nodes, primary_root);
|
||||
}
|
||||
if !self.is_online() {
|
||||
return self.adopt_stale_listing(ino, &folder_uid, cached, primary_root);
|
||||
}
|
||||
|
||||
@@ -278,6 +278,7 @@ pub(crate) fn wait_until(limit: Duration, mut done: impl FnMut() -> bool) -> boo
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::sim::fake_drive::{Entry, FakeDrive, Faults};
|
||||
use pdfs_core::control::RefreshScope;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
@@ -644,6 +645,49 @@ mod tests {
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "mounts FUSE: run with `cargo test -p pdfs-fuse sim:: -- --ignored`"]
|
||||
fn a_folder_whose_mkdir_is_queued_lists_after_a_refresh() {
|
||||
// Once its listing was dropped, the folder was asked of Drive by its
|
||||
// stand-in, and every listing and lookup in it failed with EIO until
|
||||
// its mkdir landed (B125).
|
||||
let drive = FakeDrive::new();
|
||||
let dir = scratch("queued-folder-refresh");
|
||||
let daemon = Daemon::start(&dir, drive.client(1, Faults::lan())).unwrap();
|
||||
let mnt = daemon.mountpoint.clone();
|
||||
let paused = |paused| Request::SetSyncPaused {
|
||||
paused,
|
||||
until: None,
|
||||
};
|
||||
daemon.request(&paused(true)).unwrap();
|
||||
std::fs::create_dir(mnt.join("d")).unwrap();
|
||||
std::fs::write(mnt.join("d/f.txt"), b"queued").unwrap();
|
||||
let path = mnt.join("d").to_string_lossy().into_owned();
|
||||
let refresh = Request::Refresh {
|
||||
scope: RefreshScope::Dir { path: path.clone() },
|
||||
};
|
||||
assert!(matches!(daemon.request(&refresh), Ok(Response::Ok { .. })));
|
||||
let Ok(Response::Entries { entries }) = daemon.request(&Request::ListDir { path }) else {
|
||||
panic!("the daemon did not list d");
|
||||
};
|
||||
let names: Vec<_> = entries.iter().map(|entry| entry.name.as_str()).collect();
|
||||
assert_eq!(names, ["f.txt"]);
|
||||
assert_eq!(std::fs::read(mnt.join("d/f.txt")).unwrap(), b"queued");
|
||||
daemon.request(&paused(false)).unwrap();
|
||||
assert!(
|
||||
wait_until(Duration::from_secs(30), || {
|
||||
daemon.pending().is_ok_and(|items| items.is_empty())
|
||||
&& drive.tree().get("d/f.txt")
|
||||
== Some(&Entry::File(Arc::new(b"queued".to_vec())))
|
||||
}),
|
||||
"{:?} {:?}",
|
||||
daemon.pending(),
|
||||
drive.tree()
|
||||
);
|
||||
assert!(matches!(daemon.stop(), Ok(MountOutcome::Shutdown)));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "mounts FUSE: run with `cargo test -p pdfs-fuse sim:: -- --ignored`"]
|
||||
fn a_file_moved_while_its_create_was_on_the_wire_keeps_its_new_name() {
|
||||
|
||||
Reference in new issue
Block a user