Skip to content

DirectoryNotEmptyException when moving symlink with REPLACE_EXISTING set #177

Description

@JaniruTEC

Moving a symlink (on top of another symlink) causes a DirectoryNotEmptyException:

var source = fs.getPath("/source");
var target = fs.getPath("/target");
Files.createSymbolicLink(source, fs.getPath("/linkedBySource.txt"));
Files.createSymbolicLink(target, fs.getPath("/linkedByTarget.txt"));

Assertions.assertDoesNotThrow(() -> Files.move(source, target, REPLACE_EXISTING));

Stacktrace:

java.nio.file.DirectoryNotEmptyException: /vault/d/FW/62AD46Y3CLSPBJCAZTO2EQD5TDALWH/y6Yo0PGakzpfU2ZozQWLcHrgiT8=.c9s
	at com.google.common.jimfs.FileSystemView.checkEmpty(FileSystemView.java:493)
	at com.google.common.jimfs.FileSystemView.checkDeletable(FileSystemView.java:477)
	at com.google.common.jimfs.FileSystemView.delete(FileSystemView.java:449)
	at com.google.common.jimfs.FileSystemView.copy(FileSystemView.java:539)
	at com.google.common.jimfs.JimfsFileSystemProvider.copy(JimfsFileSystemProvider.java:268)
	at com.google.common.jimfs.JimfsFileSystemProvider.move(JimfsFileSystemProvider.java:273)
	at java.base/java.nio.file.Files.move(Files.java:1432)
	at org.cryptomator.cryptofs/org.cryptomator.cryptofs.CryptoFileSystemImpl.moveSymlink(CryptoFileSystemImpl.java:585)
	at org.cryptomator.cryptofs/org.cryptomator.cryptofs.CryptoFileSystemImpl.move(CryptoFileSystemImpl.java:573)
	at org.cryptomator.cryptofs/org.cryptomator.cryptofs.MoveOperation.move(MoveOperation.java:37)
	at org.cryptomator.cryptofs/org.cryptomator.cryptofs.CryptoFileSystemProvider.move(CryptoFileSystemProvider.java:255)
	at java.base/java.nio.file.Files.move(Files.java:1432)

The same happens when using a regular filesystem instead of JIMFS.

org.cryptomator.cryptofs/org.cryptomator.cryptofs.CryptoFileSystemImpl.moveSymlink(CryptoFileSystemImpl.java:585):

CiphertextFilePath ciphertextSource = cryptoPathMapper.getCiphertextFilePath(cleartextSource);
CiphertextFilePath ciphertextTarget = cryptoPathMapper.getCiphertextFilePath(cleartextTarget);
try (OpenCryptoFiles.TwoPhaseMove twoPhaseMove = openCryptoFiles.prepareMove(ciphertextSource.getRawPath(), ciphertextTarget.getRawPath())) {
	Files.move(ciphertextSource.getRawPath(), ciphertextTarget.getRawPath(), options); //585
	if (ciphertextTarget.isShortened()) {
		ciphertextTarget.persistLongFileName();
	} else {
		Files.deleteIfExists(ciphertextTarget.getInflatedNamePath()); // no longer needed if not shortened
	}
	twoPhaseMove.commit();
}

Tests showed that both ciphertextSource.getRawPath() and ciphertextTarget.getRawPath() are directories, not regular files. I assume the problem is related to this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions