struct ceph_mds_getmap {
struct ceph_fsid fsid;
- __le32 have;
+ __le32 want;
} __attribute__ ((packed));
s = kmalloc(sizeof(struct ceph_mds_session), GFP_NOFS);
s->s_mds = mds;
+ s->s_ttl = 0;
s->s_state = CEPH_MDS_SESSION_NEW;
s->s_seq = 0;
mutex_init(&s->s_mutex);
__u32 have;
dout(30, "wait_for_new_map enter\n");
have = mdsc->mdsmap->m_epoch;
- if (mdsc->last_requested_map < mdsc->mdsmap->m_epoch) {
- mdsc->last_requested_map = have;
- spin_unlock(&mdsc->lock);
- ceph_monc_request_mdsmap(&mdsc->client->monc, have);
- } else
- spin_unlock(&mdsc->lock);
+ spin_unlock(&mdsc->lock);
+ ceph_monc_request_mdsmap(&mdsc->client->monc, have+1);
wait_for_completion(&mdsc->map_waiters);
spin_lock(&mdsc->lock);
dout(30, "wait_for_new_map exit\n");
/* handle */
spin_lock(&mdsc->lock);
session = __get_session(mdsc, mds);
+ if (session && mdsc->mdsmap)
+ session->s_ttl = jiffies + mdsc->mdsmap->m_session_autoclose;
spin_unlock(&mdsc->lock);
mutex_lock(&session->s_mutex);
int renew_interval = mdsc->mdsmap->m_cap_bit_timeout >> 2;
int renew_caps = time_after_eq(jiffies, HZ*renew_interval +
mdsc->last_renew_caps);
+ u32 want_map = 0;
dout(10, "delayed_work on %p renew_caps=%d\n", mdsc, renew_caps);
struct ceph_mds_session *session = __get_session(mdsc, i);
if (session == 0)
continue;
+ if (session->s_ttl && time_after(jiffies, session->s_ttl)) {
+ derr(1, "mds%d session probably timed out, "
+ "requesting mds map\n", session->s_mds);
+ want_map = mdsc->mdsmap->m_epoch;
+ }
if (session->s_state < CEPH_MDS_SESSION_OPEN) {
put_session(session);
continue;
spin_lock(&mdsc->lock);
}
spin_unlock(&mdsc->lock);
+
+ if (want_map)
+ ceph_monc_request_mdsmap(&mdsc->client->monc, want_map);
+
schedule_delayed(mdsc);
}
mdsc->max_sessions = 0;
mdsc->last_tid = 0;
INIT_RADIX_TREE(&mdsc->request_tree, GFP_ATOMIC);
- mdsc->last_requested_map = 0;
init_completion(&mdsc->map_waiters);
init_completion(&mdsc->session_close_waiters);
INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work);
/* do we need it? */
spin_lock(&mdsc->lock);
+ ceph_monc_got_mdsmap(&mdsc->client->monc, epoch);
if (mdsc->mdsmap && epoch <= mdsc->mdsmap->m_epoch) {
dout(2, "ceph_mdsc_handle_map epoch %u < our %u\n",
epoch, mdsc->mdsmap->m_epoch);
mdsc->mdsmap = newmap;
}
- /* stop asking */
- ceph_monc_got_mdsmap(&mdsc->client->monc, newmap->m_epoch);
-
spin_unlock(&mdsc->lock);
/* (re)schedule work */
struct ceph_mds_session {
int s_mds;
int s_state;
+ unsigned long s_ttl; /* time until mds kills us */
__u64 s_seq; /* incoming msg seq # */
struct mutex s_mutex;
spinlock_t s_cap_lock; /* protects s_cap_gen, s_cap_ttl */
int max_sessions; /* len of s_mds_sessions */
__u64 last_tid; /* most recent mds request */
struct radix_tree_root request_tree; /* pending mds requests */
- __u64 last_requested_map;
struct completion map_waiters, session_close_waiters;
struct delayed_work delayed_work; /* delayed work */
unsigned long last_renew_caps;
mds_delayed_work.work);
int mon = pick_mon(monc, -1);
- dout(5, "request_mdsmap from mon%d have %u\n", mon, monc->have_mdsmap);
+ dout(5, "request_mdsmap from mon%d want %u\n", mon, monc->want_mdsmap);
msg = ceph_msg_new(CEPH_MSG_MDS_GETMAP, sizeof(*h), 0, 0, 0);
if (IS_ERR(msg))
return;
h = msg->front.iov_base;
h->fsid = monc->monmap->fsid;
- h->have = cpu_to_le32(monc->have_mdsmap);
+ h->want = cpu_to_le32(monc->want_mdsmap);
msg->hdr.dst = monc->monmap->mon_inst[mon];
ceph_msg_send(monc->client->msgr, msg, 0);
/* keep sending request until we receive mds map */
- if (monc->have_mdsmap)
+ if (monc->want_mdsmap)
delayed_work(&monc->mds_delayed_work, &monc->mds_delay);
}
-void ceph_monc_request_mdsmap(struct ceph_mon_client *monc, __u32 have)
+void ceph_monc_request_mdsmap(struct ceph_mon_client *monc, __u32 want)
{
- monc->mds_delay = BASE_DELAY_INTERVAL;
- monc->have_mdsmap = have;
- do_request_mdsmap(&monc->mds_delayed_work.work);
+ if (want > monc->want_mdsmap) {
+ monc->mds_delay = BASE_DELAY_INTERVAL;
+ monc->want_mdsmap = want;
+ do_request_mdsmap(&monc->mds_delayed_work.work);
+ }
}
-int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, __u32 have)
+int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, __u32 got)
{
- dout(5, "ceph_monc_got_mdsmap calling cancel_delayed_work_sync\n");
-
+ if (got < monc->want_mdsmap) {
+ dout(5, "got_mdsmap got %u <= wanted %u\n",
+ got, monc->want_mdsmap);
+ return -EAGAIN;
+ }
+
+ dout(5, "got_mdsmap have %u > wanted %u\n",
+ got, monc->want_mdsmap);
+ monc->want_mdsmap = 0;
+
/* we got map so take map request out of queue */
cancel_delayed_work_sync(&monc->mds_delayed_work);
monc->mds_delay = BASE_DELAY_INTERVAL;
-
- if (have > monc->have_mdsmap) {
- monc->have_mdsmap = 0;
- dout(5, "ceph_monc_got_mdsmap have %u > wanted %u\n",
- have, monc->have_mdsmap);
- return 0;
- } else {
- dout(5, "ceph_monc_got_mdsmap have %u <= wanted %u *****\n",
- have, monc->have_mdsmap);
- return -EAGAIN;
- }
+ return 0;
}
void ceph_monc_request_osdmap(struct ceph_mon_client *monc, __u32 have)
{
- dout(5, "ceph_monc_request_osdmap have %u\n", have);
+ dout(5, "request_osdmap have %u\n", have);
monc->osd_delay = BASE_DELAY_INTERVAL;
monc->have_osdmap = have;
do_request_osdmap(&monc->osd_delayed_work.work);
int ceph_monc_got_osdmap(struct ceph_mon_client *monc, __u32 got)
{
if (got <= monc->have_osdmap) {
- dout(5, "ceph_monc_got_osdmap got %u <= had %u, will retry\n",
+ dout(5, "got_osdmap got %u <= had %u, will retry\n",
got, monc->have_osdmap);
return -EAGAIN;
}
/* we got map so take map request out of queue */
- dout(5, "ceph_monc_got_osdmap got %u > had %u\n",
- got, monc->have_osdmap);
+ dout(5, "got_osdmap got %u > had %u\n", got, monc->have_osdmap);
+ monc->have_osdmap = 0;
cancel_delayed_work_sync(&monc->osd_delayed_work);
monc->osd_delay = BASE_DELAY_INTERVAL;
- monc->have_osdmap = 0;
return 0;
}
void ceph_monc_handle_umount(struct ceph_mon_client *monc,
struct ceph_msg *msg)
{
- dout(5, "ceph_monc_handle_umount\n");
+ dout(5, "handle_umount\n");
cancel_delayed_work_sync(&monc->umount_delayed_work);
monc->client->mount_state = CEPH_MOUNT_UNMOUNTED;
wake_up(&monc->client->mount_wq);
int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
{
- dout(5, "ceph_monc_init\n");
+ dout(5, "init\n");
memset(monc, 0, sizeof(*monc));
monc->client = cl;
monc->monmap = kzalloc(sizeof(struct ceph_monmap), GFP_KERNEL);
INIT_DELAYED_WORK(&monc->osd_delayed_work, do_request_osdmap);
INIT_DELAYED_WORK(&monc->umount_delayed_work, do_request_umount);
monc->last_tid = 0;
- monc->have_mdsmap = 0;
+ monc->want_mdsmap = 0;
monc->have_osdmap = 0;
return 0;
}
+
+void ceph_monc_stop(struct ceph_mon_client *monc)
+{
+ dout(5, "stop\n");
+ cancel_delayed_work_sync(&monc->mds_delayed_work);
+ cancel_delayed_work_sync(&monc->osd_delayed_work);
+ cancel_delayed_work_sync(&monc->umount_delayed_work);
+}
unsigned long osd_delay;
unsigned long umount_delay;
- u32 have_mdsmap; /* protected by caller's lock */
+ u32 want_mdsmap; /* protected by caller's lock */
u32 have_osdmap; /* protected by caller's lock */
};
struct ceph_entity_addr *addr);
extern int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl);
+extern void ceph_monc_stop(struct ceph_mon_client *monc);
-extern void ceph_monc_request_mdsmap(struct ceph_mon_client *monc, __u32 have);
+extern void ceph_monc_request_mdsmap(struct ceph_mon_client *monc, __u32 want);
extern int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, __u32 have);
extern void ceph_monc_request_osdmap(struct ceph_mon_client *monc, __u32 have);
/* unmount */
/* ... */
+ ceph_monc_stop(&cl->monc);
ceph_osdc_stop(&cl->osdc);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
class MMDSGetMap : public Message {
public:
ceph_fsid fsid;
- epoch_t have;
+ epoch_t want;
MMDSGetMap() {}
- MMDSGetMap(ceph_fsid &f, epoch_t h=0) :
+ MMDSGetMap(ceph_fsid &f, epoch_t w=0) :
Message(CEPH_MSG_MDS_GETMAP),
fsid(f),
- have(h) { }
+ want(w) { }
const char *get_type_name() { return "mds_getmap"; }
+ void print(ostream& out) {
+ out << "mds_getmap(want " << want << ")";
+ }
void encode_payload() {
::_encode_simple(fsid, payload);
- ::_encode_simple(have, payload);
+ ::_encode_simple(want, payload);
}
void decode_payload() {
bufferlist::iterator p = payload.begin();
::_decode_simple(fsid, p);
- ::_decode_simple(have, p);
+ ::_decode_simple(want, p);
}
};
void MDSMonitor::handle_mds_getmap(MMDSGetMap *m)
{
- if (m->have < mdsmap.get_epoch())
+ if (m->want <= mdsmap.get_epoch())
send_full(m->get_source_inst());
else
waiting_for_map.push_back(m->get_source_inst());