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;