]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: update lease handler to cope with a renewal
authorSage Weil <sage@newdream.net>
Fri, 13 Mar 2009 23:23:05 +0000 (16:23 -0700)
committerSage Weil <sage@newdream.net>
Fri, 13 Mar 2009 23:23:05 +0000 (16:23 -0700)
src/include/ceph_fs.h
src/kernel/mds_client.c
src/messages/MClientLease.h

index 747df59cab885d07f0bdeb474df6f3efca45e893..8810e2853054cf19e519a2851bea7349b7586342 100644 (file)
@@ -1033,6 +1033,7 @@ enum {
        CEPH_CAP_OP_FLUSHSNAP, /* client->mds flush snapped metadata */
        CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */
        CEPH_CAP_OP_RELEASE,   /* client->mds release (clean) cap */
+       CEPH_CAP_OP_RENEW,     /* client->mds renewal request */
 };
 
 static inline const char *ceph_cap_op_name(int op)
@@ -1047,6 +1048,7 @@ static inline const char *ceph_cap_op_name(int op)
        case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap";
        case CEPH_CAP_OP_FLUSHSNAP_ACK: return "flushsnap_ack";
        case CEPH_CAP_OP_RELEASE: return "release";
+       case CEPH_CAP_OP_RENEW: return "renew";
        default: return "???";
        }
 }
@@ -1089,6 +1091,17 @@ struct ceph_mds_caps {
 #define CEPH_MDS_LEASE_RENEW            3  /* client <-> mds    */
 #define CEPH_MDS_LEASE_REVOKE_ACK       4  /* client  -> mds    */
 
+static inline const char *ceph_lease_op_name(int o)
+{
+       switch (o) {
+       case CEPH_MDS_LEASE_REVOKE: return "revoke";
+       case CEPH_MDS_LEASE_RELEASE: return "release";
+       case CEPH_MDS_LEASE_RENEW: return "renew";
+       case CEPH_MDS_LEASE_REVOKE_ACK: return "revoke_ack";
+       default: return "???";
+       }
+}
+
 struct ceph_mds_lease {
        __u8 action;
        __le16 mask;
index 0eced3493d4c2e843d055bc64e9162a3e7f22018..81073f0607864f8ffa6a2565a8149046d3a68a26 100644 (file)
@@ -1907,6 +1907,7 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
        struct ceph_vino vino;
        int mask;
        struct qstr dname;
+       int release = 0;
 
        if (le32_to_cpu(msg->hdr.src.name.type) != CEPH_ENTITY_TYPE_MDS)
                return;
@@ -1938,45 +1939,66 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
 
        /* lookup inode */
        inode = ceph_find_inode(sb, vino);
-       dout(20, "handle_lease action is %d, mask %d, ino %llx %p\n", h->action,
-            mask, vino.ino, inode);
+       dout(20, "handle_lease '%s', mask %d, ino %llx %p\n",
+            ceph_lease_op_name(h->action), mask, vino.ino, inode);
        if (inode == NULL) {
                dout(10, "handle_lease no inode %llx\n", vino.ino);
                goto release;
        }
-
-       BUG_ON(h->action != CEPH_MDS_LEASE_REVOKE);  /* for now */
-
-       /* inode */
        ci = ceph_inode(inode);
 
        /* dentry */
-       if (mask & CEPH_LOCK_DN) {
-               parent = d_find_alias(inode);
-               if (!parent) {
-                       dout(10, "no parent dentry on inode %p\n", inode);
-                       WARN_ON(1);
-                       goto release;  /* hrm... */
-               }
-               dname.hash = full_name_hash(dname.name, dname.len);
-               dentry = d_lookup(parent, &dname);
-               dput(parent);
-               if (!dentry)
-                       goto release;
-               di = ceph_dentry(dentry);
+       parent = d_find_alias(inode);
+       if (!parent) {
+               dout(10, "no parent dentry on inode %p\n", inode);
+               WARN_ON(1);
+               goto release;  /* hrm... */
+       }
+       dname.hash = full_name_hash(dname.name, dname.len);
+       dentry = d_lookup(parent, &dname);
+       dput(parent);
+       if (!dentry)
+               goto release;
+
+       spin_lock(&dentry->d_lock);
+       di = ceph_dentry(dentry);
+       switch (h->action) {
+       case CEPH_MDS_LEASE_REVOKE:
                if (di && di->lease_session == session) {
                        h->seq = cpu_to_le32(di->lease_seq);
-                       revoke_dentry_lease(dentry);
+                       __drop_dentry_lease(dentry);
                }
-               dput(dentry);
+               release = 1;
+               break;
+
+       case CEPH_MDS_LEASE_RENEW:
+               if (di && di->lease_session == session &&
+                   di->lease_gen == session->s_cap_gen) {
+                       unsigned long duration =
+                               le32_to_cpu(h->duration_ms) * HZ / 1000;
+
+                       di->lease_seq = le32_to_cpu(h->seq);
+                       dentry->d_time = le64_to_cpu(h->renew_start) +
+                               duration;
+                       di->renew_after = le64_to_cpu(h->renew_start) +
+                               (duration >> 1);
+               }
+               break;
        }
+       spin_unlock(&dentry->d_lock);
+       dput(dentry);
+
+       if (!release)
+               goto out;
 
 release:
-       iput(inode);
        /* let's just reuse the same message */
        h->action = CEPH_MDS_LEASE_REVOKE_ACK;
        ceph_msg_get(msg);
        ceph_send_msg_mds(mdsc, msg, mds);
+
+out:
+       iput(inode);
        mutex_unlock(&session->s_mutex);
        ceph_put_mds_session(session);
        return;
index 6ba6a296bd518a292709a37a8b153e101834cdaa..3e6a0d8c9cc5c58ddf2bdb6c887456693d2ed655 100644 (file)
 
 #include "msg/Message.h"
 
-static const char *get_lease_action_name(int a) {
-  switch (a) {
-  case CEPH_MDS_LEASE_REVOKE: return "revoke";
-  case CEPH_MDS_LEASE_RELEASE: return "release";
-  case CEPH_MDS_LEASE_RENEW: return "renew";
-  case CEPH_MDS_LEASE_REVOKE_ACK: return "revoke ack";
-  default: assert(0); return 0;
-  }
-}
-
-
 struct MClientLease : public Message {
   struct ceph_mds_lease h;
   nstring dname;
@@ -63,7 +52,7 @@ struct MClientLease : public Message {
 
   const char *get_type_name() { return "client_lease"; }
   void print(ostream& out) {
-    out << "client_lease(a=" << get_lease_action_name(get_action())
+    out << "client_lease(a=" << ceph_lease_op_name(get_action())
        << " seq " << get_seq()
        << " mask " << get_mask();
     out << " " << get_ino();