From bb95b37e38c63481de58d39cfc71a9e9fcbd7b21 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sun, 11 Jan 2009 12:01:07 -0800 Subject: [PATCH] mds: introduce lease seq # Only recognize a release message if the seq # matches. This prevents races between mds requested revocations and volunatry client releases. --- src/include/ceph_fs.h | 2 ++ src/mds/Locker.cc | 46 ++++++++++++++++++++----------------- src/mds/mdstypes.h | 3 ++- src/messages/MClientLease.h | 8 +++++-- src/messages/MClientReply.h | 3 +++ 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 05b2f20475838..497f18c418184 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -855,6 +855,7 @@ struct ceph_mds_reply_inode { struct ceph_mds_reply_lease { __le16 mask; __le32 duration_ms; + __le32 seq; } __attribute__ ((packed)); struct ceph_mds_reply_dirfrag { @@ -1065,6 +1066,7 @@ struct ceph_mds_lease { __le16 mask; __le64 ino; __le64 first, last; + __le32 seq; } __attribute__ ((packed)); /* followed by a __le32+string for dname */ diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 41a9c24a1c291..98c1cbb8d7275 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -1364,6 +1364,11 @@ void Locker::handle_client_lease(MClientLease *m) delete m; return; } + if (l->seq != m->get_seq()) { + dout(7) << "handle_client_lease lease seq " << l->seq << " != " << m->get_seq() << dendl; + delete m; + return; + } switch (m->get_action()) { case CEPH_MDS_LEASE_RELEASE: @@ -1390,16 +1395,20 @@ void Locker::handle_client_lease(MClientLease *m) void Locker::_issue_client_lease(MDSCacheObject *p, int mask, int pool, int client, bufferlist &bl, utime_t now, Session *session) { + LeaseStat e; + e.mask = mask; + if (mask) { ClientLease *l = p->add_client_lease(client, mask); session->touch_lease(l); + e.seq = ++l->seq; + now += mdcache->client_lease_durations[pool]; mdcache->touch_client_lease(l, pool, now); - } + } else + e.seq = 0; - LeaseStat e; - e.mask = mask; e.duration_ms = (int)(1000 * mdcache->client_lease_durations[pool]); ::encode(e, bl); dout(20) << "_issue_client_lease mask " << e.mask << " dur " << e.duration_ms << "ms" << dendl; @@ -1467,24 +1476,19 @@ void Locker::revoke_client_leases(SimpleLock *lock) continue; n++; - if (lock->get_type() == CEPH_LOCK_DN) { - CDentry *dn = (CDentry*)lock->get_parent(); - int mask = CEPH_LOCK_DN; - - // i should also revoke the dir ICONTENT lease, if they have it! - CInode *diri = dn->get_dir()->get_inode(); - mds->send_message_client(new MClientLease(CEPH_MDS_LEASE_REVOKE, - mask, - diri->ino(), - diri->first, CEPH_NOSNAP, - dn->get_name()), - l->client); - } else { - CInode *in = (CInode*)lock->get_parent(); - mds->send_message_client(new MClientLease(CEPH_MDS_LEASE_REVOKE, - lock->get_type(), in->ino(), in->first, in->last), - l->client); - } + assert(lock->get_type() == CEPH_LOCK_DN); + + CDentry *dn = (CDentry*)lock->get_parent(); + int mask = CEPH_LOCK_DN; + + // i should also revoke the dir ICONTENT lease, if they have it! + CInode *diri = dn->get_dir()->get_inode(); + mds->send_message_client(new MClientLease(CEPH_MDS_LEASE_REVOKE, l->seq, + mask, + diri->ino(), + diri->first, CEPH_NOSNAP, + dn->get_name()), + l->client); } assert(n == lock->get_num_client_lease()); } diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index e83e681cf4e91..8674109c29792 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -877,12 +877,13 @@ struct ClientLease { int mask; // CEPH_STAT_MASK_* MDSCacheObject *parent; + ceph_seq_t seq; utime_t ttl; xlist::item session_lease_item; // per-session list xlist::item lease_item; // global list ClientLease(int c, MDSCacheObject *p) : - client(c), mask(0), parent(p), + client(c), mask(0), parent(p), seq(0), session_lease_item(this), lease_item(this) { } }; diff --git a/src/messages/MClientLease.h b/src/messages/MClientLease.h index 57496c73ae1d8..7869eb9cc222b 100644 --- a/src/messages/MClientLease.h +++ b/src/messages/MClientLease.h @@ -33,24 +33,27 @@ struct MClientLease : public Message { nstring dname; int get_action() { return h.action; } + ceph_seq_t get_seq() { return h.seq; } int get_mask() { return h.mask; } inodeno_t get_ino() { return inodeno_t(h.ino); } snapid_t get_first() { return snapid_t(h.first); } snapid_t get_last() { return snapid_t(h.last); } MClientLease() : Message(CEPH_MSG_CLIENT_LEASE) {} - MClientLease(int ac, int m, __u64 i, __u64 sf, __u64 sl) : + MClientLease(int ac, ceph_seq_t seq, int m, __u64 i, __u64 sf, __u64 sl) : Message(CEPH_MSG_CLIENT_LEASE) { h.action = ac; + h.seq = seq; h.mask = m; h.ino = i; h.first = sf; h.last = sl; } - MClientLease(int ac, int m, __u64 i, __u64 sf, __u64 sl, const nstring& d) : + MClientLease(int ac, ceph_seq_t seq, int m, __u64 i, __u64 sf, __u64 sl, const nstring& d) : Message(CEPH_MSG_CLIENT_LEASE), dname(d) { h.action = ac; + h.seq = seq; h.mask = m; h.ino = i; h.first = sf; @@ -60,6 +63,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()) + << " seq " << get_seq() << " mask " << get_mask(); out << " " << get_ino(); if (h.last != CEPH_NOSNAP) diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h index 34542397d0293..5b98f1f724800 100644 --- a/src/messages/MClientReply.h +++ b/src/messages/MClientReply.h @@ -49,13 +49,16 @@ struct LeaseStat { // this matches ceph_mds_reply_lease __u16 mask; __u32 duration_ms; + __u32 seq; void encode(bufferlist &bl) const { ::encode(mask, bl); ::encode(duration_ms, bl); + ::encode(seq, bl); } void decode(bufferlist::iterator &bl) { ::decode(mask, bl); ::decode(duration_ms, bl); + ::decode(seq, bl); } }; WRITE_CLASS_ENCODER(LeaseStat) -- 2.39.5