Skip to content

Commit

Permalink
only block unmount, if at least one open file exists, which was writt…
Browse files Browse the repository at this point in the history
…en to.
  • Loading branch information
infeo committed Sep 25, 2023
1 parent b00dee3 commit e85b3d6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
15 changes: 14 additions & 1 deletion src/main/java/org/cryptomator/frontend/fuse/OpenFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ public class OpenFile implements Closeable {
private final Path path;
private final FileChannel channel;

private volatile boolean writeCalled;

private OpenFile(Path path, FileChannel channel) {
this.path = path;
this.channel = channel;
this.writeCalled = false;
}

static OpenFile create(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
FileChannel ch = FileChannel.open(path, options, attrs);
return new OpenFile(path, ch);
Expand Down Expand Up @@ -69,6 +72,7 @@ public int read(ByteBuffer buf, long num, long offset) throws IOException {
* @throws IOException If an exception occurs during write.
*/
public int write(ByteBuffer buf, long num, long offset) throws IOException {
writeCalled = true;
if (num > Integer.MAX_VALUE) {
throw new IOException("Requested too many bytes");
}
Expand All @@ -80,6 +84,15 @@ public int write(ByteBuffer buf, long num, long offset) throws IOException {
return written;
}

/**
* Tests, if the write method of this open file was called at least once.
*
* @return {@code true} if {@link OpenFile#write(ByteBuffer, long, long)} was called on this object, otherwise {@code false}
*/
public boolean isWrittenTo() {
return writeCalled;
}

@Override
public void close() throws IOException {
channel.close();
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/org/cryptomator/frontend/fuse/OpenFileFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,14 @@ public void close(long fileHandle) throws ClosedChannelException, IOException {
}
}

public int getOpenFileCount(){
return openFiles.size();
/**
* Tests, if there exists {@link OpenFile}s, which has been written to.
* The check performed in this method is not atomic and therefore requires external synchronization.
*
* @return {@code true} if and only if at least one {@link OpenFile} exists, where {@link OpenFile#isWrittenTo()} returns {@code true}. Otherwise {@code false}.
*/
public boolean hasWrittenToOpenFiles(){
return openFiles.entrySet().stream().anyMatch(entry -> entry.getValue().isWrittenTo());
}

/**
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/org/cryptomator/frontend/fuse/ReadOnlyAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public sealed class ReadOnlyAdapter implements FuseNioAdapter permits ReadWriteA
private final ReadOnlyDirectoryHandler dirHandler;
private final ReadOnlyFileHandler fileHandler;
private final ReadOnlyLinkHandler linkHandler;
private final BooleanSupplier hasOpenFiles;

protected ReadOnlyAdapter(Errno errno, Path root, int maxFileNameLength, FileNameTranscoder fileNameTranscoder, FileStore fileStore, OpenFileFactory openFiles, ReadOnlyDirectoryHandler dirHandler, ReadOnlyFileHandler fileHandler) {
this.errno = errno;
Expand All @@ -61,7 +60,6 @@ protected ReadOnlyAdapter(Errno errno, Path root, int maxFileNameLength, FileNam
this.dirHandler = dirHandler;
this.fileHandler = fileHandler;
this.linkHandler = new ReadOnlyLinkHandler(fileNameTranscoder);
this.hasOpenFiles = () -> openFiles.getOpenFileCount() != 0;
}

public static ReadOnlyAdapter create(Errno errno, Path root, int maxFileNameLength, FileNameTranscoder fileNameTranscoder) {
Expand Down Expand Up @@ -305,7 +303,7 @@ public void destroy() {
@Override
public boolean isInUse() {
try (PathLock pLock = lockManager.tryLockForWriting("/")) {
return hasOpenFiles.getAsBoolean();
return openFiles.hasWrittenToOpenFiles();
} catch (AlreadyLockedException e) {
return true;
}
Expand All @@ -320,7 +318,7 @@ public void close() throws IOException {
* Attempts to get a specific error code that best describes the given exception.
* As a side effect this logs the error.
*
* @param e An exception
* @param e An exception
* @param opDesc A human-friendly string describing what operation was attempted (for logging purposes)
* @return A specific error code or -EIO.
*/
Expand All @@ -331,8 +329,8 @@ protected int getErrorCodeForGenericFileSystemException(FileSystemException e, S
// LOG.warn("{} {} failed, name too long.", opDesc);
// return -ErrorCodes.ENAMETOOLONG();
// } else {
LOG.error(opDesc + " failed.", e);
return -errno.eio();
LOG.error(opDesc + " failed.", e);
return -errno.eio();
// }
}
}

0 comments on commit e85b3d6

Please sign in to comment.