libceph: allow ceph_osdc_new_request to accept a multi-op read

Currently we have some special-casing for multi-op writes, but in the
case of a read, we can't really handle it. All of the current multi-op
callers call it with CEPH_OSD_FLAG_WRITE set.

Have ceph_osdc_new_request check for CEPH_OSD_FLAG_READ and if it's set,
allocate multiple reply ops instead of multiple request ops. If neither
flag is set, return -EINVAL.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Reviewed-and-tested-by: Luís Henriques <lhenriques@suse.de>
Reviewed-by: Milind Changire <mchangir@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Jeff Layton 2022-08-25 09:31:16 -04:00 committed by Ilya Dryomov
parent 69dd3b3930
commit 4e8c4c2355

View File

@ -1136,15 +1136,30 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
if (flags & CEPH_OSD_FLAG_WRITE)
req->r_data_offset = off;
if (num_ops > 1)
if (num_ops > 1) {
int num_req_ops, num_rep_ops;
/*
* This is a special case for ceph_writepages_start(), but it
* also covers ceph_uninline_data(). If more multi-op request
* use cases emerge, we will need a separate helper.
* If this is a multi-op write request, assume that we'll need
* request ops. If it's a multi-op read then assume we'll need
* reply ops. Anything else and call it -EINVAL.
*/
r = __ceph_osdc_alloc_messages(req, GFP_NOFS, num_ops, 0);
else
if (flags & CEPH_OSD_FLAG_WRITE) {
num_req_ops = num_ops;
num_rep_ops = 0;
} else if (flags & CEPH_OSD_FLAG_READ) {
num_req_ops = 0;
num_rep_ops = num_ops;
} else {
r = -EINVAL;
goto fail;
}
r = __ceph_osdc_alloc_messages(req, GFP_NOFS, num_req_ops,
num_rep_ops);
} else {
r = ceph_osdc_alloc_messages(req, GFP_NOFS);
}
if (r)
goto fail;