From bc4cf523839420bf8778ae28819e17c92687f087 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 14 Jan 2008 18:22:05 -0800 Subject: [PATCH] reworked monmap --- src/kernel/client.c | 24 ++++++++++++---------- src/kernel/mon_client.c | 44 ++++++++++++++++++++++++----------------- src/kernel/mon_client.h | 8 ++++---- src/kernel/super.c | 5 +---- src/kernel/super.h | 1 - 5 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/kernel/client.c b/src/kernel/client.c index 0f03a88eae07b..14953ba13eaab 100644 --- a/src/kernel/client.c +++ b/src/kernel/client.c @@ -82,7 +82,8 @@ static struct ceph_client *create_client(struct ceph_mount_args *args) 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); @@ -143,16 +144,19 @@ trymount: 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; @@ -242,9 +246,9 @@ void ceph_dispatch(void *p, struct ceph_msg *msg) 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; diff --git a/src/kernel/mon_client.c b/src/kernel/mon_client.c index e83ee0b93459c..38aa2cd5f7041 100644 --- a/src/kernel/mon_client.c +++ b/src/kernel/mon_client.c @@ -9,12 +9,15 @@ int ceph_mon_debug = 50; #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; @@ -23,25 +26,26 @@ int ceph_monmap_decode(struct ceph_monmap *m, void *p, void *end) 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; inum_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); } /* @@ -63,18 +67,22 @@ static int pick_mon(struct ceph_mon_client *monc, int notmon) 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; } @@ -135,7 +143,7 @@ int send_statfs(struct ceph_mon_client *monc, u64 tid) 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; } diff --git a/src/kernel/mon_client.h b/src/kernel/mon_client.h index 16015e25758f6..fc88b4d98e4c2 100644 --- a/src/kernel/mon_client.h +++ b/src/kernel/mon_client.h @@ -12,7 +12,7 @@ struct ceph_monmap { 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 { @@ -25,17 +25,17 @@ 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); diff --git a/src/kernel/super.c b/src/kernel/super.c index 23bc6daf95bbd..89464a91309a9 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -78,7 +78,6 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) 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; } @@ -236,7 +235,6 @@ static int parse_mount_args(int flags, char *options, const char *dev_name, stru /* defaults */ args->mntflags = flags; args->flags = 0; - args->mon_port = CEPH_MON_PORT; /* ip1[,ip2...]:/server/path */ c = strchr(dev_name, ':'); @@ -285,7 +283,6 @@ static int parse_mount_args(int flags, char *options, const char *dev_name, stru break; case Opt_monport: dout(25, "parse_mount_args monport=%d\n", intval); - args->mon_port = intval; for (i=0; inum_mon; i++) args->mon_addr[i].ipaddr.sin_port = htons(intval); break; @@ -479,7 +476,7 @@ static int ceph_compare_super(struct super_block *sb, void *data) } else { /* do we share (a) monitor? */ for (i=0; inum_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) { diff --git a/src/kernel/super.h b/src/kernel/super.h index 5e10850393df7..74eb404ead181 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -30,7 +30,6 @@ struct ceph_mount_args { struct ceph_entity_addr my_addr; int num_mon; struct ceph_entity_addr mon_addr[5]; - int mon_port; char path[100]; }; -- 2.39.5