remove file or directory
*/
int rgw_unlink(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle, const char* path);
+ const struct rgw_file_handle *parent_fh, const char* path);
/*
lookup a directory or file
*/
int rgw_lookup(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle, const char *path,
- struct rgw_file_handle *handle);
+ const struct rgw_file_handle *parent_fh, const char *path,
+ struct rgw_file_handle **fh, uint32_t flags);
+
+/*
+ * release file handle
+ */
+int rgw_fh_rele(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+ uint32_t flags);
/*
read directory content
typedef bool (*rgw_readdir_cb)(const char *name, void *arg, uint64_t offset);
int rgw_readdir(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle, uint64_t *offset,
+ const struct rgw_file_handle *parent_fh, uint64_t *offset,
rgw_readdir_cb rcb, void *cb_arg, bool *eof);
/* XXX (get|set)attr mask bits */
get unix attributes for object
*/
int rgw_getattr(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, struct stat *st);
+ struct rgw_file_handle *handle, struct stat *st);
/*
set unix attributes for object
*/
int rgw_setattr(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, struct stat *st,
+ struct rgw_file_handle *handle, struct stat *st,
uint32_t mask);
/*
truncate file
*/
int rgw_truncate(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint64_t size);
+ struct rgw_file_handle *handle, uint64_t size);
/*
open file
*/
-int rgw_open(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint32_t flags);
+int rgw_open(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+ uint32_t flags);
/*
close file
*/
-int rgw_close(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint32_t flags);
+
+#define RGW_CLOSE_FLAG_NONE 0x0000
+#define RGW_CLOSE_FLAG_RELE 0x0001
+
+int rgw_close(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+ uint32_t flags);
/*
read data from file
*/
int rgw_read(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint64_t offset,
+ struct rgw_file_handle *fh, uint64_t offset,
size_t length, void *buffer);
+/* XXX add release fn and UIO type */
+int rgw_readv(struct rgw_fs *rgw_fs,
+ struct rgw_file_handle *fh, uint64_t offset,
+ size_t length, void *buffer);
+
/*
write data to file
*/
int rgw_write(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint64_t offset,
+ struct rgw_file_handle *fh, uint64_t offset,
+ size_t length, void *buffer);
+
+/* XXX add release fn and UIO type */
+
+int rgw_writev(struct rgw_fs *rgw_fs,
+ const struct rgw_file_handle *fh, uint64_t offset,
size_t length, void *buffer);
+
/*
sync written data
*/
-int rgw_fsync(struct rgw_fs *rgw_fs, const struct rgw_file_handle *handle);
+int rgw_fsync(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh);
int set_user_permissions(const char *uid);
lookup a directory or file
*/
int rgw_lookup(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle, const char* path,
- struct rgw_file_handle *handle)
+ const struct rgw_file_handle *parent_fh, const char* path,
+ struct rgw_file_handle **fh, uint32_t flags)
{
string uri;
int rc;
- rc = librgw.get_uri(parent_handle->handle, uri);
+ rc = librgw.get_uri(parent_fh->handle, uri);
if (rc < 0 ) { /* invalid parent */
return rc;
}
uri += "/";
uri += path;
+ RGWFileHandle* rgw_fh = new RGWFileHandle();
+ struct rgw_file_handle *rfh = rgw_fh->get_fh();
+
/* find or create a handle for the object or bucket */
- handle->handle = librgw.get_handle(uri);
+ rfh->handle = librgw.get_handle(uri);
+ *fh = rfh;
+
+ return 0;
+} /* rgw_lookup */
+
+/*
+ * release file handle
+ */
+int rgw_fh_rele(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+ uint32_t flags)
+{
+ RGWFileHandle* rgw_fh = get_rgwfh(fh);
+ rgw_fh->rele();
+
return 0;
}
get unix attributes for object
*/
int rgw_getattr(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, struct stat *st)
+ struct rgw_file_handle *fh, struct stat *st)
{
string uri;
int rc;
- rc = librgw.get_uri(handle->handle, uri);
+ rc = librgw.get_uri(fh->handle, uri);
if (rc < 0 ) { /* invalid parent */
return rc;
}
set unix attributes for object
*/
int rgw_setattr(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, struct stat *st,
+ struct rgw_file_handle *fh, struct stat *st,
uint32_t mask)
{
/* XXX no-op */
truncate file
*/
int rgw_truncate(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint64_t size)
+ struct rgw_file_handle *fh, uint64_t size)
{
return 0;
}
open file
*/
int rgw_open(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint32_t flags)
+ struct rgw_file_handle *fh, uint32_t flags)
{
+ RGWFileHandle* rgw_fh = get_rgwfh(fh);
+ rgw_fh->open(/* XXX */);
+
return 0;
}
close file
*/
int rgw_close(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint32_t flags)
+ struct rgw_file_handle *fh, uint32_t flags)
{
+ RGWFileHandle* rgw_fh = get_rgwfh(fh);
+ rgw_fh->close(/* XXX */);
+
+ if (flags & RGW_CLOSE_FLAG_RELE)
+ rgw_fh->rele();
+
return 0;
}
int rgw_readdir(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle, uint64_t *offset,
+ const struct rgw_file_handle *parent_fh, uint64_t *offset,
rgw_readdir_cb rcb, void *cb_arg, bool *eof)
{
int rc;
string uri;
- rc = librgw.get_uri(parent_handle->handle, uri);
+ rc = librgw.get_uri(parent_fh->handle, uri);
if (rc < 0 ) { /* invalid parent */
return rc;
}
read data from file
*/
int rgw_read(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint64_t offset,
+ struct rgw_file_handle *fh, uint64_t offset,
size_t length, void *buffer)
{
return 0;
write data to file
*/
int rgw_write(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *handle, uint64_t offset,
+ struct rgw_file_handle *fh, uint64_t offset,
size_t length, void *buffer)
{
+ RGWFileHandle* rgw_fh = get_rgwfh(fh);
+
return 0;
}
/*
sync written data
*/
-int rgw_fsync(struct rgw_fs *rgw_fs, const struct rgw_file_handle *handle)
+int rgw_fsync(struct rgw_fs *rgw_fs, struct rgw_file_handle *handle)
{
return 0;
}
class RGWFileHandle
{
struct rgw_file_handle fh;
+ uint32_t flags;
public:
+ static constexpr uint32_t FLAG_NONE = 0;
+ static constexpr uint32_t FLAG_OPEN = 1;
+
RGWFileHandle() {
fh.fh_private = this;
}
+ bool is_open() { return flags & FLAG_OPEN; }
+
+ void open() { flags |= FLAG_OPEN; }
+
+ void close() { flags &= ~FLAG_OPEN; }
+
+ void rele() {
+ /* XXX intrusive refcnt */
+ assert(! is_open());
+ delete this;
+ }
+
struct rgw_file_handle* get_fh() { return &fh; }
}; /* RGWFileHandle */
+static inline RGWFileHandle* get_rgwfh(struct rgw_file_handle* fh) {
+ return static_cast<RGWFileHandle*>(fh->fh_private);
+}
+
class RGWLibFS
{
struct rgw_fs fs;
}; /* RGWDeleteBucketRequest */
+/*
+ put object
+*/
+
+class RGWPutObjRequest : public RGWLibRequest,
+ public RGWPutObj_OS_Lib /* RGWOp */
+{
+public:
+ std::string& bucket_name;
+ std::string& obj_name;
+ buffer::list& bl; /* XXX */
+
+ RGWPutObjRequest(CephContext* _cct, RGWUserInfo *_user,
+ std::string& _bname, std::string& _oname,
+ buffer::list& _bl)
+ : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname),
+ bl(_bl) {
+ magic = 75;
+ op = this;
+ }
+
+ virtual bool only_bucket() { return false; }
+
+ virtual int op_init() {
+ // assign store, s, and dialect_handler
+ RGWObjectCtx* rados_ctx
+ = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+ // framework promises to call op_init after parent init
+ assert(rados_ctx);
+ RGWOp::init(rados_ctx->store, get_state(), this);
+ op = this; // assign self as op: REQUIRED
+ return 0;
+ }
+
+ virtual int header_init() {
+
+ struct req_state* s = get_state();
+ s->info.method = "PUT";
+ s->op = OP_PUT;
+
+ /* XXX derp derp derp */
+ string uri = "/" + bucket_name + "/" + obj_name;
+ s->relative_uri = uri;
+ s->info.request_uri = uri; // XXX
+ s->info.effective_uri = uri;
+ s->info.request_params = "";
+ s->info.domain = ""; /* XXX ? */
+
+ // woo
+ s->user = user;
+
+ return 0;
+ }
+}; /* RGWPubObjRequest */
+
+
#endif /* RGW_FILE_H */
~RGWDeleteBucket_OS_Lib() {}
}; /* RGWCreateBucket_OS_Lib */
+class RGWPutObj_OS_Lib : public RGWPutObj
+{
+public:
+ RGWPutObj_OS_Lib() {}
+ ~RGWPutObj_OS_Lib() {}
+
+ virtual int verify_params();
+ virtual int get_params();
+
+}; /* RGWPutObj_OS_Lib */
+
#endif /* RGW_OS_LIB_H */
RWLock::WLocker wl(lock);
entries.clear();
}
-};
+}; /* RGWChainedCacheImpl */
class RGWPutObjProcessor
{
const char *if_match = NULL, const char *if_nomatch = NULL);
CephContext *ctx();
-};
+}; /* RGWPutObjProcessor */
struct put_obj_aio_info {
void *handle;
RGWPutObjProcessor_Aio(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info) : RGWPutObjProcessor(obj_ctx, bucket_info), max_chunks(RGW_MAX_PENDING_CHUNKS), obj_len(0) {}
virtual ~RGWPutObjProcessor_Aio();
-};
+}; /* RGWPutObjProcessor_Aio */
class RGWPutObjProcessor_Atomic : public RGWPutObjProcessor_Aio
{
void set_version_id(const string& vid) {
version_id = vid;
}
-};
+}; /* RGWPutObjProcessor_Atomic */
#endif
${CMAKE_DL_LIBS}
)
+# librgw_file_gp (just the rgw_file get-put bucket ops)
+add_executable(test_librgw_file_gp
+ librgw_file_gp.cc
+ $<TARGET_OBJECTS:heap_profiler_objs>
+ )
+set_target_properties(test_librgw_file_gp PROPERTIES COMPILE_FLAGS
+ ${UNITTEST_CXX_FLAGS})
+target_link_libraries(test_librgw_file_gp
+ rgw
+ librados
+ ${UNITTEST_LIBS}
+ ${EXTRALIBS}
+ ${ALLOC_LIBS}
+ ${CMAKE_DL_LIBS}
+ )
+
if(${HAVE_LIBFUSE})
add_executable(test_cfuse_cache_invalidate
test_cfuse_cache_invalidate.cc
int ret = 0;
for (auto& fid : fids1) {
- struct rgw_file_handle *rgw_fh = new rgw_file_handle();
- ret = rgw_lookup(fs, &fs->root_fh, get<0>(fid).c_str(), rgw_fh);
+ struct rgw_file_handle *rgw_fh;
+ ret = rgw_lookup(fs, &fs->root_fh, get<0>(fid).c_str(), &rgw_fh,
+ 0 /* flags */);
ASSERT_EQ(ret, 0);
get<2>(fid) = rgw_fh;
ASSERT_NE(get<2>(fid), nullptr);
}
TEST(LibRGW, CLEANUP) {
+ int ret = 0;
using std::get;
for (auto& fids : { fids1, fids2 }) {
for (auto& fid : fids) {
- delete get<2>(fid);
+ ret = rgw_fh_rele(fs, get<2>(fid), 0 /* flags */);
}
}
}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include <stdint.h>
+#include <tuple>
+#include <iostream>
+
+#include "include/rados/librgw.h"
+#include "include/rados/rgw_file.h"
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+ librgw_t rgw = nullptr;
+ string uid("testuser");
+ string access_key("");
+ string secret_key("");
+ struct rgw_fs *fs = nullptr;
+
+ bool do_put = false;
+ bool do_get = false;
+ bool do_delete = false;
+
+ string bucket_name = "sorry_dave";
+ string object_name = "jocaml";
+
+ struct rgw_file_handle *fh = nullptr;
+
+ struct {
+ int argc;
+ char **argv;
+ } saved_args;
+}
+
+TEST(LibRGW, INIT) {
+ int ret = librgw_create(&rgw, nullptr, saved_args.argc, saved_args.argv);
+ ASSERT_EQ(ret, 0);
+ ASSERT_NE(rgw, nullptr);
+}
+
+TEST(LibRGW, MOUNT) {
+ int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+ &fs);
+ ASSERT_EQ(ret, 0);
+ ASSERT_NE(fs, nullptr);
+}
+
+TEST(LibRGW, OBJ_OPEN) {
+ int ret = rgw_lookup(fs, &fs->root_fh, bucket_name.c_str(), &fh,
+ 0 /* flags */);
+ ASSERT_EQ(ret, 0);
+ ret = rgw_open(fs, fh, 0 /* flags */);
+ ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, PUT_OBJECT) {
+ if (do_put) {
+ string data = "hi mom"; // fix this
+ int ret = rgw_write(fs, fh, 0, data.length(), (void*) data.c_str());
+ ASSERT_EQ(ret, 0);
+ }
+}
+
+TEST(LibRGW, GET_OBJECT) {
+ /* XXX soon */
+}
+
+TEST(LibRGW, CLEANUP) {
+ int ret = rgw_close(fs, fh, 0 /* flags */);
+ ASSERT_EQ(ret, 0);
+ ret = rgw_fh_rele(fs, fh, 0 /* flags */);
+ ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, UMOUNT) {
+ if (! fs)
+ return;
+
+ int ret = rgw_umount(fs);
+ ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, SHUTDOWN) {
+ librgw_shutdown(rgw);
+}
+
+int main(int argc, char *argv[])
+{
+ char *v{nullptr};
+ string val;
+ vector<const char*> args;
+
+ argv_to_vec(argc, const_cast<const char**>(argv), args);
+ env_to_vec(args);
+
+ v = getenv("AWS_ACCESS_KEY_ID");
+ if (v) {
+ access_key = v;
+ }
+
+ v = getenv("AWS_SECRET_ACCESS_KEY");
+ if (v) {
+ secret_key = v;
+ }
+
+ for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+ if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+ (char*) nullptr)) {
+ access_key = val;
+ } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+ (char*) nullptr)) {
+ secret_key = val;
+ } else if (ceph_argparse_witharg(args, arg_iter, &val, "--uid",
+ (char*) nullptr)) {
+ uid = val;
+ } else if (ceph_argparse_witharg(args, arg_iter, &val, "--bn",
+ (char*) nullptr)) {
+ bucket_name = val;
+ } else if (ceph_argparse_flag(args, arg_iter, "--get",
+ (char*) nullptr)) {
+ do_get = true;
+ } else if (ceph_argparse_flag(args, arg_iter, "--put",
+ (char*) nullptr)) {
+ do_put = true;
+ } else {
+ ++arg_iter;
+ }
+ }
+
+ /* dont accidentally run as anonymous */
+ if ((access_key == "") ||
+ (secret_key == "")) {
+ std::cout << argv[0] << " no AWS credentials, exiting" << std::endl;
+ return EPERM;
+ }
+
+ saved_args.argc = argc;
+ saved_args.argv = argv;
+
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}