diff options
-rw-r--r-- | drivers/block/rbd.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index bce1fcfb5185..842caf4aab47 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -70,7 +70,10 @@ | |||
70 | 70 | ||
71 | #define RBD_SNAP_HEAD_NAME "-" | 71 | #define RBD_SNAP_HEAD_NAME "-" |
72 | 72 | ||
73 | /* This allows a single page to hold an image name sent by OSD */ | ||
74 | #define RBD_IMAGE_NAME_LEN_MAX (PAGE_SIZE - sizeof (__le32) - 1) | ||
73 | #define RBD_IMAGE_ID_LEN_MAX 64 | 75 | #define RBD_IMAGE_ID_LEN_MAX 64 |
76 | |||
74 | #define RBD_OBJ_PREFIX_LEN_MAX 64 | 77 | #define RBD_OBJ_PREFIX_LEN_MAX 64 |
75 | 78 | ||
76 | /* Feature bits */ | 79 | /* Feature bits */ |
@@ -658,6 +661,20 @@ out_err: | |||
658 | return -ENOMEM; | 661 | return -ENOMEM; |
659 | } | 662 | } |
660 | 663 | ||
664 | static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id) | ||
665 | { | ||
666 | struct rbd_snap *snap; | ||
667 | |||
668 | if (snap_id == CEPH_NOSNAP) | ||
669 | return RBD_SNAP_HEAD_NAME; | ||
670 | |||
671 | list_for_each_entry(snap, &rbd_dev->snaps, node) | ||
672 | if (snap_id == snap->id) | ||
673 | return snap->name; | ||
674 | |||
675 | return NULL; | ||
676 | } | ||
677 | |||
661 | static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name) | 678 | static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name) |
662 | { | 679 | { |
663 | 680 | ||
@@ -2499,6 +2516,7 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) | |||
2499 | goto out_err; | 2516 | goto out_err; |
2500 | } | 2517 | } |
2501 | parent_spec->image_id = image_id; | 2518 | parent_spec->image_id = image_id; |
2519 | parent_spec->image_id_len = len; | ||
2502 | ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err); | 2520 | ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err); |
2503 | ceph_decode_64_safe(&p, end, overlap, out_err); | 2521 | ceph_decode_64_safe(&p, end, overlap, out_err); |
2504 | 2522 | ||
@@ -2514,6 +2532,117 @@ out_err: | |||
2514 | return ret; | 2532 | return ret; |
2515 | } | 2533 | } |
2516 | 2534 | ||
2535 | static char *rbd_dev_image_name(struct rbd_device *rbd_dev) | ||
2536 | { | ||
2537 | size_t image_id_size; | ||
2538 | char *image_id; | ||
2539 | void *p; | ||
2540 | void *end; | ||
2541 | size_t size; | ||
2542 | void *reply_buf = NULL; | ||
2543 | size_t len = 0; | ||
2544 | char *image_name = NULL; | ||
2545 | int ret; | ||
2546 | |||
2547 | rbd_assert(!rbd_dev->spec->image_name); | ||
2548 | |||
2549 | image_id_size = sizeof (__le32) + rbd_dev->spec->image_id_len; | ||
2550 | image_id = kmalloc(image_id_size, GFP_KERNEL); | ||
2551 | if (!image_id) | ||
2552 | return NULL; | ||
2553 | |||
2554 | p = image_id; | ||
2555 | end = (char *) image_id + image_id_size; | ||
2556 | ceph_encode_string(&p, end, rbd_dev->spec->image_id, | ||
2557 | (u32) rbd_dev->spec->image_id_len); | ||
2558 | |||
2559 | size = sizeof (__le32) + RBD_IMAGE_NAME_LEN_MAX; | ||
2560 | reply_buf = kmalloc(size, GFP_KERNEL); | ||
2561 | if (!reply_buf) | ||
2562 | goto out; | ||
2563 | |||
2564 | ret = rbd_req_sync_exec(rbd_dev, RBD_DIRECTORY, | ||
2565 | "rbd", "dir_get_name", | ||
2566 | image_id, image_id_size, | ||
2567 | (char *) reply_buf, size, | ||
2568 | CEPH_OSD_FLAG_READ, NULL); | ||
2569 | if (ret < 0) | ||
2570 | goto out; | ||
2571 | p = reply_buf; | ||
2572 | end = (char *) reply_buf + size; | ||
2573 | image_name = ceph_extract_encoded_string(&p, end, &len, GFP_KERNEL); | ||
2574 | if (IS_ERR(image_name)) | ||
2575 | image_name = NULL; | ||
2576 | else | ||
2577 | dout("%s: name is %s len is %zd\n", __func__, image_name, len); | ||
2578 | out: | ||
2579 | kfree(reply_buf); | ||
2580 | kfree(image_id); | ||
2581 | |||
2582 | return image_name; | ||
2583 | } | ||
2584 | |||
2585 | /* | ||
2586 | * When a parent image gets probed, we only have the pool, image, | ||
2587 | * and snapshot ids but not the names of any of them. This call | ||
2588 | * is made later to fill in those names. It has to be done after | ||
2589 | * rbd_dev_snaps_update() has completed because some of the | ||
2590 | * information (in particular, snapshot name) is not available | ||
2591 | * until then. | ||
2592 | */ | ||
2593 | static int rbd_dev_probe_update_spec(struct rbd_device *rbd_dev) | ||
2594 | { | ||
2595 | struct ceph_osd_client *osdc; | ||
2596 | const char *name; | ||
2597 | void *reply_buf = NULL; | ||
2598 | int ret; | ||
2599 | |||
2600 | if (rbd_dev->spec->pool_name) | ||
2601 | return 0; /* Already have the names */ | ||
2602 | |||
2603 | /* Look up the pool name */ | ||
2604 | |||
2605 | osdc = &rbd_dev->rbd_client->client->osdc; | ||
2606 | name = ceph_pg_pool_name_by_id(osdc->osdmap, rbd_dev->spec->pool_id); | ||
2607 | if (!name) | ||
2608 | return -EIO; /* pool id too large (>= 2^31) */ | ||
2609 | |||
2610 | rbd_dev->spec->pool_name = kstrdup(name, GFP_KERNEL); | ||
2611 | if (!rbd_dev->spec->pool_name) | ||
2612 | return -ENOMEM; | ||
2613 | |||
2614 | /* Fetch the image name; tolerate failure here */ | ||
2615 | |||
2616 | name = rbd_dev_image_name(rbd_dev); | ||
2617 | if (name) { | ||
2618 | rbd_dev->spec->image_name_len = strlen(name); | ||
2619 | rbd_dev->spec->image_name = (char *) name; | ||
2620 | } else { | ||
2621 | pr_warning(RBD_DRV_NAME "%d " | ||
2622 | "unable to get image name for image id %s\n", | ||
2623 | rbd_dev->major, rbd_dev->spec->image_id); | ||
2624 | } | ||
2625 | |||
2626 | /* Look up the snapshot name. */ | ||
2627 | |||
2628 | name = rbd_snap_name(rbd_dev, rbd_dev->spec->snap_id); | ||
2629 | if (!name) { | ||
2630 | ret = -EIO; | ||
2631 | goto out_err; | ||
2632 | } | ||
2633 | rbd_dev->spec->snap_name = kstrdup(name, GFP_KERNEL); | ||
2634 | if(!rbd_dev->spec->snap_name) | ||
2635 | goto out_err; | ||
2636 | |||
2637 | return 0; | ||
2638 | out_err: | ||
2639 | kfree(reply_buf); | ||
2640 | kfree(rbd_dev->spec->pool_name); | ||
2641 | rbd_dev->spec->pool_name = NULL; | ||
2642 | |||
2643 | return ret; | ||
2644 | } | ||
2645 | |||
2517 | static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver) | 2646 | static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver) |
2518 | { | 2647 | { |
2519 | size_t size; | 2648 | size_t size; |
@@ -3372,6 +3501,10 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) | |||
3372 | if (ret) | 3501 | if (ret) |
3373 | return ret; | 3502 | return ret; |
3374 | 3503 | ||
3504 | ret = rbd_dev_probe_update_spec(rbd_dev); | ||
3505 | if (ret) | ||
3506 | goto err_out_snaps; | ||
3507 | |||
3375 | ret = rbd_dev_set_mapping(rbd_dev); | 3508 | ret = rbd_dev_set_mapping(rbd_dev); |
3376 | if (ret) | 3509 | if (ret) |
3377 | goto err_out_snaps; | 3510 | goto err_out_snaps; |