libceph: allow ceph_osdc_new_request to accept a multi-op read
authorJeff Layton <jlayton@kernel.org>
Thu, 25 Aug 2022 13:31:16 +0000 (09:31 -0400)
committerIlya Dryomov <idryomov@gmail.com>
Thu, 24 Aug 2023 09:24:35 +0000 (11:24 +0200)
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>
net/ceph/osd_client.c

index 7f159e4..d3a759e 100644 (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;