summaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-06 10:51:29 -0400
committerAlex Elder <elder@inktank.com>2013-05-08 18:00:37 -0400
commit662518b128c27def65e9af4bea2b56a1e04b3251 (patch)
tree195365fca5ff452ad5364fb876f2b9a720e8ee5a /drivers/block/rbd.c
parentbb23e37acb2ae9604130c4819fb8ae0f784a3a2b (diff)
rbd: update in-core header directly
Now that rbd_header_from_disk() only fills in one-time fields once, we can extend it slightly so it releases the other fields before replacing their values. This way there's no need to pass a temporary buffer and then copy all the results in. Just use the rbd device header structure in rbd_header_from_disk() so its values get updated directly. Note that this means we need to take the header semaphore at the point we update things. So pass the rbd_dev rather than the address of its header as its first argument to rbd_header_from_disk(), and have it return an error code. As a result, rbd_dev_v1_header_read() does all the work, rbd_read_header() becomes unnecessary, and rbd_dev_v1_refresh() becomes a very simple wrapper. 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.c98
1 files changed, 27 insertions, 71 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index a3b6bf5e9ae8..e4586f2e04c2 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -730,9 +730,10 @@ static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk)
730 * Fill an rbd image header with information from the given format 1 730 * Fill an rbd image header with information from the given format 1
731 * on-disk header. 731 * on-disk header.
732 */ 732 */
733static int rbd_header_from_disk(struct rbd_image_header *header, 733static int rbd_header_from_disk(struct rbd_device *rbd_dev,
734 struct rbd_image_header_ondisk *ondisk) 734 struct rbd_image_header_ondisk *ondisk)
735{ 735{
736 struct rbd_image_header *header = &rbd_dev->header;
736 bool first_time = header->object_prefix == NULL; 737 bool first_time = header->object_prefix == NULL;
737 struct ceph_snap_context *snapc; 738 struct ceph_snap_context *snapc;
738 char *object_prefix = NULL; 739 char *object_prefix = NULL;
@@ -802,6 +803,7 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
802 803
803 /* We won't fail any more, fill in the header */ 804 /* We won't fail any more, fill in the header */
804 805
806 down_write(&rbd_dev->header_rwsem);
805 if (first_time) { 807 if (first_time) {
806 header->object_prefix = object_prefix; 808 header->object_prefix = object_prefix;
807 header->obj_order = ondisk->options.order; 809 header->obj_order = ondisk->options.order;
@@ -811,6 +813,10 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
811 header->stripe_unit = 0; 813 header->stripe_unit = 0;
812 header->stripe_count = 0; 814 header->stripe_count = 0;
813 header->features = 0; 815 header->features = 0;
816 } else {
817 ceph_put_snap_context(header->snapc);
818 kfree(header->snap_names);
819 kfree(header->snap_sizes);
814 } 820 }
815 821
816 /* The remaining fields always get updated (when we refresh) */ 822 /* The remaining fields always get updated (when we refresh) */
@@ -820,6 +826,14 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
820 header->snap_names = snap_names; 826 header->snap_names = snap_names;
821 header->snap_sizes = snap_sizes; 827 header->snap_sizes = snap_sizes;
822 828
829 /* Make sure mapping size is consistent with header info */
830
831 if (rbd_dev->spec->snap_id == CEPH_NOSNAP || first_time)
832 if (rbd_dev->mapping.size != header->image_size)
833 rbd_dev->mapping.size = header->image_size;
834
835 up_write(&rbd_dev->header_rwsem);
836
823 return 0; 837 return 0;
824out_2big: 838out_2big:
825 ret = -EIO; 839 ret = -EIO;
@@ -3032,17 +3046,11 @@ out:
3032} 3046}
3033 3047
3034/* 3048/*
3035 * Read the complete header for the given rbd device. 3049 * Read the complete header for the given rbd device. On successful
3036 * 3050 * return, the rbd_dev->header field will contain up-to-date
3037 * Returns a pointer to a dynamically-allocated buffer containing 3051 * information about the image.
3038 * the complete and validated header. Caller can pass the address
3039 * of a variable that will be filled in with the version of the
3040 * header object at the time it was read.
3041 *
3042 * Returns a pointer-coded errno if a failure occurs.
3043 */ 3052 */
3044static struct rbd_image_header_ondisk * 3053static int rbd_dev_v1_header_read(struct rbd_device *rbd_dev)
3045rbd_dev_v1_header_read(struct rbd_device *rbd_dev)
3046{ 3054{
3047 struct rbd_image_header_ondisk *ondisk = NULL; 3055 struct rbd_image_header_ondisk *ondisk = NULL;
3048 u32 snap_count = 0; 3056 u32 snap_count = 0;
@@ -3067,22 +3075,22 @@ rbd_dev_v1_header_read(struct rbd_device *rbd_dev)
3067 size += names_size; 3075 size += names_size;
3068 ondisk = kmalloc(size, GFP_KERNEL); 3076 ondisk = kmalloc(size, GFP_KERNEL);
3069 if (!ondisk) 3077 if (!ondisk)
3070 return ERR_PTR(-ENOMEM); 3078 return -ENOMEM;
3071 3079
3072 ret = rbd_obj_read_sync(rbd_dev, rbd_dev->header_name, 3080 ret = rbd_obj_read_sync(rbd_dev, rbd_dev->header_name,
3073 0, size, ondisk); 3081 0, size, ondisk);
3074 if (ret < 0) 3082 if (ret < 0)
3075 goto out_err; 3083 goto out;
3076 if ((size_t)ret < size) { 3084 if ((size_t)ret < size) {
3077 ret = -ENXIO; 3085 ret = -ENXIO;
3078 rbd_warn(rbd_dev, "short header read (want %zd got %d)", 3086 rbd_warn(rbd_dev, "short header read (want %zd got %d)",
3079 size, ret); 3087 size, ret);
3080 goto out_err; 3088 goto out;
3081 } 3089 }
3082 if (!rbd_dev_ondisk_valid(ondisk)) { 3090 if (!rbd_dev_ondisk_valid(ondisk)) {
3083 ret = -ENXIO; 3091 ret = -ENXIO;
3084 rbd_warn(rbd_dev, "invalid header"); 3092 rbd_warn(rbd_dev, "invalid header");
3085 goto out_err; 3093 goto out;
3086 } 3094 }
3087 3095
3088 names_size = le64_to_cpu(ondisk->snap_names_len); 3096 names_size = le64_to_cpu(ondisk->snap_names_len);
@@ -3090,27 +3098,8 @@ rbd_dev_v1_header_read(struct rbd_device *rbd_dev)
3090 snap_count = le32_to_cpu(ondisk->snap_count); 3098 snap_count = le32_to_cpu(ondisk->snap_count);
3091 } while (snap_count != want_count); 3099 } while (snap_count != want_count);
3092 3100
3093 return ondisk; 3101 ret = rbd_header_from_disk(rbd_dev, ondisk);
3094 3102out:
3095out_err:
3096 kfree(ondisk);
3097
3098 return ERR_PTR(ret);
3099}
3100
3101/*
3102 * reload the ondisk the header
3103 */
3104static int rbd_read_header(struct rbd_device *rbd_dev,
3105 struct rbd_image_header *header)
3106{
3107 struct rbd_image_header_ondisk *ondisk;
3108 int ret;
3109
3110 ondisk = rbd_dev_v1_header_read(rbd_dev);
3111 if (IS_ERR(ondisk))
3112 return PTR_ERR(ondisk);
3113 ret = rbd_header_from_disk(header, ondisk);
3114 kfree(ondisk); 3103 kfree(ondisk);
3115 3104
3116 return ret; 3105 return ret;
@@ -3121,40 +3110,7 @@ static int rbd_read_header(struct rbd_device *rbd_dev,
3121 */ 3110 */
3122static int rbd_dev_v1_refresh(struct rbd_device *rbd_dev) 3111static int rbd_dev_v1_refresh(struct rbd_device *rbd_dev)
3123{ 3112{
3124 int ret; 3113 return rbd_dev_v1_header_read(rbd_dev);
3125 struct rbd_image_header h;
3126
3127 memset(&h, 0, sizeof (h));
3128 ret = rbd_read_header(rbd_dev, &h);
3129 if (ret < 0)
3130 return ret;
3131
3132 down_write(&rbd_dev->header_rwsem);
3133
3134 /* Update image size, and check for resize of mapped image */
3135 rbd_dev->header.image_size = h.image_size;
3136 if (rbd_dev->spec->snap_id == CEPH_NOSNAP)
3137 if (rbd_dev->mapping.size != rbd_dev->header.image_size)
3138 rbd_dev->mapping.size = rbd_dev->header.image_size;
3139
3140 /* rbd_dev->header.object_prefix shouldn't change */
3141 kfree(rbd_dev->header.snap_sizes);
3142 kfree(rbd_dev->header.snap_names);
3143 /* osd requests may still refer to snapc */
3144 ceph_put_snap_context(rbd_dev->header.snapc);
3145
3146 rbd_dev->header.image_size = h.image_size;
3147 rbd_dev->header.snapc = h.snapc;
3148 rbd_dev->header.snap_names = h.snap_names;
3149 rbd_dev->header.snap_sizes = h.snap_sizes;
3150 /* Free the extra copy of the object prefix */
3151 if (strcmp(rbd_dev->header.object_prefix, h.object_prefix))
3152 rbd_warn(rbd_dev, "object prefix changed (ignoring)");
3153 kfree(h.object_prefix);
3154
3155 up_write(&rbd_dev->header_rwsem);
3156
3157 return ret;
3158} 3114}
3159 3115
3160/* 3116/*
@@ -4517,7 +4473,7 @@ static int rbd_dev_v1_probe(struct rbd_device *rbd_dev)
4517 4473
4518 /* Populate rbd image metadata */ 4474 /* Populate rbd image metadata */
4519 4475
4520 ret = rbd_read_header(rbd_dev, &rbd_dev->header); 4476 ret = rbd_dev_v1_header_read(rbd_dev);
4521 if (ret < 0) 4477 if (ret < 0)
4522 goto out_err; 4478 goto out_err;
4523 4479