mds/snap.h\
messages/MCacheExpire.h\
messages/MClientCaps.h\
+ messages/MClientCapRelease.h\
messages/MClientLease.h\
messages/MClientMount.h\
messages/MClientMountAck.h\
#define CEPH_MSG_CLIENT_CAPS 0x310
#define CEPH_MSG_CLIENT_LEASE 0x311
#define CEPH_MSG_CLIENT_SNAP 0x312
+#define CEPH_MSG_CLIENT_CAPRELEASE 0x313
/* osd */
#define CEPH_MSG_OSD_GETMAP 40
__le32 time_warp_seq;
} __attribute__ ((packed));
+struct ceph_mds_cap_release {
+ __le32 num;
+} __attribute__ ((packed));
+
+struct ceph_mds_cap_item {
+ __le64 ino;
+ __le64 cap_id;
+ __le32 migrate_seq, seq;
+} __attribute__ ((packed));
#define CEPH_MDS_LEASE_REVOKE 1 /* mds -> client */
#define CEPH_MDS_LEASE_RELEASE 2 /* client -> mds */
WRITE_RAW_ENCODER(ceph_client_ticket)
WRITE_RAW_ENCODER(ceph_mds_request_head)
WRITE_RAW_ENCODER(ceph_mds_caps)
+WRITE_RAW_ENCODER(ceph_mds_cap_release)
+WRITE_RAW_ENCODER(ceph_mds_cap_item)
WRITE_RAW_ENCODER(ceph_mds_lease)
WRITE_RAW_ENCODER(ceph_mds_snap_head)
WRITE_RAW_ENCODER(ceph_mds_snap_realm)
#include "messages/MClientRequest.h"
#include "messages/MClientReply.h"
#include "messages/MClientCaps.h"
+#include "messages/MClientCapRelease.h"
#include "messages/MMDSSlaveRequest.h"
case CEPH_MSG_CLIENT_CAPS:
handle_client_caps((MClientCaps*)m);
break;
+ case CEPH_MSG_CLIENT_CAPRELEASE:
+ handle_client_cap_release((MClientCapRelease*)m);
+ break;
case CEPH_MSG_CLIENT_LEASE:
handle_client_lease((MClientLease*)m);
break;
return true;
}
+void Locker::handle_client_cap_release(MClientCapRelease *m)
+{
+ int client = m->get_source().num();
+ dout(10) << "handle_client_cap_release " << *m << dendl;
+
+ for (vector<ceph_mds_cap_item>::iterator p = m->caps.begin(); p != m->caps.end(); p++) {
+ inodeno_t ino((__u64)p->ino);
+ CInode *in = mdcache->get_inode(ino);
+ if (!in) {
+ dout(10) << " missing ino " << ino << dendl;
+ continue;
+ }
+ Capability *cap = in->get_client_cap(client);
+ if (!cap) {
+ dout(10) << " no cap on " << *in << dendl;
+ continue;
+ }
+ if (cap->get_cap_id() != p->cap_id) {
+ dout(7) << " ignoring client capid " << p->cap_id << " != my " << cap->get_cap_id() << " on " << *in << dendl;
+ continue;
+ }
+ if (ceph_seq_cmp(p->migrate_seq, cap->get_mseq()) < 0) {
+ dout(7) << " mseq " << p->migrate_seq << " < " << cap->get_mseq()
+ << " on " << *in << dendl;
+ continue;
+ }
+ if (p->seq != cap->get_last_sent()) {
+ dout(10) << " seq " << p->seq << " != " << cap->get_last_seq() << " on " << *in << dendl;
+ continue;
+ }
+
+ dout(7) << "removing cap on " << *in << dendl;
+ mdcache->remove_client_cap(in, client, false);
+ }
+
+ delete m;
+}
void Locker::handle_client_lease(MClientLease *m)
{
bool _do_cap_update(CInode *in, Capability *cap, int had, int wanted, snapid_t follows, MClientCaps *m,
MClientCaps *ack=0, ceph_seq_t releasecap=0);
void _finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClientCaps *ack);
+ void handle_client_cap_release(class MClientCapRelease *m);
public:
void request_inode_file_caps(CInode *in);
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef __MCLIENTCAPRELEASE_H
+#define __MCLIENTCAPRELEASE_H
+
+#include "msg/Message.h"
+
+
+class MClientCapRelease : public Message {
+ public:
+ struct ceph_mds_cap_release head;
+ vector<ceph_mds_cap_item> caps;
+
+ MClientCapRelease() :
+ Message(CEPH_MSG_CLIENT_CAPRELEASE) {
+ memset(&head, 0, sizeof(head));
+ }
+
+ const char *get_type_name() { return "client_cap_release";}
+ void print(ostream& out) {
+ out << "client_cap_release(" << head.num << ")";
+ }
+
+ void decode_payload() {
+ bufferlist::iterator p = payload.begin();
+ ::decode(head, p);
+ ::decode_nohead(head.num, caps, p);
+ }
+ void encode_payload() {
+ head.num = caps.size();
+ ::encode(head, payload);
+ ::encode_nohead(caps, payload);
+ }
+};
+
+#endif
#include "messages/MClientRequestForward.h"
#include "messages/MClientReply.h"
#include "messages/MClientCaps.h"
+#include "messages/MClientCapRelease.h"
#include "messages/MClientLease.h"
#include "messages/MClientSnap.h"
case CEPH_MSG_CLIENT_CAPS:
m = new MClientCaps;
break;
+ case CEPH_MSG_CLIENT_CAPRELEASE:
+ m = new MClientCapRelease;
+ break;
case CEPH_MSG_CLIENT_LEASE:
m = new MClientLease;
break;