Skip to content

Commit e6a2644

Browse files
Fixed directory moving (severe dir id caching issues), corrected vault version number
1 parent bdd9633 commit e6a2644

File tree

4 files changed

+32
-13
lines changed

4 files changed

+32
-13
lines changed

src/main/java/org/cryptomator/cryptofs/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class Constants {
1616
public static final String METADATA_DIR_NAME = "m";
1717
public static final String DIR_PREFIX = "0";
1818
public static final int NAME_SHORTENING_THRESHOLD = 129;
19-
public static final int VAULT_VERSION = 4;
19+
public static final int VAULT_VERSION = 5;
2020

2121
public static final String SEPARATOR = "/";
2222

src/main/java/org/cryptomator/cryptofs/CryptoFileSystem.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ void createDirectory(CryptoPath cleartextDir, FileAttribute<?>... attrs) throws
322322
} finally {
323323
if (!success) {
324324
Files.delete(ciphertextDirFile);
325-
dirIdProvider.invalidate(ciphertextDirFile);
325+
dirIdProvider.delete(ciphertextDirFile);
326326
}
327327
}
328328
}
@@ -350,7 +350,7 @@ void delete(CryptoPath cleartextPath) throws IOException {
350350
// should not happen. Nevertheless this is a valid state, so who no big deal...
351351
LOG.warn("Successfully deleted dir {}, but didn't find corresponding dir file {}", ciphertextDir, ciphertextDirFile);
352352
}
353-
dirIdProvider.invalidate(ciphertextDirFile);
353+
dirIdProvider.delete(ciphertextDirFile);
354354
} catch (NoSuchFileException e) {
355355
// translate ciphertext path to cleartext path
356356
throw new NoSuchFileException(cleartextPath.toString());
@@ -458,11 +458,10 @@ void move(CryptoPath cleartextSource, CryptoPath cleartextTarget, CopyOption...
458458
}
459459
}
460460
Files.delete(ciphertextTargetDir);
461-
dirIdProvider.invalidate(ciphertextTargetDirFile);
462461
}
463462
Files.move(ciphertextSourceDirFile, ciphertextTargetDirFile, options);
464463
}
465-
dirIdProvider.invalidate(ciphertextSourceDirFile);
464+
dirIdProvider.move(ciphertextSourceDirFile, ciphertextTargetDirFile);
466465
} else {
467466
throw new NoSuchFileException(cleartextSource.toString());
468467
}

src/main/java/org/cryptomator/cryptofs/DirectoryIdProvider.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,29 @@ public String load(Path dirFilePath) throws IOException {
5454
}
5555
}
5656

57-
public void invalidate(Path dirFilePath) {
57+
/**
58+
* Removes the id currently associated with <code>dirFilePath</code> from cache. Useful during folder delete operations.
59+
* This method has no effect if the content of the given dirFile is not currently cached.
60+
*
61+
* @param dirFilePath The dirFile for which the cache should be deleted.
62+
*/
63+
public void delete(Path dirFilePath) {
5864
ids.invalidate(dirFilePath);
5965
}
6066

67+
/**
68+
* Transfers ownership from the id currently associated with <code>srcDirFilePath</code> to <code>dstDirFilePath</code>. Usefule during folder move operations.
69+
* This method has no effect if the content of the source dirFile is not currently cached.
70+
*
71+
* @param srcDirFilePath The dirFile that contained the cached id until now.
72+
* @param dstDirFilePath The dirFile that will contain the id from now on.
73+
*/
74+
public void move(Path srcDirFilePath, Path dstDirFilePath) {
75+
String id = ids.getIfPresent(srcDirFilePath);
76+
if (id != null) {
77+
ids.put(dstDirFilePath, id);
78+
ids.invalidate(srcDirFilePath);
79+
}
80+
}
81+
6182
}

src/test/java/org/cryptomator/cryptofs/CryptoFileSystemTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public void testDeleteExistingDirectory() throws IOException {
241241
inTest.delete(cleartextPath);
242242
verify(physicalFsProv).delete(ciphertextDirPath);
243243
verify(physicalFsProv).deleteIfExists(ciphertextDirFilePath);
244-
verify(dirIdProvider).invalidate(ciphertextDirFilePath);
244+
verify(dirIdProvider).delete(ciphertextDirFilePath);
245245
}
246246

247247
@Test
@@ -332,7 +332,7 @@ public void moveDirectoryDontReplaceExisting() throws IOException {
332332
CopyOption option2 = mock(CopyOption.class);
333333
inTest.move(cleartextSource, cleartextTarget, option1, option2);
334334
verify(physicalFsProv).move(ciphertextSourceDirFile, ciphertextTargetDirFile, option1, option2);
335-
verify(dirIdProvider).invalidate(ciphertextSourceDirFile);
335+
verify(dirIdProvider).move(ciphertextSourceDirFile, ciphertextTargetDirFile);
336336
}
337337

338338
@Test
@@ -348,8 +348,7 @@ public void moveDirectoryReplaceExisting() throws IOException {
348348
inTest.move(cleartextSource, cleartextTarget, StandardCopyOption.REPLACE_EXISTING);
349349
verify(physicalFsProv).delete(ciphertextTargetDir);
350350
verify(physicalFsProv).move(ciphertextSourceDirFile, ciphertextTargetDirFile, StandardCopyOption.REPLACE_EXISTING);
351-
verify(dirIdProvider).invalidate(ciphertextSourceDirFile);
352-
verify(dirIdProvider).invalidate(ciphertextTargetDirFile);
351+
verify(dirIdProvider).move(ciphertextSourceDirFile, ciphertextTargetDirFile);
353352
}
354353

355354
@Test
@@ -444,7 +443,7 @@ public void copyDirectory() throws IOException {
444443
inTest.copy(cleartextSource, cleartextTarget);
445444
verify(ciphertextTargetDirFileChannel).write(any(ByteBuffer.class));
446445
verify(physicalFsProv).createDirectory(ciphertextTargetDir);
447-
verify(dirIdProvider, Mockito.never()).invalidate(Mockito.any());
446+
verify(dirIdProvider, Mockito.never()).delete(Mockito.any());
448447
}
449448

450449
@Test
@@ -461,7 +460,7 @@ public void copyDirectoryReplaceExisting() throws IOException {
461460
inTest.copy(cleartextSource, cleartextTarget, StandardCopyOption.REPLACE_EXISTING);
462461
verify(ciphertextTargetDirFileChannel, Mockito.never()).write(any(ByteBuffer.class));
463462
verify(physicalFsProv, Mockito.never()).createDirectory(Mockito.any());
464-
verify(dirIdProvider, Mockito.never()).invalidate(Mockito.any());
463+
verify(dirIdProvider, Mockito.never()).delete(Mockito.any());
465464
}
466465

467466
@Test
@@ -562,7 +561,7 @@ public void moveDirectoryReplaceExistingNonEmpty() throws IOException {
562561
} finally {
563562
verify(ciphertextTargetDirFileChannel, Mockito.never()).write(any(ByteBuffer.class));
564563
verify(physicalFsProv, Mockito.never()).createDirectory(Mockito.any());
565-
verify(dirIdProvider, Mockito.never()).invalidate(Mockito.any());
564+
verify(dirIdProvider, Mockito.never()).delete(Mockito.any());
566565
}
567566
}
568567

0 commit comments

Comments
 (0)