]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add osdmap epoch for setxattr of MClientRequest.
authorJianpeng Ma <jianpeng.ma@intel.com>
Tue, 25 Aug 2015 00:29:44 +0000 (08:29 +0800)
committerJianpeng Ma <jianpeng.ma@intel.com>
Mon, 31 Aug 2015 03:47:14 +0000 (11:47 +0800)
  Now we use setxattr set file/dir layout. This may need data pool
info. So in mds server, it need check osdmap. At present, if mds
don't find data pool, it will get the latest osdmap. Now if pass osd epoch
as a parameter for setxattr. We can only check this epoch of osdmap.
  But for compatible, we still need old code for old client.

Signed-off-by: Jianpeng Ma <jianpeng.ma@intel.com>
src/include/ceph_fs.h
src/mds/Server.cc
src/messages/MClientRequest.h

index 769f51966a4a62542e8bd16d34fb73dd7b7c07db..08ef460bfe055626596e52c91d8603563f5551ac 100644 (file)
@@ -409,6 +409,7 @@ union ceph_mds_request_args {
        } __attribute__ ((packed)) open;
        struct {
                __le32 flags;
+               __le32 osdmap_epoch;        /* use for set file/dir layout */
        } __attribute__ ((packed)) setxattr;
        struct {
                struct ceph_file_layout layout;
index be3a9269975c4cf7bf2356884730a885f7bea531..2b7554cf09ae8623c7ee6f7e16b02bea59e217cc 100644 (file)
@@ -4019,16 +4019,21 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
       rest = name.substr(name.find("layout"));
       const OSDMap *osdmap = mds->objecter->get_osdmap_read();
       int r = parse_layout_vxattr(rest, value, osdmap, &layout);
+      epoch_t epoch = osdmap->get_epoch();
       mds->objecter->put_osdmap_read();
       if (r < 0) {
        if (r == -ENOENT) {
-         if (!mdr->waited_for_osdmap) {
-           // make sure we have the latest map.
-           // FIXME: we should get the client's osdmap epoch and just
-           // make sure we have *that*.
+         epoch_t req_epoch = req->get_osdmap_epoch();
+         if (req_epoch > epoch) {
+           if (!mds->objecter->wait_for_map(req_epoch,
+                 new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher)))
+           return;
+         } else  if (req_epoch == 0 && !mdr->waited_for_osdmap) {
+           // For compatibility with client w/ old code, we still need get the latest map. 
+           // One day if COMPACT_VERSION of MClientRequest >=3, we can remove those code.
            mdr->waited_for_osdmap = true;
            mds->objecter->wait_for_latest_osdmap(
-             new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
+               new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
            return;
          }
          r = -EINVAL;
@@ -4057,13 +4062,18 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
       rest = name.substr(name.find("layout"));
       const OSDMap *osdmap = mds->objecter->get_osdmap_read();
       int r = parse_layout_vxattr(rest, value, osdmap, &layout);
+      epoch_t epoch = osdmap->get_epoch();
       mds->objecter->put_osdmap_read();
       if (r < 0) {
        if (r == -ENOENT) {
-         if (!mdr->waited_for_osdmap) {
-           // make sure we have the latest map.
-           // FIXME: we should get the client's osdmap epoch and just
-           // make sure we have *that*.
+         epoch_t req_epoch = req->get_osdmap_epoch();
+         if (req_epoch > epoch) {
+           if (!mds->objecter->wait_for_map(req_epoch,
+               new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher)))
+           return;
+         } else if (req_epoch == 0 && !mdr->waited_for_osdmap) {
+           // For compatibility with client w/ old code, we still need get the latest map. 
+           // One day if COMPACT_VERSION of MClientRequest >=3, we can remove those code.
            mdr->waited_for_osdmap = true;
            mds->objecter->wait_for_latest_osdmap(
              new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
index 35dbb1757666feb70717b7435e95a1ab1b0fa934..1c374591057600c61be3d1ca6f9ea6ad1b41169b 100644 (file)
@@ -46,7 +46,7 @@
 // metadata ops.
 
 class MClientRequest : public Message {
-  static const int HEAD_VERSION = 2;
+  static const int HEAD_VERSION = 3;
   static const int COMPAT_VERSION = 1;
 
 public:
@@ -93,6 +93,17 @@ private:
 public:
   void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; }
   epoch_t get_mdsmap_epoch() { return head.mdsmap_epoch; }
+  epoch_t get_osdmap_epoch() const {
+    assert(head.op == CEPH_MDS_OP_SETXATTR);
+    if (header.version >= 3)
+      return head.args.setxattr.osdmap_epoch;
+    else
+      return 0;
+  }
+  void set_osdmap_epoch(epoch_t e) {
+    assert(head.op == CEPH_MDS_OP_SETXATTR);
+    head.args.setxattr.osdmap_epoch = e;
+  }
 
   metareqid_t get_reqid() {
     // FIXME: for now, assume clients always have 1 incarnation