]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: include nfiles/nsubdirs of directory inode in MClientCaps 21866/head
authorYan, Zheng <zyan@redhat.com>
Thu, 26 Apr 2018 07:12:48 +0000 (15:12 +0800)
committerPatrick Donnelly <pdonnell@redhat.com>
Mon, 7 May 2018 22:45:26 +0000 (15:45 -0700)
Directory inode's dirstat gets updated by request reply, but not by
cap message. This causes problem for following case.

1. MDS modifies a directory
2. MDS issues CEPH_CAP_ANY_SHARED to client
3. The client satifies stat(2) by its cached metadata.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Fixes: http://tracker.ceph.com/issues/23855
(cherry picked from commit ee2c628f6783954e9b25fab8ac9b572a58666a91)

src/client/Client.cc
src/mds/CInode.cc
src/messages/MClientCaps.h

index 131f80ce451b41ca35abd87673ffc8a9bd290144..10135ae68b7b885ad32091418ad24a9fe0221096 100644 (file)
@@ -5056,6 +5056,12 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient
     decode(in->xattrs, p);
     in->xattr_version = m->head.xattr_version;
   }
+
+  if ((new_caps & CEPH_CAP_FILE_SHARED) && m->dirstat_is_valid()) {
+    in->dirstat.nfiles = m->get_nfiles();
+    in->dirstat.nsubdirs = m->get_nsubdirs();
+  }
+
   update_inode_file_bits(in, m->get_truncate_seq(), m->get_truncate_size(), m->get_size(),
                         m->get_change_attr(), m->get_time_warp_seq(), m->get_ctime(),
                         m->get_mtime(), m->get_atime(),
index 894524149c4ef279771e391fc5543c9940ec742e..4b9379cc781d34bc52b1e79188b323f07056dc1a 100644 (file)
@@ -3636,6 +3636,8 @@ void CInode::encode_cap_message(MClientCaps *m, Capability *cap)
   m->ctime = i->ctime;
   m->change_attr = i->change_attr;
   m->time_warp_seq = i->time_warp_seq;
+  m->nfiles = i->dirstat.nfiles;
+  m->nsubdirs = i->dirstat.nsubdirs;
 
   if (cap->client_inline_version < i->inline_data.version) {
     m->inline_version = cap->client_inline_version = i->inline_data.version;
index 8df0679ca36b3fb7d6cad087809b6d984ec70d59..33218f740f74af6d6eb3bf766ebfc2609d22fad4 100644 (file)
@@ -19,7 +19,7 @@
 #include "include/ceph_features.h"
 
 class MClientCaps : public Message {
-  static const int HEAD_VERSION = 10;
+  static const int HEAD_VERSION = 11;
   static const int COMPAT_VERSION = 1;
 
  public:
@@ -29,27 +29,32 @@ class MClientCaps : public Message {
 
   struct ceph_mds_caps_head head;
 
-  uint64_t size, max_size, truncate_size, change_attr;
-  uint32_t truncate_seq;
+  uint64_t size = 0;
+  uint64_t max_size = 0;
+  uint64_t truncate_size = 0;
+  uint64_t change_attr = 0;
+  uint32_t truncate_seq = 0;
   utime_t mtime, atime, ctime, btime;
-  uint32_t time_warp_seq;
+  uint32_t time_warp_seq = 0;
+  int64_t nfiles = -1;         // files in dir
+  int64_t nsubdirs = -1;       // subdirs in dir
 
   struct ceph_mds_cap_peer peer;
 
   bufferlist snapbl;
   bufferlist xattrbl;
   bufferlist flockbl;
-  version_t  inline_version;
+  version_t  inline_version = 0;
   bufferlist inline_data;
 
   // Receivers may not use their new caps until they have this OSD map
-  epoch_t osd_epoch_barrier;
-  ceph_tid_t oldest_flush_tid;
-  uint32_t caller_uid;
-  uint32_t caller_gid;
+  epoch_t osd_epoch_barrier = 0;
+  ceph_tid_t oldest_flush_tid = 0;
+  uint32_t caller_uid = 0;
+  uint32_t caller_gid = 0;
 
   /* advisory CLIENT_CAPS_* flags to send to mds */
-  unsigned flags;
+  unsigned flags = 0;
 
   int      get_caps() { return head.caps; }
   int      get_wanted() { return head.wanted; }
@@ -72,6 +77,9 @@ class MClientCaps : public Message {
   utime_t get_atime() { return atime; }
   __u64 get_change_attr() { return change_attr; }
   __u32 get_time_warp_seq() { return time_warp_seq; }
+  uint64_t get_nfiles() { return nfiles; }
+  uint64_t get_nsubdirs() { return nsubdirs; }
+  bool dirstat_is_valid() const { return nfiles != -1 || nsubdirs != -1; }
 
   const file_layout_t& get_layout() {
     return layout;
@@ -117,19 +125,7 @@ class MClientCaps : public Message {
   void clear_dirty() { head.dirty = 0; }
 
   MClientCaps()
-    : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
-      size(0),
-      max_size(0),
-      truncate_size(0),
-      change_attr(0),
-      truncate_seq(0),
-      time_warp_seq(0),
-      osd_epoch_barrier(0),
-      oldest_flush_tid(0),
-      caller_uid(0), caller_gid(0),
-      flags(0) {
-    inline_version = 0;
-  }
+    : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION) {}
   MClientCaps(int op,
              inodeno_t ino,
              inodeno_t realm,
@@ -141,16 +137,7 @@ class MClientCaps : public Message {
              int mseq,
               epoch_t oeb)
     : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
-      size(0),
-      max_size(0),
-      truncate_size(0),
-      change_attr(0),
-      truncate_seq(0),
-      time_warp_seq(0),
-      osd_epoch_barrier(oeb),
-      oldest_flush_tid(0),
-      caller_uid(0), caller_gid(0),
-      flags(0) {
+      osd_epoch_barrier(oeb) {
     memset(&head, 0, sizeof(head));
     head.op = op;
     head.ino = ino;
@@ -162,22 +149,12 @@ class MClientCaps : public Message {
     head.dirty = dirty;
     head.migrate_seq = mseq;
     memset(&peer, 0, sizeof(peer));
-    inline_version = 0;
   }
   MClientCaps(int op,
              inodeno_t ino, inodeno_t realm,
              uint64_t id, int mseq, epoch_t oeb)
     : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
-      size(0),
-      max_size(0),
-      truncate_size(0),
-      change_attr(0),
-      truncate_seq(0),
-      time_warp_seq(0),
-      osd_epoch_barrier(oeb),
-      oldest_flush_tid(0),
-      caller_uid(0), caller_gid(0),
-      flags(0) {
+      osd_epoch_barrier(oeb) {
     memset(&head, 0, sizeof(head));
     head.op = op;
     head.ino = ino;
@@ -185,7 +162,6 @@ class MClientCaps : public Message {
     head.cap_id = id;
     head.migrate_seq = mseq;
     memset(&peer, 0, sizeof(peer));
-    inline_version = 0;
   }
 private:
   file_layout_t layout;
@@ -281,6 +257,10 @@ public:
     if (header.version >= 10) {
       decode(flags, p);
     }
+    if (header.version >= 11) {
+      decode(nfiles, p);
+      decode(nsubdirs, p);
+    }
   }
   void encode_payload(uint64_t features) override {
     using ceph::encode;
@@ -342,6 +322,8 @@ public:
     encode(btime, payload);
     encode(change_attr, payload);
     encode(flags, payload);
+    encode(nfiles, payload);
+    encode(nsubdirs, payload);
   }
 };