13d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh#include <linux/ceph/ceph_debug.h>
2ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
33d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh#include <linux/module.h>
4ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil#include <linux/types.h>
55a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
6ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil#include <linux/random.h>
7ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil#include <linux/sched.h>
8ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
93d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh#include <linux/ceph/mon_client.h>
103d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh#include <linux/ceph/libceph.h>
11ab434b60ab07f8c44246b6fb0cddee436687a09aSage Weil#include <linux/ceph/debugfs.h>
123d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh#include <linux/ceph/decode.h>
133d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh#include <linux/ceph/auth.h>
14ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
15ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
16ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Interact with Ceph monitor cluster.  Handle requests for new map
17ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * versions, and periodically resend as needed.  Also implement
18ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * statfs() and umount().
19ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil *
20ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * A small cluster of Ceph "monitors" are responsible for managing critical
21ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * cluster configuration and state information.  An odd number (e.g., 3, 5)
22ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * of cmon daemons use a modified version of the Paxos part-time parliament
23ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * algorithm to manage the MDS map (mds cluster membership), OSD map, and
24ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * list of clients who have mounted the file system.
25ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil *
26ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * We maintain an open, active session with a monitor at all times in order to
27ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * receive timely MDSMap updates.  We periodically send a keepalive byte on the
28ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * TCP socket to ensure we detect a failure.  If the connection does break, we
29ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * randomly hunt for a new monitor.  Once the connection is reestablished, we
30ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * resend any outstanding requests.
31ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
32ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
339e32789f63fc5ad91c8b10f68ec23a86856d5af5Tobias Klauserstatic const struct ceph_connection_operations mon_con_ops;
34ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
359bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weilstatic int __validate_auth(struct ceph_mon_client *monc);
369bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
37ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
38ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Decode a monmap blob (e.g., during mount).
39ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
40ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstruct ceph_monmap *ceph_monmap_decode(void *p, void *end)
41ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
42ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_monmap *m = NULL;
43ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	int i, err = -EINVAL;
44ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_fsid fsid;
45ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	u32 epoch, num_mon;
46ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	u16 version;
474e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	u32 len;
484e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
494e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	ceph_decode_32_safe(&p, end, len, bad);
504e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	ceph_decode_need(&p, end, len, bad);
51ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
52ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p));
53ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
54ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	ceph_decode_16_safe(&p, end, version, bad);
55ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
56ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	ceph_decode_need(&p, end, sizeof(fsid) + 2*sizeof(u32), bad);
57ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	ceph_decode_copy(&p, &fsid, sizeof(fsid));
58c89136ea4253c73e89e97f5138bb22d97ad9f564Sage Weil	epoch = ceph_decode_32(&p);
59ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
60c89136ea4253c73e89e97f5138bb22d97ad9f564Sage Weil	num_mon = ceph_decode_32(&p);
61ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad);
62ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
63ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (num_mon >= CEPH_MAX_MON)
64ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		goto bad;
65ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS);
66ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (m == NULL)
67ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		return ERR_PTR(-ENOMEM);
68ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	m->fsid = fsid;
69ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	m->epoch = epoch;
70ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	m->num_mon = num_mon;
71ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0]));
7263f2d211954b790fea0a9caeae605c7956535af6Sage Weil	for (i = 0; i < num_mon; i++)
7363f2d211954b790fea0a9caeae605c7956535af6Sage Weil		ceph_decode_addr(&m->mon_inst[i].addr);
74ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
75ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("monmap_decode epoch %d, num_mon %d\n", m->epoch,
76ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	     m->num_mon);
77ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	for (i = 0; i < m->num_mon; i++)
78ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		dout("monmap_decode  mon%d is %s\n", i,
793d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		     ceph_pr_addr(&m->mon_inst[i].addr.in_addr));
80ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return m;
81ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
82ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilbad:
83ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("monmap_decode failed with %d\n", err);
84ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	kfree(m);
85ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return ERR_PTR(err);
86ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
87ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
88ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
89ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * return true if *addr is included in the monmap.
90ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
91ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilint ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr)
92ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
93ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	int i;
94ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
95ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	for (i = 0; i < m->num_mon; i++)
96103e2d3ae57d38d18aaac1b327266c1407499ac1Sage Weil		if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0)
97ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			return 1;
98ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return 0;
99ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
100ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
101ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
1025ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil * Send an auth request.
1035ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil */
1045ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weilstatic void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
1055ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil{
1065ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil	monc->pending_auth = 1;
1075ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil	monc->m_auth->front.iov_len = len;
1085ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil	monc->m_auth->hdr.front_len = cpu_to_le32(len);
1096740a845b2543cc46e1902ba21bac743fbadd0dcAlex Elder	ceph_msg_revoke(monc->m_auth);
1105ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil	ceph_msg_get(monc->m_auth);  /* keep our ref */
11167130934fb579fdf0f2f6d745960264378b57dc8Alex Elder	ceph_con_send(&monc->con, monc->m_auth);
1125ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil}
1135ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil
1145ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil/*
115ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Close monitor session, if any.
116ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
117ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void __close_session(struct ceph_mon_client *monc)
118ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
119f6a2f5be07463ef532b9f4e3cb9e42ab9df85832Sage Weil	dout("__close_session closing mon%d\n", monc->cur_mon);
1206740a845b2543cc46e1902ba21bac743fbadd0dcAlex Elder	ceph_msg_revoke(monc->m_auth);
1214f471e4a9c7db0256834e1b376ea50c82e345c3cSage Weil	ceph_msg_revoke_incoming(monc->m_auth_reply);
1224f471e4a9c7db0256834e1b376ea50c82e345c3cSage Weil	ceph_msg_revoke(monc->m_subscribe);
1234f471e4a9c7db0256834e1b376ea50c82e345c3cSage Weil	ceph_msg_revoke_incoming(monc->m_subscribe_ack);
12467130934fb579fdf0f2f6d745960264378b57dc8Alex Elder	ceph_con_close(&monc->con);
125f6a2f5be07463ef532b9f4e3cb9e42ab9df85832Sage Weil	monc->cur_mon = -1;
126f6a2f5be07463ef532b9f4e3cb9e42ab9df85832Sage Weil	monc->pending_auth = 0;
127f6a2f5be07463ef532b9f4e3cb9e42ab9df85832Sage Weil	ceph_auth_reset(monc->auth);
128ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
129ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
130ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
131ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Open a session with a (new) monitor.
132ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
133ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic int __open_session(struct ceph_mon_client *monc)
134ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
135ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	char r;
1364e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	int ret;
137ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
138ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (monc->cur_mon < 0) {
139ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		get_random_bytes(&r, 1);
140ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->cur_mon = r % monc->monmap->num_mon;
141ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		dout("open_session num=%d r=%d -> mon%d\n",
142ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		     monc->monmap->num_mon, r, monc->cur_mon);
143ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->sub_sent = 0;
144ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->sub_renew_after = jiffies;  /* i.e., expired */
145ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->want_next_osdmap = !!monc->want_next_osdmap;
146ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
14720581c1faf7b15ae1f8b80c0ec757877b0b53151Alex Elder		dout("open_session mon%d opening\n", monc->cur_mon);
14867130934fb579fdf0f2f6d745960264378b57dc8Alex Elder		ceph_con_open(&monc->con,
149b7a9e5dd40f17a48a72f249b8bbc989b63bae5fdSage Weil			      CEPH_ENTITY_TYPE_MON, monc->cur_mon,
150ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			      &monc->monmap->mon_inst[monc->cur_mon].addr);
1514e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
1524e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		/* initiatiate authentication handshake */
1534e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		ret = ceph_auth_build_hello(monc->auth,
1544e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil					    monc->m_auth->front.iov_base,
1553cea4c3071d4e55e9d7356efe9d0ebf92f0c2204Ilya Dryomov					    monc->m_auth->front_alloc_len);
1565ce6e9dbe6805ab8ee67e21936d17f431adc63c6Sage Weil		__send_prepared_auth_request(monc, ret);
157ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	} else {
158ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		dout("open_session mon%d already open\n", monc->cur_mon);
159ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
160ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return 0;
161ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
162ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
163ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic bool __sub_expired(struct ceph_mon_client *monc)
164ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
165ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return time_after_eq(jiffies, monc->sub_renew_after);
166ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
167ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
168ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
169ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Reschedule delayed work timer.
170ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
171ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void __schedule_delayed(struct ceph_mon_client *monc)
172ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
17395c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazet	unsigned int delay;
174ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1754e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	if (monc->cur_mon < 0 || __sub_expired(monc))
176ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		delay = 10 * HZ;
177ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	else
178ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		delay = 20 * HZ;
179ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("__schedule_delayed after %u\n", delay);
180ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	schedule_delayed_work(&monc->delayed_work, delay);
181ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
182ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
183ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
184ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Send subscribe request for mdsmap and/or osdmap.
185ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
186ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void __send_subscribe(struct ceph_mon_client *monc)
187ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
188ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("__send_subscribe sub_sent=%u exp=%u want_osd=%d\n",
18995c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazet	     (unsigned int)monc->sub_sent, __sub_expired(monc),
190ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	     monc->want_next_osdmap);
191ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if ((__sub_expired(monc) && !monc->sub_sent) ||
192ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	    monc->want_next_osdmap == 1) {
193240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil		struct ceph_msg *msg = monc->m_subscribe;
194ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		struct ceph_mon_subscribe_item *i;
195ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		void *p, *end;
1963d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		int num;
197ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
198ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		p = msg->front.iov_base;
1993cea4c3071d4e55e9d7356efe9d0ebf92f0c2204Ilya Dryomov		end = p + msg->front_alloc_len;
200ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
2013d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		num = 1 + !!monc->want_next_osdmap + !!monc->want_mdsmap;
2023d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		ceph_encode_32(&p, num);
2033d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh
204ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		if (monc->want_next_osdmap) {
205ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			dout("__send_subscribe to 'osdmap' %u\n",
20695c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazet			     (unsigned int)monc->have_osdmap);
207ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			ceph_encode_string(&p, end, "osdmap", 6);
208ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			i = p;
209ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			i->have = cpu_to_le64(monc->have_osdmap);
210ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			i->onetime = 1;
211ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			p += sizeof(*i);
212ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			monc->want_next_osdmap = 2;  /* requested */
213ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		}
2143d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		if (monc->want_mdsmap) {
2153d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			dout("__send_subscribe to 'mdsmap' %u+\n",
21695c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazet			     (unsigned int)monc->have_mdsmap);
2173d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			ceph_encode_string(&p, end, "mdsmap", 6);
2183d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			i = p;
2193d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			i->have = cpu_to_le64(monc->have_mdsmap);
2203d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			i->onetime = 0;
2213d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			p += sizeof(*i);
2223d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		}
2234e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		ceph_encode_string(&p, end, "monmap", 6);
2244e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		i = p;
2254e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		i->have = 0;
2264e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		i->onetime = 0;
2274e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		p += sizeof(*i);
228ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
229ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		msg->front.iov_len = p - msg->front.iov_base;
230ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
2316740a845b2543cc46e1902ba21bac743fbadd0dcAlex Elder		ceph_msg_revoke(msg);
23267130934fb579fdf0f2f6d745960264378b57dc8Alex Elder		ceph_con_send(&monc->con, ceph_msg_get(msg));
233ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
234ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->sub_sent = jiffies | 1;  /* never 0 */
235ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
236ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
237ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
238ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void handle_subscribe_ack(struct ceph_mon_client *monc,
239ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil				 struct ceph_msg *msg)
240ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
24195c961747284a6b83a5e2d81240e214b0fa3464dEric Dumazet	unsigned int seconds;
24207bd10fb9853a41a7f0bb271721cca97d15eccaeSage Weil	struct ceph_mon_subscribe_ack *h = msg->front.iov_base;
24307bd10fb9853a41a7f0bb271721cca97d15eccaeSage Weil
24407bd10fb9853a41a7f0bb271721cca97d15eccaeSage Weil	if (msg->front.iov_len < sizeof(*h))
24507bd10fb9853a41a7f0bb271721cca97d15eccaeSage Weil		goto bad;
24607bd10fb9853a41a7f0bb271721cca97d15eccaeSage Weil	seconds = le32_to_cpu(h->duration);
247ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
248ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
249ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (monc->hunting) {
250ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		pr_info("mon%d %s session established\n",
2513d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			monc->cur_mon,
25267130934fb579fdf0f2f6d745960264378b57dc8Alex Elder			ceph_pr_addr(&monc->con.peer_addr.in_addr));
253ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->hunting = false;
254ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
255ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("handle_subscribe_ack after %d seconds\n", seconds);
2560656d11ba6ffa3dee0e8916a1903f96185651217Sage Weil	monc->sub_renew_after = monc->sub_sent + (seconds >> 1)*HZ - 1;
257ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->sub_sent = 0;
258ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
259ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return;
260ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilbad:
261ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	pr_err("got corrupt subscribe-ack msg\n");
2629ec7cab14e6de732d4e7c355fe67c5810c32c758Sage Weil	ceph_msg_dump(msg);
263ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
264ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
265ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
266ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Keep track of which maps we have
267ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
268ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilint ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 got)
269ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
270ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
271ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->have_mdsmap = got;
272ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
273ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return 0;
274ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
2753d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda SadehEXPORT_SYMBOL(ceph_monc_got_mdsmap);
276ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
277ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilint ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 got)
278ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
279ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
280ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->have_osdmap = got;
281ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->want_next_osdmap = 0;
282ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
283ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return 0;
284ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
285ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
286ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
287ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Register interest in the next osdmap
288ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
289ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilvoid ceph_monc_request_next_osdmap(struct ceph_mon_client *monc)
290ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
291ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("request_next_osdmap have %u\n", monc->have_osdmap);
292ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
293ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (!monc->want_next_osdmap)
294ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->want_next_osdmap = 1;
295ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (monc->want_next_osdmap < 2)
296ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		__send_subscribe(monc);
297ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
298ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
2996044cde6f2a94d88142d4401624152a741866338Ilya DryomovEXPORT_SYMBOL(ceph_monc_request_next_osdmap);
3006044cde6f2a94d88142d4401624152a741866338Ilya Dryomov
3016044cde6f2a94d88142d4401624152a741866338Ilya Dryomovint ceph_monc_wait_osdmap(struct ceph_mon_client *monc, u32 epoch,
3026044cde6f2a94d88142d4401624152a741866338Ilya Dryomov			  unsigned long timeout)
3036044cde6f2a94d88142d4401624152a741866338Ilya Dryomov{
3046044cde6f2a94d88142d4401624152a741866338Ilya Dryomov	unsigned long started = jiffies;
3056044cde6f2a94d88142d4401624152a741866338Ilya Dryomov	int ret;
3066044cde6f2a94d88142d4401624152a741866338Ilya Dryomov
3076044cde6f2a94d88142d4401624152a741866338Ilya Dryomov	mutex_lock(&monc->mutex);
3086044cde6f2a94d88142d4401624152a741866338Ilya Dryomov	while (monc->have_osdmap < epoch) {
3096044cde6f2a94d88142d4401624152a741866338Ilya Dryomov		mutex_unlock(&monc->mutex);
3106044cde6f2a94d88142d4401624152a741866338Ilya Dryomov
3116044cde6f2a94d88142d4401624152a741866338Ilya Dryomov		if (timeout != 0 && time_after_eq(jiffies, started + timeout))
3126044cde6f2a94d88142d4401624152a741866338Ilya Dryomov			return -ETIMEDOUT;
3136044cde6f2a94d88142d4401624152a741866338Ilya Dryomov
3146044cde6f2a94d88142d4401624152a741866338Ilya Dryomov		ret = wait_event_interruptible_timeout(monc->client->auth_wq,
3156044cde6f2a94d88142d4401624152a741866338Ilya Dryomov					 monc->have_osdmap >= epoch, timeout);
3166044cde6f2a94d88142d4401624152a741866338Ilya Dryomov		if (ret < 0)
3176044cde6f2a94d88142d4401624152a741866338Ilya Dryomov			return ret;
3186044cde6f2a94d88142d4401624152a741866338Ilya Dryomov
3196044cde6f2a94d88142d4401624152a741866338Ilya Dryomov		mutex_lock(&monc->mutex);
3206044cde6f2a94d88142d4401624152a741866338Ilya Dryomov	}
3216044cde6f2a94d88142d4401624152a741866338Ilya Dryomov
3226044cde6f2a94d88142d4401624152a741866338Ilya Dryomov	mutex_unlock(&monc->mutex);
3236044cde6f2a94d88142d4401624152a741866338Ilya Dryomov	return 0;
3246044cde6f2a94d88142d4401624152a741866338Ilya Dryomov}
3256044cde6f2a94d88142d4401624152a741866338Ilya DryomovEXPORT_SYMBOL(ceph_monc_wait_osdmap);
326ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
3274e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil/*
32850b885b96c903e420a1eac54dd27626244704a06Sage Weil *
3294e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil */
3304e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weilint ceph_monc_open_session(struct ceph_mon_client *monc)
331ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
332ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
3334e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	__open_session(monc);
334ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	__schedule_delayed(monc);
335ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
336ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return 0;
337ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
3383d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda SadehEXPORT_SYMBOL(ceph_monc_open_session);
339ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
3404e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil/*
341d1c338a509cea5378df59629ad47382810c38623Sage Weil * We require the fsid and global_id in order to initialize our
342d1c338a509cea5378df59629ad47382810c38623Sage Weil * debugfs dir.
343d1c338a509cea5378df59629ad47382810c38623Sage Weil */
344d1c338a509cea5378df59629ad47382810c38623Sage Weilstatic bool have_debugfs_info(struct ceph_mon_client *monc)
345d1c338a509cea5378df59629ad47382810c38623Sage Weil{
346d1c338a509cea5378df59629ad47382810c38623Sage Weil	dout("have_debugfs_info fsid %d globalid %lld\n",
347d1c338a509cea5378df59629ad47382810c38623Sage Weil	     (int)monc->client->have_fsid, monc->auth->global_id);
348d1c338a509cea5378df59629ad47382810c38623Sage Weil	return monc->client->have_fsid && monc->auth->global_id > 0;
349d1c338a509cea5378df59629ad47382810c38623Sage Weil}
350d1c338a509cea5378df59629ad47382810c38623Sage Weil
351d1c338a509cea5378df59629ad47382810c38623Sage Weil/*
3524e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil * The monitor responds with mount ack indicate mount success.  The
3534e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil * included client ticket allows the client to talk to MDSs and OSDs.
3544e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil */
3550743304d871559cb4c7c066357de2caa60e94c2fSage Weilstatic void ceph_monc_handle_map(struct ceph_mon_client *monc,
3560743304d871559cb4c7c066357de2caa60e94c2fSage Weil				 struct ceph_msg *msg)
3574e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil{
3584e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	struct ceph_client *client = monc->client;
3594e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	struct ceph_monmap *monmap = NULL, *old = monc->monmap;
3604e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	void *p, *end;
361d1c338a509cea5378df59629ad47382810c38623Sage Weil	int had_debugfs_info, init_debugfs = 0;
3624e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
3634e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	mutex_lock(&monc->mutex);
3644e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
365d1c338a509cea5378df59629ad47382810c38623Sage Weil	had_debugfs_info = have_debugfs_info(monc);
366d1c338a509cea5378df59629ad47382810c38623Sage Weil
3674e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	dout("handle_monmap\n");
3684e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	p = msg->front.iov_base;
3694e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	end = p + msg->front.iov_len;
3704e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
3714e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	monmap = ceph_monmap_decode(p, end);
3724e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	if (IS_ERR(monmap)) {
3734e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		pr_err("problem decoding monmap, %d\n",
3744e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		       (int)PTR_ERR(monmap));
375d4a780ce8821a37dd135f15b6150a5bfc5604f29Sage Weil		goto out;
3764e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	}
3770743304d871559cb4c7c066357de2caa60e94c2fSage Weil
3780743304d871559cb4c7c066357de2caa60e94c2fSage Weil	if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) {
3794e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		kfree(monmap);
380d4a780ce8821a37dd135f15b6150a5bfc5604f29Sage Weil		goto out;
3814e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	}
3824e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
3834e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	client->monc.monmap = monmap;
3844e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	kfree(old);
3854e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
386ab434b60ab07f8c44246b6fb0cddee436687a09aSage Weil	if (!client->have_fsid) {
387ab434b60ab07f8c44246b6fb0cddee436687a09aSage Weil		client->have_fsid = true;
388d1c338a509cea5378df59629ad47382810c38623Sage Weil		if (!had_debugfs_info && have_debugfs_info(monc)) {
389d1c338a509cea5378df59629ad47382810c38623Sage Weil			pr_info("client%lld fsid %pU\n",
390d1c338a509cea5378df59629ad47382810c38623Sage Weil				ceph_client_id(monc->client),
391d1c338a509cea5378df59629ad47382810c38623Sage Weil				&monc->client->fsid);
392d1c338a509cea5378df59629ad47382810c38623Sage Weil			init_debugfs = 1;
393d1c338a509cea5378df59629ad47382810c38623Sage Weil		}
394ab434b60ab07f8c44246b6fb0cddee436687a09aSage Weil		mutex_unlock(&monc->mutex);
395d1c338a509cea5378df59629ad47382810c38623Sage Weil
396d1c338a509cea5378df59629ad47382810c38623Sage Weil		if (init_debugfs) {
397d1c338a509cea5378df59629ad47382810c38623Sage Weil			/*
398d1c338a509cea5378df59629ad47382810c38623Sage Weil			 * do debugfs initialization without mutex to avoid
399d1c338a509cea5378df59629ad47382810c38623Sage Weil			 * creating a locking dependency
400d1c338a509cea5378df59629ad47382810c38623Sage Weil			 */
401d1c338a509cea5378df59629ad47382810c38623Sage Weil			ceph_debugfs_client_init(monc->client);
402d1c338a509cea5378df59629ad47382810c38623Sage Weil		}
403d1c338a509cea5378df59629ad47382810c38623Sage Weil
404ab434b60ab07f8c44246b6fb0cddee436687a09aSage Weil		goto out_unlocked;
405ab434b60ab07f8c44246b6fb0cddee436687a09aSage Weil	}
406d4a780ce8821a37dd135f15b6150a5bfc5604f29Sage Weilout:
4074e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	mutex_unlock(&monc->mutex);
408ab434b60ab07f8c44246b6fb0cddee436687a09aSage Weilout_unlocked:
40903066f23452ff088ad8e2c8acdf4443043f35b51Yehuda Sadeh	wake_up_all(&client->auth_wq);
4104e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil}
4114e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
412ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
413e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh * generic requests (e.g., statfs, poolop)
414ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
415f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadehstatic struct ceph_mon_generic_request *__lookup_generic_req(
41685ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	struct ceph_mon_client *monc, u64 tid)
41785ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil{
418f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct ceph_mon_generic_request *req;
419f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct rb_node *n = monc->generic_request_tree.rb_node;
42085ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil
42185ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	while (n) {
422f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		req = rb_entry(n, struct ceph_mon_generic_request, node);
42385ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil		if (tid < req->tid)
42485ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil			n = n->rb_left;
42585ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil		else if (tid > req->tid)
42685ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil			n = n->rb_right;
42785ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil		else
42885ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil			return req;
42985ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	}
43085ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	return NULL;
43185ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil}
43285ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil
433f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadehstatic void __insert_generic_request(struct ceph_mon_client *monc,
434f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh			    struct ceph_mon_generic_request *new)
43585ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil{
436f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct rb_node **p = &monc->generic_request_tree.rb_node;
43785ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	struct rb_node *parent = NULL;
438f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct ceph_mon_generic_request *req = NULL;
43985ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil
44085ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	while (*p) {
44185ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil		parent = *p;
442f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		req = rb_entry(parent, struct ceph_mon_generic_request, node);
44385ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil		if (new->tid < req->tid)
44485ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil			p = &(*p)->rb_left;
44585ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil		else if (new->tid > req->tid)
44685ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil			p = &(*p)->rb_right;
44785ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil		else
44885ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil			BUG();
44985ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	}
45085ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil
45185ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	rb_link_node(&new->node, parent, p);
452f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	rb_insert_color(&new->node, &monc->generic_request_tree);
45385ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil}
45485ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil
455f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadehstatic void release_generic_request(struct kref *kref)
4563143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil{
457f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct ceph_mon_generic_request *req =
458f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		container_of(kref, struct ceph_mon_generic_request, kref);
4593143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
4603143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	if (req->reply)
4613143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		ceph_msg_put(req->reply);
4623143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	if (req->request)
4633143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		ceph_msg_put(req->request);
464205475679a74fe40b63a1c7f41110fdb64daa8b9Yehuda Sadeh
465205475679a74fe40b63a1c7f41110fdb64daa8b9Yehuda Sadeh	kfree(req);
4663143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil}
4673143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
468f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadehstatic void put_generic_request(struct ceph_mon_generic_request *req)
4693143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil{
470f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	kref_put(&req->kref, release_generic_request);
4713143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil}
4723143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
473f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadehstatic void get_generic_request(struct ceph_mon_generic_request *req)
4743143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil{
4753143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	kref_get(&req->kref);
4763143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil}
4773143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
478f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadehstatic struct ceph_msg *get_generic_reply(struct ceph_connection *con,
4793143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil					 struct ceph_msg_header *hdr,
4803143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil					 int *skip)
4813143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil{
4823143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	struct ceph_mon_client *monc = con->private;
483f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct ceph_mon_generic_request *req;
4843143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	u64 tid = le64_to_cpu(hdr->tid);
4853143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	struct ceph_msg *m;
4863143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
4873143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	mutex_lock(&monc->mutex);
488f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	req = __lookup_generic_req(monc, tid);
4893143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	if (!req) {
490f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		dout("get_generic_reply %lld dne\n", tid);
4913143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		*skip = 1;
4923143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		m = NULL;
4933143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	} else {
494f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		dout("get_generic_reply %lld got %p\n", tid, req->reply);
4951c20f2d26795803fc4f5155fe4fca5717a5944b6Alex Elder		*skip = 0;
4963143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		m = ceph_msg_get(req->reply);
4973143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		/*
4983143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		 * we don't need to track the connection reading into
4993143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		 * this reply because we only have one open connection
5003143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		 * at a time, ever.
5013143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		 */
5023143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	}
5033143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	mutex_unlock(&monc->mutex);
5043143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	return m;
5053143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil}
5063143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
507513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomovstatic int __do_generic_request(struct ceph_mon_client *monc, u64 tid,
508513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov				struct ceph_mon_generic_request *req)
509e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh{
510e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	int err;
511e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
512e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	/* register request */
513513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	req->tid = tid != 0 ? tid : ++monc->last_tid;
514e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	req->request->hdr.tid = cpu_to_le64(req->tid);
515e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	__insert_generic_request(monc, req);
516e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	monc->num_generic_requests++;
51767130934fb579fdf0f2f6d745960264378b57dc8Alex Elder	ceph_con_send(&monc->con, ceph_msg_get(req->request));
518e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	mutex_unlock(&monc->mutex);
519e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
520e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	err = wait_for_completion_interruptible(&req->completion);
521e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
522e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	mutex_lock(&monc->mutex);
523e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	rb_erase(&req->node, &monc->generic_request_tree);
524e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	monc->num_generic_requests--;
525e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
526e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (!err)
527e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		err = req->result;
528e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	return err;
529e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh}
530e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
531513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomovstatic int do_generic_request(struct ceph_mon_client *monc,
532513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov			      struct ceph_mon_generic_request *req)
533513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov{
534513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	int err;
535513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
536513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	mutex_lock(&monc->mutex);
537513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	err = __do_generic_request(monc, 0, req);
538513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	mutex_unlock(&monc->mutex);
539513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
540513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	return err;
541513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov}
542513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
543e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh/*
544e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh * statfs
545e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh */
546ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void handle_statfs_reply(struct ceph_mon_client *monc,
547ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil				struct ceph_msg *msg)
548ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
549f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct ceph_mon_generic_request *req;
550ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_mon_statfs_reply *reply = msg->front.iov_base;
5513143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	u64 tid = le64_to_cpu(msg->hdr.tid);
552ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
553ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (msg->front.iov_len != sizeof(*reply))
554ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		goto bad;
555ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("handle_statfs_reply %p tid %llu\n", msg, tid);
556ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
557ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
558f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	req = __lookup_generic_req(monc, tid);
559ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (req) {
560f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		*(struct ceph_statfs *)req->buf = reply->st;
561ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		req->result = 0;
562f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		get_generic_request(req);
563ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
564ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
5653143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	if (req) {
56603066f23452ff088ad8e2c8acdf4443043f35b51Yehuda Sadeh		complete_all(&req->completion);
567f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		put_generic_request(req);
5683143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	}
569ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return;
570ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
571ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilbad:
572e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	pr_err("corrupt generic reply, tid %llu\n", tid);
5739ec7cab14e6de732d4e7c355fe67c5810c32c758Sage Weil	ceph_msg_dump(msg);
574ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
575ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
576ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
5773143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil * Do a synchronous statfs().
578ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
5793143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weilint ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf)
580ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
581f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct ceph_mon_generic_request *req;
582ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_mon_statfs *h;
5833143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	int err;
5843143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
585cffe7b6d8cc029d13524acedf4917210dc0102abJulia Lawall	req = kzalloc(sizeof(*req), GFP_NOFS);
5863143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	if (!req)
5873143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		return -ENOMEM;
5883143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
5893143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	kref_init(&req->kref);
5903143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	req->buf = buf;
591e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	req->buf_len = sizeof(*buf);
5923143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	init_completion(&req->completion);
593ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
594a79832f26be370ee26ea81eecdfd42d10e49d66aSage Weil	err = -ENOMEM;
595b61c27636fffbaf1980e675282777b9467254a40Sage Weil	req->request = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), GFP_NOFS,
596b61c27636fffbaf1980e675282777b9467254a40Sage Weil				    true);
597a79832f26be370ee26ea81eecdfd42d10e49d66aSage Weil	if (!req->request)
5983143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		goto out;
599b61c27636fffbaf1980e675282777b9467254a40Sage Weil	req->reply = ceph_msg_new(CEPH_MSG_STATFS_REPLY, 1024, GFP_NOFS,
600b61c27636fffbaf1980e675282777b9467254a40Sage Weil				  true);
601a79832f26be370ee26ea81eecdfd42d10e49d66aSage Weil	if (!req->reply)
6023143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil		goto out;
6033143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
6043143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	/* fill out request */
6053143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil	h = req->request->front.iov_base;
60613e38c8ae771d73bf6d1f0f98e35f99c0f0d48ffSage Weil	h->monhdr.have_version = 0;
60713e38c8ae771d73bf6d1f0f98e35f99c0f0d48ffSage Weil	h->monhdr.session_mon = cpu_to_le16(-1);
60813e38c8ae771d73bf6d1f0f98e35f99c0f0d48ffSage Weil	h->monhdr.session_mon_tid = 0;
609ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	h->fsid = monc->monmap->fsid;
610ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
611e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	err = do_generic_request(monc, req);
612ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
613e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadehout:
614e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	kref_put(&req->kref, release_generic_request);
615e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	return err;
616e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh}
6173d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda SadehEXPORT_SYMBOL(ceph_monc_do_statfs);
618e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
619513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomovstatic void handle_get_version_reply(struct ceph_mon_client *monc,
620513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov				     struct ceph_msg *msg)
621513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov{
622513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	struct ceph_mon_generic_request *req;
623513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	u64 tid = le64_to_cpu(msg->hdr.tid);
624513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	void *p = msg->front.iov_base;
625513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	void *end = p + msg->front_alloc_len;
626513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	u64 handle;
627513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
628513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	dout("%s %p tid %llu\n", __func__, msg, tid);
629513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
630513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	ceph_decode_need(&p, end, 2*sizeof(u64), bad);
631513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	handle = ceph_decode_64(&p);
632513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	if (tid != 0 && tid != handle)
633513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		goto bad;
634513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
635513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	mutex_lock(&monc->mutex);
636513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	req = __lookup_generic_req(monc, handle);
637513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	if (req) {
638513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		*(u64 *)req->buf = ceph_decode_64(&p);
639513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		req->result = 0;
640513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		get_generic_request(req);
641513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	}
642513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	mutex_unlock(&monc->mutex);
643513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	if (req) {
644513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		complete_all(&req->completion);
645513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		put_generic_request(req);
646513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	}
647513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
648513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	return;
649513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomovbad:
650513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	pr_err("corrupt mon_get_version reply\n");
651513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	ceph_msg_dump(msg);
652513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov}
653513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
654513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov/*
655513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov * Send MMonGetVersion and wait for the reply.
656513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov *
657513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov * @what: one of "mdsmap", "osdmap" or "monmap"
658513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov */
659513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomovint ceph_monc_do_get_version(struct ceph_mon_client *monc, const char *what,
660513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov			     u64 *newest)
661513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov{
662513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	struct ceph_mon_generic_request *req;
663513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	void *p, *end;
664513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	u64 tid;
665513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	int err;
666513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
667513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	req = kzalloc(sizeof(*req), GFP_NOFS);
668513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	if (!req)
669513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		return -ENOMEM;
670513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
671513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	kref_init(&req->kref);
672513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	req->buf = newest;
673513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	req->buf_len = sizeof(*newest);
674513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	init_completion(&req->completion);
675513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
676513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	req->request = ceph_msg_new(CEPH_MSG_MON_GET_VERSION,
677513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov				    sizeof(u64) + sizeof(u32) + strlen(what),
678513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov				    GFP_NOFS, true);
679513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	if (!req->request) {
680513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		err = -ENOMEM;
681513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		goto out;
682513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	}
683513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
684513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	req->reply = ceph_msg_new(CEPH_MSG_MON_GET_VERSION_REPLY, 1024,
685513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov				  GFP_NOFS, true);
686513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	if (!req->reply) {
687513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		err = -ENOMEM;
688513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		goto out;
689513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	}
690513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
691513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	p = req->request->front.iov_base;
692513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	end = p + req->request->front_alloc_len;
693513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
694513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	/* fill out request */
695513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	mutex_lock(&monc->mutex);
696513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	tid = ++monc->last_tid;
697513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	ceph_encode_64(&p, tid); /* handle */
698513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	ceph_encode_string(&p, end, what, strlen(what));
699513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
700513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	err = __do_generic_request(monc, tid, req);
701513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
702513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	mutex_unlock(&monc->mutex);
703513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomovout:
704513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	kref_put(&req->kref, release_generic_request);
705513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	return err;
706513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov}
707513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya DryomovEXPORT_SYMBOL(ceph_monc_do_get_version);
708513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
709e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh/*
710e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh * pool ops
711e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh */
712e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadehstatic int get_poolop_reply_buf(const char *src, size_t src_len,
713e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh				char *dst, size_t dst_len)
714e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh{
715e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	u32 buf_len;
716e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
717e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (src_len != sizeof(u32) + dst_len)
718e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		return -EINVAL;
719e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
720e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	buf_len = le32_to_cpu(*(u32 *)src);
721e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (buf_len != dst_len)
722e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		return -EINVAL;
723e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
724e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	memcpy(dst, src + sizeof(u32), dst_len);
725e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	return 0;
726e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh}
727e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
728e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadehstatic void handle_poolop_reply(struct ceph_mon_client *monc,
729e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh				struct ceph_msg *msg)
730e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh{
731e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	struct ceph_mon_generic_request *req;
732e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	struct ceph_mon_poolop_reply *reply = msg->front.iov_base;
733e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	u64 tid = le64_to_cpu(msg->hdr.tid);
734e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
735e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (msg->front.iov_len < sizeof(*reply))
736e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		goto bad;
737e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	dout("handle_poolop_reply %p tid %llu\n", msg, tid);
738ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
739ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
740e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	req = __lookup_generic_req(monc, tid);
741e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (req) {
742e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		if (req->buf_len &&
743e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		    get_poolop_reply_buf(msg->front.iov_base + sizeof(*reply),
744e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh				     msg->front.iov_len - sizeof(*reply),
745e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh				     req->buf, req->buf_len) < 0) {
746e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh			mutex_unlock(&monc->mutex);
747e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh			goto bad;
748e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		}
749e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		req->result = le32_to_cpu(reply->reply_code);
750e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		get_generic_request(req);
751e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	}
752ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
753e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (req) {
754e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		complete(&req->completion);
755e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		put_generic_request(req);
756e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	}
757e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	return;
758ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
759e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadehbad:
760e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	pr_err("corrupt generic reply, tid %llu\n", tid);
761e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	ceph_msg_dump(msg);
762e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh}
763e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
764e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh/*
765e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh * Do a synchronous pool op.
766e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh */
7677698f2f5e0d7b7a062213fa970b7c4e121adf38eIulius Curtstatic int do_poolop(struct ceph_mon_client *monc, u32 op,
768e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh			u32 pool, u64 snapid,
769e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh			char *buf, int len)
770e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh{
771e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	struct ceph_mon_generic_request *req;
772e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	struct ceph_mon_poolop *h;
773e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	int err;
774e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
775e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	req = kzalloc(sizeof(*req), GFP_NOFS);
776e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (!req)
777e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		return -ENOMEM;
778e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
779e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	kref_init(&req->kref);
780e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	req->buf = buf;
781e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	req->buf_len = len;
782e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	init_completion(&req->completion);
783e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
784e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	err = -ENOMEM;
785b61c27636fffbaf1980e675282777b9467254a40Sage Weil	req->request = ceph_msg_new(CEPH_MSG_POOLOP, sizeof(*h), GFP_NOFS,
786b61c27636fffbaf1980e675282777b9467254a40Sage Weil				    true);
787e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (!req->request)
788e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		goto out;
789b61c27636fffbaf1980e675282777b9467254a40Sage Weil	req->reply = ceph_msg_new(CEPH_MSG_POOLOP_REPLY, 1024, GFP_NOFS,
790b61c27636fffbaf1980e675282777b9467254a40Sage Weil				  true);
791e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	if (!req->reply)
792e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		goto out;
793e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
794e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	/* fill out request */
795e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	req->request->hdr.version = cpu_to_le16(2);
796e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h = req->request->front.iov_base;
797e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->monhdr.have_version = 0;
798e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->monhdr.session_mon = cpu_to_le16(-1);
799e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->monhdr.session_mon_tid = 0;
800e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->fsid = monc->monmap->fsid;
801e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->pool = cpu_to_le32(pool);
802e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->op = cpu_to_le32(op);
803e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->auid = 0;
804e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->snapid = cpu_to_le64(snapid);
805e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	h->name_len = 0;
806e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
807e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	err = do_generic_request(monc, req);
8083143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weil
8093143edd3a185f1fd370ebdd21b4151aa9f3283a3Sage Weilout:
810f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	kref_put(&req->kref, release_generic_request);
811ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return err;
812ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
813ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
814e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadehint ceph_monc_create_snapid(struct ceph_mon_client *monc,
815e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh			    u32 pool, u64 *snapid)
816e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh{
8177698f2f5e0d7b7a062213fa970b7c4e121adf38eIulius Curt	return do_poolop(monc,  POOL_OP_CREATE_UNMANAGED_SNAP,
818e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh				   pool, 0, (char *)snapid, sizeof(*snapid));
819e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
820e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh}
8213d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda SadehEXPORT_SYMBOL(ceph_monc_create_snapid);
822e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
823e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadehint ceph_monc_delete_snapid(struct ceph_mon_client *monc,
824e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh			    u32 pool, u64 snapid)
825e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh{
8267698f2f5e0d7b7a062213fa970b7c4e121adf38eIulius Curt	return do_poolop(monc,  POOL_OP_CREATE_UNMANAGED_SNAP,
827154171678989950f6c392e126fa8006a145ed1ccAlex Elder				   pool, snapid, NULL, 0);
828e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
829e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh}
830e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
831ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
832e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh * Resend pending generic requests.
833ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
834f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadehstatic void __resend_generic_request(struct ceph_mon_client *monc)
835ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
836f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	struct ceph_mon_generic_request *req;
83785ff03f6bfef7d5b59ab3aefd4773f497ffad8a4Sage Weil	struct rb_node *p;
838ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
839f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	for (p = rb_first(&monc->generic_request_tree); p; p = rb_next(p)) {
840f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		req = rb_entry(p, struct ceph_mon_generic_request, node);
8416740a845b2543cc46e1902ba21bac743fbadd0dcAlex Elder		ceph_msg_revoke(req->request);
8424f471e4a9c7db0256834e1b376ea50c82e345c3cSage Weil		ceph_msg_revoke_incoming(req->reply);
84367130934fb579fdf0f2f6d745960264378b57dc8Alex Elder		ceph_con_send(&monc->con, ceph_msg_get(req->request));
844ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
845ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
846ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
847ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
848ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Delayed work.  If we haven't mounted yet, retry.  Otherwise,
849ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * renew/retry subscription as needed (in case it is timing out, or we
850ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * got an ENOMEM).  And keep the monitor connection alive.
851ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
852ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void delayed_work(struct work_struct *work)
853ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
854ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_mon_client *monc =
855ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		container_of(work, struct ceph_mon_client, delayed_work.work);
856ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
857ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("monc delayed_work\n");
858ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
8594e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	if (monc->hunting) {
8604e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		__close_session(monc);
8614e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		__open_session(monc);  /* continue hunting */
862ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	} else {
86367130934fb579fdf0f2f6d745960264378b57dc8Alex Elder		ceph_con_keepalive(&monc->con);
8649bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
8659bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil		__validate_auth(monc);
8669bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
86727859f9773e4a0b2042435b13400ee2c891a61f4Sage Weil		if (ceph_auth_is_authenticated(monc->auth))
8684e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil			__send_subscribe(monc);
869ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
870ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	__schedule_delayed(monc);
871ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
872ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
873ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
8746b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil/*
8756b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil * On startup, we build a temporary monmap populated with the IPs
8766b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil * provided by mount(2).
8776b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil */
8786b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weilstatic int build_initial_monmap(struct ceph_mon_client *monc)
8796b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil{
8803d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh	struct ceph_options *opt = monc->client->options;
8813d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh	struct ceph_entity_addr *mon_addr = opt->mon_addr;
8823d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh	int num_mon = opt->num_mon;
8836b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	int i;
8846b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil
8856b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	/* build initial monmap */
8866b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	monc->monmap = kzalloc(sizeof(*monc->monmap) +
8876b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil			       num_mon*sizeof(monc->monmap->mon_inst[0]),
8886b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil			       GFP_KERNEL);
8896b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	if (!monc->monmap)
8906b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil		return -ENOMEM;
8916b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	for (i = 0; i < num_mon; i++) {
8926b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil		monc->monmap->mon_inst[i].addr = mon_addr[i];
8936b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil		monc->monmap->mon_inst[i].addr.nonce = 0;
8946b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil		monc->monmap->mon_inst[i].name.type =
8956b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil			CEPH_ENTITY_TYPE_MON;
8966b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil		monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
8976b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	}
8986b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	monc->monmap->num_mon = num_mon;
8996b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	return 0;
9006b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil}
9016b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil
902ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilint ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
903ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
904ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	int err = 0;
905ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
906ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("init\n");
907ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	memset(monc, 0, sizeof(*monc));
908ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->client = cl;
909ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->monmap = NULL;
910ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_init(&monc->mutex);
911ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
9126b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	err = build_initial_monmap(monc);
9136b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil	if (err)
9146b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil		goto out;
9156b8051855d983db8480ff1ea1b02ef2b49203c22Sage Weil
916f6a2f5be07463ef532b9f4e3cb9e42ab9df85832Sage Weil	/* connection */
9174e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	/* authentication */
9183d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh	monc->auth = ceph_auth_init(cl->options->name,
9198323c3aa74cd92465350294567142d12ffdcc963Tommi Virtanen				    cl->options->key);
92049d9224c047f23089c49a6749609447abd09ee03Noah Watkins	if (IS_ERR(monc->auth)) {
92149d9224c047f23089c49a6749609447abd09ee03Noah Watkins		err = PTR_ERR(monc->auth);
92267130934fb579fdf0f2f6d745960264378b57dc8Alex Elder		goto out_monmap;
92349d9224c047f23089c49a6749609447abd09ee03Noah Watkins	}
9244e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	monc->auth->want_keys =
9254e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON |
9264e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS;
9274e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
928240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil	/* msgs */
929a79832f26be370ee26ea81eecdfd42d10e49d66aSage Weil	err = -ENOMEM;
9307c315c552c7442eab73461de61dbcce579a31d3aSage Weil	monc->m_subscribe_ack = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE_ACK,
93134d23762d988b7dcb08390ac72a353df3d60193cYehuda Sadeh				     sizeof(struct ceph_mon_subscribe_ack),
932b61c27636fffbaf1980e675282777b9467254a40Sage Weil				     GFP_NOFS, true);
933a79832f26be370ee26ea81eecdfd42d10e49d66aSage Weil	if (!monc->m_subscribe_ack)
93449d9224c047f23089c49a6749609447abd09ee03Noah Watkins		goto out_auth;
9356694d6b95cf3b41751e78815d05968fa2084d7bfSage Weil
936b61c27636fffbaf1980e675282777b9467254a40Sage Weil	monc->m_subscribe = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, GFP_NOFS,
937b61c27636fffbaf1980e675282777b9467254a40Sage Weil					 true);
938240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil	if (!monc->m_subscribe)
939240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil		goto out_subscribe_ack;
940240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil
941b61c27636fffbaf1980e675282777b9467254a40Sage Weil	monc->m_auth_reply = ceph_msg_new(CEPH_MSG_AUTH_REPLY, 4096, GFP_NOFS,
942b61c27636fffbaf1980e675282777b9467254a40Sage Weil					  true);
943a79832f26be370ee26ea81eecdfd42d10e49d66aSage Weil	if (!monc->m_auth_reply)
944240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil		goto out_subscribe;
9454e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
946b61c27636fffbaf1980e675282777b9467254a40Sage Weil	monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, GFP_NOFS, true);
9479bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	monc->pending_auth = 0;
948a79832f26be370ee26ea81eecdfd42d10e49d66aSage Weil	if (!monc->m_auth)
9496694d6b95cf3b41751e78815d05968fa2084d7bfSage Weil		goto out_auth_reply;
950ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
951735a72ef952d42a256f79ae3e6dc1c17a45c041bSage Weil	ceph_con_init(&monc->con, monc, &mon_con_ops,
952735a72ef952d42a256f79ae3e6dc1c17a45c041bSage Weil		      &monc->client->msgr);
953735a72ef952d42a256f79ae3e6dc1c17a45c041bSage Weil
954ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->cur_mon = -1;
9554e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	monc->hunting = true;
956ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->sub_renew_after = jiffies;
957ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->sub_sent = 0;
958ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
959ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	INIT_DELAYED_WORK(&monc->delayed_work, delayed_work);
960f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	monc->generic_request_tree = RB_ROOT;
961f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh	monc->num_generic_requests = 0;
962ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->last_tid = 0;
963ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
964ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->have_mdsmap = 0;
965ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->have_osdmap = 0;
966ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	monc->want_next_osdmap = 1;
9674e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	return 0;
9684e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
9696694d6b95cf3b41751e78815d05968fa2084d7bfSage Weilout_auth_reply:
9706694d6b95cf3b41751e78815d05968fa2084d7bfSage Weil	ceph_msg_put(monc->m_auth_reply);
971240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weilout_subscribe:
972240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil	ceph_msg_put(monc->m_subscribe);
9737c315c552c7442eab73461de61dbcce579a31d3aSage Weilout_subscribe_ack:
9747c315c552c7442eab73461de61dbcce579a31d3aSage Weil	ceph_msg_put(monc->m_subscribe_ack);
97549d9224c047f23089c49a6749609447abd09ee03Noah Watkinsout_auth:
97649d9224c047f23089c49a6749609447abd09ee03Noah Watkins	ceph_auth_destroy(monc->auth);
9774e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weilout_monmap:
9784e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	kfree(monc->monmap);
979ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilout:
980ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	return err;
981ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
9823d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda SadehEXPORT_SYMBOL(ceph_monc_init);
983ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
984ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilvoid ceph_monc_stop(struct ceph_mon_client *monc)
985ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
986ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("stop\n");
987ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	cancel_delayed_work_sync(&monc->delayed_work);
988ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
989ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
990ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	__close_session(monc);
991f6a2f5be07463ef532b9f4e3cb9e42ab9df85832Sage Weil
992ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
993ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
994f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil	/*
995f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil	 * flush msgr queue before we destroy ourselves to ensure that:
996f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil	 *  - any work that references our embedded con is finished.
997f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil	 *  - any osd_client or other work that may reference an authorizer
998f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil	 *    finishes before we shut down the auth subsystem.
999f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil	 */
1000f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil	ceph_msgr_flush();
1001f3dea7edd3d449fe7a6d402c1ce56a294b985261Sage Weil
10024e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	ceph_auth_destroy(monc->auth);
10034e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
10044e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	ceph_msg_put(monc->m_auth);
10056694d6b95cf3b41751e78815d05968fa2084d7bfSage Weil	ceph_msg_put(monc->m_auth_reply);
1006240ed68eb567d80dd6bab739341999a5ab0ad55dSage Weil	ceph_msg_put(monc->m_subscribe);
10077c315c552c7442eab73461de61dbcce579a31d3aSage Weil	ceph_msg_put(monc->m_subscribe_ack);
1008ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1009ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	kfree(monc->monmap);
1010ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
10113d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda SadehEXPORT_SYMBOL(ceph_monc_stop);
1012ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
10134e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weilstatic void handle_auth_reply(struct ceph_mon_client *monc,
10144e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil			      struct ceph_msg *msg)
10154e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil{
10164e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	int ret;
101709c4d6a7d40dd26c1b35674c582382b7ea551368Sage Weil	int was_auth = 0;
1018d1c338a509cea5378df59629ad47382810c38623Sage Weil	int had_debugfs_info, init_debugfs = 0;
10194e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
10204e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	mutex_lock(&monc->mutex);
1021d1c338a509cea5378df59629ad47382810c38623Sage Weil	had_debugfs_info = have_debugfs_info(monc);
102227859f9773e4a0b2042435b13400ee2c891a61f4Sage Weil	was_auth = ceph_auth_is_authenticated(monc->auth);
10239bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	monc->pending_auth = 0;
10244e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base,
10254e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil				     msg->front.iov_len,
10264e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil				     monc->m_auth->front.iov_base,
10273cea4c3071d4e55e9d7356efe9d0ebf92f0c2204Ilya Dryomov				     monc->m_auth->front_alloc_len);
10284e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	if (ret < 0) {
10299bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil		monc->client->auth_err = ret;
103003066f23452ff088ad8e2c8acdf4443043f35b51Yehuda Sadeh		wake_up_all(&monc->client->auth_wq);
10314e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	} else if (ret > 0) {
10329bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil		__send_prepared_auth_request(monc, ret);
103327859f9773e4a0b2042435b13400ee2c891a61f4Sage Weil	} else if (!was_auth && ceph_auth_is_authenticated(monc->auth)) {
10344e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		dout("authenticated, starting session\n");
10350743304d871559cb4c7c066357de2caa60e94c2fSage Weil
103615d9882c336db2db73ccf9871ae2398e452f694cAlex Elder		monc->client->msgr.inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
103715d9882c336db2db73ccf9871ae2398e452f694cAlex Elder		monc->client->msgr.inst.name.num =
10380cf5537b158caae42bcc03f0f6db10f68585b1ecYehuda Sadeh					cpu_to_le64(monc->auth->global_id);
10390743304d871559cb4c7c066357de2caa60e94c2fSage Weil
10404e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		__send_subscribe(monc);
1041f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		__resend_generic_request(monc);
10424e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	}
1043d1c338a509cea5378df59629ad47382810c38623Sage Weil
1044d1c338a509cea5378df59629ad47382810c38623Sage Weil	if (!had_debugfs_info && have_debugfs_info(monc)) {
1045d1c338a509cea5378df59629ad47382810c38623Sage Weil		pr_info("client%lld fsid %pU\n",
1046d1c338a509cea5378df59629ad47382810c38623Sage Weil			ceph_client_id(monc->client),
1047d1c338a509cea5378df59629ad47382810c38623Sage Weil			&monc->client->fsid);
1048d1c338a509cea5378df59629ad47382810c38623Sage Weil		init_debugfs = 1;
1049d1c338a509cea5378df59629ad47382810c38623Sage Weil	}
10504e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	mutex_unlock(&monc->mutex);
1051d1c338a509cea5378df59629ad47382810c38623Sage Weil
1052d1c338a509cea5378df59629ad47382810c38623Sage Weil	if (init_debugfs) {
1053d1c338a509cea5378df59629ad47382810c38623Sage Weil		/*
1054d1c338a509cea5378df59629ad47382810c38623Sage Weil		 * do debugfs initialization without mutex to avoid
1055d1c338a509cea5378df59629ad47382810c38623Sage Weil		 * creating a locking dependency
1056d1c338a509cea5378df59629ad47382810c38623Sage Weil		 */
1057d1c338a509cea5378df59629ad47382810c38623Sage Weil		ceph_debugfs_client_init(monc->client);
1058d1c338a509cea5378df59629ad47382810c38623Sage Weil	}
10594e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil}
10604e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
10619bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weilstatic int __validate_auth(struct ceph_mon_client *monc)
10629bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil{
10639bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	int ret;
10649bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
10659bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	if (monc->pending_auth)
10669bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil		return 0;
10679bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
10689bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	ret = ceph_build_auth(monc->auth, monc->m_auth->front.iov_base,
10693cea4c3071d4e55e9d7356efe9d0ebf92f0c2204Ilya Dryomov			      monc->m_auth->front_alloc_len);
10709bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	if (ret <= 0)
10719bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil		return ret; /* either an error, or no need to authenticate */
10729bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	__send_prepared_auth_request(monc, ret);
10739bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	return 0;
10749bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil}
10759bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
10769bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weilint ceph_monc_validate_auth(struct ceph_mon_client *monc)
10779bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil{
10789bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	int ret;
10799bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
10809bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	mutex_lock(&monc->mutex);
10819bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	ret = __validate_auth(monc);
10829bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	mutex_unlock(&monc->mutex);
10839bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil	return ret;
10849bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil}
10853d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda SadehEXPORT_SYMBOL(ceph_monc_validate_auth);
10869bd2e6f8ba71facf1cadb7154a7e0e4d345a6abaSage Weil
1087ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
1088ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * handle incoming message
1089ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
1090ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
1091ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
1092ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_mon_client *monc = con->private;
1093ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	int type = le16_to_cpu(msg->hdr.type);
1094ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1095ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (!monc)
1096ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		return;
1097ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1098ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	switch (type) {
10994e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	case CEPH_MSG_AUTH_REPLY:
11004e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		handle_auth_reply(monc, msg);
1101ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		break;
1102ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1103ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	case CEPH_MSG_MON_SUBSCRIBE_ACK:
1104ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		handle_subscribe_ack(monc, msg);
1105ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		break;
1106ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1107ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	case CEPH_MSG_STATFS_REPLY:
1108ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		handle_statfs_reply(monc, msg);
1109ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		break;
1110ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1111513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	case CEPH_MSG_MON_GET_VERSION_REPLY:
1112513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		handle_get_version_reply(monc, msg);
1113513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		break;
1114513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
1115e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	case CEPH_MSG_POOLOP_REPLY:
1116e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		handle_poolop_reply(monc, msg);
1117e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh		break;
1118e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh
11194e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	case CEPH_MSG_MON_MAP:
11204e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		ceph_monc_handle_map(monc, msg);
11214e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		break;
11224e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil
1123ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	case CEPH_MSG_OSD_MAP:
1124ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		ceph_osdc_handle_map(&monc->client->osdc, msg);
1125ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		break;
1126ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1127ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	default:
11283d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		/* can the chained handler handle it? */
11293d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		if (monc->client->extra_mon_dispatch &&
11303d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh		    monc->client->extra_mon_dispatch(monc->client, msg) == 0)
11313d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh			break;
11323d14c5d2b6e15c21d8e5467dc62d33127c23a644Yehuda Sadeh
1133ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		pr_err("received unknown message type %d %s\n", type,
1134ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		       ceph_msg_type_name(type));
1135ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
1136ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	ceph_msg_put(msg);
1137ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
1138ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1139ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
1140ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * Allocate memory for incoming message
1141ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
1142ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
11432450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh				      struct ceph_msg_header *hdr,
11442450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh				      int *skip)
1145ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
1146ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_mon_client *monc = con->private;
1147ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	int type = le16_to_cpu(hdr->type);
11482450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh	int front_len = le32_to_cpu(hdr->front_len);
11495b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil	struct ceph_msg *m = NULL;
1150ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
11512450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh	*skip = 0;
11520547a9b30a5ac8680325752b61d3ffa9d4971b6eYehuda Sadeh
1153ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	switch (type) {
1154ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	case CEPH_MSG_MON_SUBSCRIBE_ACK:
11557c315c552c7442eab73461de61dbcce579a31d3aSage Weil		m = ceph_msg_get(monc->m_subscribe_ack);
11562450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh		break;
1157e56fa10e92e077d456cbc33b7025032887772b33Yehuda Sadeh	case CEPH_MSG_POOLOP_REPLY:
1158ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	case CEPH_MSG_STATFS_REPLY:
1159f8c76f6f250edbdc9d2011b0e05d196a3d8ae895Yehuda Sadeh		return get_generic_reply(con, hdr, skip);
11604e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil	case CEPH_MSG_AUTH_REPLY:
11616694d6b95cf3b41751e78815d05968fa2084d7bfSage Weil		m = ceph_msg_get(monc->m_auth_reply);
11622450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh		break;
1163513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov	case CEPH_MSG_MON_GET_VERSION_REPLY:
1164513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		if (le64_to_cpu(hdr->tid) != 0)
1165513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov			return get_generic_reply(con, hdr, skip);
1166513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov
1167513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		/*
1168513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		 * Older OSDs don't set reply tid even if the orignal
1169513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		 * request had a non-zero tid.  Workaround this weirdness
1170513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		 * by falling through to the allocate case.
1171513a8243d67f8e8d27f2883bd2f18bc87c7ca376Ilya Dryomov		 */
11725b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil	case CEPH_MSG_MON_MAP:
11735b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil	case CEPH_MSG_MDS_MAP:
11745b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil	case CEPH_MSG_OSD_MAP:
1175b61c27636fffbaf1980e675282777b9467254a40Sage Weil		m = ceph_msg_new(type, front_len, GFP_NOFS, false);
11761c20f2d26795803fc4f5155fe4fca5717a5944b6Alex Elder		if (!m)
11771c20f2d26795803fc4f5155fe4fca5717a5944b6Alex Elder			return NULL;	/* ENOMEM--return skip == 0 */
11785b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil		break;
1179ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
11802450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh
11815b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil	if (!m) {
11825b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil		pr_info("alloc_msg unknown type %d\n", type);
11832450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh		*skip = 1;
118473c3d4812b4c755efeca0140f606f83772a39ce4Sage Weil	} else if (front_len > m->front_alloc_len) {
1185b9a678994b4a64b1106ab2cf7cfe7cbc10bb6f40Joe Perches		pr_warn("mon_alloc_msg front %d > prealloc %d (%u#%llu)\n",
1186b9a678994b4a64b1106ab2cf7cfe7cbc10bb6f40Joe Perches			front_len, m->front_alloc_len,
1187b9a678994b4a64b1106ab2cf7cfe7cbc10bb6f40Joe Perches			(unsigned int)con->peer_name.type,
1188b9a678994b4a64b1106ab2cf7cfe7cbc10bb6f40Joe Perches			le64_to_cpu(con->peer_name.num));
118973c3d4812b4c755efeca0140f606f83772a39ce4Sage Weil		ceph_msg_put(m);
119073c3d4812b4c755efeca0140f606f83772a39ce4Sage Weil		m = ceph_msg_new(type, front_len, GFP_NOFS, false);
11915b3a4db3e4009aff918abb1353eb3f4925393a7bSage Weil	}
119273c3d4812b4c755efeca0140f606f83772a39ce4Sage Weil
11932450418c47b7998ad55a73f23707b1e21c371eefYehuda Sadeh	return m;
1194ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
1195ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1196ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil/*
1197ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * If the monitor connection resets, pick a new monitor and resubmit
1198ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil * any pending requests.
1199ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil */
1200ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilstatic void mon_fault(struct ceph_connection *con)
1201ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil{
1202ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	struct ceph_mon_client *monc = con->private;
1203ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1204ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (!monc)
1205ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		return;
1206ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1207ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	dout("mon_fault\n");
1208ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_lock(&monc->mutex);
1209ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (!con->private)
1210ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		goto out;
1211ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1212f6a2f5be07463ef532b9f4e3cb9e42ab9df85832Sage Weil	if (!monc->hunting)
1213ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		pr_info("mon%d %s session lost, "
1214ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil			"hunting for new mon\n", monc->cur_mon,
121567130934fb579fdf0f2f6d745960264378b57dc8Alex Elder			ceph_pr_addr(&monc->con.peer_addr.in_addr));
1216ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1217ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	__close_session(monc);
1218ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	if (!monc->hunting) {
1219ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		/* start hunting */
1220ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		monc->hunting = true;
12214e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bcSage Weil		__open_session(monc);
1222ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	} else {
1223ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		/* already hunting, let's wait a bit */
1224ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil		__schedule_delayed(monc);
1225ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	}
1226ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weilout:
1227ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	mutex_unlock(&monc->mutex);
1228ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil}
1229ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil
1230ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil/*
1231ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil * We can ignore refcounting on the connection struct, as all references
1232ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil * will come from the messenger workqueue, which is drained prior to
1233ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil * mon_client destruction.
1234ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil */
1235ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weilstatic struct ceph_connection *con_get(struct ceph_connection *con)
1236ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil{
1237ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil	return con;
1238ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil}
1239ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil
1240ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weilstatic void con_put(struct ceph_connection *con)
1241ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil{
1242ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil}
1243ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil
12449e32789f63fc5ad91c8b10f68ec23a86856d5af5Tobias Klauserstatic const struct ceph_connection_operations mon_con_ops = {
1245ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil	.get = con_get,
1246ec87ef4309d33bd9c87a53bb5152a86ae7a65f25Sage Weil	.put = con_put,
1247ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	.dispatch = dispatch,
1248ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	.fault = mon_fault,
1249ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil	.alloc_msg = mon_alloc_msg,
1250ba75bb98cfb93b62c54af25bf67ff90857264bbeSage Weil};
1251