]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: all directories are virtual with respect to contents 28887/head
authorMatt Benjamin <mbenjamin@redhat.com>
Fri, 7 Jun 2019 14:20:01 +0000 (10:20 -0400)
committerPrashant D <pdhange@redhat.com>
Thu, 4 Jul 2019 23:39:44 +0000 (19:39 -0400)
This change causes directory handles to always report an mtime of
"now."  This is not an invalidate per se--it interacts with the
nfs implementation to produce that result when the implementation
updates its cached attributes.  Hence, it can be modulated by timers
or other rules governing attribute caching at the upper layer.

Fixes: http://tracker.ceph.com/issues/40204
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
(cherry picked from commit b4c7d0faeff667c25ab255786999ef0cc844ea2b)

src/rgw/rgw_file.cc
src/rgw/rgw_file.h

index 7fd5790dcbd370a8f8e6761087e4500b1be51fba..32fbea242305d2c735a032c4fabdd88fa56524ba 100644 (file)
@@ -676,7 +676,7 @@ namespace rgw {
     default:
       break;
     };
-
+    /* if rgw_fh is a directory, mtime will be advanced */
     return rgw_fh->stat(st);
   } /* RGWLibFS::getattr */
 
index 2f031e1a2124a4e29ba4ae2352fd5d047278088c..e7193f27f692037f149dc2deac7b558072963628 100644 (file)
@@ -230,6 +230,15 @@ namespace rgw {
 
     void clear_state();
 
+    void advance_mtime() {
+      /* intended for use on directories, fast-forward mtime so as to
+       * ensure a new, higher value for the change attribute */
+      lock_guard guard(mtx);
+      /* sets ctime as well as mtime, to avoid masking updates should
+       * ctime inexplicably hold a higher value */
+      set_times(real_clock::now());
+    }
+
     boost::variant<file, directory> variant_type;
 
     uint16_t depth;
@@ -333,6 +342,8 @@ namespace rgw {
       switch (fh.fh_type) {
       case RGW_FS_TYPE_DIRECTORY:
        state.unix_mode = RGW_RWXMODE|S_IFDIR;
+       /* virtual directories are always invalid */
+       advance_mtime();
        break;
       case RGW_FS_TYPE_FILE:
        state.unix_mode = RGW_RWMODE|S_IFREG;
@@ -393,8 +404,12 @@ namespace rgw {
 
       if (mask & RGW_SETATTR_ATIME)
        state.atime = st->st_atim;
-      if (mask & RGW_SETATTR_MTIME)
-       state.mtime = st->st_mtim;
+
+      if (mask & RGW_SETATTR_MTIME) {
+       if (fh.fh_type != RGW_FS_TYPE_DIRECTORY)
+         state.mtime = st->st_mtim;
+      }
+
       if (mask & RGW_SETATTR_CTIME)
        state.ctime = st->st_ctim;
     }
@@ -410,18 +425,10 @@ namespace rgw {
 
       st->st_mode = state.unix_mode;
 
-#ifdef HAVE_STAT_ST_MTIMESPEC_TV_NSEC
-      st->st_atimespec = state.atime;
-      st->st_mtimespec = state.mtime;
-      st->st_ctimespec = state.ctime;
-#else
-      st->st_atim = state.atime;
-      st->st_mtim = state.mtime;
-      st->st_ctim = state.ctime;
-#endif
-
       switch (fh.fh_type) {
       case RGW_FS_TYPE_DIRECTORY:
+       /* virtual directories are always invalid */
+       advance_mtime();
        st->st_nlink = state.nlink;
        break;
       case RGW_FS_TYPE_FILE:
@@ -433,6 +440,16 @@ namespace rgw {
        break;
       }
 
+#ifdef HAVE_STAT_ST_MTIMESPEC_TV_NSEC
+      st->st_atimespec = state.atime;
+      st->st_mtimespec = state.mtime;
+      st->st_ctimespec = state.ctime;
+#else
+      st->st_atim = state.atime;
+      st->st_mtim = state.mtime;
+      st->st_ctim = state.ctime;
+#endif
+
       return 0;
     }