The existing sg_zero_buffer() function is a bit restrictive.
For example protection information (PI) blocks are usually
initialized to 0xff bytes. As its name suggests sgl_memset()
is modelled on memset(). One difference is the type of the
val argument which is u8 rather than int. Plus it returns
the number of bytes (over)written.
Signed-off-by: Douglas Gilbert <dgilbert@xxxxxxxxxxxx>
---
+
+/**
+ * sgl_memset - set byte 'val' up to n_bytes times on SG list
+ * @sgl: The SG list
+ * @nents: Number of SG entries in sgl
+ * @skip: Number of bytes to skip before starting
+ * @val: byte value to write to sgl
+ * @n_bytes: The (maximum) number of bytes to modify
+ *
+ * Returns:
+ * The number of bytes written.
+ *
+ * Notes:
+ * Stops writing if either sgl or n_bytes is exhausted. If n_bytes is
+ * set SIZE_MAX then val will be written to each byte until the end
+ * of sgl.
+ *
+ * The notes in sgl_copy_sgl() about large sgl_s _applies here as well.
+ *
+ **/
+size_t sgl_memset(struct scatterlist *sgl, unsigned int nents, off_t skip,
+ u8 val, size_t n_bytes)
+{
+ size_t offset = 0;
+ size_t len;
+ struct sg_mapping_iter miter;
+
+ if (n_bytes == 0)
+ return 0;
+ sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC | SG_MITER_TO_SG);
+ if (!sg_miter_skip(&miter, skip))
+ goto fini;
+
+ while ((offset < n_bytes) && sg_miter_next(&miter)) {
+ len = min(miter.length, n_bytes - offset);
+ memset(miter.addr, val, len);
+ offset += len;
+ miter.consumed = len;
+ sg_miter_stop(&miter);
+ }
+fini:
+ sg_miter_stop(&miter);
+ return offset;
+}
+EXPORT_SYMBOL(sgl_memset);
+