]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librgw: implement RGWLibFS::stat_leaf
authorMatt Benjamin <mbenjamin@redhat.com>
Sun, 6 Dec 2015 19:25:24 +0000 (14:25 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:06:14 +0000 (12:06 -0500)
Stats one of <object>, <object/>.   Additional control over handle
creation has been added to RGWLibFS::lookup_fh.

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index 295b099348666eedda4cfe7cee99de699087f38d..1c8f42ffcedec1d8e62dc77c154f59b09be7b2a4 100644 (file)
@@ -35,6 +35,32 @@ const string RGWFileHandle::root_name = "/";
 
 atomic<uint32_t> RGWLibFS::fs_inst;
 
+LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent,
+                                 const char *path,
+                                 uint32_t flags)
+{
+  /* find either-of <object_name>, <object_name/>, only one of
+   * which can exist;  atomicity? */
+  RGWLibFS* fs = parent->get_fs();
+  LookupFHResult fhr{nullptr, 0};
+  std::string object_name{path};
+
+  for (auto ix : { 0, 1 }) {
+    ignore(ix);
+    RGWStatObjRequest req(cct, fs->get_user(),
+                         parent->bucket_name(), object_name,
+                         RGWStatObjRequest::FLAG_NONE);
+    int rc = librgw.get_fe()->execute_req(&req);
+    if ((rc == 0) &&
+       (req.get_ret() == 0)) {
+      fhr = fs->lookup_fh(parent, path);
+      break;
+    }
+    object_name += "/";
+  }
+  return fhr;
+} /* RGWLibFS::stat_leaf */
+
 /* librgw */
 extern "C" {
 
@@ -293,6 +319,7 @@ int rgw_lookup(struct rgw_fs *rgw_fs,
   }
 
   RGWFileHandle* rgw_fh;
+  LookupFHResult fhr;
 
   if (parent->is_root()) {
     /* special: lookup on root itself */
@@ -301,31 +328,21 @@ int rgw_lookup(struct rgw_fs *rgw_fs,
     } else {
       /* name lookup in root--for now) just get a handle */
       /* XXX RGWStatBucket? */
-      LookupFHResult fhr = fs->lookup_fh(parent, path);
+      fhr = fs->lookup_fh(parent, path);
       rgw_fh = get<0>(fhr);
 
       if (! rgw_fh)
        return -ENOMEM;
     }
   } else {
-    /* XXX need to stat either-of <object_name>, <object_name/>,
-     * only one of which can exist;  atomicity? */
-    std::string object_name{path};
-    RGWStatObjRequest req(cct, fs->get_user(),
-                         parent->bucket_name(), object_name,
-                         RGWStatObjRequest::FLAG_NONE);
-
-    int rc = librgw.get_fe()->execute_req(&req);
-    if (((rc != 0) ||
-           (req.get_ret() != 0)) &&
-       (! (flags & RGW_LOOKUP_FLAG_CREATE)))
-      return -ENOENT;
-
-    LookupFHResult fhr = fs->lookup_fh(parent, path);
+    fhr = fs->stat_leaf(parent, path, RGWFileHandle::FLAG_NONE);
+    if (! get<0>(fhr)) {
+      if (! (flags & RGW_LOOKUP_FLAG_CREATE))
+       return -ENOENT;
+      else
+       fhr = fs->lookup_fh(parent, path, RGWFileHandle::FLAG_CREATE);
+    }
     rgw_fh = get<0>(fhr);
-
-    if (! rgw_fh)
-      return -ENOENT;
   } /* !root */
 
   struct rgw_file_handle *rfh = rgw_fh->get_fh();
index 0a36804cc5fd28b8fc711114dda8dbeadf02e808..321e6a45efce6a26f365e3954bd71f69f5962978 100644 (file)
 
 namespace rgw {
 
+  template <typename T>
+  static inline void ignore(T &&) {}
+
+
   namespace bi = boost::intrusive;
 
   class RGWLibFS;
@@ -113,6 +117,7 @@ namespace rgw {
   {
     struct rgw_file_handle fh;
     mutable std::atomic<uint64_t> refcnt;
+    std::mutex mtx;
     RGWLibFS* fs;
     RGWFHRef parent;
     /* const */ std::string name; /* XXX file or bucket name */
@@ -141,6 +146,7 @@ namespace rgw {
     static constexpr uint32_t FLAG_ROOT =   0x0002;
     static constexpr uint32_t FLAG_CREATE = 0x0004;
     static constexpr uint32_t FLAG_PSEUDO = 0x0008;
+    static constexpr uint32_t FLAG_LOCK =   0x0010;
 
     friend class RGWLibFS;
 
@@ -192,6 +198,8 @@ namespace rgw {
 
     struct rgw_file_handle* get_fh() { return &fh; }
 
+    RGWLibFS* get_fs() { return fs; }
+
     int stat(struct stat *st) {
       /* partial Unix attrs */
       memset(st, 0, sizeof(struct stat));
@@ -466,15 +474,17 @@ namespace rgw {
                            fhk /* key */, lat /* serializer */,
                            RGWFileHandle::FHCache::FLAG_LOCK);
       /* LATCHED */
-      if (! fh) {
+      if ((! fh) &&
+         (cflags & RGWFileHandle::FLAG_CREATE)) {
        fh = new RGWFileHandle(this, get_inst(), parent, fhk, sname);
        intrusive_ptr_add_ref(fh); /* sentinel ref */
        fh_cache.insert_latched(fh, lat,
-                               RGWFileHandle::FHCache::FLAG_NONE);
+                                 RGWFileHandle::FHCache::FLAG_NONE);
        if (cflags & RGWFileHandle::FLAG_PSEUDO)
          fh->set_pseudo();
        get<1>(fhr) = RGWFileHandle::FLAG_CREATE;
       }
+
       intrusive_ptr_add_ref(fh); /* call path/handle ref */
       lat.lock->unlock(); /* !LATCHED */
 
@@ -483,6 +493,10 @@ namespace rgw {
       return fhr;
     }
 
+    LookupFHResult stat_leaf(RGWFileHandle* parent,
+                           const char *path,
+                           uint32_t flags);
+
     /* find or create an RGWFileHandle */
     RGWFileHandle* lookup_handle(struct rgw_fh_hk fh_hk) {