mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-09-05 23:57:31 +00:00
Changes to filesystem API and nio implementation
* Partial implementation of nio filesystem * Removed timeouts from openReadable and openWritable * Added convenience methods for copying * Added utility to support deadlock safe opening of multiple files
This commit is contained in:
@@ -10,8 +10,6 @@ package org.cryptomator.crypto.fs;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.cryptomator.crypto.engine.Cryptor;
|
||||
import org.cryptomator.filesystem.File;
|
||||
@@ -37,13 +35,13 @@ public class CryptoFile extends CryptoNode implements File {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadableFile openReadable(long timeout, TimeUnit unit) throws TimeoutException {
|
||||
public ReadableFile openReadable() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WritableFile openWritable(long timeout, TimeUnit unit) throws TimeoutException {
|
||||
public WritableFile openWritable() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@@ -53,4 +51,9 @@ public class CryptoFile extends CryptoNode implements File {
|
||||
return parent.toString() + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(File o) {
|
||||
return toString().compareTo(o.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,12 +8,8 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.crypto.fs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.cryptomator.crypto.engine.Cryptor;
|
||||
import org.cryptomator.filesystem.File;
|
||||
@@ -50,12 +46,13 @@ public class CryptoFileSystem extends CryptoFolder implements FileSystem {
|
||||
}
|
||||
assert masterkeyFile.exists() : "A CryptoFileSystem can not exist without a masterkey file.";
|
||||
final File backupFile = physicalRoot.file(MASTERKEY_BACKUP_FILENAME);
|
||||
backupMasterKeyFileSilently(masterkeyFile, backupFile);
|
||||
masterkeyFile.copyTo(backupFile);
|
||||
}
|
||||
|
||||
private static boolean decryptMasterKeyFile(Cryptor cryptor, File masterkeyFile, CharSequence passphrase) {
|
||||
try (ReadableFile file = masterkeyFile.openReadable(1, TimeUnit.SECONDS)) {
|
||||
// TODO we need to read the whole file but can not be sure about the buffer size:
|
||||
try (ReadableFile file = masterkeyFile.openReadable()) {
|
||||
// TODO we need to read the whole file but can not be sure about the
|
||||
// buffer size:
|
||||
final ByteBuffer bigEnoughBuffer = ByteBuffer.allocate(500);
|
||||
file.read(bigEnoughBuffer);
|
||||
bigEnoughBuffer.flip();
|
||||
@@ -63,25 +60,13 @@ public class CryptoFileSystem extends CryptoFolder implements FileSystem {
|
||||
final byte[] fileContents = new byte[bigEnoughBuffer.remaining()];
|
||||
bigEnoughBuffer.get(fileContents);
|
||||
return cryptor.readKeysFromMasterkeyFile(fileContents, passphrase);
|
||||
} catch (TimeoutException e) {
|
||||
throw new UncheckedIOException(new IOException("Failed to lock masterkey file in time. " + masterkeyFile, e));
|
||||
}
|
||||
}
|
||||
|
||||
private static void encryptMasterKeyFile(Cryptor cryptor, File masterkeyFile, CharSequence passphrase) {
|
||||
try (WritableFile file = masterkeyFile.openWritable(1, TimeUnit.SECONDS)) {
|
||||
try (WritableFile file = masterkeyFile.openWritable()) {
|
||||
final byte[] fileContents = cryptor.writeKeysToMasterkeyFile(passphrase);
|
||||
file.write(ByteBuffer.wrap(fileContents));
|
||||
} catch (TimeoutException e) {
|
||||
throw new UncheckedIOException(new IOException("Failed to lock masterkey file in time. " + masterkeyFile, e));
|
||||
}
|
||||
}
|
||||
|
||||
private static void backupMasterKeyFileSilently(File masterkeyFile, File backupFile) {
|
||||
try (ReadableFile src = masterkeyFile.openReadable(1, TimeUnit.SECONDS); WritableFile dst = backupFile.openWritable(1, TimeUnit.SECONDS)) {
|
||||
src.copyTo(dst);
|
||||
} catch (TimeoutException e) {
|
||||
LOG.warn("Failed to lock masterkey file (" + masterkeyFile + ") or backup file (" + backupFile + ") in time. Skipping backup.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,11 +100,9 @@ public class CryptoFileSystem extends CryptoFolder implements FileSystem {
|
||||
physicalDataRoot().create(mode);
|
||||
final File dirFile = physicalFile();
|
||||
final String directoryId = getDirectoryId();
|
||||
try (WritableFile writable = dirFile.openWritable(1, TimeUnit.SECONDS)) {
|
||||
try (WritableFile writable = dirFile.openWritable()) {
|
||||
final ByteBuffer buf = ByteBuffer.wrap(directoryId.getBytes());
|
||||
writable.write(buf);
|
||||
} catch (TimeoutException e) {
|
||||
throw new UncheckedIOException(new IOException("Failed to lock directory file in time. " + dirFile, e));
|
||||
}
|
||||
physicalFolder().create(FolderCreateMode.INCLUDING_PARENTS);
|
||||
}
|
||||
|
||||
@@ -9,13 +9,10 @@
|
||||
package org.cryptomator.crypto.fs;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -46,15 +43,13 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
if (directoryId.get() == null) {
|
||||
File dirFile = physicalFile();
|
||||
if (dirFile.exists()) {
|
||||
try (ReadableFile readable = dirFile.openReadable(1, TimeUnit.SECONDS)) {
|
||||
try (ReadableFile readable = dirFile.openReadable()) {
|
||||
final ByteBuffer buf = ByteBuffer.allocate(64);
|
||||
readable.read(buf);
|
||||
buf.flip();
|
||||
byte[] bytes = new byte[buf.remaining()];
|
||||
buf.get(bytes);
|
||||
directoryId.set(new String(bytes));
|
||||
} catch (TimeoutException e) {
|
||||
throw new UncheckedIOException(new IOException("Failed to lock directory file in time." + dirFile, e));
|
||||
}
|
||||
} else {
|
||||
directoryId.compareAndSet(null, UUID.randomUUID().toString());
|
||||
@@ -125,11 +120,9 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
}
|
||||
assert parent.exists();
|
||||
final String directoryId = getDirectoryId();
|
||||
try (WritableFile writable = dirFile.openWritable(1, TimeUnit.SECONDS)) {
|
||||
try (WritableFile writable = dirFile.openWritable()) {
|
||||
final ByteBuffer buf = ByteBuffer.wrap(directoryId.getBytes());
|
||||
writable.write(buf);
|
||||
} catch (TimeoutException e) {
|
||||
throw new UncheckedIOException(new IOException("Failed to lock directory file in time." + dirFile, e));
|
||||
}
|
||||
physicalFolder().create(FolderCreateMode.INCLUDING_PARENTS);
|
||||
}
|
||||
@@ -150,12 +143,11 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
|
||||
target.physicalFile().parent().get().create(FolderCreateMode.INCLUDING_PARENTS);
|
||||
assert target.physicalFile().parent().get().exists();
|
||||
try (WritableFile src = this.physicalFile().openWritable(1, TimeUnit.SECONDS); WritableFile dst = target.physicalFile().openWritable(1, TimeUnit.SECONDS)) {
|
||||
try (WritableFile src = this.physicalFile().openWritable(); WritableFile dst = target.physicalFile().openWritable()) {
|
||||
src.moveTo(dst);
|
||||
} catch (TimeoutException e) {
|
||||
throw new UncheckedIOException(new IOException("Failed to lock file for moving (src: " + this + ", dst: " + target + ")", e));
|
||||
}
|
||||
// directoryId is now used by target, we must no longer use the same id (we'll generate a new one when needed)
|
||||
// directoryId is now used by target, we must no longer use the same id
|
||||
// (we'll generate a new one when needed)
|
||||
directoryId.set(null);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user