]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: ok, make RGW vnodes cache Unix attrs
authorMatt Benjamin <mbenjamin@redhat.com>
Thu, 12 Nov 2015 16:55:37 +0000 (11:55 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:05:57 +0000 (12:05 -0500)
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>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index c2baf04af889e1727a0f0de15baf4755cf181d6a..537f9c06a97ed06a6ab23a3f4fe05670c626a7cc 100644 (file)
@@ -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;
 }
 
index a11f4d6f88d35665b00574b7d858155870461075..de8a7135127ec16ed96983b0167064722369f960 100644 (file)
  */
 #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);