Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c5df893 authored by Josh Durgin's avatar Josh Durgin Committed by Ilya Dryomov
Browse files

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: default avatarJosh Durgin <josh.durgin@inktank.com>
parent 90e98c52
Loading
Loading
Loading
Loading
+12 −6
Original line number Original line Diff line number Diff line
@@ -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;
			} else {
				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;
					opcode = CEPH_OSD_OP_TRUNCATE;
				else
				else
					opcode = CEPH_OSD_OP_ZERO;
					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;