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