summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Benjamin <matt@linuxbox.com>2013-05-23 19:32:15 -0700
committerSage Weil <sage@inktank.com>2013-09-04 17:53:03 -0700
commit8750bc39e2430f862afcd2594ce00647b0300fa6 (patch)
tree955c51061362211f043112147d9e9c9e388d04ff
parentc5351d9d03203fa72e434d2a640af07def27db75 (diff)
downloadceph-8750bc39e2430f862afcd2594ce00647b0300fa6.tar.gz
libcephfs: expose new client ll_ interface
This patch exposes all changes made for interfacing with Ganesha and layout support and David Zafman's proposed modifications to the low-level API. Signed-off-by: Adam Emerson <aemerson@linuxbox.com> Signed-off-by: Matt Benjamin <matt@linuxbox.com>
-rw-r--r--src/include/cephfs/libcephfs.h159
-rw-r--r--src/libcephfs.cc304
2 files changed, 458 insertions, 5 deletions
diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h
index 2f69ba7a3b9..824f4be05be 100644
--- a/src/include/cephfs/libcephfs.h
+++ b/src/include/cephfs/libcephfs.h
@@ -20,6 +20,8 @@
#include <sys/types.h>
#include <sys/statvfs.h>
#include <sys/socket.h>
+#include <stdint.h>
+#include <stdbool.h>
// FreeBSD compatibility
#ifdef __FreeBSD__
@@ -38,6 +40,56 @@ extern "C" {
# error libceph: must define __USE_FILE_OFFSET64 or readdir results will be corrupted
#endif
+/*
+ * XXXX redeclarations from ceph_fs.h, rados.h, etc. We need more of this
+ * in the interface, but shouldn't be re-typing it (and using different
+ * C data types).
+ */
+#ifndef __cplusplus
+
+#define CEPH_INO_ROOT 1
+#define CEPH_NOSNAP ((uint64_t)(-2))
+
+struct ceph_file_layout {
+ /* file -> object mapping */
+ uint32_t fl_stripe_unit; /* stripe unit, in bytes. must be multiple
+ of page size. */
+ uint32_t fl_stripe_count; /* over this many objects */
+ uint32_t fl_object_size; /* until objects are this big, then move to
+ new objects */
+ uint32_t fl_cas_hash; /* 0 = none; 1 = sha256 */
+
+ /* pg -> disk layout */
+ uint32_t fl_object_stripe_unit; /* for per-object parity, if any */
+
+ /* object -> pg layout */
+ uint32_t fl_pg_preferred; /* preferred primary for pg (-1 for none) */
+ uint32_t fl_pg_pool; /* namespace, crush ruleset, rep level */
+} __attribute__ ((packed));
+
+
+typedef struct _inodeno_t {
+ uint64_t val;
+} inodeno_t;
+
+typedef struct _snapid_t {
+ uint64_t val;
+} snapid_t;
+
+typedef struct vinodeno_t {
+ inodeno_t ino;
+ snapid_t snapid;
+} vinodeno_t;
+
+typedef struct Fh Fh;
+
+#endif /* ! __cplusplus */
+
+struct Inode;
+typedef struct Inode Inode;
+
+struct vinodeno_t;
+typedef struct vinodeno_t vinodeno;
class ceph_mount_info;
struct ceph_dir_result;
class CephContext;
@@ -1134,24 +1186,123 @@ int ceph_get_local_osd(class ceph_mount_info *cmount);
/**
* Get the capabilities currently issued to the client.
- *
+ *
* @param cmount the ceph mount handle to use.
* @param fd the file descriptor to get issued
* @returns the current capabilities issued to this client
- * for the open file
+ * for the open file
*/
int ceph_debug_get_fd_caps(class ceph_mount_info *cmount, int fd);
/**
* Get the capabilities currently issued to the client.
- *
+ *
* @param cmount the ceph mount handle to use.
* @param the path to the file
* @returns the current capabilities issued to this client
- * for the file
+ * for the file
*/
int ceph_debug_get_file_caps(class ceph_mount_info *cmount, const char *path);
+/* Low Level */
+struct Inode *ceph_ll_get_inode(struct ceph_mount_info *cmount,
+ vinodeno_t vino);
+int ceph_ll_lookup(struct ceph_mount_info *cmount, struct Inode *parent,
+ const char *name, struct stat *attr,
+ Inode **out, int uid, int gid);
+int ceph_ll_put(struct ceph_mount_info *cmount, struct Inode *in);
+int ceph_ll_forget(struct ceph_mount_info *cmount, struct Inode *in,
+ int count);
+int ceph_ll_walk(struct ceph_mount_info *cmount, const char *name,
+ struct Inode **i,
+ struct stat *attr);
+int ceph_ll_getattr(struct ceph_mount_info *cmount, struct Inode *in,
+ struct stat *attr, int uid, int gid);
+int ceph_ll_setattr(struct ceph_mount_info *cmount, struct Inode *in,
+ struct stat *st, int mask, int uid, int gid);
+int ceph_ll_open(struct ceph_mount_info *cmount, struct Inode *in, int flags,
+ struct Fh **fh, int uid, int gid);
+loff_t ceph_ll_lseek(struct ceph_mount_info *cmount, struct Fh* filehandle,
+ loff_t offset, int whence);
+int ceph_ll_read(struct ceph_mount_info *cmount, struct Fh* filehandle,
+ int64_t off, uint64_t len, char* buf);
+int ceph_ll_fsync(struct ceph_mount_info *cmount, struct Fh *fh,
+ int syncdataonly);
+int ceph_ll_write(struct ceph_mount_info *cmount, struct Fh* filehandle,
+ int64_t off, uint64_t len, const char *data);
+int64_t ceph_ll_readv(struct ceph_mount_info *cmount, struct Fh *fh,
+ const struct iovec *iov, int iovcnt, int64_t off);
+int64_t ceph_ll_writev(struct ceph_mount_info *cmount, struct Fh *fh,
+ const struct iovec *iov, int iovcnt, int64_t off);
+int ceph_ll_close(struct ceph_mount_info *cmount, struct Fh* filehandle);
+int ceph_ll_iclose(struct ceph_mount_info *cmount, struct Inode *in, int mode);
+int ceph_ll_getxattr(struct ceph_mount_info *cmount, struct Inode *in,
+ const char *name, void *value, size_t size, int uid,
+ int gid);
+int ceph_ll_setxattr(struct ceph_mount_info *cmount, struct Inode *in,
+ const char *name, const void *value, size_t size,
+ int flags, int uid, int gid);
+int ceph_ll_removexattr(struct ceph_mount_info *cmount, struct Inode *in,
+ const char *name, int uid, int gid);
+int ceph_ll_create(struct ceph_mount_info *cmount, struct Inode *parent,
+ const char *name, mode_t mode, int flags,
+ struct stat *attr, struct Inode **out, Fh **fhp,
+ int uid, int gid);
+int ceph_ll_mkdir(struct ceph_mount_info *cmount, struct Inode *parent,
+ const char *name, mode_t mode, struct stat *attr,
+ Inode **out, int uid, int gid);
+int ceph_ll_link(struct ceph_mount_info *cmount, struct Inode *in,
+ struct Inode *newparrent, const char *name,
+ struct stat *attr, int uid, int gid);
+int ceph_ll_truncate(struct ceph_mount_info *cmount, struct Inode *in,
+ uint64_t length, int uid, int gid);
+int ceph_ll_opendir(struct ceph_mount_info *cmount, struct Inode *in,
+ struct ceph_dir_result **dirpp, int uid, int gid);
+int ceph_ll_releasedir(struct ceph_mount_info *cmount,
+ struct ceph_dir_result* dir);
+int ceph_ll_rename(struct ceph_mount_info *cmount, struct Inode *parent,
+ const char *name, struct Inode *newparent,
+ const char *newname, int uid, int gid);
+int ceph_ll_unlink(struct ceph_mount_info *cmount, struct Inode *in,
+ const char *name, int uid, int gid);
+int ceph_ll_statfs(struct ceph_mount_info *cmount, struct Inode *in,
+ struct statvfs *stbuf);
+int ceph_ll_readlink(struct ceph_mount_info *cmount, struct Inode *in,
+ char **value, int uid, int gid);
+int ceph_ll_symlink(struct ceph_mount_info *cmount, struct Inode *parent,
+ const char *name, const char *value, struct stat *attr,
+ struct Inode **in, int uid, int gid);
+int ceph_ll_rmdir(struct ceph_mount_info *cmount, struct Inode *in,
+ const char *name, int uid, int gid);
+uint32_t ceph_ll_stripe_unit(struct ceph_mount_info *cmount,
+ struct Inode *in);
+uint32_t ceph_ll_file_layout(struct ceph_mount_info *cmount,
+ struct Inode *in,
+ struct ceph_file_layout *layout);
+uint64_t ceph_ll_snap_seq(struct ceph_mount_info *cmount,
+ struct Inode *in);
+int ceph_ll_get_stripe_osd(struct ceph_mount_info *cmount,
+ struct Inode *in,
+ uint64_t blockno,
+ struct ceph_file_layout* layout);
+int ceph_ll_num_osds(struct ceph_mount_info *cmount);
+int ceph_ll_osdaddr(struct ceph_mount_info *cmount,
+ int osd, uint32_t *addr);
+uint64_t ceph_ll_get_internal_offset(struct ceph_mount_info *cmount,
+ struct Inode *in, uint64_t blockno);
+int ceph_ll_read_block(struct ceph_mount_info *cmount,
+ struct Inode *in, uint64_t blockid,
+ char* bl, uint64_t offset, uint64_t length,
+ struct ceph_file_layout* layout);
+int ceph_ll_write_block(struct ceph_mount_info *cmount,
+ struct Inode *in, uint64_t blockid,
+ char* buf, uint64_t offset,
+ uint64_t length, struct ceph_file_layout* layout,
+ uint64_t snapseq, uint32_t sync);
+int ceph_ll_commit_blocks(struct ceph_mount_info *cmount,
+ struct Inode *in, uint64_t offset, uint64_t range);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/libcephfs.cc b/src/libcephfs.cc
index cdd06f461e6..58ad819dd1a 100644
--- a/src/libcephfs.cc
+++ b/src/libcephfs.cc
@@ -1145,9 +1145,311 @@ extern "C" int ceph_get_pool_id(class ceph_mount_info *cmount, const char *pool_
return (int)pool_id;
}
-extern "C" int ceph_get_pool_replication(class ceph_mount_info *cmount, int pool_id)
+extern "C" int ceph_get_pool_replication(class ceph_mount_info *cmount,
+ int pool_id)
{
if (!cmount->is_mounted())
return -ENOTCONN;
return cmount->get_client()->get_pool_replication(pool_id);
}
+/* Low-level exports */
+
+extern "C" struct Inode *ceph_ll_get_inode(class ceph_mount_info *cmount,
+ vinodeno_t vino)
+{
+ return (cmount->get_client())->ll_get_inode(vino);
+}
+
+extern "C" int ceph_ll_lookup(class ceph_mount_info *cmount,
+ struct Inode *parent, const char *name,
+ struct stat *attr, Inode **out,
+ int uid, int gid)
+{
+ return (cmount->get_client())->ll_lookup(parent, name, attr, out, uid, gid);
+}
+
+extern "C" int ceph_ll_put(class ceph_mount_info *cmount, Inode *in)
+{
+ return (cmount->get_client()->ll_put(in));
+}
+
+extern "C" int ceph_ll_forget(class ceph_mount_info *cmount, Inode *in,
+ int count)
+{
+ return (cmount->get_client()->ll_forget(in, count));
+}
+
+extern "C" int ceph_ll_walk(class ceph_mount_info *cmount, const char *name,
+ struct Inode **i,
+ struct stat *attr)
+{
+ return(cmount->get_client()->ll_walk(name, i, attr));
+}
+
+extern "C" int ceph_ll_getattr(class ceph_mount_info *cmount,
+ Inode *in, struct stat *attr,
+ int uid, int gid)
+{
+ return (cmount->get_client()->ll_getattr(in, attr, uid, gid));
+}
+
+extern "C" int ceph_ll_setattr(class ceph_mount_info *cmount,
+ Inode *in, struct stat *st,
+ int mask, int uid, int gid)
+{
+ return (cmount->get_client()->ll_setattr(in, st, mask, uid, gid));
+}
+
+extern "C" int ceph_ll_open(class ceph_mount_info *cmount, Inode *in,
+ int flags, Fh **fh, int uid, int gid)
+{
+ return (cmount->get_client()->ll_open(in, flags, fh, uid, gid));
+}
+
+extern "C" int ceph_ll_read(class ceph_mount_info *cmount, Fh* filehandle,
+ int64_t off, uint64_t len, char* buf)
+{
+ bufferlist bl;
+ int r = 0;
+
+ r = cmount->get_client()->ll_read(filehandle, off, len, &bl);
+ if (r >= 0)
+ {
+ bl.copy(0, bl.length(), buf);
+ r = bl.length();
+ }
+ return r;
+}
+
+extern "C" int ceph_ll_read_block(class ceph_mount_info *cmount,
+ Inode *in, uint64_t blockid,
+ char* buf, uint64_t offset,
+ uint64_t length,
+ struct ceph_file_layout* layout)
+{
+
+ return (cmount->get_client()->ll_read_block(in, blockid, buf, offset,
+ length, layout));
+}
+
+extern "C" int ceph_ll_write_block(class ceph_mount_info *cmount,
+ Inode *in, uint64_t blockid,
+ char *buf, uint64_t offset,
+ uint64_t length,
+ struct ceph_file_layout *layout,
+ uint64_t snapseq, uint32_t sync)
+{
+ return (cmount->get_client()->ll_write_block(in, blockid, buf, offset,
+ length, layout, snapseq, sync));
+}
+
+extern "C" int ceph_ll_commit_blocks(class ceph_mount_info *cmount,
+ Inode *in, uint64_t offset,
+ uint64_t range)
+{
+ return (cmount->get_client()->ll_commit_blocks(in, offset, range));
+}
+
+extern "C" int ceph_ll_fsync(class ceph_mount_info *cmount,
+ Fh *fh, int syncdataonly)
+{
+ return (cmount->get_client()->ll_fsync(fh, syncdataonly));
+}
+
+extern "C" loff_t ceph_ll_lseek(class ceph_mount_info *cmount,
+ Fh *fh, loff_t offset, int whence)
+{
+ return (cmount->get_client()->ll_lseek(fh, offset, whence));
+}
+
+extern "C" int ceph_ll_write(class ceph_mount_info *cmount,
+ Fh *fh, int64_t off, uint64_t len,
+ const char *data)
+{
+ return (cmount->get_client()->ll_write(fh, off, len, data));
+}
+
+extern "C" int64_t ceph_ll_readv(class ceph_mount_info *cmount,
+ struct Fh *fh, const struct iovec *iov,
+ int iovcnt, int64_t off)
+{
+ return -1; // TODO: implement
+}
+
+extern "C" int64_t ceph_ll_writev(class ceph_mount_info *cmount,
+ struct Fh *fh, const struct iovec *iov,
+ int iovcnt, int64_t off)
+{
+ return -1; // TODO: implement
+}
+
+extern "C" int ceph_ll_close(class ceph_mount_info *cmount, Fh* fh)
+{
+ return (cmount->get_client()->ll_release(fh));
+}
+
+extern "C" int ceph_ll_create(class ceph_mount_info *cmount,
+ struct Inode *parent, const char *name,
+ mode_t mode, int flags, struct stat *attr,
+ struct Inode **out, Fh **fhp, int uid, int gid)
+{
+ return (cmount->get_client())->ll_create(parent, name, mode, flags,
+ attr, out, fhp, uid, gid);
+}
+
+extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount,
+ Inode *parent, const char *name,
+ mode_t mode, struct stat *attr, Inode **out,
+ int uid, int gid)
+{
+ return (cmount->get_client()->ll_mkdir(parent, name, mode, attr, out, uid,
+ gid));
+}
+
+extern "C" int ceph_ll_link(class ceph_mount_info *cmount,
+ Inode *in, Inode *newparent,
+ const char *name, struct stat *attr, int uid,
+ int gid)
+{
+ return (cmount->get_client()->ll_link(in, newparent, name, attr, uid,
+ gid));
+}
+
+extern "C" int ceph_ll_truncate(class ceph_mount_info *cmount,
+ Inode *in, uint64_t length, int uid,
+ int gid)
+{
+ struct stat st;
+ st.st_size=length;
+
+ return(cmount->get_client()->ll_setattr(in, &st, CEPH_SETATTR_SIZE, uid,
+ gid));
+}
+
+extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount,
+ Inode *in,
+ struct ceph_dir_result **dirpp,
+ int uid, int gid)
+{
+ return (cmount->get_client()->ll_opendir(in, (dir_result_t**) dirpp, uid,
+ gid));
+}
+
+extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount,
+ ceph_dir_result *dir)
+{
+ (void) cmount->get_client()->ll_releasedir((dir_result_t*) dir);
+ return (0);
+}
+
+extern "C" int ceph_ll_rename(class ceph_mount_info *cmount,
+ Inode *parent, const char *name,
+ Inode *newparent, const char *newname,
+ int uid, int gid)
+{
+ return (cmount->get_client()->ll_rename(parent, name, newparent, newname,
+ uid, gid));
+}
+
+extern "C" int ceph_ll_unlink(class ceph_mount_info *cmount,
+ Inode *in, const char *name,
+ int uid, int gid)
+{
+ return (cmount->get_client()->ll_unlink(in, name, uid, gid));
+}
+
+extern "C" int ceph_ll_statfs(class ceph_mount_info *cmount,
+ Inode *in, struct statvfs *stbuf)
+{
+ return (cmount->get_client()->ll_statfs(in, stbuf));
+}
+
+extern "C" int ceph_ll_readlink(class ceph_mount_info *cmount,
+ Inode *in, char **value, int uid,
+ int gid)
+{
+ return (cmount->get_client()->ll_readlink(in, (const char**) value,
+ uid, gid));
+}
+
+extern "C" int ceph_ll_symlink(class ceph_mount_info *cmount,
+ Inode *in, const char *name,
+ const char *value, struct stat *attr,
+ Inode **out, int uid, int gid)
+{
+ return (cmount->get_client()->ll_symlink(in, name, value, attr, out, uid,
+ gid));
+}
+
+extern "C" int ceph_ll_rmdir(class ceph_mount_info *cmount,
+ Inode *in, const char *name,
+ int uid, int gid)
+{
+ return (cmount->get_client()->ll_rmdir(in, name, uid, gid));
+}
+
+extern "C" int ceph_ll_getxattr(class ceph_mount_info *cmount,
+ Inode *in, const char *name, void *value,
+ size_t size, int uid, int gid)
+{
+ return (cmount->get_client()->ll_getxattr(in, name, value, size, uid, gid));
+}
+
+extern "C" int ceph_ll_setxattr(class ceph_mount_info *cmount,
+ Inode *in, const char *name,
+ const void *value, size_t size,
+ int flags, int uid, int gid)
+{
+ return (cmount->get_client()->ll_setxattr(in, name, value, size, flags, uid,
+ gid));
+}
+
+extern "C" int ceph_ll_removexattr(class ceph_mount_info *cmount,
+ Inode *in, const char *name,
+ int uid, int gid)
+{
+ return (cmount->get_client()->ll_removexattr(in, name, uid, gid));
+}
+
+extern "C" uint32_t ceph_ll_stripe_unit(class ceph_mount_info *cmount,
+ Inode *in)
+{
+ return (cmount->get_client()->ll_stripe_unit(in));
+}
+
+extern "C" uint32_t ceph_ll_file_layout(class ceph_mount_info *cmount,
+ Inode *in,
+ struct ceph_file_layout *layout)
+{
+ return (cmount->get_client()->ll_file_layout(in, layout));
+}
+
+uint64_t ceph_ll_snap_seq(class ceph_mount_info *cmount, Inode *in)
+{
+ return (cmount->get_client()->ll_snap_seq(in));
+}
+
+extern "C" int ceph_ll_get_stripe_osd(class ceph_mount_info *cmount,
+ Inode *in, uint64_t blockno,
+ struct ceph_file_layout* layout)
+{
+ return (cmount->get_client()->ll_get_stripe_osd(in, blockno, layout));
+}
+
+extern "C" int ceph_ll_num_osds(class ceph_mount_info *cmount)
+{
+ return (cmount->get_client()->ll_num_osds());
+}
+
+extern "C" int ceph_ll_osdaddr(class ceph_mount_info *cmount,
+ int osd, uint32_t *addr)
+{
+ return (cmount->get_client()->ll_osdaddr(osd, addr));
+}
+
+extern "C" uint64_t ceph_ll_get_internal_offset(class ceph_mount_info *cmount,
+ Inode *in,
+ uint64_t blockno)
+{
+ return (cmount->get_client()->ll_get_internal_offset(in, blockno));
+}