rbd: decouple header read-in from updating rbd_dev->header
commit 510a7330c82a7754d5df0117a8589e8a539067c7 upstream. Make rbd_dev_header_info() populate a passed struct rbd_image_header instead of rbd_dev->header and introduce rbd_dev_update_header() for updating mutable fields in rbd_dev->header upon refresh. The initial read-in of both mutable and immutable fields in rbd_dev_image_probe() passes in rbd_dev->header so no update step is required there. rbd_init_layout() is now called directly from rbd_dev_image_probe() instead of individually in format 1 and format 2 implementations. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
7c4f11d73b
commit
3ceb306f9b
@@ -632,7 +632,8 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...)
|
|||||||
static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
|
static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
|
||||||
|
|
||||||
static int rbd_dev_refresh(struct rbd_device *rbd_dev);
|
static int rbd_dev_refresh(struct rbd_device *rbd_dev);
|
||||||
static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev);
|
static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev,
|
||||||
|
struct rbd_image_header *header);
|
||||||
static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
|
static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
|
||||||
u64 snap_id);
|
u64 snap_id);
|
||||||
static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
|
static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
|
||||||
@@ -1045,15 +1046,24 @@ static void rbd_init_layout(struct rbd_device *rbd_dev)
|
|||||||
RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL);
|
RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rbd_image_header_cleanup(struct rbd_image_header *header)
|
||||||
|
{
|
||||||
|
kfree(header->object_prefix);
|
||||||
|
ceph_put_snap_context(header->snapc);
|
||||||
|
kfree(header->snap_sizes);
|
||||||
|
kfree(header->snap_names);
|
||||||
|
|
||||||
|
memset(header, 0, sizeof(*header));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill an rbd image header with information from the given format 1
|
* Fill an rbd image header with information from the given format 1
|
||||||
* on-disk header.
|
* on-disk header.
|
||||||
*/
|
*/
|
||||||
static int rbd_header_from_disk(struct rbd_device *rbd_dev,
|
static int rbd_header_from_disk(struct rbd_image_header *header,
|
||||||
struct rbd_image_header_ondisk *ondisk)
|
struct rbd_image_header_ondisk *ondisk,
|
||||||
|
bool first_time)
|
||||||
{
|
{
|
||||||
struct rbd_image_header *header = &rbd_dev->header;
|
|
||||||
bool first_time = header->object_prefix == NULL;
|
|
||||||
struct ceph_snap_context *snapc;
|
struct ceph_snap_context *snapc;
|
||||||
char *object_prefix = NULL;
|
char *object_prefix = NULL;
|
||||||
char *snap_names = NULL;
|
char *snap_names = NULL;
|
||||||
@@ -1120,11 +1130,6 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev,
|
|||||||
if (first_time) {
|
if (first_time) {
|
||||||
header->object_prefix = object_prefix;
|
header->object_prefix = object_prefix;
|
||||||
header->obj_order = ondisk->options.order;
|
header->obj_order = ondisk->options.order;
|
||||||
rbd_init_layout(rbd_dev);
|
|
||||||
} else {
|
|
||||||
ceph_put_snap_context(header->snapc);
|
|
||||||
kfree(header->snap_names);
|
|
||||||
kfree(header->snap_sizes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The remaining fields always get updated (when we refresh) */
|
/* The remaining fields always get updated (when we refresh) */
|
||||||
@@ -4914,7 +4919,9 @@ out_req:
|
|||||||
* return, the rbd_dev->header field will contain up-to-date
|
* return, the rbd_dev->header field will contain up-to-date
|
||||||
* information about the image.
|
* information about the image.
|
||||||
*/
|
*/
|
||||||
static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev)
|
static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev,
|
||||||
|
struct rbd_image_header *header,
|
||||||
|
bool first_time)
|
||||||
{
|
{
|
||||||
struct rbd_image_header_ondisk *ondisk = NULL;
|
struct rbd_image_header_ondisk *ondisk = NULL;
|
||||||
u32 snap_count = 0;
|
u32 snap_count = 0;
|
||||||
@@ -4962,7 +4969,7 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev)
|
|||||||
snap_count = le32_to_cpu(ondisk->snap_count);
|
snap_count = le32_to_cpu(ondisk->snap_count);
|
||||||
} while (snap_count != want_count);
|
} while (snap_count != want_count);
|
||||||
|
|
||||||
ret = rbd_header_from_disk(rbd_dev, ondisk);
|
ret = rbd_header_from_disk(header, ondisk, first_time);
|
||||||
out:
|
out:
|
||||||
kfree(ondisk);
|
kfree(ondisk);
|
||||||
|
|
||||||
@@ -5541,17 +5548,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev)
|
static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev,
|
||||||
{
|
char **pobject_prefix)
|
||||||
return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP,
|
|
||||||
&rbd_dev->header.obj_order,
|
|
||||||
&rbd_dev->header.image_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev)
|
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
void *reply_buf;
|
void *reply_buf;
|
||||||
|
char *object_prefix;
|
||||||
int ret;
|
int ret;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
@@ -5569,16 +5571,16 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
p = reply_buf;
|
p = reply_buf;
|
||||||
rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
|
object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL,
|
||||||
p + ret, NULL, GFP_NOIO);
|
GFP_NOIO);
|
||||||
|
if (IS_ERR(object_prefix)) {
|
||||||
|
ret = PTR_ERR(object_prefix);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
if (IS_ERR(rbd_dev->header.object_prefix)) {
|
*pobject_prefix = object_prefix;
|
||||||
ret = PTR_ERR(rbd_dev->header.object_prefix);
|
dout(" object_prefix = %s\n", object_prefix);
|
||||||
rbd_dev->header.object_prefix = NULL;
|
|
||||||
} else {
|
|
||||||
dout(" object_prefix = %s\n", rbd_dev->header.object_prefix);
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
kfree(reply_buf);
|
kfree(reply_buf);
|
||||||
|
|
||||||
@@ -5629,13 +5631,6 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
|
|
||||||
{
|
|
||||||
return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
|
|
||||||
rbd_is_ro(rbd_dev),
|
|
||||||
&rbd_dev->header.features);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are generic image flags, but since they are used only for
|
* These are generic image flags, but since they are used only for
|
||||||
* object map, store them in rbd_dev->object_map_flags.
|
* object map, store them in rbd_dev->object_map_flags.
|
||||||
@@ -5910,14 +5905,14 @@ out_err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev)
|
static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev,
|
||||||
|
u64 *stripe_unit, u64 *stripe_count)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
__le64 stripe_unit;
|
__le64 stripe_unit;
|
||||||
__le64 stripe_count;
|
__le64 stripe_count;
|
||||||
} __attribute__ ((packed)) striping_info_buf = { 0 };
|
} __attribute__ ((packed)) striping_info_buf = { 0 };
|
||||||
size_t size = sizeof (striping_info_buf);
|
size_t size = sizeof (striping_info_buf);
|
||||||
void *p;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
|
ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
|
||||||
@@ -5929,27 +5924,33 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev)
|
|||||||
if (ret < size)
|
if (ret < size)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
p = &striping_info_buf;
|
*stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit);
|
||||||
rbd_dev->header.stripe_unit = ceph_decode_64(&p);
|
*stripe_count = le64_to_cpu(striping_info_buf.stripe_count);
|
||||||
rbd_dev->header.stripe_count = ceph_decode_64(&p);
|
dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit,
|
||||||
|
*stripe_count);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev)
|
static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id)
|
||||||
{
|
{
|
||||||
__le64 data_pool_id;
|
__le64 data_pool_buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
|
ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
|
||||||
&rbd_dev->header_oloc, "get_data_pool",
|
&rbd_dev->header_oloc, "get_data_pool",
|
||||||
NULL, 0, &data_pool_id, sizeof(data_pool_id));
|
NULL, 0, &data_pool_buf,
|
||||||
|
sizeof(data_pool_buf));
|
||||||
|
dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (ret < sizeof(data_pool_id))
|
if (ret < sizeof(data_pool_buf))
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id);
|
*data_pool_id = le64_to_cpu(data_pool_buf);
|
||||||
WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL);
|
dout(" data_pool_id = %lld\n", *data_pool_id);
|
||||||
|
WARN_ON(*data_pool_id == CEPH_NOPOOL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6141,7 +6142,8 @@ out_err:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)
|
static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev,
|
||||||
|
struct ceph_snap_context **psnapc)
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -6202,9 +6204,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)
|
|||||||
for (i = 0; i < snap_count; i++)
|
for (i = 0; i < snap_count; i++)
|
||||||
snapc->snaps[i] = ceph_decode_64(&p);
|
snapc->snaps[i] = ceph_decode_64(&p);
|
||||||
|
|
||||||
ceph_put_snap_context(rbd_dev->header.snapc);
|
*psnapc = snapc;
|
||||||
rbd_dev->header.snapc = snapc;
|
|
||||||
|
|
||||||
dout(" snap context seq = %llu, snap_count = %u\n",
|
dout(" snap context seq = %llu, snap_count = %u\n",
|
||||||
(unsigned long long)seq, (unsigned int)snap_count);
|
(unsigned long long)seq, (unsigned int)snap_count);
|
||||||
out:
|
out:
|
||||||
@@ -6253,38 +6253,42 @@ out:
|
|||||||
return snap_name;
|
return snap_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
|
static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev,
|
||||||
|
struct rbd_image_header *header,
|
||||||
|
bool first_time)
|
||||||
{
|
{
|
||||||
bool first_time = rbd_dev->header.object_prefix == NULL;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rbd_dev_v2_image_size(rbd_dev);
|
ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP,
|
||||||
|
first_time ? &header->obj_order : NULL,
|
||||||
|
&header->image_size);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (first_time) {
|
if (first_time) {
|
||||||
ret = rbd_dev_v2_header_onetime(rbd_dev);
|
ret = rbd_dev_v2_header_onetime(rbd_dev, header);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = rbd_dev_v2_snap_context(rbd_dev);
|
ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc);
|
||||||
if (ret && first_time) {
|
if (ret)
|
||||||
kfree(rbd_dev->header.object_prefix);
|
return ret;
|
||||||
rbd_dev->header.object_prefix = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_header_info(struct rbd_device *rbd_dev)
|
static int rbd_dev_header_info(struct rbd_device *rbd_dev,
|
||||||
|
struct rbd_image_header *header,
|
||||||
|
bool first_time)
|
||||||
{
|
{
|
||||||
rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
|
rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
|
||||||
|
rbd_assert(!header->object_prefix && !header->snapc);
|
||||||
|
|
||||||
if (rbd_dev->image_format == 1)
|
if (rbd_dev->image_format == 1)
|
||||||
return rbd_dev_v1_header_info(rbd_dev);
|
return rbd_dev_v1_header_info(rbd_dev, header, first_time);
|
||||||
|
|
||||||
return rbd_dev_v2_header_info(rbd_dev);
|
return rbd_dev_v2_header_info(rbd_dev, header, first_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6771,60 +6775,49 @@ out:
|
|||||||
*/
|
*/
|
||||||
static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
|
static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
|
||||||
{
|
{
|
||||||
struct rbd_image_header *header;
|
|
||||||
|
|
||||||
rbd_dev_parent_put(rbd_dev);
|
rbd_dev_parent_put(rbd_dev);
|
||||||
rbd_object_map_free(rbd_dev);
|
rbd_object_map_free(rbd_dev);
|
||||||
rbd_dev_mapping_clear(rbd_dev);
|
rbd_dev_mapping_clear(rbd_dev);
|
||||||
|
|
||||||
/* Free dynamic fields from the header, then zero it out */
|
/* Free dynamic fields from the header, then zero it out */
|
||||||
|
|
||||||
header = &rbd_dev->header;
|
rbd_image_header_cleanup(&rbd_dev->header);
|
||||||
ceph_put_snap_context(header->snapc);
|
|
||||||
kfree(header->snap_sizes);
|
|
||||||
kfree(header->snap_names);
|
|
||||||
kfree(header->object_prefix);
|
|
||||||
memset(header, 0, sizeof (*header));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
|
static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev,
|
||||||
|
struct rbd_image_header *header)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rbd_dev_v2_object_prefix(rbd_dev);
|
ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_err;
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the and check features for the image. Currently the
|
* Get the and check features for the image. Currently the
|
||||||
* features are assumed to never change.
|
* features are assumed to never change.
|
||||||
*/
|
*/
|
||||||
ret = rbd_dev_v2_features(rbd_dev);
|
ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
|
||||||
|
rbd_is_ro(rbd_dev), &header->features);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_err;
|
return ret;
|
||||||
|
|
||||||
/* If the image supports fancy striping, get its parameters */
|
/* If the image supports fancy striping, get its parameters */
|
||||||
|
|
||||||
if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) {
|
if (header->features & RBD_FEATURE_STRIPINGV2) {
|
||||||
ret = rbd_dev_v2_striping_info(rbd_dev);
|
ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit,
|
||||||
if (ret < 0)
|
&header->stripe_count);
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) {
|
|
||||||
ret = rbd_dev_v2_data_pool(rbd_dev);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_err;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
rbd_init_layout(rbd_dev);
|
if (header->features & RBD_FEATURE_DATA_POOL) {
|
||||||
return 0;
|
ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
out_err:
|
return 0;
|
||||||
rbd_dev->header.features = 0;
|
|
||||||
kfree(rbd_dev->header.object_prefix);
|
|
||||||
rbd_dev->header.object_prefix = NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7019,13 +7012,15 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
|
|||||||
if (!depth)
|
if (!depth)
|
||||||
down_write(&rbd_dev->header_rwsem);
|
down_write(&rbd_dev->header_rwsem);
|
||||||
|
|
||||||
ret = rbd_dev_header_info(rbd_dev);
|
ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret == -ENOENT && !need_watch)
|
if (ret == -ENOENT && !need_watch)
|
||||||
rbd_print_dne(rbd_dev, false);
|
rbd_print_dne(rbd_dev, false);
|
||||||
goto err_out_probe;
|
goto err_out_probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rbd_init_layout(rbd_dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this image is the one being mapped, we have pool name and
|
* If this image is the one being mapped, we have pool name and
|
||||||
* id, image name and id, and snap name - need to fill snap id.
|
* id, image name and id, and snap name - need to fill snap id.
|
||||||
@@ -7080,15 +7075,39 @@ err_out_format:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rbd_dev_update_header(struct rbd_device *rbd_dev,
|
||||||
|
struct rbd_image_header *header)
|
||||||
|
{
|
||||||
|
rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
|
||||||
|
rbd_assert(rbd_dev->header.object_prefix); /* !first_time */
|
||||||
|
|
||||||
|
rbd_dev->header.image_size = header->image_size;
|
||||||
|
|
||||||
|
ceph_put_snap_context(rbd_dev->header.snapc);
|
||||||
|
rbd_dev->header.snapc = header->snapc;
|
||||||
|
header->snapc = NULL;
|
||||||
|
|
||||||
|
if (rbd_dev->image_format == 1) {
|
||||||
|
kfree(rbd_dev->header.snap_names);
|
||||||
|
rbd_dev->header.snap_names = header->snap_names;
|
||||||
|
header->snap_names = NULL;
|
||||||
|
|
||||||
|
kfree(rbd_dev->header.snap_sizes);
|
||||||
|
rbd_dev->header.snap_sizes = header->snap_sizes;
|
||||||
|
header->snap_sizes = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int rbd_dev_refresh(struct rbd_device *rbd_dev)
|
static int rbd_dev_refresh(struct rbd_device *rbd_dev)
|
||||||
{
|
{
|
||||||
|
struct rbd_image_header header = { 0 };
|
||||||
u64 mapping_size;
|
u64 mapping_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
down_write(&rbd_dev->header_rwsem);
|
down_write(&rbd_dev->header_rwsem);
|
||||||
mapping_size = rbd_dev->mapping.size;
|
mapping_size = rbd_dev->mapping.size;
|
||||||
|
|
||||||
ret = rbd_dev_header_info(rbd_dev);
|
ret = rbd_dev_header_info(rbd_dev, &header, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -7102,6 +7121,8 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rbd_dev_update_header(rbd_dev, &header);
|
||||||
|
|
||||||
rbd_assert(!rbd_is_snap(rbd_dev));
|
rbd_assert(!rbd_is_snap(rbd_dev));
|
||||||
rbd_dev->mapping.size = rbd_dev->header.image_size;
|
rbd_dev->mapping.size = rbd_dev->header.image_size;
|
||||||
|
|
||||||
@@ -7110,6 +7131,7 @@ out:
|
|||||||
if (!ret && mapping_size != rbd_dev->mapping.size)
|
if (!ret && mapping_size != rbd_dev->mapping.size)
|
||||||
rbd_dev_update_size(rbd_dev);
|
rbd_dev_update_size(rbd_dev);
|
||||||
|
|
||||||
|
rbd_image_header_cleanup(&header);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user