Merge tag 'nfs-for-6.6-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[platform/kernel/linux-rpi.git] / net / sunrpc / xdr.c
index f501134..62e07c3 100644 (file)
@@ -165,6 +165,56 @@ xdr_free_bvec(struct xdr_buf *buf)
 }
 
 /**
+ * xdr_buf_to_bvec - Copy components of an xdr_buf into a bio_vec array
+ * @bvec: bio_vec array to populate
+ * @bvec_size: element count of @bio_vec
+ * @xdr: xdr_buf to be copied
+ *
+ * Returns the number of entries consumed in @bvec.
+ */
+unsigned int xdr_buf_to_bvec(struct bio_vec *bvec, unsigned int bvec_size,
+                            const struct xdr_buf *xdr)
+{
+       const struct kvec *head = xdr->head;
+       const struct kvec *tail = xdr->tail;
+       unsigned int count = 0;
+
+       if (head->iov_len) {
+               bvec_set_virt(bvec++, head->iov_base, head->iov_len);
+               ++count;
+       }
+
+       if (xdr->page_len) {
+               unsigned int offset, len, remaining;
+               struct page **pages = xdr->pages;
+
+               offset = offset_in_page(xdr->page_base);
+               remaining = xdr->page_len;
+               while (remaining > 0) {
+                       len = min_t(unsigned int, remaining,
+                                   PAGE_SIZE - offset);
+                       bvec_set_page(bvec++, *pages++, len, offset);
+                       remaining -= len;
+                       offset = 0;
+                       if (unlikely(++count > bvec_size))
+                               goto bvec_overflow;
+               }
+       }
+
+       if (tail->iov_len) {
+               bvec_set_virt(bvec, tail->iov_base, tail->iov_len);
+               if (unlikely(++count > bvec_size))
+                       goto bvec_overflow;
+       }
+
+       return count;
+
+bvec_overflow:
+       pr_warn_once("%s: bio_vec array overflow\n", __func__);
+       return count - 1;
+}
+
+/**
  * xdr_inline_pages - Prepare receive buffer for a large reply
  * @xdr: xdr_buf into which reply will be placed
  * @offset: expected offset where data payload will start, in bytes