Reify root handle, remove traces of legacy (counter) handles.
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
uint64_t bucket;
uint64_t object;
} fh_hk;
- uint64_t handle; // XXX deprecating
void *fh_private; /* librgw private data */
/* object type */
enum rgw_fh_type fh_type;
uint64_t f_namemax; /* maximum filename length */
};
-/*
- get entity handle
-*/
-int rgw_get_handle(const char *uri, struct rgw_file_handle *handle);
-
-/*
- check handle
-*/
-int rgw_check_handle(const struct rgw_file_handle *handle);
-
/*
attach rgw namespace
*/
get filesystem attributes
*/
int rgw_statfs(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle,
+ struct rgw_file_handle *parent_fh,
struct rgw_statvfs *vfs_st);
create file
*/
int rgw_create(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle,
+ struct rgw_file_handle *parent_fh,
const char *name, mode_t mode, struct stat *st,
- struct rgw_file_handle *handle);
+ struct rgw_file_handle *fh);
/*
create a new directory
*/
int rgw_mkdir(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle,
+ struct rgw_file_handle *parent_fh,
const char *name, mode_t mode, struct stat *st,
- struct rgw_file_handle *handle);
+ struct rgw_file_handle *fh);
/*
rename object
*/
int rgw_rename(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *olddir, const char* old_name,
- const struct rgw_file_handle *newdir, const char* new_name);
+ struct rgw_file_handle *olddir, const char* old_name,
+ struct rgw_file_handle *newdir, const char* new_name);
/*
remove file or directory
*/
int rgw_unlink(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_fh, const char* path);
+ struct rgw_file_handle *parent_fh, const char* path);
/*
lookup a directory or file
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_fh, uint64_t *offset,
+ 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,
- struct rgw_file_handle *handle, struct stat *st);
+ struct rgw_file_handle *fh, struct stat *st);
/*
set unix attributes for object
*/
int rgw_setattr(struct rgw_fs *rgw_fs,
- struct rgw_file_handle *handle, struct stat *st,
+ struct rgw_file_handle *fh, struct stat *st,
uint32_t mask);
/*
truncate file
*/
int rgw_truncate(struct rgw_fs *rgw_fs,
- struct rgw_file_handle *handle, uint64_t size);
+ struct rgw_file_handle *fh, uint64_t size);
/*
open file
*/
int rgw_fsync(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh);
+/* XXXX not implemented (needed?) */
+
int set_user_permissions(const char *uid);
int get_user_permissions(const char *uid);
-int set_dir_permissions(const struct rgw_file_handle *handle);
+int set_dir_permissions(const struct rgw_file_handle *fh);
-int get_dir_permissions(const struct rgw_file_handle *handle);
+int get_dir_permissions(const struct rgw_file_handle *fh);
-int set_file_permissions(const struct rgw_file_handle *handle);
+int set_file_permissions(const struct rgw_file_handle *fh);
-int get_file_permissions(const struct rgw_file_handle *handle);
+int get_file_permissions(const struct rgw_file_handle *fh);
int rgw_acl2perm();
return 0;
} /* RGWLib::stop() */
-int RGWLib::get_uri(const uint64_t handle, string& uri)
-{
- ceph::unordered_map<uint64_t, string>::iterator i = handles_map.find(handle);
- if (i != handles_map.end()) {
- uri = i->second;
- return 0;
- }
- return -1;
-}
-
-uint64_t RGWLib::get_handle(const string& uri)
-{
- ceph::unordered_map<string, uint64_t>::iterator i =
- allocated_objects_handles.find(uri);
- if (i != allocated_objects_handles.end()) {
- return i->second;
- }
-
- allocated_objects_handles[uri] = last_allocated_handle.inc();
- handles_map[last_allocated_handle.read()] = uri;
-
- return last_allocated_handle.read();
-}
-
-int RGWLib::check_handle(uint64_t handle)
-{
- ceph::unordered_map<uint64_t, string>::const_iterator i =
- handles_map.find(handle);
- return (i != handles_map.end());
-}
-
int RGWLibIO::set_uid(RGWRados *store, const rgw_user& uid)
{
int ret = rgw_get_user_info_by_uid(store, uid, user_info, NULL);
extern RGWLib librgw;
-bool is_root(const string& uri)
-{
- return (uri == "");
-}
-
-bool is_bucket(const string& uri)
-{
- /* XXX */
- int pos = uri.find('/');
- return (pos < 0);
-}
-
const string RGWFileHandle::root_name = "/";
-/*
- get generate rgw_file_handle
-*/
-int rgw_get_handle(const char* uri, struct rgw_file_handle* handle)
-{
- handle->handle = librgw.get_handle(uri);
- return 0;
-}
-
-/*
- check rgw_file_handle
-*/
-int rgw_check_handle(const struct rgw_file_handle* handle)
-{
- return librgw.check_handle(handle->handle);
-}
-
/* librgw */
extern "C" {
struct rgw_fs *fs = new_fs->get_fs();;
fs->rgw = rgw;
- /* stash the root */
- rc = rgw_get_handle("", &fs->root_fh);
- if (rc != 0) {
- delete new_fs;
- return -EINVAL;
- }
+ /* XXX we no longer assume "/" is unique, but we aren't tracking the
+ * roots atm */
*rgw_fs = fs;
get filesystem attributes
*/
int rgw_statfs(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle,
+ struct rgw_file_handle *parent_fh,
struct rgw_statvfs *vfs_st)
{
memset(vfs_st, 0, sizeof(struct rgw_statvfs));
generic create
*/
int rgw_create(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle,
+ struct rgw_file_handle *parent_fh,
const char *name, mode_t mode, struct stat *st,
struct rgw_file_handle *handle)
{
- string uri;
- int rc;
-
- rc = librgw.get_uri(parent_handle->handle, uri);
- if (rc < 0 ) { /* invalid parent */
- return rc;
- }
-
- uri += "\\";
- uri += name;
-
- /* TODO: implement */
-
- return rgw_get_handle(uri.c_str(), handle);
+ return 0;
}
/*
create a new directory
*/
int rgw_mkdir(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_handle,
+ struct rgw_file_handle *parent_fh,
const char *name, mode_t mode, struct stat *st,
struct rgw_file_handle *handle)
{
int rc;
- string uri;
- rc = librgw.get_uri(parent_handle->handle, uri);
- if (rc < 0 ) { /* invalid parent */
- return rc;
- }
+ /* XXXX remove uri, deal with bucket names */
+ string uri;
RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
- /* cannot create a bucket in a bucket */
- if (! is_root(uri)) {
+ RGWFileHandle* parent = get_rgwfh(parent_fh);
+ if (! parent) {
+ /* bad parent */
return EINVAL;
}
- // fix this
+ if (! parent->is_root()) {
+ /* cannot create a bucket in a bucket */
+ return ENOTDIR;
+ }
+
+ // XXXX fix this
uri += "/";
uri += name;
RGWCreateBucketRequest req(cct, fs->get_user(), uri);
rename object
*/
int rgw_rename(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *olddir, const char* old_name,
- const struct rgw_file_handle *newdir, const char* new_name)
+ struct rgw_file_handle *olddir, const char* old_name,
+ struct rgw_file_handle *newdir, const char* new_name)
{
/* -ENOTSUP */
return -EINVAL;
/*
remove file or directory
*/
-int rgw_unlink(struct rgw_fs *rgw_fs, const struct rgw_file_handle* parent,
+int rgw_unlink(struct rgw_fs *rgw_fs, struct rgw_file_handle* parent,
const char* path)
{
+ /* XXXX remove uri and deal with bucket and object names */
string uri;
int rc = 0;
/*
* object
*/
- rc = librgw.get_uri(parent->handle, uri);
- if (rc < 0 ) { /* invalid parent */
- return rc;
- }
- uri += path;
/* TODO: implement
* RGWDeleteObjectRequest req(cct, fs->get_user(), uri);
*/
struct rgw_file_handle *parent_fh, const char* path,
struct rgw_file_handle **fh, uint32_t flags)
{
- string uri;
- int rc;
+ RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
- rc = librgw.get_uri(parent_fh->handle, uri);
- if (rc < 0 ) { /* invalid parent */
- return rc;
+ RGWFileHandle* parent = get_rgwfh(parent_fh);
+ if (! parent) {
+ /* bad parent */
+ return EINVAL;
}
- #warning get_bucket and ?get_object? unimplemented
- /* TODO: implement */
- if (is_root(uri)) {
- //librgw.get_bucket(uri);
- } else if (0 /* is_bucket(uri) */) {
- /* get the object */
- } else { /* parent cannot be an object */
- return -1;
+ RGWFileHandle* rgw_fh = new RGWFileHandle(fs, parent, path);
+ if (! rgw_fh) {
+ /* not found */
+ return ENOENT;
}
- uri += "/";
- uri += path;
-
- RGWFileHandle* parent = get_rgwfh(parent_fh);
- RGWFileHandle* rgw_fh = new RGWFileHandle(parent, path);
struct rgw_file_handle *rfh = rgw_fh->get_fh();
-
- /* find or create a handle for the object or bucket */
- rfh->handle = librgw.get_handle(uri);
*fh = rfh;
return 0;
int rgw_getattr(struct rgw_fs *rgw_fs,
struct rgw_file_handle *fh, struct stat *st)
{
- string uri;
- int rc;
-
- rc = librgw.get_uri(fh->handle, uri);
- if (rc < 0 ) { /* invalid parent */
- return rc;
- }
-
return 0;
}
}
int rgw_readdir(struct rgw_fs *rgw_fs,
- const struct rgw_file_handle *parent_fh, uint64_t *offset,
+ 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_fh->handle, uri);
- if (rc < 0 ) { /* invalid parent */
- return rc;
- }
+ /* XXXX remove uri, deal with bucket and object names */
+ string uri;
RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
* deal with authorization
* consider non-default tenancy/user and bucket layouts
*/
- if (is_root(uri)) {
- /* for now, root always contains one user's bucket namespace */
+ RGWFileHandle* parent = get_rgwfh(parent_fh);
+ if (! parent) {
+ /* bad parent */
+ return EINVAL;
+ }
+
+ if (parent->is_root()) {
RGWListBucketsRequest req(cct, fs->get_user(), rcb, cb_arg, offset);
rc = librgw.get_fe()->execute_req(&req);
} else {
#include "xxhash.h"
#include "include/buffer.h"
+class RGWLibFS;
class RGWFileHandle;
+
typedef boost::intrusive_ptr<RGWFileHandle> RGWFHRef;
class RGWFileHandle
struct rgw_file_handle fh;
mutable std::atomic<uint64_t> refcnt;
RGWFHRef parent;
- const static string root_name;
string name; /* XXX file or bucket name */
uint32_t flags;
public:
+ const static string root_name;
+
static constexpr uint32_t FLAG_NONE = 0x0000;
static constexpr uint32_t FLAG_OPEN = 0x0001;
static constexpr uint32_t FLAG_ROOT = 0x0002;
- RGWFileHandle(RGWFileHandle* _parent, const char* _name)
+ RGWFileHandle(RGWLibFS* fs, RGWFileHandle* _parent, const char* _name)
: parent(_parent), name(_name), flags(FLAG_NONE) {
- fh.fh_type = parent->is_root() ? RGW_FS_TYPE_DIRECTORY : RGW_FS_TYPE_FILE;
- fh.fh_private = this;
- /* content-addressable hash */
- fh.fh_hk.bucket = (parent) ? parent->get_fh()->fh_hk.object : 0;
+ if (parent) {
+ fh.fh_type = parent->is_root() ?
+ RGW_FS_TYPE_DIRECTORY : RGW_FS_TYPE_FILE;
+ /* content-addressable hash (bucket part) */
+ fh.fh_hk.bucket = parent->get_fh()->fh_hk.object;
+ } else {
+ /* root */
+ fh.fh_type = RGW_FS_TYPE_DIRECTORY;
+ /* XXX give root buckets a locally-unique bucket hash part */
+ fh.fh_hk.bucket = XXH64(reinterpret_cast<char*>(fs), 8, 8675309);
+ flags |= FLAG_ROOT;
+ }
+ /* content-addressable hash (object part) */
fh.fh_hk.object = XXH64(name.c_str(), name.length(), 8675309 /* XXX */);
+ fh.fh_private = this;
}
struct rgw_file_handle* get_fh() { return &fh; }
const std::string& object_name() { return name; }
- bool is_open() { return flags & FLAG_OPEN; }
- bool is_root() { return flags & FLAG_ROOT; }
- bool is_bucket() { return (fh.fh_type == RGW_FS_TYPE_DIRECTORY); }
- bool is_object() { return (fh.fh_type == RGW_FS_TYPE_FILE); }
+ bool is_open() const { return flags & FLAG_OPEN; }
+ bool is_root() const { return flags & FLAG_ROOT; }
+ bool is_bucket() const { return (fh.fh_type == RGW_FS_TYPE_DIRECTORY); }
+ bool is_object() const { return (fh.fh_type == RGW_FS_TYPE_FILE); }
void open() {
flags |= FLAG_OPEN;
friend void intrusive_ptr_release(const RGWFileHandle* fh) {
if (fh->refcnt.fetch_sub(1, std::memory_order_release) == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
- delete fh;
+ /* root handles are expanded in RGWLibFS */
+ if (! const_cast<RGWFileHandle*>(fh)->is_root())
+ delete fh;
}
}
class RGWLibFS
{
struct rgw_fs fs;
+ RGWFileHandle root_fh;
std::string uid; // should match user.user_id, iiuc
public:
RGWLibFS(const char *_uid, const char *_user_id, const char* _key)
- : uid(_uid), key(_user_id, _key) {
+ : root_fh(this, nullptr, RGWFileHandle::root_name.c_str()), uid(_uid),
+ key(_user_id, _key) {
fs.fs_private = this;
}
RGWREST rest; // XXX needed for RGWProcessEnv
RGWProcessEnv env;
RGWRados* store;
- ceph::unordered_map<string, uint64_t> allocated_objects_handles;
- ceph::unordered_map<uint64_t, string> handles_map;
- atomic64_t last_allocated_handle;
+
public:
RGWLib() {}
~RGWLib() {}
int init();
int init(vector<const char *>& args);
int stop();
-
- /* generate dynamic handle currently unique per librgw object */
- uint64_t get_handle(const string& url);
-
- /* look for a matching handle (by number) */
- int check_handle(uint64_t handle);
-
- /* return the saved uri corresponding to handle */
- int get_uri(const uint64_t handle, string &uri);
};
/* request interface */