scatterlist: add sg_zero_buffer() helper
authorJohannes Thumshirn <jthumshirn@suse.de>
Wed, 7 Jun 2017 09:45:28 +0000 (11:45 +0200)
committerChristoph Hellwig <hch@lst.de>
Thu, 15 Jun 2017 12:30:14 +0000 (14:30 +0200)
The sg_zero_buffer() helper is used to zero fill an area in a SG
list.

Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
[hch: renamed to sg_zero_buffer]
Signed-off-by: Christoph Hellwig <hch@lst.de>
include/linux/scatterlist.h
lib/scatterlist.c

index cb3c8fe6acd776f55f78ca9cebe05028b8c7cf70..4b3286ac60c86e3185ced18b1c14452eb80f5679 100644 (file)
@@ -278,6 +278,8 @@ size_t sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents,
                            const void *buf, size_t buflen, off_t skip);
 size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents,
                          void *buf, size_t buflen, off_t skip);
+size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents,
+                      size_t buflen, off_t skip);
 
 /*
  * Maximum number of entries that will be allocated in one piece, if
index c6cf82242d655d929a63e2a5d517510af6a657ad..be7b4dd6b68d789d1301e061f124786a55952908 100644 (file)
@@ -751,3 +751,38 @@ size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents,
        return sg_copy_buffer(sgl, nents, buf, buflen, skip, true);
 }
 EXPORT_SYMBOL(sg_pcopy_to_buffer);
+
+/**
+ * sg_zero_buffer - Zero-out a part of a SG list
+ * @sgl:                The SG list
+ * @nents:              Number of SG entries
+ * @buflen:             The number of bytes to zero out
+ * @skip:               Number of bytes to skip before zeroing
+ *
+ * Returns the number of bytes zeroed.
+ **/
+size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents,
+                      size_t buflen, off_t skip)
+{
+       unsigned int offset = 0;
+       struct sg_mapping_iter miter;
+       unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
+
+       sg_miter_start(&miter, sgl, nents, sg_flags);
+
+       if (!sg_miter_skip(&miter, skip))
+               return false;
+
+       while (offset < buflen && sg_miter_next(&miter)) {
+               unsigned int len;
+
+               len = min(miter.length, buflen - offset);
+               memset(miter.addr, 0, len);
+
+               offset += len;
+       }
+
+       sg_miter_stop(&miter);
+       return offset;
+}
+EXPORT_SYMBOL(sg_zero_buffer);