mirror of
https://github.com/ceph/ceph
synced 2025-01-01 08:32:24 +00:00
librgw: ok, make RGW vnodes cache Unix attrs
Ganesa ULP needs to see a sane progression of attrs in the CREATE path. With this change shell actions like $ echo "hi" > /nfs41/mybucket/mom work as expected. Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
This commit is contained in:
parent
5f4ef7edff
commit
fbfafb3eee
@ -35,13 +35,6 @@ const string RGWFileHandle::root_name = "/";
|
||||
|
||||
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" {
|
||||
|
||||
@ -144,22 +137,14 @@ int rgw_create(struct rgw_fs *rgw_fs,
|
||||
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;
|
||||
|
||||
@ -377,39 +362,17 @@ int rgw_getattr(struct rgw_fs *rgw_fs,
|
||||
|
||||
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();
|
||||
|
||||
@ -419,25 +382,22 @@ int rgw_getattr(struct rgw_fs *rgw_fs,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -520,6 +480,8 @@ int rgw_readdir(struct rgw_fs *rgw_fs,
|
||||
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 */
|
||||
@ -593,6 +555,11 @@ int rgw_write(struct rgw_fs *rgw_fs,
|
||||
|
||||
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;
|
||||
@ -701,6 +668,8 @@ int rgw_readv(struct rgw_fs *rgw_fs,
|
||||
|
||||
int rc = librgw.get_fe()->execute_req(&req);
|
||||
|
||||
/* XXX update size (in request) */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,13 @@
|
||||
*/
|
||||
#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;
|
||||
@ -104,6 +111,7 @@ namespace rgw {
|
||||
RGWFHRef parent;
|
||||
/* const */ std::string name; /* XXX file or bucket name */
|
||||
/* const */ fh_key fhk;
|
||||
struct stat st;
|
||||
uint32_t flags;
|
||||
|
||||
public:
|
||||
@ -117,11 +125,21 @@ namespace rgw {
|
||||
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;
|
||||
}
|
||||
@ -131,13 +149,15 @@ namespace rgw {
|
||||
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()
|
||||
@ -147,6 +167,27 @@ namespace rgw {
|
||||
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;
|
||||
}
|
||||
@ -157,6 +198,8 @@ namespace rgw {
|
||||
|
||||
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;
|
||||
@ -280,7 +323,7 @@ namespace rgw {
|
||||
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-" +
|
||||
@ -323,7 +366,7 @@ namespace rgw {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user