Commit 4e8c4c23 authored by Jeff Layton's avatar Jeff Layton Committed by Ilya Dryomov
Browse files

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: default avatarJeff Layton <jlayton@kernel.org>
Reviewed-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-and-tested-by: default avatarLuís Henriques <lhenriques@suse.de>
Reviewed-by: default avatarMilind Changire <mchangir@redhat.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 69dd3b39
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -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;