#define LIBRGW_FILE_VER_MAJOR 1
#define LIBRGW_FILE_VER_MINOR 1
-#define LIBRGW_FILE_VER_EXTRA 4
+#define LIBRGW_FILE_VER_EXTRA 5
#define LIBRGW_FILE_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra)
#define LIBRGW_FILE_VERSION_CODE LIBRGW_FILE_VERSION(LIBRGW_FILE_VER_MAJOR, LIBRGW_FILE_VER_MINOR, LIBRGW_FILE_VER_EXTRA)
const char *secret, struct rgw_fs **rgw_fs,
uint32_t flags);
+int rgw_mount2(librgw_t rgw, const char *uid, const char *key,
+ const char *secret, const char *root, struct rgw_fs **rgw_fs,
+ uint32_t flags);
+
/*
register invalidate callbacks
*/
fs->fh_cache.remove(fh.fh_hk.object, this, FHCache::FLAG_LOCK);
}
/* cond-unref parent */
- if (parent && (! parent->is_root())) {
+ if (parent && (! parent->is_mount())) {
/* safe because if parent->unref causes its deletion,
* there are a) by refcnt, no other objects/paths pointing
* to it and b) by the semantics of valid iteration of
/* stash access data for "mount" */
RGWLibFS* new_fs = new RGWLibFS(static_cast<CephContext*>(rgw), uid, acc_key,
- sec_key);
+ sec_key, "/");
+ assert(new_fs);
+
+ rc = new_fs->authorize(rgwlib.get_store());
+ if (rc != 0) {
+ delete new_fs;
+ return -EINVAL;
+ }
+
+ /* register fs for shared gc */
+ rgwlib.get_fe()->get_process()->register_fs(new_fs);
+
+ struct rgw_fs *fs = new_fs->get_fs();
+ fs->rgw = rgw;
+
+ /* XXX we no longer assume "/" is unique, but we aren't tracking the
+ * roots atm */
+
+ *rgw_fs = fs;
+
+ return 0;
+}
+
+int rgw_mount2(librgw_t rgw, const char *uid, const char *acc_key,
+ const char *sec_key, const char *root, struct rgw_fs **rgw_fs,
+ uint32_t flags)
+{
+ int rc = 0;
+
+ /* stash access data for "mount" */
+ RGWLibFS* new_fs = new RGWLibFS(static_cast<CephContext*>(rgw), uid, acc_key,
+ sec_key, root);
assert(new_fs);
rc = new_fs->authorize(rgwlib.get_store());
static constexpr uint32_t FLAG_LOCKED = 0x0200;
static constexpr uint32_t FLAG_STATELESS_OPEN = 0x0400;
static constexpr uint32_t FLAG_EXACT_MATCH = 0x0800;
+ static constexpr uint32_t FLAG_MOUNT = 0x1000;
#define CREATE_FLAGS(x) \
((x) & ~(RGWFileHandle::FLAG_CREATE|RGWFileHandle::FLAG_LOCK))
private:
RGWFileHandle(RGWLibFS* _fs)
: fs(_fs), bucket(nullptr), parent(nullptr), variant_type{directory()},
- depth(0), flags(FLAG_ROOT)
+ depth(0), flags(FLAG_NONE)
{
/* root */
fh.fh_type = RGW_FS_TYPE_DIRECTORY;
return XXH64(uid.c_str(), uid.length(), fh_key::seed);
}
- void init_rootfs(std::string& fsid, const std::string& object_name) {
+ void init_rootfs(std::string& fsid, const std::string& object_name,
+ bool is_bucket) {
/* fh_key */
fh.fh_hk.bucket = XXH64(fsid.c_str(), fsid.length(), fh_key::seed);
fh.fh_hk.object = XXH64(object_name.c_str(), object_name.length(),
name = object_name;
state.dev = init_fsid(fsid);
+
+ if (is_bucket) {
+ flags |= RGWFileHandle::FLAG_BUCKET | RGWFileHandle::FLAG_MOUNT;
+ bucket = this;
+ depth = 1;
+ } else {
+ flags |= RGWFileHandle::FLAG_ROOT | RGWFileHandle::FLAG_MOUNT;
+ }
}
public:
bool is_open() const { return flags & FLAG_OPEN; }
bool is_root() const { return flags & FLAG_ROOT; }
+ bool is_mount() const { return flags & FLAG_MOUNT; }
bool is_bucket() const { return flags & FLAG_BUCKET; }
bool is_object() const { return !is_bucket(); }
bool is_file() const { return (fh.fh_type == RGW_FS_TYPE_FILE); }
};
RGWLibFS(CephContext* _cct, const char *_uid, const char *_user_id,
- const char* _key)
+ const char* _key, const char *root)
: cct(_cct), root_fh(this), invalidate_cb(nullptr),
invalidate_arg(nullptr), shutdown(false), refcnt(1),
fh_cache(cct->_conf->rgw_nfs_fhcache_partitions,
cct->_conf->rgw_nfs_lru_lane_hiwat),
uid(_uid), key(_user_id, _key) {
- root_fh.init_rootfs(uid, RGWFileHandle::root_name);
+ if (!root || !strcmp(root, "/")) {
+ root_fh.init_rootfs(uid, RGWFileHandle::root_name, false);
+ } else {
+ root_fh.init_rootfs(uid, root, true);
+ }
/* pointer to self */
fs.fs_private = this;
fh_cache.insert_latched(fh, lat, RGWFileHandle::FHCache::FLAG_UNLOCK);
get<1>(fhr) |= RGWFileHandle::FLAG_CREATE;
/* ref parent (non-initial ref cannot fail on valid object) */
- if (! parent->is_root()) {
+ if (! parent->is_mount()) {
(void) fh_lru.ref(parent, cohort::lru::FLAG_NONE);
}
goto out; /* !LATCHED */
} /* lookup_fh(RGWFileHandle*, const char *, const uint32_t) */
inline void unref(RGWFileHandle* fh) {
- if (likely(! fh->is_root())) {
+ if (likely(! fh->is_mount())) {
(void) fh_lru.unref(fh, cohort::lru::FLAG_NONE);
}
}
inline RGWFileHandle* ref(RGWFileHandle* fh) {
- if (likely(! fh->is_root())) {
+ if (likely(! fh->is_mount())) {
fh_lru.ref(fh, cohort::lru::FLAG_NONE);
}
return fh;
}
TEST(LibRGW, MOUNT) {
- int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
- &fs, RGW_MOUNT_FLAG_NONE);
+ int ret = rgw_mount2(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+ "/", &fs, RGW_MOUNT_FLAG_NONE);
ASSERT_EQ(ret, 0);
ASSERT_NE(fs, nullptr);
}
}
TEST(LibRGW, MOUNT) {
- int ret = rgw_mount(rgw, userid.c_str(), access_key.c_str(),
- secret_key.c_str(), &fs, RGW_MOUNT_FLAG_NONE);
+ int ret = rgw_mount2(rgw, userid.c_str(), access_key.c_str(),
+ secret_key.c_str(), "/", &fs, RGW_MOUNT_FLAG_NONE);
ASSERT_EQ(ret, 0);
ASSERT_NE(fs, nullptr);
}
}
TEST(LibRGW, MOUNT) {
- int ret = rgw_mount(rgw, userid.c_str(), access_key.c_str(),
- secret_key.c_str(), &fs, RGW_MOUNT_FLAG_NONE);
+ int ret = rgw_mount2(rgw, userid.c_str(), access_key.c_str(),
+ secret_key.c_str(), "/", &fs, RGW_MOUNT_FLAG_NONE);
ASSERT_EQ(ret, 0);
ASSERT_NE(fs, nullptr);
}
}
TEST(LibRGW, MOUNT) {
- int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
- &fs, RGW_MOUNT_FLAG_NONE);
+ int ret = rgw_mount2(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+ "/", &fs, RGW_MOUNT_FLAG_NONE);
ASSERT_EQ(ret, 0);
ASSERT_NE(fs, nullptr);
}
}
TEST(LibRGW, MOUNT) {
- int ret = rgw_mount(rgw_h, userid.c_str(), access_key.c_str(),
- secret_key.c_str(), &fs, RGW_MOUNT_FLAG_NONE);
+ int ret = rgw_mount2(rgw_h, userid.c_str(), access_key.c_str(),
+ secret_key.c_str(), "/", &fs, RGW_MOUNT_FLAG_NONE);
ASSERT_EQ(ret, 0);
ASSERT_NE(fs, nullptr);