]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librgw: conditionally send '.' and '..' (rgw_readdir)
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 8 Jan 2016 17:40:48 +0000 (12:40 -0500)
committerMatt Benjamin <mbenjamin@redhat.com>
Fri, 12 Feb 2016 17:07:37 +0000 (12:07 -0500)
Ganesha traditionally does not expect them, but they may be needed
when bypassing the MDCACHE (2.4).

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/include/rados/rgw_file.h
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/test/librgw_file.cc
src/test/librgw_file_gp.cc
src/test/librgw_file_nfsns.cc

index 040426ef7a019be7ebad2b0ea0878a96952a6b67..98e005825a08f746e10dbf866b015ca3c75005f2 100644 (file)
@@ -152,9 +152,13 @@ int rgw_unlink(struct rgw_fs *rgw_fs,
 */
 typedef bool (*rgw_readdir_cb)(const char *name, void *arg, uint64_t offset);
 
+#define RGW_READDIR_FLAG_NONE      0x0000
+#define RGW_READDIR_FLAG_DOTDOT    0x0001 /* send dot names */
+
 int rgw_readdir(struct rgw_fs *rgw_fs,
                struct rgw_file_handle *parent_fh, uint64_t *offset,
-               rgw_readdir_cb rcb, void *cb_arg, bool *eof);
+               rgw_readdir_cb rcb, void *cb_arg, bool *eof,
+               uint32_t flags);
 
 /* XXX (get|set)attr mask bits */
 #define RGW_SETATTR_MODE   1
index 63b5c86badfb71a74798625a9ee04dfe2d2c21cf..e56a094b4b07404ba1ef4bc7c224cce0d331b91c 100644 (file)
@@ -210,7 +210,7 @@ namespace rgw {
   } /* RGWFileHandle::reclaim */
 
   int RGWFileHandle::readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset,
-                            bool *eof)
+                            bool *eof, uint32_t flags)
   {
     using event = RGWLibFS::event;
     int rc = 0;
@@ -220,6 +220,12 @@ namespace rgw {
 
     (void) clock_gettime(CLOCK_MONOTONIC_COARSE, &now); /* !LOCKED */
 
+    if (flags & RGW_READDIR_FLAG_DOTDOT) {
+      /* send '.' and '..' with their NFS-defined offsets */
+      rcb(".", cb_arg, 1);
+      rcb("..", cb_arg, 2);
+    }
+
     if (is_root()) {
       RGWListBucketsRequest req(cct, fs->get_user(), this, rcb, cb_arg,
                                offset);
@@ -957,14 +963,15 @@ int rgw_close(struct rgw_fs *rgw_fs,
 
 int rgw_readdir(struct rgw_fs *rgw_fs,
                struct rgw_file_handle *parent_fh, uint64_t *offset,
-               rgw_readdir_cb rcb, void *cb_arg, bool *eof)
+               rgw_readdir_cb rcb, void *cb_arg, bool *eof,
+               uint32_t flags)
 {
   RGWFileHandle* parent = get_rgwfh(parent_fh);
   if (! parent) {
     /* bad parent */
     return -EINVAL;
   }
-  int rc = parent->readdir(rcb, cb_arg, offset, eof);
+  int rc = parent->readdir(rcb, cb_arg, offset, eof, flags);
   return -rc;
 }
 
index a6ca509744b0f39e964cce71b028ada4f6ddb987..7009bd559b0c95e23d8dd3309d66212cd49d0681 100644 (file)
@@ -417,7 +417,8 @@ namespace rgw {
       return EPERM;
     }
 
-    int readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset, bool *eof);
+    int readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset, bool *eof,
+               uint32_t flags);
     int write(uint64_t off, size_t len, size_t *nbytes, void *buffer);
     int write_finish();
     int close();
index 0af400cc2084a93a354c3ffdca11b6b2ddf85909..949e2eaa9236ce66d5274545a64bfb30c5506413 100644 (file)
@@ -97,7 +97,8 @@ TEST(LibRGW, LIST_BUCKETS) {
 
   bool eof = false;
   uint64_t offset = 0;
-  int ret = rgw_readdir(fs, fs->root_fh, &offset, r1_cb, &fids1, &eof);
+  int ret = rgw_readdir(fs, fs->root_fh, &offset, r1_cb, &fids1, &eof,
+                       RGW_READDIR_FLAG_NONE);
   for (auto& fid : fids1) {
     std::cout << "fname: " << get<0>(fid) << " fid: " << get<1>(fid)
              << std::endl;
@@ -170,7 +171,8 @@ TEST(LibRGW, LIST_OBJECTS) {
 
     bool eof = false;
     uint64_t offset = 0;
-    int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &obj_vector, &eof);
+    int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &obj_vector, &eof,
+                         RGW_READDIR_FLAG_NONE);
     for (auto& obj : obj_vector) {
       std::cout << "fname: " << get<0>(obj) << " fid: " << get<1>(obj)
                << std::endl;
index ed988e92f42d4b15b9bf2ebe0a6e6935ec755077..eab64a8aa813c36d658364cffb4c91dd0627c01b 100644 (file)
@@ -208,7 +208,7 @@ TEST(LibRGW, LIST_OBJECTS) {
     bool eof = false;
     uint64_t offset = 0;
     int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &fids,
-                         &eof);
+                         &eof, RGW_READDIR_FLAG_NONE);
     for (auto& fid : fids) {
       std::cout << "fname: " << get<0>(fid) << " fid: " << get<1>(fid)
                << std::endl;
index 4aada698ac2d40cf0c6f437d7dd6352ea13517ec..e91e452af292aebcf31c61fc3a6fce210ecc1b6c 100644 (file)
@@ -167,8 +167,12 @@ extern "C" {
                           << " dir=" << rgw_fh->full_object_name()
                           << " called back name=" << name
                           << dendl;
-    obj_stack.push(
-      obj_rec{name, nullptr, parent_fh, nullptr});
+    string name_str{name};
+    if (! ((name_str == ".") ||
+          (name_str == ".."))) {
+      obj_stack.push(
+       obj_rec{std::move(name_str), nullptr, parent_fh, nullptr});
+    }
     return true; /* XXX */
   }
 }
@@ -222,7 +226,8 @@ TEST(LibRGW, ENUMERATE1) {
            << " object_name: " << elt.rgw_fh->object_name()
            << " full_name: " << elt.rgw_fh->full_object_name()
            << dendl;
-         rc = rgw_readdir(fs, elt.fh, &offset, r1_cb, elt.fh, &eof);
+         rc = rgw_readdir(fs, elt.fh, &offset, r1_cb, elt.fh, &eof,
+                          RGW_READDIR_FLAG_DOTDOT);
          elt.state.readdir = true;
          ASSERT_EQ(rc, 0);
          // ASSERT_TRUE(eof); // XXXX working incorrectly w/single readdir
@@ -324,7 +329,11 @@ extern "C" {
                           << " iv count=" << dvec.count
                           << " called back name=" << name
                           << dendl;
-    dvec.obj_names.push_back(dirent_t{name, offset});
+    string name_str{name};
+    if (! ((name_str == ".") ||
+          (name_str == ".."))) {
+      dvec.obj_names.push_back(dirent_t{std::move(name_str), offset});
+    }
     return true; /* XXX */
   }
 }
@@ -347,7 +356,8 @@ TEST(LibRGW, MARKER1_READDIR)
 
     do {
       ASSERT_TRUE(dvec.count <= max_iterations);
-      int ret = rgw_readdir(fs, marker_fh, &offset, r2_cb, &dvec, &eof);
+      int ret = rgw_readdir(fs, marker_fh, &offset, r2_cb, &dvec, &eof,
+                           RGW_READDIR_FLAG_DOTDOT);
       ASSERT_EQ(ret, 0);
       ASSERT_EQ(offset, get<1>(dvec.obj_names.back())); // cookie check
       ++dvec.count;