@@ 28,6 28,7 @@ import android.util.Log;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Vector;
@@ 114,72 115,7 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
lthread.handler.sendMessage(msg);
}
- // Wrapper to make IOException from JNI catchable
- private interface CephOperation<T> {
- T execute() throws IOException;
- }
-
- private void throwOrAddErrorExtra(String error, Cursor cursor) {
- if (cursor != null) {
- Bundle extra = new Bundle();
- extra.putString(DocumentsContract.EXTRA_ERROR, error);
- cursor.setExtras(extra);
- } else {
- toast(error);
- throw new IllegalStateException(error);
- }
- }
-
- private <T> T doCephOperation(CephOperation<T> op) {
- return doCephOperation(op, null);
- }
-
- private <T> T doCephOperation(CephOperation<T> op, Cursor cursor) {
- if (cm == null) {
- try {
- cm = setupCeph();
- } catch (IOException e) {
- throwOrAddErrorExtra("Unable to mount root: " + e.getMessage(),
- cursor);
- return null;
- }
- }
- int r = retries;
- while (r-- != 0) {
- try {
- return op.execute();
- } catch (IOException e) {
- if (e.getMessage().equals("Cannot send after transport endpoint shutdown")) {
- if (r != 0) {
- Log.e(APP_NAME, "Mount died, " + r + "attempts remaining, retrying");
- cm.unmount();
- try {
- new CephOperation<Void>() {
- @Override
- public Void execute() throws IOException {
- cm.mount(path);
- return null;
- }
- }.execute();
- } catch (IOException e2) {
- toast("Unable to remount root: " + e2);
- }
- } else {
- throwOrAddErrorExtra("Operation failed: " +
- e.getMessage(), cursor);
- return null;
- }
- } else {
- throwOrAddErrorExtra("Operation failed: " + e.getMessage(),
- cursor);
- return null;
- }
- }
- }
- return null;
- }
-
- private CephMount setupCeph() throws IOException {
+ private CephFSOperations.Operation<CephMount> setupMount = () -> {
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(getContext());
mon = settings.getString("mon", "");
@@ 199,6 135,24 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
}
newMount.mount(path); // IOException if fails
return newMount;
+ };
+
+ // TODO refactor to a executor, and port to CephFSProxyFileDescriptorCallback
+ private <T> CephFSOperations.Operation<T> withLazyRetriedMount(
+ CephFSOperations.Operation<T> op) {
+ return () -> {
+ if (cm == null) {
+ cm = setupMount.execute();
+ }
+ return CephFSOperations.retryOnESHUTDOWN(
+ () -> {
+ cm.unmount();
+ Log.e(APP_NAME, "Mount died, retrying");
+ cm = setupMount.execute();
+ return null;
+ },
+ op).execute();
+ };
}
@Override
@@ 221,21 175,16 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
String filename = parentDocumentId.substring(parentDocumentId.indexOf("/") + 1)
+ "/" + displayName;
if (mimeType.equals(Document.MIME_TYPE_DIR)) {
- doCephOperation(() -> {
+ CephFSOperations.translateToUnchecked(withLazyRetriedMount(() -> {
cm.mkdir(filename, 0700);
return null;
- });
+ }));
} else {
- doCephOperation(() -> {
- try {
- int fd = cm.open(filename, CephMount.O_WRONLY | CephMount.O_CREAT | CephMount.O_EXCL, 0700);
- cm.close(fd);
- return null;
- } catch (FileNotFoundException e) {
- Log.e(APP_NAME, "Create " + filename + " not found");
- throw new FileNotFoundException(parentDocumentId + " not found");
- }
- });
+ CephFSOperations.translateToUnchecked(withLazyRetriedMount(() -> {
+ int fd = cm.open(filename, CephMount.O_WRONLY | CephMount.O_CREAT | CephMount.O_EXCL, 0700);
+ cm.close(fd);
+ return null;
+ }));
}
return parentDocumentId + "/" + displayName;
}
@@ 267,21 216,17 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
default:
throw new UnsupportedOperationException("Mode " + mode + " not implemented");
}
+
String filename = documentId.substring(documentId.indexOf("/") + 1);
- int fd = doCephOperation(() -> {
- try {
- return cm.open(filename, flag, 0);
- } catch (FileNotFoundException e) {
- Log.e(APP_NAME, "Open " + documentId + " not found");
- throw new FileNotFoundException(documentId + "not found");
- }
- });
+ int fd = CephFSOperations.translateToUnchecked(withLazyRetriedMount(() -> {
+ return cm.open(filename, flag, 0);
+ }));
+
try {
- return sm.openProxyFileDescriptor(fdmode,
- new CephFSProxyFileDescriptorCallback(cm, fd),
- ioHandler);
+ return sm.openProxyFileDescriptor(
+ fdmode, new CephFSProxyFileDescriptorCallback(cm, fd), ioHandler);
} catch (IOException e) {
- throw new IllegalStateException("openProxyFileDescriptor: " + e.toString());
+ throw new UncheckedIOException(e);
}
}
@@ 290,7 235,7 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
- throw new IllegalStateException();
+ throw new IllegalStateException(e);
}
md5.update(("./" + name).getBytes());
byte[] digest = md5.digest();
@@ 315,16 260,16 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
private void lstatBuildDocumentRow(String dir, String displayName,
String documentId, String[] thumbnails, MatrixCursor result)
throws FileNotFoundException {
+ // TODO consider EXTRA_ERROR?
CephStat cs = new CephStat();
- doCephOperation(() -> {
+ CephFSOperations.translateToUnchecked(withLazyRetriedMount(() -> {
try {
cm.lstat(dir + displayName, cs);
return null;
- } catch (FileNotFoundException|CephNotDirectoryException e) {
- Log.e(APP_NAME, "lstat: " + dir + displayName + " not found");
- throw new FileNotFoundException(documentId + " not found");
+ } catch (CephNotDirectoryException e) {
+ throw new FileNotFoundException(e.getMessage());
}
- });
+ }));
MatrixCursor.RowBuilder row = result.newRow();
row.add(Document.COLUMN_DOCUMENT_ID, documentId);
row.add(Document.COLUMN_DISPLAY_NAME, displayName);
@@ 332,15 277,15 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
row.add(Document.COLUMN_LAST_MODIFIED, cs.m_time);
if (cs.isSymlink()) {
- doCephOperation(() -> {
+ CephFSOperations.translateToUnchecked(withLazyRetriedMount(() -> {
try {
cm.stat(dir + displayName, cs);
return null;
} catch (FileNotFoundException|CephNotDirectoryException e) {
- Log.e(APP_NAME, "stat: " + dir + displayName + " not found");
+ Log.e(APP_NAME, "stat: " + dir + displayName + " not found", e);
return null;
}
- });
+ }));
}
String mimeType = getMime(cs.mode, displayName);
row.add(Document.COLUMN_MIME_TYPE, mimeType);
@@ 375,14 320,14 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
}
} else {
String thubmailPath = dir + ".sh_thumbnails/normal/" + getXDGThumbnailFile(displayName);
- thumbnailFound = doCephOperation(() -> {
+ thumbnailFound = CephFSOperations.translateToUnchecked(withLazyRetriedMount(() -> {
try {
cm.stat(thubmailPath, cs);
return true;
} catch (FileNotFoundException|CephNotDirectoryException e) {
return false;
}
- });
+ }));
}
if (thumbnailFound) {
@@ 398,24 343,25 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOC_PROJECTION);
Log.v(APP_NAME, "queryChildDocuments " + parentDocumentId);
String filename = parentDocumentId.substring(parentDocumentId.indexOf("/") + 1);
- String[] res = doCephOperation(() -> {
- try {
- return cm.listdir(filename);
- } catch (FileNotFoundException e) {
- Log.e(APP_NAME, "queryChildDocuments " + parentDocumentId + " not found");
- throw new FileNotFoundException(parentDocumentId + " not found");
- }
- }, result);
+ String[] res = CephFSOperations.translateToCursorExtra(withLazyRetriedMount(() -> {
+ return cm.listdir(filename);
+ }), result);
if (res == null) {
return result;
}
- String[] thumbnails = doCephOperation(() -> {
+
+ // TODO make this not fatal instead?
+ String[] thumbnails = CephFSOperations.translateToCursorExtra(withLazyRetriedMount(() -> {
try {
return cm.listdir(filename + "/.sh_thumbnails/normal");
} catch (FileNotFoundException e) {
return new String[0];
}
- }, result);
+ }), result);
+ if (res == null) {
+ return result;
+ }
+
for (String entry : res) {
lstatBuildDocumentRow(filename + "/", entry,
parentDocumentId + "/" + entry, thumbnails, result);
@@ 476,14 422,10 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
cm = null;
}
CephStatVFS csvfs = new CephStatVFS();
- doCephOperation(() -> {
- try {
- cm.statfs("/", csvfs);
- return null;
- } catch (FileNotFoundException e) {
- throw new FileNotFoundException("/ not found");
- }
- });
+ CephFSOperations.translateToUnchecked(withLazyRetriedMount(() -> {
+ cm.statfs("/", csvfs);
+ return null;
+ }));
MatrixCursor.RowBuilder row = result.newRow();
row.add(Root.COLUMN_ROOT_ID, id + "@" + mon + ":" + path);
row.add(Root.COLUMN_DOCUMENT_ID, "root/");
@@ 0,0 1,151 @@
+package org.safcephfs;
+
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+
+public class CephFSOperations {
+ protected interface Operation<T> {
+ T execute() throws IOException;
+ }
+
+ /*
+ * libcephfs_jni throws IOException with message from strerror()
+ * Bionic strerror:
+ * https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/private/bionic_errdefs.h
+ * sed 's|__BIONIC_ERRDEF(\([^,]*\), \([^)]*\).*|case \2 -> OsConstants.\1;|'
+ * and delete where there are no matching OsConstants
+ */
+ private static int cephIOEToOsConstants(IOException e) {
+ return switch (e.getMessage()) {
+ case "Operation not permitted" -> OsConstants.EPERM;
+ case "No such file or directory" -> OsConstants.ENOENT;
+ case "No such process" -> OsConstants.ESRCH;
+ case "Interrupted system call" -> OsConstants.EINTR;
+ case "I/O error" -> OsConstants.EIO;
+ case "No such device or address" -> OsConstants.ENXIO;
+ case "Argument list too long" -> OsConstants.E2BIG;
+ case "Exec format error" -> OsConstants.ENOEXEC;
+ case "Bad file descriptor" -> OsConstants.EBADF;
+ case "No child processes" -> OsConstants.ECHILD;
+ case "Try again" -> OsConstants.EAGAIN;
+ case "Out of memory" -> OsConstants.ENOMEM;
+ case "Permission denied" -> OsConstants.EACCES;
+ case "Bad address" -> OsConstants.EFAULT;
+ case "Device or resource busy" -> OsConstants.EBUSY;
+ case "File exists" -> OsConstants.EEXIST;
+ case "Cross-device link" -> OsConstants.EXDEV;
+ case "No such device" -> OsConstants.ENODEV;
+ case "Not a directory" -> OsConstants.ENOTDIR;
+ case "Is a directory" -> OsConstants.EISDIR;
+ case "Invalid argument" -> OsConstants.EINVAL;
+ case "File table overflow" -> OsConstants.ENFILE;
+ case "Too many open files" -> OsConstants.EMFILE;
+ case "Inappropriate ioctl for device" -> OsConstants.ENOTTY;
+ case "Text file busy" -> OsConstants.ETXTBSY;
+ case "File too large" -> OsConstants.EFBIG;
+ case "No space left on device" -> OsConstants.ENOSPC;
+ case "Illegal seek" -> OsConstants.ESPIPE;
+ case "Read-only file system" -> OsConstants.EROFS;
+ case "Too many links" -> OsConstants.EMLINK;
+ case "Broken pipe" -> OsConstants.EPIPE;
+ case "Math argument out of domain of func" -> OsConstants.EDOM;
+ case "Math result not representable" -> OsConstants.ERANGE;
+ case "Resource deadlock would occur" -> OsConstants.EDEADLK;
+ case "File name too long" -> OsConstants.ENAMETOOLONG;
+ case "No record locks available" -> OsConstants.ENOLCK;
+ case "Function not implemented" -> OsConstants.ENOSYS;
+ case "Directory not empty" -> OsConstants.ENOTEMPTY;
+ case "Too many symbolic links encountered" -> OsConstants.ELOOP;
+ case "No message of desired type" -> OsConstants.ENOMSG;
+ case "Identifier removed" -> OsConstants.EIDRM;
+ case "Device not a stream" -> OsConstants.ENOSTR;
+ case "No data available" -> OsConstants.ENODATA;
+ case "Timer expired" -> OsConstants.ETIME;
+ case "Out of streams resources" -> OsConstants.ENOSR;
+ case "Machine is not on the network" -> OsConstants.ENONET;
+ case "Link has been severed" -> OsConstants.ENOLINK;
+ case "Protocol error" -> OsConstants.EPROTO;
+ case "Multihop attempted" -> OsConstants.EMULTIHOP;
+ case "Not a data message" -> OsConstants.EBADMSG;
+ case "Value too large for defined data type" -> OsConstants.EOVERFLOW;
+ case "Illegal byte sequence" -> OsConstants.EILSEQ;
+ case "Socket operation on non-socket" -> OsConstants.ENOTSOCK;
+ case "Destination address required" -> OsConstants.EDESTADDRREQ;
+ case "Message too long" -> OsConstants.EMSGSIZE;
+ case "Protocol wrong type for socket" -> OsConstants.EPROTOTYPE;
+ case "Protocol not available" -> OsConstants.ENOPROTOOPT;
+ case "Protocol not supported" -> OsConstants.EPROTONOSUPPORT;
+ case "Operation not supported on transport endpoint" -> OsConstants.EOPNOTSUPP;
+ case "Address family not supported by protocol" -> OsConstants.EAFNOSUPPORT;
+ case "Address already in use" -> OsConstants.EADDRINUSE;
+ case "Cannot assign requested address" -> OsConstants.EADDRNOTAVAIL;
+ case "Network is down" -> OsConstants.ENETDOWN;
+ case "Network is unreachable" -> OsConstants.ENETUNREACH;
+ case "Network dropped connection because of reset" -> OsConstants.ENETRESET;
+ case "Software caused connection abort" -> OsConstants.ECONNABORTED;
+ case "Connection reset by peer" -> OsConstants.ECONNRESET;
+ case "No buffer space available" -> OsConstants.ENOBUFS;
+ case "Transport endpoint is already connected" -> OsConstants.EISCONN;
+ case "Transport endpoint is not connected" -> OsConstants.ENOTCONN;
+ case "Connection timed out" -> OsConstants.ETIMEDOUT;
+ case "Connection refused" -> OsConstants.ECONNREFUSED;
+ case "No route to host" -> OsConstants.EHOSTUNREACH;
+ case "Operation already in progress" -> OsConstants.EALREADY;
+ case "Operation now in progress" -> OsConstants.EINPROGRESS;
+ case "Stale NFS file handle" -> OsConstants.ESTALE;
+ case "Quota exceeded" -> OsConstants.EDQUOT;
+ case "Operation Canceled" -> OsConstants.ECANCELED;
+ default -> OsConstants.EIO;
+ };
+ }
+
+ protected static <T> T translateToErrnoException(
+ String functionName, Operation<T> op) throws ErrnoException {
+ try {
+ return op.execute();
+ } catch (IOException e) {
+ throw new ErrnoException(functionName, cephIOEToOsConstants(e));
+ }
+ }
+
+ protected static <T> T translateToCursorExtra(Operation<T> op, Cursor c) {
+ try {
+ return op.execute();
+ } catch (IOException e) {
+ var extra = new Bundle();
+ extra.putString(DocumentsContract.EXTRA_ERROR, e.getMessage());
+ c.setExtras(extra);
+ return null;
+ }
+ }
+
+ protected static <T> T translateToUnchecked(Operation<T> op) {
+ try {
+ return op.execute();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ protected static <T> Operation<T> retryOnESHUTDOWN(
+ Operation<Object> setup, Operation<T> op) {
+ return () -> {
+ try {
+ return op.execute();
+ } catch (IOException e) {
+ if (e.getMessage().equals("Cannot send after transport endpoint shutdown")) {
+ setup.execute();
+ return op.execute();
+ } else {
+ throw e;
+ }
+ }
+ };
+ }
+}
@@ 13,188 13,6 @@ public class CephFSProxyFileDescriptorCallback extends ProxyFileDescriptorCallba
private CephMount cm;
private int fd;
- /*
- * libcephfs_jni throws IOException with message from strerror()
- * Bionic strerror:
- * https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/bionic/strerror.cpp
- * lazy solution: copy error strings line,
- * `sed -E 's/ \[([A-Z0-9]+)\] = ([^,]+),/\t\tcase \2:\n\t\t\treturn OsConstants.\1;/'`,
- * and delete where there are no matching OsConstants
- */
- private static int cephIOEToOsConstants(IOException e) {
- switch (e.getMessage()) {
- case "Operation not permitted":
- return OsConstants.EPERM;
- case "No such file or directory":
- return OsConstants.ENOENT;
- case "No such process":
- return OsConstants.ESRCH;
- case "Interrupted system call":
- return OsConstants.EINTR;
- case "I/O error":
- return OsConstants.EIO;
- case "No such device or address":
- return OsConstants.ENXIO;
- case "Argument list too long":
- return OsConstants.E2BIG;
- case "Exec format error":
- return OsConstants.ENOEXEC;
- case "Bad file descriptor":
- return OsConstants.EBADF;
- case "No child processes":
- return OsConstants.ECHILD;
- case "Try again":
- return OsConstants.EAGAIN;
- case "Out of memory":
- return OsConstants.ENOMEM;
- case "Permission denied":
- return OsConstants.EACCES;
- case "Bad address":
- return OsConstants.EFAULT;
- case "Device or resource busy":
- return OsConstants.EBUSY;
- case "File exists":
- return OsConstants.EEXIST;
- case "Cross-device link":
- return OsConstants.EXDEV;
- case "No such device":
- return OsConstants.ENODEV;
- case "Not a directory":
- return OsConstants.ENOTDIR;
- case "Is a directory":
- return OsConstants.EISDIR;
- case "Invalid argument":
- return OsConstants.EINVAL;
- case "File table overflow":
- return OsConstants.ENFILE;
- case "Too many open files":
- return OsConstants.EMFILE;
- case "Inappropriate ioctl for device":
- return OsConstants.ENOTTY;
- case "Text file busy":
- return OsConstants.ETXTBSY;
- case "File too large":
- return OsConstants.EFBIG;
- case "No space left on device":
- return OsConstants.ENOSPC;
- case "Illegal seek":
- return OsConstants.ESPIPE;
- case "Read-only file system":
- return OsConstants.EROFS;
- case "Too many links":
- return OsConstants.EMLINK;
- case "Broken pipe":
- return OsConstants.EPIPE;
- case "Math argument out of domain of func":
- return OsConstants.EDOM;
- case "Math result not representable":
- return OsConstants.ERANGE;
- case "Resource deadlock would occur":
- return OsConstants.EDEADLK;
- case "File name too long":
- return OsConstants.ENAMETOOLONG;
- case "No record locks available":
- return OsConstants.ENOLCK;
- case "Function not implemented":
- return OsConstants.ENOSYS;
- case "Directory not empty":
- return OsConstants.ENOTEMPTY;
- case "Too many symbolic links encountered":
- return OsConstants.ELOOP;
- case "No message of desired type":
- return OsConstants.ENOMSG;
- case "Identifier removed":
- return OsConstants.EIDRM;
- case "Device not a stream":
- return OsConstants.ENOSTR;
- case "No data available":
- return OsConstants.ENODATA;
- case "Timer expired":
- return OsConstants.ETIME;
- case "Out of streams resources":
- return OsConstants.ENOSR;
- case "Link has been severed":
- return OsConstants.ENOLINK;
- case "Protocol error":
- return OsConstants.EPROTO;
- case "Multihop attempted":
- return OsConstants.EMULTIHOP;
- case "Not a data message":
- return OsConstants.EBADMSG;
- case "Value too large for defined data type":
- return OsConstants.EOVERFLOW;
- case "Illegal byte sequence":
- return OsConstants.EILSEQ;
- case "Socket operation on non-socket":
- return OsConstants.ENOTSOCK;
- case "Destination address required":
- return OsConstants.EDESTADDRREQ;
- case "Message too long":
- return OsConstants.EMSGSIZE;
- case "Protocol wrong type for socket":
- return OsConstants.EPROTOTYPE;
- case "Protocol not available":
- return OsConstants.ENOPROTOOPT;
- case "Protocol not supported":
- return OsConstants.EPROTONOSUPPORT;
- case "Operation not supported on transport endpoint":
- return OsConstants.EOPNOTSUPP;
- case "Address family not supported by protocol":
- return OsConstants.EAFNOSUPPORT;
- case "Address already in use":
- return OsConstants.EADDRINUSE;
- case "Cannot assign requested address":
- return OsConstants.EADDRNOTAVAIL;
- case "Network is down":
- return OsConstants.ENETDOWN;
- case "Network is unreachable":
- return OsConstants.ENETUNREACH;
- case "Network dropped connection because of reset":
- return OsConstants.ENETRESET;
- case "Software caused connection abort":
- return OsConstants.ECONNABORTED;
- case "Connection reset by peer":
- return OsConstants.ECONNRESET;
- case "No buffer space available":
- return OsConstants.ENOBUFS;
- case "Transport endpoint is already connected":
- return OsConstants.EISCONN;
- case "Transport endpoint is not connected":
- return OsConstants.ENOTCONN;
- case "Connection timed out":
- return OsConstants.ETIMEDOUT;
- case "Connection refused":
- return OsConstants.ECONNREFUSED;
- case "No route to host":
- return OsConstants.EHOSTUNREACH;
- case "Operation already in progress":
- return OsConstants.EALREADY;
- case "Operation now in progress":
- return OsConstants.EINPROGRESS;
- case "Stale NFS file handle":
- return OsConstants.ESTALE;
- case "Quota exceeded":
- return OsConstants.EDQUOT;
- case "Operation Canceled":
- return OsConstants.ECANCELED;
- default:
- return OsConstants.EIO;
- }
- }
-
- private interface CephFDOperation<T> {
- T execute() throws IOException;
- }
-
- private <T> T doCephFDOperation(String funcName, CephFDOperation<T> op)
- throws ErrnoException {
- try {
- return op.execute();
- } catch (IOException e) {
- throw new ErrnoException(funcName, cephIOEToOsConstants(e));
- }
- }
-
public CephFSProxyFileDescriptorCallback(CephMount cm, int fd) {
this.cm = cm;
this.fd = fd;
@@ 202,7 20,7 @@ public class CephFSProxyFileDescriptorCallback extends ProxyFileDescriptorCallba
@Override
public void onFsync() throws ErrnoException {
- doCephFDOperation("fsync", () -> {
+ CephFSOperations.translateToErrnoException("fsync", () -> {
cm.fsync(fd, false);
return null;
});
@@ 211,7 29,7 @@ public class CephFSProxyFileDescriptorCallback extends ProxyFileDescriptorCallba
@Override
public long onGetSize() throws ErrnoException {
CephStat cs = new CephStat();
- doCephFDOperation("fstat", () -> {
+ CephFSOperations.translateToErrnoException("fstat", () -> {
cm.fstat(fd, cs);
return null;
});
@@ 221,7 39,7 @@ public class CephFSProxyFileDescriptorCallback extends ProxyFileDescriptorCallba
@Override
public int onRead(long offset, int size, byte[] data)
throws ErrnoException {
- return doCephFDOperation("read", () -> {
+ return CephFSOperations.translateToErrnoException("read", () -> {
return cm.read(fd, data, size, offset);
}).intValue();
}
@@ 234,7 52,7 @@ public class CephFSProxyFileDescriptorCallback extends ProxyFileDescriptorCallba
@Override
public int onWrite(long offset, int size, byte[] data)
throws ErrnoException {
- return doCephFDOperation("write", () -> {
+ return CephFSOperations.translateToErrnoException("write", () -> {
return cm.write(fd, data, size, offset);
}).intValue();
}