mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 08:56:59 +01:00
fix(fuse,core): renames across folders, replaced files, and writes after a create
Found by the seeded simulation runs (docs/BUGS.md). - B122: a rename across folders goes to Drive as one move-multiple request, so a sibling holding the new name in the old folder no longer fails it with EIO. The drain uses the same request. - B123: a second write open on a file just written no longer fails with EIO. An empty file counts as complete, our own renames, moves and online creates record their echo, a duplicated event is skipped, a rename keeps the file's mtime while its revision stays, and a landed upload is cached before open handles are rebased onto it. - B124: a node put back after a failed replacing rename leaves `hidden` and its folder is listed again, so it shows in the mount. - B131: a landed create is read back with the same short retry as an online create, and its bytes are cached under the real uid before an open handle is repointed at it. - B135: an online rename settles the tree through the state guard, so the database has both folders unlisted before the reply. A lookup right after it no longer rebuilds the destination without the file. The simulation runs no longer tolerate B122 or B131.
This commit is contained in:
1 parent
1c262eb601
commit
cd90c566cd
10 files changed
+679
-190
No files matched your search
@@ -365,6 +365,14 @@ pub struct StagedWrite {
|
||||
pub based_on: Option<Baseline>,
|
||||
}
|
||||
|
||||
impl StagedWrite {
|
||||
/// Whether `authored` ranges cover a file of `len` bytes, so the staged
|
||||
/// bytes are its complete new content. An empty file has nothing to cover.
|
||||
pub fn covers(authored: &[(u64, u64)], len: u64) -> bool {
|
||||
len == 0 || authored == [(0, len)]
|
||||
}
|
||||
}
|
||||
|
||||
/// The identity of a remote revision, as far as we can observe it.
|
||||
///
|
||||
/// `revision_id` is the authoritative identity when present: the server assigns a
|
||||
@@ -2056,6 +2064,17 @@ mod tests {
|
||||
NodeUid::new(VolumeId::from("vol"), LinkId::from(link))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_empty_write_covers_the_file_and_a_gap_does_not() {
|
||||
assert!(
|
||||
StagedWrite::covers(&[], 0),
|
||||
"an empty file has nothing to cover"
|
||||
);
|
||||
assert!(StagedWrite::covers(&[(0, 7)], 7));
|
||||
assert!(!StagedWrite::covers(&[(0, 3), (4, 7)], 7));
|
||||
assert!(!StagedWrite::covers(&[], 7));
|
||||
}
|
||||
|
||||
/// A unique temp directory removed on drop; avoids a dev-dependency.
|
||||
struct TempDir(PathBuf);
|
||||
impl TempDir {
|
||||
|
||||
Reference in new issue
Block a user