From: Sage Weil Date: Fri, 13 Mar 2009 23:23:05 +0000 (-0700) Subject: kclient: update lease handler to cope with a renewal X-Git-Tag: v0.7.1^2~11 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=466484b2526278029b6a79cb293ffb2836547db8;p=ceph.git kclient: update lease handler to cope with a renewal --- diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 747df59cab885..8810e2853054c 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -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; diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 0eced3493d4c2..81073f0607864 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -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; diff --git a/src/messages/MClientLease.h b/src/messages/MClientLease.h index 6ba6a296bd518..3e6a0d8c9cc5c 100644 --- a/src/messages/MClientLease.h +++ b/src/messages/MClientLease.h @@ -18,17 +18,6 @@ #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();