atomic<uint32_t> RGWLibFS::fs_inst;
-
-#define RGW_RWXMODE (S_IRWXU | S_IRWXG | S_IRWXO)
-
-#define RGW_RWMODE (RGW_RWXMODE & \
- ~(S_IXUSR | S_IXGRP | S_IXOTH))
-
-
/* librgw */
extern "C" {
if (get<1>(fhr) & RGWFileHandle::FLAG_CREATE) {
/* fill in stat data */
time_t now = time(0);
- memset(st, 0, sizeof(struct stat));
- st->st_dev = fs->get_inst();
- st->st_ino = rgw_fh->get_fh()->fh_hk.object; // XXX
- st->st_mode = RGW_RWMODE|S_IFREG;
- st->st_nlink = 1;
- st->st_uid = 0; // XXX
- st->st_gid = 0; // XXX
- st->st_size = 0;
- st->st_blksize = 4096;
- st->st_blocks = 0;
- st->st_atim.tv_sec = now;
- st->st_mtim.tv_sec = now;
- st->st_ctim.tv_sec = now;
+ rgw_fh->get_stat()->st_atim.tv_sec = now;
+ rgw_fh->get_stat()->st_mtim.tv_sec = now;
+ rgw_fh->get_stat()->st_ctim.tv_sec = now;
rgw_fh->open_for_create();
}
+ *st = *(rgw_fh->get_stat());
+
struct rgw_file_handle *rfh = rgw_fh->get_fh();
*fh = rfh;
RGWFileHandle* rgw_fh = get_rgwfh(fh);
- if (rgw_fh->is_root()) {
- /* XXX do something */
- memset(st, 0, sizeof(struct stat));
- st->st_dev = fs->get_inst();
- st->st_ino = rgw_fh->get_fh()->fh_hk.object; // XXX
- st->st_mode = RGW_RWXMODE|S_IFDIR;
- st->st_nlink = 3;
- st->st_uid = 0; // XXX
- st->st_gid = 0; // XXX
-#if 0
- /* XXX cluster create time? do we know that? */
- st->st_atim.tv_sec = req.mtime();
- st->st_mtim.tv_sec = req.mtime();
- st->st_ctim.tv_sec = req.ctime();
-#endif
- } else if (rgw_fh->is_bucket()) {
- /* bucket */
- /* fill in stat data */
- memset(st, 0, sizeof(struct stat));
- st->st_dev = fs->get_inst();
- st->st_ino = rgw_fh->get_fh()->fh_hk.object; // XXX
- st->st_mode = RGW_RWXMODE|S_IFDIR;
- st->st_nlink = 3;
- st->st_uid = 0; // XXX
- st->st_gid = 0; // XXX
-#if 0
- /* XXX we can at least get creation_time */
- st->st_atim.tv_sec = req.mtime();
- st->st_mtim.tv_sec = req.mtime();
- st->st_ctim.tv_sec = req.ctime();
-#endif
+ if (rgw_fh->is_root() ||
+ rgw_fh->is_bucket()) {
+ /* XXX nothing */
} else {
/* object */
+
+ /* an object being created isn't expected to exist (if it does,
+ * we'll detect the conflict later */
+ if (rgw_fh->creating())
+ goto done;
+
const std::string bname = rgw_fh->bucket_name();
const std::string oname = rgw_fh->object_name();
int rc = librgw.get_fe()->execute_req(&req);
if ((rc != 0) ||
- (req.get_ret() != 0))
+ (req.get_ret() != 0)) {
+ /* XXX EINVAL is likely illegal protocol return--if the object
+ * should but doesn't exist, it should probably be ENOENT */
return -EINVAL;
+ }
/* fill in stat data */
- memset(st, 0, sizeof(struct stat));
- st->st_dev = fs->get_inst();
- st->st_ino = rgw_fh->get_fh()->fh_hk.object; // XXX
- st->st_mode = RGW_RWMODE|S_IFREG;
- st->st_nlink = 1;
- st->st_uid = 0; // XXX
- st->st_gid = 0; // XXX
- st->st_size = req.size();
- st->st_blksize = 4096;
- st->st_blocks = (st->st_size) / 512;
- st->st_atim.tv_sec = req.mtime();
- st->st_mtim.tv_sec = req.mtime();
- st->st_ctim.tv_sec = req.ctime();
+ rgw_fh->get_stat()->st_size = req.size();
+ rgw_fh->get_stat()->st_blocks = (st->st_size) / 512;
+ rgw_fh->get_stat()->st_atim.tv_sec = req.mtime();
+ rgw_fh->get_stat()->st_mtim.tv_sec = req.mtime();
+ rgw_fh->get_stat()->st_ctim.tv_sec = req.ctime();
}
+done:
+ *st = *(rgw_fh->get_stat());
return 0;
}
RGWListBucketRequest req(cct, fs->get_user(), uri, rcb, cb_arg, offset);
rc = librgw.get_fe()->execute_req(&req);
+ /* XXX update link count (incorrectly) */
+ parent->get_stat()->st_nlink = 3 + *offset;
}
/* XXXX request MUST set this */
int rc = librgw.get_fe()->execute_req(&req);
+ /* XXX move into request */
+ ssize_t min_size = offset+length;
+ if (min_size > rgw_fh->get_stat()->st_size)
+ rgw_fh->get_stat()->st_size = min_size;
+
*bytes_written = (rc == 0) ? req.bytes_written : 0;
return rc;
int rc = librgw.get_fe()->execute_req(&req);
+ /* XXX update size (in request) */
+
return rc;
}
*/
#include "include/assert.h"
+
+#define RGW_RWXMODE (S_IRWXU | S_IRWXG | S_IRWXO)
+
+#define RGW_RWMODE (RGW_RWXMODE & \
+ ~(S_IXUSR | S_IXGRP | S_IXOTH))
+
+
namespace rgw {
namespace bi = boost::intrusive;
RGWFHRef parent;
/* const */ std::string name; /* XXX file or bucket name */
/* const */ fh_key fhk;
+ struct stat st;
uint32_t flags;
public:
friend class RGWLibFS;
private:
- RGWFileHandle(RGWLibFS* _fs)
+ RGWFileHandle(RGWLibFS* _fs, uint32_t fs_inst)
: refcnt(1), fs(_fs), parent(nullptr), flags(FLAG_ROOT)
{
/* root */
fh.fh_type = RGW_FS_TYPE_DIRECTORY;
+
+ /* partial Unix attrs */
+ memset(&st, 0, sizeof(struct stat));
+ st.st_dev = fs_inst;
+ st.st_mode = RGW_RWXMODE|S_IFDIR;
+ st.st_nlink = 3;
+
+ st.st_uid = 0; // XXX
+ st.st_gid = 0; // XXX
+
/* pointer to self */
fh.fh_private = this;
}
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(),
fh_key::seed);
+ /* fixup Unix attrs */
+ st.st_ino = fh.fh_hk.object;
fhk = fh.fh_hk;
name = object_name;
}
public:
- RGWFileHandle(RGWLibFS* fs, RGWFileHandle* _parent, const fh_key& _fhk,
- const char *_name)
+ RGWFileHandle(RGWLibFS* fs, uint32_t fs_inst, RGWFileHandle* _parent,
+ const fh_key& _fhk, const char *_name)
: parent(_parent), name(_name), fhk(_fhk), flags(FLAG_NONE) {
fh.fh_type = parent->is_root()
fh_key fhk(parent->name, name);
fh.fh_hk = fhk.fh_hk; /* XXX redundant in fh_hk */
+ /* partial Unix attrs */
+ memset(&st, 0, sizeof(struct stat));
+ st.st_dev = fs_inst;
+ st.st_ino = fh.fh_hk.object; // XXX
+
+ st.st_uid = 0; // XXX
+ st.st_gid = 0; // XXX
+
+ switch (fh.fh_type) {
+ case RGW_FS_TYPE_DIRECTORY:
+ st.st_mode = RGW_RWXMODE|S_IFDIR;
+ st.st_nlink = 3;
+ break;
+ case RGW_FS_TYPE_FILE:
+ st.st_mode = RGW_RWMODE|S_IFREG;
+ st.st_nlink = 1;
+ st.st_blksize = 4096;
+ default:
+ break;
+ }
+
/* pointer to self */
fh.fh_private = this;
}
struct rgw_file_handle* get_fh() { return &fh; }
+ struct stat *get_stat() { return &st; }
+
const std::string& bucket_name() const {
if (is_root())
return root_name;
public:
RGWLibFS(CephContext* _cct, const char *_uid, const char *_user_id,
const char* _key)
- : cct(_cct), root_fh(this), uid(_uid), key(_user_id, _key) {
+ : cct(_cct), root_fh(this, get_inst()), uid(_uid), key(_user_id, _key) {
/* no bucket may be named rgw_fs_inst-(.*) */
fsid = RGWFileHandle::root_name + "rgw_fs_inst-" +
RGWFileHandle::FHCache::FLAG_LOCK);
/* LATCHED */
if (! fh) {
- fh = new RGWFileHandle(this, parent, fhk, name);
+ fh = new RGWFileHandle(this, get_inst(), parent, fhk, name);
intrusive_ptr_add_ref(fh); /* sentinel ref */
fh_cache.insert_latched(fh, lat,
RGWFileHandle::FHCache::FLAG_NONE);