libceph: remove MAX_EXTENTS check for sparse reads
authorXiubo Li <xiubli@redhat.com>
Tue, 7 Nov 2023 01:37:47 +0000 (09:37 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 15 Jan 2024 14:40:50 +0000 (15:40 +0100)
There is no any limit for the extent array size and it's possible
that when reading with a large size contents the total number of
extents will exceed 4096. Then the messager will fail by reseting
the connection and keeps resending the inflight IOs infinitely.

[ idryomov: adjust error message ]

Link: https://tracker.ceph.com/issues/62081
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
net/ceph/osd_client.c

index d3a759e052c81f066710a467cc9d9baf3dbf8e20..625622016f5761e36bccc3f7a239e265039ce95d 100644 (file)
@@ -5850,8 +5850,6 @@ static inline void convert_extent_map(struct ceph_sparse_read *sr)
 }
 #endif
 
-#define MAX_EXTENTS 4096
-
 static int osd_sparse_read(struct ceph_connection *con,
                           struct ceph_msg_data_cursor *cursor,
                           char **pbuf)
@@ -5882,23 +5880,16 @@ next_op:
 
                if (count > 0) {
                        if (!sr->sr_extent || count > sr->sr_ext_len) {
-                               /*
-                                * Apply a hard cap to the number of extents.
-                                * If we have more, assume something is wrong.
-                                */
-                               if (count > MAX_EXTENTS) {
-                                       dout("%s: OSD returned 0x%x extents in a single reply!\n",
-                                            __func__, count);
-                                       return -EREMOTEIO;
-                               }
-
                                /* no extent array provided, or too short */
                                kfree(sr->sr_extent);
                                sr->sr_extent = kmalloc_array(count,
                                                              sizeof(*sr->sr_extent),
                                                              GFP_NOIO);
-                               if (!sr->sr_extent)
+                               if (!sr->sr_extent) {
+                                       pr_err("%s: failed to allocate %u extents\n",
+                                              __func__, count);
                                        return -ENOMEM;
+                               }
                                sr->sr_ext_len = count;
                        }
                        ret = count * sizeof(*sr->sr_extent);