@@ 1,13 1,16 @@
package org.safcephfs;
+import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.CancellationSignal;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
+import android.os.storage.StorageManager;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract.Document;
@@ 17,7 20,7 @@ import android.webkit.MimeTypeMap;
import android.widget.Toast;
import android.util.Log;
-import java.io.IOException;
+import java.io.FileNotFoundException;
import java.util.Vector;
import com.ceph.fs.CephMount;
@@ 25,6 28,8 @@ import com.ceph.fs.CephStat;
public class CephFSDocumentsProvider extends DocumentsProvider {
private String id, mon, path, key;
+ private StorageManager sm;
+ private Handler ioHandler;
private ToastThread lthread;
private static final String[] DEFAULT_ROOT_PROJECTION = new String[]{
@@ 57,19 62,66 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
@Override
public boolean onCreate() {
+ sm = (StorageManager) getContext()
+ .getSystemService(Context.STORAGE_SERVICE);
lthread = new ToastThread(getContext());
lthread.start();
+ HandlerThread ioThread = new HandlerThread("IO thread");
+ ioThread.start();
+ ioHandler = new Handler(ioThread.getLooper());
return true;
}
public ParcelFileDescriptor openDocument(String documentId,
- String mode,CancellationSignal cancellationSignal) {
- throw new UnsupportedOperationException("TODO");
+ String mode,CancellationSignal cancellationSignal)
+ throws UnsupportedOperationException,
+ FileNotFoundException {
+ Log.v("CephFS","open " + documentId);
+ int flag, fdmode;
+ switch (mode) {
+ case "r":
+ flag = CephMount.O_RDONLY;
+ fdmode = ParcelFileDescriptor.MODE_READ_ONLY;
+ break;
+ case "rw":
+ flag = CephMount.O_RDWR;
+ fdmode = ParcelFileDescriptor.MODE_READ_WRITE;
+ break;
+ case "w":
+ flag = CephMount.O_WRONLY;
+ fdmode = ParcelFileDescriptor.MODE_WRITE_ONLY;
+ break;
+ default:
+ throw new UnsupportedOperationException("Mode " + mode + " not implemented");
+ }
+ String filename = documentId.substring(documentId.indexOf("/") + 1);
+ CephMount cm = new CephMount(id);
+ cm.conf_set("mon_host", mon);
+ cm.conf_set("key", key);
+ cm.mount(path);
+ int fd;
+ try {
+ fd = cm.open(filename, flag, 0);
+ } catch (FileNotFoundException e) {
+ Log.e("CephFS","open " + documentId + " not found");
+ throw e;
+ }
+ try {
+ return sm.openProxyFileDescriptor(fdmode,
+ new CephFSProxyFileDescriptorCallback(cm, fd),
+ ioHandler);
+ } catch (Exception e) {
+ Log.e("CephFS","open " + documentId + " " + e.toString());
+ Message msg = lthread.handler.obtainMessage();
+ msg.obj = e.toString();
+ lthread.handler.sendMessage(msg);
+ return null;
+ }
}
public Cursor queryChildDocuments(String parentDocumentId,
- String[] projection,String sortOrder) {
- MatrixCursor result=new MatrixCursor(projection != null ? projection : DEFAULT_DOC_PROJECTION);
+ String[] projection, String sortOrder) {
+ MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOC_PROJECTION);
Log.v("CephFS","qcf " + parentDocumentId);
String filename = parentDocumentId.substring(parentDocumentId.indexOf("/") + 1);
CephMount cm = new CephMount(id);
@@ 135,8 187,8 @@ public class CephFSDocumentsProvider extends DocumentsProvider {
}
public Cursor queryRoots(String[] projection) {
- MatrixCursor result=new MatrixCursor(projection != null ? projection : DEFAULT_ROOT_PROJECTION);
- SharedPreferences settings=PreferenceManager
+ MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_ROOT_PROJECTION);
+ SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(getContext());
mon = settings.getString("mon", "");
key = settings.getString("key", "");
@@ 0,0 1,47 @@
+package org.safcephfs;
+
+import android.os.ProxyFileDescriptorCallback;
+import android.system.ErrnoException;
+
+import com.ceph.fs.CephMount;
+import com.ceph.fs.CephStat;
+
+public class CephFSProxyFileDescriptorCallback extends ProxyFileDescriptorCallback {
+ private CephMount cm;
+ private int fd;
+
+ public CephFSProxyFileDescriptorCallback(CephMount cm, int fd) {
+ this.cm = cm;
+ this.fd = fd;
+ }
+
+ @Override
+ public void onFsync() throws ErrnoException {
+ cm.fsync(fd, false);
+ }
+
+ @Override
+ public long onGetSize() throws ErrnoException {
+ CephStat cs = new CephStat();
+ cm.fstat(fd, cs);
+ return cs.size;
+ }
+
+ @Override
+ public int onRead(long offset, int size, byte[] data)
+ throws ErrnoException {
+ return (int) cm.read(fd, data, size, offset);
+ }
+
+ @Override
+ public void onRelease() {
+ cm.close(fd);
+ cm.unmount();
+ }
+
+ @Override
+ public int onWrite(long offset, int size, byte[] data)
+ throws ErrnoException {
+ return (int) cm.write(fd, data, size, offset);
+ }
+}