cl->msgr->prepare_pages = ceph_osdc_prepare_pages;
cl->whoami = -1;
- ceph_monc_init(&cl->monc, cl);
+ if ((err = ceph_monc_init(&cl->monc, cl)) < 0)
+ goto fail;
ceph_mdsc_init(&cl->mdsc, cl);
ceph_osdc_init(&cl->osdc, cl);
static void handle_monmap(struct ceph_client *client, struct ceph_msg *msg)
{
int err;
- int first = (client->monc.monmap.epoch == 0);
-
- dout(1, "handle_monmap had epoch %d\n", client->monc.monmap.epoch);
+ int first = (client->monc.monmap->epoch == 0);
+ void *new;
- /* parse */
- err = ceph_monmap_decode(&client->monc.monmap,
- msg->front.iov_base,
+ dout(1, "handle_monmap had epoch %d\n", client->monc.monmap->epoch);
+ new = ceph_monmap_decode(msg->front.iov_base,
msg->front.iov_base + msg->front.iov_len);
- if (err != 0)
+ if (IS_ERR(new)) {
+ err = PTR_ERR(new);
+ derr(0, "problem decoding monmap, %d\n", err);
return;
+ }
+ kfree(client->monc.monmap);
+ client->monc.monmap = new;
if (first) {
client->whoami = msg->hdr.dst.name.num;
switch (msg->hdr.type) {
/* me */
case CEPH_MSG_MON_MAP:
- had = client->monc.monmap.epoch ? 1:0;
+ had = client->monc.monmap->epoch ? 1:0;
handle_monmap(client, msg);
- if (!had && client->monc.monmap.epoch)
+ if (!had && client->monc.monmap->epoch)
got_first_map(client, 0);
break;
#include "super.h"
-int ceph_monmap_decode(struct ceph_monmap *m, void *p, void *end)
+struct ceph_monmap *ceph_monmap_decode(void *p, void *end)
{
- int err;
- void *old;
+ struct ceph_monmap *m;
+ int i, err;
dout(30, "monmap_decode %p %p\n", p, end);
+ m = kmalloc(end-p, GFP_KERNEL);
+ if (m == NULL)
+ return ERR_PTR(-ENOMEM);
if ((err = ceph_decode_32(&p, end, &m->epoch)) < 0)
goto bad;
if ((err = ceph_decode_64(&p, end, &m->fsid.minor)) < 0)
goto bad;
if ((err = ceph_decode_32(&p, end, &m->num_mon)) < 0)
- return err;
-
- old = m->mon_inst;
- m->mon_inst = kmalloc(m->num_mon*sizeof(*m->mon_inst), GFP_KERNEL);
- if (m->mon_inst == NULL) {
- m->mon_inst = old;
- return -ENOMEM;
- }
- kfree(old);
+ goto bad;
- if ((err = ceph_decode_copy(&p, end, m->mon_inst, m->num_mon*sizeof(m->mon_inst[0]))) < 0)
+ if (p + m->num_mon*sizeof(m->mon_inst[0]) != end) {
+ err = -EINVAL;
goto bad;
+ }
+ memcpy(m->mon_inst, p, end-p);
+ for (i=0; i<m->num_mon; i++) {
+ ceph_decode_inst(&m->mon_inst[i]);
+ dout(30, "monmap_decode mon%d is %x:%d\n", i,
+ ntohl(m->mon_inst[i].addr.ipaddr.sin_addr.s_addr),
+ ntohs(m->mon_inst[i].addr.ipaddr.sin_port));
+ }
dout(30, "monmap_decode got epoch %d, num_mon %d\n", m->epoch, m->num_mon);
- return 0;
+ return m;
bad:
dout(30, "monmap_decode failed with %d\n", err);
- return err;
+ return ERR_PTR(err);
}
/*
if (notmon < 0 && monc->last_mon >= 0)
return monc->last_mon;
get_random_bytes(&r, 1);
- monc->last_mon = r % monc->monmap.num_mon;
+ monc->last_mon = r % monc->monmap->num_mon;
return monc->last_mon;
}
-void ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
+int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
{
dout(5, "ceph_monc_init\n");
memset(monc, 0, sizeof(*monc));
monc->client = cl;
+ monc->monmap = kzalloc(sizeof(struct ceph_monmap), GFP_KERNEL);
+ if (monc->monmap == NULL)
+ return -ENOMEM;
spin_lock_init(&monc->lock);
INIT_RADIX_TREE(&monc->statfs_request_tree, GFP_KERNEL);
+ return 0;
}
if (IS_ERR(msg))
return PTR_ERR(msg);
*(__le64*)msg->front.iov_base = cpu_to_le64(tid);
- msg->hdr.dst = monc->monmap.mon_inst[mon];
+ msg->hdr.dst = monc->monmap->mon_inst[mon];
ceph_msg_send(monc->client->msgr, msg, BASE_DELAY_INTERVAL);
return 0;
}
ceph_epoch_t epoch;
struct ceph_fsid fsid;
__u32 num_mon;
- struct ceph_entity_inst *mon_inst;
+ struct ceph_entity_inst mon_inst[0];
};
struct ceph_mon_statfs_request {
struct ceph_mon_client {
struct ceph_client *client;
int last_mon; /* last monitor i contacted */
- struct ceph_monmap monmap;
+ struct ceph_monmap *monmap;
spinlock_t lock;
struct radix_tree_root statfs_request_tree; /* statfs requests */
u64 last_tid;
};
-extern int ceph_monmap_decode(struct ceph_monmap *m, void *p, void *end);
+extern struct ceph_monmap *ceph_monmap_decode(void *p, void *end);
extern int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr);
-extern void ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl);
+extern int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl);
extern void ceph_monc_request_mdsmap(struct ceph_mon_client *monc, __u64 have);
extern void ceph_monc_request_osdmap(struct ceph_mon_client *monc, __u64 have);
args->fsid.major, args->fsid.minor);
if (args->flags & CEPH_MOUNT_NOSHARE)
seq_puts(m, ",noshare");
- seq_printf(m, ",monport=%d", args->mon_port);
return 0;
}
/* defaults */
args->mntflags = flags;
args->flags = 0;
- args->mon_port = CEPH_MON_PORT;
/* ip1[,ip2...]:/server/path */
c = strchr(dev_name, ':');
break;
case Opt_monport:
dout(25, "parse_mount_args monport=%d\n", intval);
- args->mon_port = intval;
for (i=0; i<args->num_mon; i++)
args->mon_addr[i].ipaddr.sin_port = htons(intval);
break;
} else {
/* do we share (a) monitor? */
for (i=0; i<args->num_mon; i++)
- if (ceph_monmap_contains(&other->sb_client->monc.monmap,
+ if (ceph_monmap_contains(other->sb_client->monc.monmap,
&args->mon_addr[i]))
break;
if (i == args->num_mon) {
struct ceph_entity_addr my_addr;
int num_mon;
struct ceph_entity_addr mon_addr[5];
- int mon_port;
char path[100];
};