diff options
| author | Alex Elder <elder@inktank.com> | 2013-04-30 01:44:33 -0400 |
|---|---|---|
| committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:20:19 -0400 |
| commit | 54cac61fb6b3bacecf5367d3838307b1dd69ace2 (patch) | |
| tree | de7d9b8a50637f1d02c289379fbe6d5cb22f635b /drivers/block/rbd.c | |
| parent | 9682fc6d3a8b63f58fbfc5084f32c038170cfd6b (diff) | |
rbd: use snap_id not index to look up snap info
In order to align with what was needed for format 1 rbd images,
rbd_dev_v2_snap_info() was set up to take as argument an index into
the array of snapshot ids in a rbd device's snapshot context.
This switches that around, so we pass the snapshot id instead.
In doing this, rbd_snap_name() now returns a dynamically-allocated
string rather than a fixed one, so there's no need to make a
duplicate in its caller, rbd_dev_spec_update().
This means the following functions take a snapshot id where they
previously used an index value:
rbd_dev_snap_info()
rbd_dev_v1_snap_info()
rbd_dev_v2_snap_info()
A new function, rbd_dev_snap_index(), determines the snap index for
format 1 images and uses it to look up the name.
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
| -rw-r--r-- | drivers/block/rbd.c | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 5d1ed184bed2..eb78d575d9b2 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -433,6 +433,8 @@ static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); | |||
| 433 | 433 | ||
| 434 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); | 434 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); |
| 435 | static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev); | 435 | static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev); |
| 436 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, | ||
| 437 | u64 snap_id); | ||
| 436 | 438 | ||
| 437 | static int rbd_open(struct block_device *bdev, fmode_t mode) | 439 | static int rbd_open(struct block_device *bdev, fmode_t mode) |
| 438 | { | 440 | { |
| @@ -838,18 +840,27 @@ static u32 rbd_dev_snap_index(struct rbd_device *rbd_dev, u64 snap_id) | |||
| 838 | return BAD_SNAP_INDEX; | 840 | return BAD_SNAP_INDEX; |
| 839 | } | 841 | } |
| 840 | 842 | ||
| 841 | static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id) | 843 | static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u64 snap_id) |
| 842 | { | 844 | { |
| 843 | struct rbd_snap *snap; | 845 | u32 which; |
| 844 | 846 | ||
| 847 | which = rbd_dev_snap_index(rbd_dev, snap_id); | ||
| 848 | if (which == BAD_SNAP_INDEX) | ||
| 849 | return NULL; | ||
| 850 | |||
| 851 | return _rbd_dev_v1_snap_name(rbd_dev, which); | ||
| 852 | } | ||
| 853 | |||
| 854 | static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id) | ||
| 855 | { | ||
| 845 | if (snap_id == CEPH_NOSNAP) | 856 | if (snap_id == CEPH_NOSNAP) |
| 846 | return RBD_SNAP_HEAD_NAME; | 857 | return RBD_SNAP_HEAD_NAME; |
| 847 | 858 | ||
| 848 | list_for_each_entry(snap, &rbd_dev->snaps, node) | 859 | rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); |
| 849 | if (snap_id == snap->id) | 860 | if (rbd_dev->image_format == 1) |
| 850 | return snap->name; | 861 | return rbd_dev_v1_snap_name(rbd_dev, snap_id); |
| 851 | 862 | ||
| 852 | return NULL; | 863 | return rbd_dev_v2_snap_name(rbd_dev, snap_id); |
| 853 | } | 864 | } |
| 854 | 865 | ||
| 855 | static struct rbd_snap *snap_by_name(struct rbd_device *rbd_dev, | 866 | static struct rbd_snap *snap_by_name(struct rbd_device *rbd_dev, |
| @@ -3446,11 +3457,15 @@ static struct rbd_snap *rbd_snap_create(struct rbd_device *rbd_dev, | |||
| 3446 | * Returns a dynamically-allocated snapshot name if successful, or a | 3457 | * Returns a dynamically-allocated snapshot name if successful, or a |
| 3447 | * pointer-coded error otherwise. | 3458 | * pointer-coded error otherwise. |
| 3448 | */ | 3459 | */ |
| 3449 | static const char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, u32 which, | 3460 | static const char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, |
| 3450 | u64 *snap_size, u64 *snap_features) | 3461 | u64 snap_id, u64 *snap_size, u64 *snap_features) |
| 3451 | { | 3462 | { |
| 3452 | const char *snap_name; | 3463 | const char *snap_name; |
| 3464 | u32 which; | ||
| 3453 | 3465 | ||
| 3466 | which = rbd_dev_snap_index(rbd_dev, snap_id); | ||
| 3467 | if (which == BAD_SNAP_INDEX) | ||
| 3468 | return ERR_PTR(-ENOENT); | ||
| 3454 | snap_name = _rbd_dev_v1_snap_name(rbd_dev, which); | 3469 | snap_name = _rbd_dev_v1_snap_name(rbd_dev, which); |
| 3455 | if (!snap_name) | 3470 | if (!snap_name) |
| 3456 | return ERR_PTR(-ENOMEM); | 3471 | return ERR_PTR(-ENOMEM); |
| @@ -3816,12 +3831,6 @@ static int rbd_dev_spec_update(struct rbd_device *rbd_dev) | |||
| 3816 | 3831 | ||
| 3817 | snap_name = rbd_snap_name(rbd_dev, spec->snap_id); | 3832 | snap_name = rbd_snap_name(rbd_dev, spec->snap_id); |
| 3818 | if (!snap_name) { | 3833 | if (!snap_name) { |
| 3819 | rbd_warn(rbd_dev, "no snapshot with id %llu", spec->snap_id); | ||
| 3820 | ret = -EIO; | ||
| 3821 | goto out_err; | ||
| 3822 | } | ||
| 3823 | snap_name = kstrdup(snap_name, GFP_KERNEL); | ||
| 3824 | if (!snap_name) { | ||
| 3825 | ret = -ENOMEM; | 3834 | ret = -ENOMEM; |
| 3826 | goto out_err; | 3835 | goto out_err; |
| 3827 | } | 3836 | } |
| @@ -3909,11 +3918,12 @@ out: | |||
| 3909 | return ret; | 3918 | return ret; |
| 3910 | } | 3919 | } |
| 3911 | 3920 | ||
| 3912 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u32 which) | 3921 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, |
| 3922 | u64 snap_id) | ||
| 3913 | { | 3923 | { |
| 3914 | size_t size; | 3924 | size_t size; |
| 3915 | void *reply_buf; | 3925 | void *reply_buf; |
| 3916 | __le64 snap_id; | 3926 | __le64 snapid; |
| 3917 | int ret; | 3927 | int ret; |
| 3918 | void *p; | 3928 | void *p; |
| 3919 | void *end; | 3929 | void *end; |
| @@ -3924,11 +3934,10 @@ static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u32 which) | |||
| 3924 | if (!reply_buf) | 3934 | if (!reply_buf) |
| 3925 | return ERR_PTR(-ENOMEM); | 3935 | return ERR_PTR(-ENOMEM); |
| 3926 | 3936 | ||
| 3927 | rbd_assert(which < rbd_dev->header.snapc->num_snaps); | 3937 | snapid = cpu_to_le64(snap_id); |
| 3928 | snap_id = cpu_to_le64(rbd_dev->header.snapc->snaps[which]); | ||
| 3929 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, | 3938 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
| 3930 | "rbd", "get_snapshot_name", | 3939 | "rbd", "get_snapshot_name", |
| 3931 | &snap_id, sizeof (snap_id), | 3940 | &snapid, sizeof (snapid), |
| 3932 | reply_buf, size); | 3941 | reply_buf, size); |
| 3933 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); | 3942 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
| 3934 | if (ret < 0) { | 3943 | if (ret < 0) { |
| @@ -3943,24 +3952,21 @@ static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u32 which) | |||
| 3943 | goto out; | 3952 | goto out; |
| 3944 | 3953 | ||
| 3945 | dout(" snap_id 0x%016llx snap_name = %s\n", | 3954 | dout(" snap_id 0x%016llx snap_name = %s\n", |
| 3946 | (unsigned long long)le64_to_cpu(snap_id), snap_name); | 3955 | (unsigned long long)snap_id, snap_name); |
| 3947 | out: | 3956 | out: |
| 3948 | kfree(reply_buf); | 3957 | kfree(reply_buf); |
| 3949 | 3958 | ||
| 3950 | return snap_name; | 3959 | return snap_name; |
| 3951 | } | 3960 | } |
| 3952 | 3961 | ||
| 3953 | static const char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev, u32 which, | 3962 | static const char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev, |
| 3954 | u64 *snap_size, u64 *snap_features) | 3963 | u64 snap_id, u64 *snap_size, u64 *snap_features) |
| 3955 | { | 3964 | { |
| 3956 | u64 snap_id; | ||
| 3957 | u64 size; | 3965 | u64 size; |
| 3958 | u64 features; | 3966 | u64 features; |
| 3959 | const char *snap_name; | 3967 | const char *snap_name; |
| 3960 | int ret; | 3968 | int ret; |
| 3961 | 3969 | ||
| 3962 | rbd_assert(which < rbd_dev->header.snapc->num_snaps); | ||
| 3963 | snap_id = rbd_dev->header.snapc->snaps[which]; | ||
| 3964 | ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size); | 3970 | ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size); |
| 3965 | if (ret) | 3971 | if (ret) |
| 3966 | goto out_err; | 3972 | goto out_err; |
| @@ -3969,7 +3975,7 @@ static const char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev, u32 which, | |||
| 3969 | if (ret) | 3975 | if (ret) |
| 3970 | goto out_err; | 3976 | goto out_err; |
| 3971 | 3977 | ||
| 3972 | snap_name = rbd_dev_v2_snap_name(rbd_dev, which); | 3978 | snap_name = rbd_dev_v2_snap_name(rbd_dev, snap_id); |
| 3973 | if (!IS_ERR(snap_name)) { | 3979 | if (!IS_ERR(snap_name)) { |
| 3974 | *snap_size = size; | 3980 | *snap_size = size; |
| 3975 | *snap_features = features; | 3981 | *snap_features = features; |
| @@ -3980,14 +3986,14 @@ out_err: | |||
| 3980 | return ERR_PTR(ret); | 3986 | return ERR_PTR(ret); |
| 3981 | } | 3987 | } |
| 3982 | 3988 | ||
| 3983 | static const char *rbd_dev_snap_info(struct rbd_device *rbd_dev, u32 which, | 3989 | static const char *rbd_dev_snap_info(struct rbd_device *rbd_dev, |
| 3984 | u64 *snap_size, u64 *snap_features) | 3990 | u64 snap_id, u64 *snap_size, u64 *snap_features) |
| 3985 | { | 3991 | { |
| 3986 | if (rbd_dev->image_format == 1) | 3992 | if (rbd_dev->image_format == 1) |
| 3987 | return rbd_dev_v1_snap_info(rbd_dev, which, | 3993 | return rbd_dev_v1_snap_info(rbd_dev, snap_id, |
| 3988 | snap_size, snap_features); | 3994 | snap_size, snap_features); |
| 3989 | if (rbd_dev->image_format == 2) | 3995 | if (rbd_dev->image_format == 2) |
| 3990 | return rbd_dev_v2_snap_info(rbd_dev, which, | 3996 | return rbd_dev_v2_snap_info(rbd_dev, snap_id, |
| 3991 | snap_size, snap_features); | 3997 | snap_size, snap_features); |
| 3992 | return ERR_PTR(-EINVAL); | 3998 | return ERR_PTR(-EINVAL); |
| 3993 | } | 3999 | } |
| @@ -4085,7 +4091,7 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev) | |||
| 4085 | continue; | 4091 | continue; |
| 4086 | } | 4092 | } |
| 4087 | 4093 | ||
| 4088 | snap_name = rbd_dev_snap_info(rbd_dev, index, | 4094 | snap_name = rbd_dev_snap_info(rbd_dev, snap_id, |
| 4089 | &snap_size, &snap_features); | 4095 | &snap_size, &snap_features); |
| 4090 | if (IS_ERR(snap_name)) { | 4096 | if (IS_ERR(snap_name)) { |
| 4091 | ret = PTR_ERR(snap_name); | 4097 | ret = PTR_ERR(snap_name); |
