diff options
-rw-r--r-- | fs/ceph/osdmap.c | 180 | ||||
-rw-r--r-- | fs/ceph/osdmap.h | 1 | ||||
-rw-r--r-- | fs/ceph/rados.h | 6 |
3 files changed, 114 insertions, 73 deletions
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index d82fe87c2a6e..7526d6d33016 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c | |||
@@ -312,71 +312,6 @@ bad: | |||
312 | return ERR_PTR(err); | 312 | return ERR_PTR(err); |
313 | } | 313 | } |
314 | 314 | ||
315 | |||
316 | /* | ||
317 | * osd map | ||
318 | */ | ||
319 | void ceph_osdmap_destroy(struct ceph_osdmap *map) | ||
320 | { | ||
321 | dout("osdmap_destroy %p\n", map); | ||
322 | if (map->crush) | ||
323 | crush_destroy(map->crush); | ||
324 | while (!RB_EMPTY_ROOT(&map->pg_temp)) { | ||
325 | struct ceph_pg_mapping *pg = | ||
326 | rb_entry(rb_first(&map->pg_temp), | ||
327 | struct ceph_pg_mapping, node); | ||
328 | rb_erase(&pg->node, &map->pg_temp); | ||
329 | kfree(pg); | ||
330 | } | ||
331 | while (!RB_EMPTY_ROOT(&map->pg_pools)) { | ||
332 | struct ceph_pg_pool_info *pi = | ||
333 | rb_entry(rb_first(&map->pg_pools), | ||
334 | struct ceph_pg_pool_info, node); | ||
335 | rb_erase(&pi->node, &map->pg_pools); | ||
336 | kfree(pi); | ||
337 | } | ||
338 | kfree(map->osd_state); | ||
339 | kfree(map->osd_weight); | ||
340 | kfree(map->osd_addr); | ||
341 | kfree(map); | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * adjust max osd value. reallocate arrays. | ||
346 | */ | ||
347 | static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) | ||
348 | { | ||
349 | u8 *state; | ||
350 | struct ceph_entity_addr *addr; | ||
351 | u32 *weight; | ||
352 | |||
353 | state = kcalloc(max, sizeof(*state), GFP_NOFS); | ||
354 | addr = kcalloc(max, sizeof(*addr), GFP_NOFS); | ||
355 | weight = kcalloc(max, sizeof(*weight), GFP_NOFS); | ||
356 | if (state == NULL || addr == NULL || weight == NULL) { | ||
357 | kfree(state); | ||
358 | kfree(addr); | ||
359 | kfree(weight); | ||
360 | return -ENOMEM; | ||
361 | } | ||
362 | |||
363 | /* copy old? */ | ||
364 | if (map->osd_state) { | ||
365 | memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); | ||
366 | memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); | ||
367 | memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); | ||
368 | kfree(map->osd_state); | ||
369 | kfree(map->osd_addr); | ||
370 | kfree(map->osd_weight); | ||
371 | } | ||
372 | |||
373 | map->osd_state = state; | ||
374 | map->osd_weight = weight; | ||
375 | map->osd_addr = addr; | ||
376 | map->max_osd = max; | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | /* | 315 | /* |
381 | * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid | 316 | * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid |
382 | * to a set of osds) | 317 | * to a set of osds) |
@@ -480,6 +415,13 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id) | |||
480 | return NULL; | 415 | return NULL; |
481 | } | 416 | } |
482 | 417 | ||
418 | static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi) | ||
419 | { | ||
420 | rb_erase(&pi->node, root); | ||
421 | kfree(pi->name); | ||
422 | kfree(pi); | ||
423 | } | ||
424 | |||
483 | void __decode_pool(void **p, struct ceph_pg_pool_info *pi) | 425 | void __decode_pool(void **p, struct ceph_pg_pool_info *pi) |
484 | { | 426 | { |
485 | ceph_decode_copy(p, &pi->v, sizeof(pi->v)); | 427 | ceph_decode_copy(p, &pi->v, sizeof(pi->v)); |
@@ -488,6 +430,98 @@ void __decode_pool(void **p, struct ceph_pg_pool_info *pi) | |||
488 | *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; | 430 | *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; |
489 | } | 431 | } |
490 | 432 | ||
433 | static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map) | ||
434 | { | ||
435 | struct ceph_pg_pool_info *pi; | ||
436 | u32 num, len, pool; | ||
437 | |||
438 | ceph_decode_32_safe(p, end, num, bad); | ||
439 | dout(" %d pool names\n", num); | ||
440 | while (num--) { | ||
441 | ceph_decode_32_safe(p, end, pool, bad); | ||
442 | ceph_decode_32_safe(p, end, len, bad); | ||
443 | dout(" pool %d len %d\n", pool, len); | ||
444 | pi = __lookup_pg_pool(&map->pg_pools, pool); | ||
445 | if (pi) { | ||
446 | kfree(pi->name); | ||
447 | pi->name = kmalloc(len + 1, GFP_NOFS); | ||
448 | if (pi->name) { | ||
449 | memcpy(pi->name, *p, len); | ||
450 | pi->name[len] = '\0'; | ||
451 | dout(" name is %s\n", pi->name); | ||
452 | } | ||
453 | } | ||
454 | *p += len; | ||
455 | } | ||
456 | return 0; | ||
457 | |||
458 | bad: | ||
459 | return -EINVAL; | ||
460 | } | ||
461 | |||
462 | /* | ||
463 | * osd map | ||
464 | */ | ||
465 | void ceph_osdmap_destroy(struct ceph_osdmap *map) | ||
466 | { | ||
467 | dout("osdmap_destroy %p\n", map); | ||
468 | if (map->crush) | ||
469 | crush_destroy(map->crush); | ||
470 | while (!RB_EMPTY_ROOT(&map->pg_temp)) { | ||
471 | struct ceph_pg_mapping *pg = | ||
472 | rb_entry(rb_first(&map->pg_temp), | ||
473 | struct ceph_pg_mapping, node); | ||
474 | rb_erase(&pg->node, &map->pg_temp); | ||
475 | kfree(pg); | ||
476 | } | ||
477 | while (!RB_EMPTY_ROOT(&map->pg_pools)) { | ||
478 | struct ceph_pg_pool_info *pi = | ||
479 | rb_entry(rb_first(&map->pg_pools), | ||
480 | struct ceph_pg_pool_info, node); | ||
481 | __remove_pg_pool(&map->pg_pools, pi); | ||
482 | } | ||
483 | kfree(map->osd_state); | ||
484 | kfree(map->osd_weight); | ||
485 | kfree(map->osd_addr); | ||
486 | kfree(map); | ||
487 | } | ||
488 | |||
489 | /* | ||
490 | * adjust max osd value. reallocate arrays. | ||
491 | */ | ||
492 | static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) | ||
493 | { | ||
494 | u8 *state; | ||
495 | struct ceph_entity_addr *addr; | ||
496 | u32 *weight; | ||
497 | |||
498 | state = kcalloc(max, sizeof(*state), GFP_NOFS); | ||
499 | addr = kcalloc(max, sizeof(*addr), GFP_NOFS); | ||
500 | weight = kcalloc(max, sizeof(*weight), GFP_NOFS); | ||
501 | if (state == NULL || addr == NULL || weight == NULL) { | ||
502 | kfree(state); | ||
503 | kfree(addr); | ||
504 | kfree(weight); | ||
505 | return -ENOMEM; | ||
506 | } | ||
507 | |||
508 | /* copy old? */ | ||
509 | if (map->osd_state) { | ||
510 | memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); | ||
511 | memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); | ||
512 | memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); | ||
513 | kfree(map->osd_state); | ||
514 | kfree(map->osd_addr); | ||
515 | kfree(map->osd_weight); | ||
516 | } | ||
517 | |||
518 | map->osd_state = state; | ||
519 | map->osd_weight = weight; | ||
520 | map->osd_addr = addr; | ||
521 | map->max_osd = max; | ||
522 | return 0; | ||
523 | } | ||
524 | |||
491 | /* | 525 | /* |
492 | * decode a full map. | 526 | * decode a full map. |
493 | */ | 527 | */ |
@@ -524,7 +558,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
524 | ceph_decode_32_safe(p, end, max, bad); | 558 | ceph_decode_32_safe(p, end, max, bad); |
525 | while (max--) { | 559 | while (max--) { |
526 | ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); | 560 | ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); |
527 | pi = kmalloc(sizeof(*pi), GFP_NOFS); | 561 | pi = kzalloc(sizeof(*pi), GFP_NOFS); |
528 | if (!pi) | 562 | if (!pi) |
529 | goto bad; | 563 | goto bad; |
530 | pi->id = ceph_decode_32(p); | 564 | pi->id = ceph_decode_32(p); |
@@ -537,6 +571,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
537 | __decode_pool(p, pi); | 571 | __decode_pool(p, pi); |
538 | __insert_pg_pool(&map->pg_pools, pi); | 572 | __insert_pg_pool(&map->pg_pools, pi); |
539 | } | 573 | } |
574 | |||
575 | if (version >= 5 && __decode_pool_names(p, end, map) < 0) | ||
576 | goto bad; | ||
577 | |||
540 | ceph_decode_32_safe(p, end, map->pool_max, bad); | 578 | ceph_decode_32_safe(p, end, map->pool_max, bad); |
541 | 579 | ||
542 | ceph_decode_32_safe(p, end, map->flags, bad); | 580 | ceph_decode_32_safe(p, end, map->flags, bad); |
@@ -710,7 +748,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
710 | } | 748 | } |
711 | pi = __lookup_pg_pool(&map->pg_pools, pool); | 749 | pi = __lookup_pg_pool(&map->pg_pools, pool); |
712 | if (!pi) { | 750 | if (!pi) { |
713 | pi = kmalloc(sizeof(*pi), GFP_NOFS); | 751 | pi = kzalloc(sizeof(*pi), GFP_NOFS); |
714 | if (!pi) { | 752 | if (!pi) { |
715 | err = -ENOMEM; | 753 | err = -ENOMEM; |
716 | goto bad; | 754 | goto bad; |
@@ -720,6 +758,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
720 | } | 758 | } |
721 | __decode_pool(p, pi); | 759 | __decode_pool(p, pi); |
722 | } | 760 | } |
761 | if (version >= 5 && __decode_pool_names(p, end, map) < 0) | ||
762 | goto bad; | ||
723 | 763 | ||
724 | /* old_pool */ | 764 | /* old_pool */ |
725 | ceph_decode_32_safe(p, end, len, bad); | 765 | ceph_decode_32_safe(p, end, len, bad); |
@@ -728,10 +768,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
728 | 768 | ||
729 | ceph_decode_32_safe(p, end, pool, bad); | 769 | ceph_decode_32_safe(p, end, pool, bad); |
730 | pi = __lookup_pg_pool(&map->pg_pools, pool); | 770 | pi = __lookup_pg_pool(&map->pg_pools, pool); |
731 | if (pi) { | 771 | if (pi) |
732 | rb_erase(&pi->node, &map->pg_pools); | 772 | __remove_pg_pool(&map->pg_pools, pi); |
733 | kfree(pi); | ||
734 | } | ||
735 | } | 773 | } |
736 | 774 | ||
737 | /* new_up */ | 775 | /* new_up */ |
diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index 1fb55afb2642..8bc9f1e4f562 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h | |||
@@ -23,6 +23,7 @@ struct ceph_pg_pool_info { | |||
23 | int id; | 23 | int id; |
24 | struct ceph_pg_pool v; | 24 | struct ceph_pg_pool v; |
25 | int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; | 25 | int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; |
26 | char *name; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | struct ceph_pg_mapping { | 29 | struct ceph_pg_mapping { |
diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index 26ac8b89a676..a1fc1d017b58 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h | |||
@@ -11,8 +11,10 @@ | |||
11 | /* | 11 | /* |
12 | * osdmap encoding versions | 12 | * osdmap encoding versions |
13 | */ | 13 | */ |
14 | #define CEPH_OSDMAP_INC_VERSION 4 | 14 | #define CEPH_OSDMAP_INC_VERSION 5 |
15 | #define CEPH_OSDMAP_VERSION 4 | 15 | #define CEPH_OSDMAP_INC_VERSION_EXT 5 |
16 | #define CEPH_OSDMAP_VERSION 5 | ||
17 | #define CEPH_OSDMAP_VERSION_EXT 5 | ||
16 | 18 | ||
17 | /* | 19 | /* |
18 | * fs id | 20 | * fs id |