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 |
