struct ceph_mds_reply_lease {
__le16 mask;
__le32 duration_ms;
+ __le32 seq;
} __attribute__ ((packed));
struct ceph_mds_reply_dirfrag {
__le16 mask;
__le64 ino;
__le64 first, last;
+ __le32 seq;
} __attribute__ ((packed));
/* followed by a __le32+string for dname */
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:
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;
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());
}
int mask; // CEPH_STAT_MASK_*
MDSCacheObject *parent;
+ ceph_seq_t seq;
utime_t ttl;
xlist<ClientLease*>::item session_lease_item; // per-session list
xlist<ClientLease*>::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) { }
};
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;
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)
// 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)