git: 3e0856b63fe0 - main - linuxkpi: Fix `sg_alloc_table_from_pages()` to have the same API as Linux

From: Jean-Sébastien Pédron <dumbbell_at_FreeBSD.org>
Date: Fri, 27 Jan 2023 21:27:48 UTC
The branch main has been updated by dumbbell (ports committer):

URL: https://cgit.FreeBSD.org/src/commit/?id=3e0856b63fe0e375a0951e05c2ef98bb2ebd9421

commit 3e0856b63fe0e375a0951e05c2ef98bb2ebd9421
Author:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2023-01-10 10:10:30 +0000
Commit:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
CommitDate: 2023-01-27 20:53:59 +0000

    linuxkpi: Fix `sg_alloc_table_from_pages()` to have the same API as Linux
    
    It now returns a `struct scatterlist *` pointer instead of an error
    code only.
    
    The implementation is incomplete because it doesn't use the `prv`
    argument.
    
    Reviewed by:    manu
    Approved by:    manu
    Differential Revision:  https://reviews.freebsd.org/D38077
---
 .../linuxkpi/common/include/linux/scatterlist.h    | 44 +++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/scatterlist.h b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
index 86aeefafb501..d1a71258c27d 100644
--- a/sys/compat/linuxkpi/common/include/linux/scatterlist.h
+++ b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
@@ -327,18 +327,40 @@ sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
 	return (ret);
 }
 
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+static inline struct scatterlist *
+__sg_alloc_table_from_pages(struct sg_table *sgt,
+    struct page **pages, unsigned int count,
+    unsigned long off, unsigned long size,
+    unsigned int max_segment,
+    struct scatterlist *prv, unsigned int left_pages,
+    gfp_t gfp_mask)
+#else
 static inline int
 __sg_alloc_table_from_pages(struct sg_table *sgt,
     struct page **pages, unsigned int count,
     unsigned long off, unsigned long size,
     unsigned int max_segment, gfp_t gfp_mask)
+#endif
 {
 	unsigned int i, segs, cur, len;
 	int rc;
 	struct scatterlist *s;
 
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+	if (prv != NULL) {
+		panic(
+		    "Support for prv != NULL not implemented in "
+		    "__sg_alloc_table_from_pages()");
+	}
+#endif
+
 	if (__predict_false(!max_segment || offset_in_page(max_segment)))
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+		return (ERR_PTR(-EINVAL));
+#else
 		return (-EINVAL);
+#endif
 
 	len = 0;
 	for (segs = i = 1; i < count; ++i) {
@@ -350,13 +372,19 @@ __sg_alloc_table_from_pages(struct sg_table *sgt,
 		}
 	}
 	if (__predict_false((rc = sg_alloc_table(sgt, segs, gfp_mask))))
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+		return (ERR_PTR(rc));
+#else
 		return (rc);
+#endif
 
 	cur = 0;
-	for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+	for (i = 0, s = sgt->sgl; i < sgt->orig_nents; i++) {
 		unsigned long seg_size;
 		unsigned int j;
 
+		s = sg_next(s);
+
 		len = 0;
 		for (j = cur + 1; j < count; ++j) {
 			len += PAGE_SIZE;
@@ -371,7 +399,16 @@ __sg_alloc_table_from_pages(struct sg_table *sgt,
 		off = 0;
 		cur = j;
 	}
+	KASSERT(s != NULL, ("s is NULL after loop in __sg_alloc_table_from_pages()"));
+
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+	if (left_pages == 0)
+		sg_mark_end(s);
+
+	return (s);
+#else
 	return (0);
+#endif
 }
 
 static inline int
@@ -381,8 +418,13 @@ sg_alloc_table_from_pages(struct sg_table *sgt,
     gfp_t gfp_mask)
 {
 
+#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 51300
+	return (PTR_ERR_OR_ZERO(__sg_alloc_table_from_pages(sgt, pages, count, off, size,
+	    SCATTERLIST_MAX_SEGMENT, NULL, 0, gfp_mask)));
+#else
 	return (__sg_alloc_table_from_pages(sgt, pages, count, off, size,
 	    SCATTERLIST_MAX_SEGMENT, gfp_mask));
+#endif
 }
 
 static inline int