[PATCH] libceph: rework sparse_read API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We can just return the length to be read instead of using a separate
length pointer. We'll never need more than INT_MAX anyway.

Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
 include/linux/ceph/messenger.h |  7 +++----
 net/ceph/messenger_v1.c        |  6 +++---
 net/ceph/messenger_v2.c        | 26 ++++++++++++--------------
 net/ceph/osd_client.c          | 24 ++++++++++++++++--------
 4 files changed, 34 insertions(+), 29 deletions(-)

This is an update to the sparse read series that simplifies the new
operation. I'll probably just fold this into the patch that's sitting
in testing now since it's not merged yet.

diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h
index 3697049e1465..f4adbfee56d5 100644
--- a/include/linux/ceph/messenger.h
+++ b/include/linux/ceph/messenger.h
@@ -76,17 +76,16 @@ struct ceph_connection_operations {
 	 * sparse_read: read sparse data
 	 * @con: connection we're reading from
 	 * @cursor: data cursor for reading extents
-	 * @len: len of the data that msgr should read
 	 * @buf: optional buffer to read into
 	 *
 	 * This should be called more than once, each time setting up to
 	 * receive an extent into the current cursor position, and zeroing
 	 * the holes between them.
 	 *
-	 * Returns 1 if there is more data to be read, 0 if reading is
+	 * Returns amount of data to be read (in bytes), 0 if reading is
 	 * complete, or -errno if there was an error.
 	 *
-	 * If @buf is set on a 1 return, then the data should be read into
+	 * If @buf is set on a >0 return, then the data should be read into
 	 * the provided buffer. Otherwise, it should be read into the cursor.
 	 *
 	 * The sparse read operation is expected to initialize the cursor
@@ -94,7 +93,7 @@ struct ceph_connection_operations {
 	 */
 	int (*sparse_read)(struct ceph_connection *con,
 			   struct ceph_msg_data_cursor *cursor,
-			   u64 *len, char **buf);
+			   char **buf);
 
 };
 
diff --git a/net/ceph/messenger_v1.c b/net/ceph/messenger_v1.c
index 957ba4d4cae5..bf385e458a01 100644
--- a/net/ceph/messenger_v1.c
+++ b/net/ceph/messenger_v1.c
@@ -1059,9 +1059,9 @@ static int read_sparse_msg_data(struct ceph_connection *con)
 		}
 
 		memset(&con->v1.in_sr_kvec, 0, sizeof(con->v1.in_sr_kvec));
-		con->v1.in_sr_len = 0;
-		ret = con->ops->sparse_read(con, cursor, &con->v1.in_sr_len,
-					(char **)&con->v1.in_sr_kvec.iov_base);
+		ret = con->ops->sparse_read(con, cursor,
+				(char **)&con->v1.in_sr_kvec.iov_base);
+		con->v1.in_sr_len = ret;
 	} while (ret > 0);
 
 	if (do_datacrc)
diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c
index c9f6b67fcdda..3dcaee6f8903 100644
--- a/net/ceph/messenger_v2.c
+++ b/net/ceph/messenger_v2.c
@@ -1088,20 +1088,19 @@ static int process_v2_sparse_read(struct ceph_connection *con, struct page **pag
 	int ret;
 
 	for (;;) {
-		u64 elen;
 		char *buf = NULL;
 
-		ret = con->ops->sparse_read(con, cursor, &elen, &buf);
+		ret = con->ops->sparse_read(con, cursor, &buf);
 		if (ret <= 0)
 			return ret;
 
-		dout("%s: sparse_read return elen %llx buf %p\n", __func__, elen, buf);
+		dout("%s: sparse_read return %x buf %p\n", __func__, ret, buf);
 
 		do {
 			int idx = spos >> PAGE_SHIFT;
 			int soff = offset_in_page(spos);
 			struct page *spage = con->v2.in_enc_pages[idx];
-			int len = min_t(int, elen, PAGE_SIZE - soff);
+			int len = min_t(int, ret, PAGE_SIZE - soff);
 
 			if (buf) {
 				memcpy_from_page(buf, spage, soff, len);
@@ -1116,8 +1115,8 @@ static int process_v2_sparse_read(struct ceph_connection *con, struct page **pag
 				ceph_msg_data_advance(cursor, len);
 			}
 			spos += len;
-			elen -= len;
-		} while (elen);
+			ret -= len;
+		} while (ret);
 	}
 }
 
@@ -1927,7 +1926,6 @@ static int prepare_sparse_read_cont(struct ceph_connection *con)
 	struct bio_vec bv;
 	char *buf = NULL;
 	struct ceph_msg_data_cursor *cursor = &con->v2.in_cursor;
-	u64 len = 0;
 
 	WARN_ON(con->v2.in_state != IN_S_PREPARE_SPARSE_DATA_CONT);
 
@@ -1977,7 +1975,7 @@ static int prepare_sparse_read_cont(struct ceph_connection *con)
 	}
 
 	/* get next extent */
-	ret = con->ops->sparse_read(con, cursor, &len, &buf);
+	ret = con->ops->sparse_read(con, cursor, &buf);
 	if (ret <= 0) {
 		if (ret < 0)
 			return ret;
@@ -1991,14 +1989,14 @@ static int prepare_sparse_read_cont(struct ceph_connection *con)
 	if (buf) {
 		/* receive into buffer */
 		reset_in_kvecs(con);
-		add_in_kvec(con, buf, len);
-		con->v2.data_len_remain -= len;
+		add_in_kvec(con, buf, ret);
+		con->v2.data_len_remain -= ret;
 		return 0;
 	}
 
-	if (len > cursor->total_resid) {
-		pr_warn("%s: len 0x%llx total_resid 0x%zx resid 0x%zx last %d\n",
-			__func__, len, cursor->total_resid, cursor->resid,
+	if (ret > cursor->total_resid) {
+		pr_warn("%s: ret 0x%x total_resid 0x%zx resid 0x%zx last %d\n",
+			__func__, ret, cursor->total_resid, cursor->resid,
 			cursor->last_piece);
 		return -EIO;
 	}
@@ -2018,7 +2016,7 @@ static int prepare_sparse_read_cont(struct ceph_connection *con)
 		bv.bv_offset = 0;
 	}
 	set_in_bvec(con, &bv);
-	con->v2.data_len_remain -= len;
+	con->v2.data_len_remain -= ret;
 	return ret;
 }
 
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index cb199a3f3caf..5cb7635bb457 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -5881,7 +5881,7 @@ static inline void convert_extent_map(struct ceph_sparse_read *sr)
 
 static int osd_sparse_read(struct ceph_connection *con,
 			   struct ceph_msg_data_cursor *cursor,
-			   u64 *plen, char **pbuf)
+			   char **pbuf)
 {
 	struct ceph_osd *o = con->private;
 	struct ceph_sparse_read *sr = &o->o_sparse_read;
@@ -5897,7 +5897,7 @@ static int osd_sparse_read(struct ceph_connection *con,
 			return ret;
 
 		/* number of extents */
-		*plen = sizeof(sr->sr_count);
+		ret = sizeof(sr->sr_count);
 		*pbuf = (char *)&sr->sr_count;
 		sr->sr_state = CEPH_SPARSE_READ_EXTENTS;
 		break;
@@ -5913,8 +5913,11 @@ static int osd_sparse_read(struct ceph_connection *con,
 				 * Apply a hard cap to the number of extents.
 				 * If we have more, assume something is wrong.
 				 */
-				if (count > MAX_EXTENTS)
-					return -EIO;
+				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);
@@ -5925,7 +5928,7 @@ static int osd_sparse_read(struct ceph_connection *con,
 					return -ENOMEM;
 				sr->sr_ext_len = count;
 			}
-			*plen = count * sizeof(*sr->sr_extent);
+			ret = count * sizeof(*sr->sr_extent);
 			*pbuf = (char *)sr->sr_extent;
 			sr->sr_state = CEPH_SPARSE_READ_DATA_LEN;
 			break;
@@ -5934,7 +5937,7 @@ static int osd_sparse_read(struct ceph_connection *con,
 		fallthrough;
 	case CEPH_SPARSE_READ_DATA_LEN:
 		convert_extent_map(sr);
-		*plen = sizeof(sr->sr_datalen);
+		ret = sizeof(sr->sr_datalen);
 		*pbuf = (char *)&sr->sr_datalen;
 		sr->sr_state = CEPH_SPARSE_READ_DATA;
 		break;
@@ -5950,6 +5953,11 @@ static int osd_sparse_read(struct ceph_connection *con,
 		dout("[%d] ext %d off 0x%llx len 0x%llx\n",
 		     o->o_osd, sr->sr_index, eoff, elen);
 
+		if (elen > INT_MAX) {
+			dout("Sparse read extent length too long (0x%llx)\n", elen);
+			return -EREMOTEIO;
+		}
+
 		/* zero out anything from sr_pos to start of extent */
 		if (sr->sr_pos < eoff)
 			advance_cursor(cursor, eoff - sr->sr_pos, true);
@@ -5959,14 +5967,14 @@ static int osd_sparse_read(struct ceph_connection *con,
 
 		/* send back the new length and nullify the ptr */
 		cursor->sr_resid = elen;
-		*plen = elen;
+		ret = elen;
 		*pbuf = NULL;
 
 		/* Bump the array index */
 		++sr->sr_index;
 		break;
 	}
-	return 1;
+	return ret;
 }
 
 static const struct ceph_connection_operations osd_con_ops = {
-- 
2.35.1




[Index of Archives]     [CEPH Users]     [Ceph Large]     [Ceph Dev]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux