all: depend ${TARGETS}
-test: depend ${TEST_TARGETS}
-
# real bits
mkmonmap: mkmonmap.cc common.o
# handy
clean:
- rm -f *.o */*.o crush/*.co ${TARGETS} ${TEST_TARGETS}
+ rm -f *.o */*.o crush/*.co ${TARGETS}
count:
cat ${SRCS} | wc -l
mds_sessions[mds]++;
// reap?
- if (m->get_op() == MClientFileCaps::OP_IMPORT) {
- int other = m->get_mds();
+ if (m->get_op() == CEPH_CAP_OP_IMPORT) {
+ int other = m->get_migrate_mds();
/*
* FIXME: there is a race here.. if the caps are exported twice in succession,
assert(in);
// stale?
- if (m->get_op() == MClientFileCaps::OP_EXPORT) {
+ if (m->get_op() == CEPH_CAP_OP_EXPORT) {
dout(5) << "handle_file_caps on ino " << m->get_ino() << " seq " << m->get_seq() << " from mds" << mds << " now exported/stale" << dendl;
// move to stale list
// delayed reap?
if (cap_reap_queue.count(in->ino()) &&
cap_reap_queue[in->ino()].count(mds)) {
- dout(5) << "handle_file_caps on ino " << m->get_ino() << " from mds" << mds << " delayed reap on mds" << m->get_mds() << dendl;
+ dout(5) << "handle_file_caps on ino " << m->get_ino() << " from mds" << mds
+ << " delayed reap on mds?FIXME?" << dendl; /* FIXME */
// process delayed reap
handle_file_caps( cap_reap_queue[in->ino()][mds] );
}
// release?
- if (m->get_op() == MClientFileCaps::OP_RELEASE) {
+ if (m->get_op() == CEPH_CAP_OP_RELEASE) {
dout(5) << "handle_file_caps on ino " << m->get_ino() << " from mds" << mds << " release" << dendl;
assert(in->caps.count(mds));
in->caps.erase(mds);
<< " seq " << m->get_seq()
<< " " << cap_string(m->get_caps())
<< ", which we don't want caps for, releasing." << dendl;
- m->set_op(MClientFileCaps::OP_ACK);
+ m->set_op(CEPH_CAP_OP_ACK);
m->set_caps(0);
m->set_wanted(0);
messenger->send_message(m, m->get_source_inst());
// release (some of?) these caps
it->second.caps = retain & it->second.caps;
// note: tell mds _full_ wanted; it'll filter/behave based on what it is allowed to do
- MClientFileCaps *m = new MClientFileCaps(MClientFileCaps::OP_ACK,
+ MClientFileCaps *m = new MClientFileCaps(CEPH_CAP_OP_ACK,
in->inode,
it->second.seq,
it->second.caps,
for (map<int,InodeCap>::iterator it = in->caps.begin();
it != in->caps.end();
it++) {
- MClientFileCaps *m = new MClientFileCaps(MClientFileCaps::OP_ACK,
+ MClientFileCaps *m = new MClientFileCaps(CEPH_CAP_OP_ACK,
in->inode,
it->second.seq,
it->second.caps,
#define CEPH_INO_ROOT 1
struct ceph_timeval {
- __u32 tv_sec;
- __u32 tv_usec;
+ __le32 tv_sec;
+ __le32 tv_usec;
};
/*
} __attribute__ ((packed));
/* client file caps */
+enum {
+ CEPH_CAP_OP_GRANT, /* mds->client grant */
+ CEPH_CAP_OP_ACK, /* client->mds ack (if prior grant was a recall) */
+ CEPH_CAP_OP_RELEASE, /* mds->client release (*) */
+ CEPH_CAP_OP_EXPORT, /* mds has exported the cap */
+ CEPH_CAP_OP_IMPORT /* mds has imported the cap from specified mds */
+};
+ /*
+ * (*) it's a bit counterintuitive, but the mds has to
+ * close the cap because the client isn't able to tell
+ * if a concurrent open() would map to the same inode.
+ */
struct ceph_mds_file_caps {
- __le32 op;
- __le32 mds;
__le64 seq;
__le32 caps, wanted;
__le64 ino;
__le64 size;
+ __le32 op;
+ __le32 migrate_mds;
+ __le32 migrate_seq;
struct ceph_timeval mtime, atime;
} __attribute__ ((packed));
// --------
// utime_t
-typedef struct ceph_timeval _utime_t;
-
class utime_t {
- _utime_t tv;
+ struct ceph_timeval tv;
friend class Clock;
utime_t() { tv.tv_sec = 0; tv.tv_usec = 0; normalize(); }
//utime_t(time_t s) { tv.tv_sec = s; tv.tv_usec = 0; }
utime_t(time_t s, int u) { tv.tv_sec = s; tv.tv_usec = u; normalize(); }
- utime_t(const _utime_t &v) : tv(v) {}
+ utime_t(const struct ceph_timeval &v) : tv(v) {}
utime_t(const struct timeval &v) {
set_from_timeval(&v);
}
}
*/
-struct ceph_client *ceph_get_client(struct ceph_mount_args *args)
+struct ceph_client *ceph_create_client(struct ceph_mount_args *args, struct super_block *sb)
{
struct ceph_client *client = 0;
int ret;
- /* existing, by fsid? */
- /*
- if (args->flags & CEPH_MOUNT_FSID)
- client = ceph_get_client_fsid(&args->fsid);
- if (client)
- return client;
- */
- /* existing, by monitors? */
- /* write me. */
-
/* create new client */
client = create_client(args);
if (IS_ERR(client))
return client;
atomic_inc(&client->nref);
-
+ client->sb = sb;
+
/* request mount */
ret = mount(client, args);
if (ret < 0) {
case CEPH_MSG_CLIENT_REQUEST_FORWARD:
ceph_mdsc_handle_forward(&client->mdsc, msg);
break;
+ case CEPH_MSG_CLIENT_FILECAPS:
+ ceph_handle_filecaps(&client->mdsc, msg);
+ break;
/* osd client */
case CEPH_MSG_OSD_MAP:
struct ceph_fsid fsid;
atomic_t nref;
+ struct super_block *sb;
+
unsigned long mounting; /* map bitset; 4=mon, 2=mds, 1=osd map */
struct completion mount_completion;
struct list_head sb_list;
};
-extern struct ceph_client *ceph_get_client(struct ceph_mount_args *args);
+extern struct ceph_client *ceph_create_client(struct ceph_mount_args *args, struct super_block *sb);
extern void ceph_put_client(struct ceph_client *cl);
#endif
}
+/* caps */
+
+void ceph_handle_filecaps(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
+{
+ struct super_block *sb = mdsc->client->sb;
+ struct ceph_client *client = ceph_sbinfo(sb)->sb_client;
+ struct inode *inode;
+ struct ceph_mds_file_caps *h;
+ int mds = msg->hdr.src.name.num;
+ int op;
+ __u64 ino;
+
+ dout(10, "handle_filecaps from mds%d\n", mds);
+
+ /* decode */
+ if (msg->front.iov_len != sizeof(*h))
+ goto bad;
+ h = msg->front.iov_base;
+ op = le32_to_cpu(h->op);
+ ino = le64_to_cpu(h->ino);
+
+ /* lookup ino */
+ inode = ilookup(sb, ino);
+ dout(20, "op is %d, inode is %llx %p\n", op, ino, inode);
+
+ switch (op) {
+
+ }
+
+ return;
+bad:
+ dout(10, "corrupt filecaps message\n");
+}
+
+
/*
extern void ceph_mdsc_destroy_reply_info(struct ceph_mds_reply_info *info);
extern void ceph_mdsc_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *i);
+
#endif
/*
- * message handlers
+ * statfs
*/
void ceph_monc_handle_statfs_reply(struct ceph_mon_client *monc, struct ceph_msg *msg)
dout(20, "do_statfs waiting for reply\n");
wait_for_completion(&req.completion);
-
return 0;
}
/* client */
if (!sbinfo->sb_client) {
- sbinfo->sb_client = ceph_get_client(&mount_args);
+ sbinfo->sb_client = ceph_create_client(&mount_args, sb);
if (IS_ERR(sbinfo->sb_client)) {
err = PTR_ERR(sbinfo->sb_client);
sbinfo->sb_client = 0;
extern struct ceph_inode_cap *ceph_add_cap(struct inode *inode, int mds, u32 cap, u32 seq);
extern int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
+extern void ceph_handle_filecaps(struct ceph_mds_client *mdsc, struct ceph_msg *msg);
/* addr.c */
if (seq > 0 &&
!it->second.is_suppress()) {
dout(7) << " sending MClientFileCaps to client" << it->first << " seq " << it->second.get_last_seq() << " new pending " << cap_string(it->second.pending()) << " was " << cap_string(before) << dendl;
- mds->send_message_client(new MClientFileCaps(MClientFileCaps::OP_GRANT,
+ mds->send_message_client(new MClientFileCaps(CEPH_CAP_OP_GRANT,
in->inode,
it->second.get_last_seq(),
it->second.pending(),
request_inode_file_caps(in);
// tell client.
- MClientFileCaps *r = new MClientFileCaps(MClientFileCaps::OP_RELEASE,
+ MClientFileCaps *r = new MClientFileCaps(CEPH_CAP_OP_RELEASE,
in->inode,
0, 0, 0);
mds->send_message_client(r, m->get_source_inst());
// send REAP
// FIXME client session weirdness.
- MClientFileCaps *reap = new MClientFileCaps(MClientFileCaps::OP_IMPORT,
+ MClientFileCaps *reap = new MClientFileCaps(CEPH_CAP_OP_IMPORT,
in->inode,
in->client_caps[client].get_last_seq(),
in->client_caps[client].pending(),
in->client_caps[client].wanted());
- reap->set_mds( frommds ); // reap from whom?
+ reap->set_migrate_mds(frommds); // reap from whom?
mds->messenger->send_message(reap, mds->clientmap.get_inst(client));
}
it++) {
dout(7) << "finish_export_inode telling client" << it->first
<< " exported caps on " << *in << dendl;
- MClientFileCaps *m = new MClientFileCaps(MClientFileCaps::OP_EXPORT,
+ MClientFileCaps *m = new MClientFileCaps(CEPH_CAP_OP_EXPORT,
in->inode,
it->second.get_last_seq(),
it->second.pending(),
it != new_caps.end();
it++) {
dout(0) << "finish_import_inode_caps for client" << *it << " on " << *in << dendl;
- MClientFileCaps *caps = new MClientFileCaps(MClientFileCaps::OP_IMPORT,
+ MClientFileCaps *caps = new MClientFileCaps(CEPH_CAP_OP_IMPORT,
in->inode,
in->client_caps[*it].get_last_seq(),
in->client_caps[*it].pending(),
- in->client_caps[*it].wanted());
- caps->set_mds(from); // from whom?
+ in->client_caps[*it].wanted(),
+ from);
mds->send_message_client(caps, *it);
}
}
// mark client caps stale.
inode_t fake_inode;
fake_inode.ino = p->first;
- MClientFileCaps *stale = new MClientFileCaps(MClientFileCaps::OP_EXPORT,
+ MClientFileCaps *stale = new MClientFileCaps(CEPH_CAP_OP_EXPORT,
fake_inode,
0,
0, // doesn't matter.
class MClientFileCaps : public Message {
public:
- static const int OP_GRANT = 0; // mds->client grant.
- static const int OP_ACK = 1; // client->mds ack (if prior grant was a recall)
- static const int OP_RELEASE = 2; // mds->client release cap (*)
- static const int OP_EXPORT = 3; // mds has exported the cap
- static const int OP_IMPORT = 4; // mds has imported the cap from get_mds()
- /*
- * (*) it's a bit counterintuitive, but the mds has to
- * close the cap because the client isn't able to tell
- * if a concurrent open() would map to the same inode.
- */
static const char* get_opname(int op) {
switch (op) {
- case OP_GRANT: return "grant";
- case OP_ACK: return "ack";
- case OP_RELEASE: return "release";
- case OP_EXPORT: return "export";
- case OP_IMPORT: return "import";
+ case CEPH_CAP_OP_GRANT: return "grant";
+ case CEPH_CAP_OP_ACK: return "ack";
+ case CEPH_CAP_OP_RELEASE: return "release";
+ case CEPH_CAP_OP_EXPORT: return "export";
+ case CEPH_CAP_OP_IMPORT: return "import";
default: assert(0); return 0;
}
}
utime_t get_atime() { return utime_t(h.atime); }
// for cap migration
- int get_mds() { return le32_to_cpu(h.mds); }
+ int get_migrate_mds() { return le32_to_cpu(h.migrate_mds); }
+ int get_migrate_seq() { return le32_to_cpu(h.migrate_seq); }
int get_op() { return le32_to_cpu(h.op); }
void set_caps(int c) { h.caps = cpu_to_le32(c); }
void set_wanted(int w) { h.wanted = cpu_to_le32(w); }
- void set_mds(int m) { h.mds = cpu_to_le32(m); }
+ void set_migrate_mds(int m) { h.migrate_mds = cpu_to_le32(m); }
+ void set_migrate_seq(int m) { h.migrate_seq = cpu_to_le32(m); }
void set_op(int o) { h.op = cpu_to_le32(o); }
void set_size(loff_t s) { h.size = cpu_to_le64(s); }
long seq,
int caps,
int wanted,
- int mds=0) :
+ int mmds=0,
+ int mseq=0) :
Message(CEPH_MSG_CLIENT_FILECAPS) {
- h.op = cpu_to_le32(op);
- h.mds = cpu_to_le32(mds);
h.seq = cpu_to_le64(seq);
h.caps = cpu_to_le32(caps);
h.wanted = cpu_to_le32(wanted);
h.ino = cpu_to_le64(inode.ino);
h.size = cpu_to_le64(inode.size);
+ h.op = cpu_to_le32(op);
+ h.migrate_mds = cpu_to_le32(mmds);
+ h.migrate_seq = cpu_to_le32(mseq);
h.mtime = inode.mtime.tv_ref();
h.atime = inode.atime.tv_ref();
}