rbd: read image size for discard check safely
In rbd_img_request_fill() the image size is only checked to determine whether we can truncate an object instead of zeroing it for discard requests. Take rbd_dev->header_rwsem while reading the image size, and move this read into the discard check, so that non-discard ops don't need to take the semaphore in this function. Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
This commit is contained in:
parent
90e98c5229
commit
3c5df89367
|
@ -2332,7 +2332,6 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
|
||||||
(int)type, data_desc);
|
(int)type, data_desc);
|
||||||
|
|
||||||
img_offset = img_request->offset;
|
img_offset = img_request->offset;
|
||||||
img_end = rbd_dev->header.image_size;
|
|
||||||
resid = img_request->length;
|
resid = img_request->length;
|
||||||
rbd_assert(resid > 0);
|
rbd_assert(resid > 0);
|
||||||
|
|
||||||
|
@ -2397,13 +2396,20 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
|
||||||
if (!offset && (length == object_size)
|
if (!offset && (length == object_size)
|
||||||
&& (!img_request_layered_test(img_request) ||
|
&& (!img_request_layered_test(img_request) ||
|
||||||
(rbd_dev->parent_overlap <=
|
(rbd_dev->parent_overlap <=
|
||||||
obj_request->img_offset)))
|
obj_request->img_offset))) {
|
||||||
opcode = CEPH_OSD_OP_DELETE;
|
opcode = CEPH_OSD_OP_DELETE;
|
||||||
else if ((offset + length == object_size) ||
|
} else if ((offset + length == object_size)) {
|
||||||
(obj_request->img_offset + length == img_end))
|
|
||||||
opcode = CEPH_OSD_OP_TRUNCATE;
|
opcode = CEPH_OSD_OP_TRUNCATE;
|
||||||
else
|
} else {
|
||||||
opcode = CEPH_OSD_OP_ZERO;
|
down_read(&rbd_dev->header_rwsem);
|
||||||
|
img_end = rbd_dev->header.image_size;
|
||||||
|
up_read(&rbd_dev->header_rwsem);
|
||||||
|
|
||||||
|
if (obj_request->img_offset + length == img_end)
|
||||||
|
opcode = CEPH_OSD_OP_TRUNCATE;
|
||||||
|
else
|
||||||
|
opcode = CEPH_OSD_OP_ZERO;
|
||||||
|
}
|
||||||
} else if (img_request_write_test(img_request)) {
|
} else if (img_request_write_test(img_request)) {
|
||||||
op_type = OBJ_OP_WRITE;
|
op_type = OBJ_OP_WRITE;
|
||||||
opcode = CEPH_OSD_OP_WRITE;
|
opcode = CEPH_OSD_OP_WRITE;
|
||||||
|
|
Loading…
Reference in New Issue