From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>,
"Fabio M. De Francesco" <fmdefrancesco@gmail.com>,
Ira Weiny <ira.weiny@intel.com>,
linux-mm@kvack.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH] mm: Add memcpy_from_file_folio()
Date: Thu, 26 Jan 2023 20:15:52 +0000 [thread overview]
Message-ID: <20230126201552.1681588-1-willy@infradead.org> (raw)
This is the equivalent of memcpy_from_page(). It differs in that it
takes the position in a file instead of offset in a folio, it accepts
the total number of bytes to be copied (instead of the number of bytes
to be copied from this folio) and it returns how many bytes were copied
from the folio, rather than making the caller calculate that and then
checking if the caller got it right.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
include/linux/highmem.h | 29 +++++++++++++++++++++++++++++
include/linux/page-flags.h | 1 +
2 files changed, 30 insertions(+)
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index e22509420ac6..b517707b028d 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -413,6 +413,35 @@ static inline void memzero_page(struct page *page, size_t offset, size_t len)
kunmap_local(addr);
}
+/**
+ * memcpy_from_file_folio - Copy some bytes from a file folio.
+ * @to: The destination buffer.
+ * @folio: The folio to copy from.
+ * @pos: The position in the file.
+ * @len: The maximum number of bytes to copy.
+ *
+ * Copy up to @len bytes from this folio. This may be limited by PAGE_SIZE
+ * if the folio comes from HIGHMEM, and by the size of the folio.
+ *
+ * Return: The number of bytes copied from the folio.
+ */
+static inline size_t memcpy_from_file_folio(char *to, struct folio *folio,
+ loff_t pos, size_t len)
+{
+ size_t offset = offset_in_folio(folio, pos);
+ char *from = kmap_local_folio(folio, offset);
+
+ if (folio_test_highmem(folio))
+ len = min(len, PAGE_SIZE - offset);
+ else
+ len = min(len, folio_size(folio) - offset);
+
+ memcpy(to, from, len);
+ kunmap_local(from);
+
+ return len;
+}
+
/**
* folio_zero_segments() - Zero two byte ranges in a folio.
* @folio: The folio to write to.
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 09804ad91927..0425f22a9c82 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -531,6 +531,7 @@ PAGEFLAG(Readahead, readahead, PF_NO_COMPOUND)
* available at this point.
*/
#define PageHighMem(__p) is_highmem_idx(page_zonenum(__p))
+#define folio_test_highmem(__f) is_highmem_idx(folio_zonenum(__f))
#else
PAGEFLAG_FALSE(HighMem, highmem)
#endif
--
2.35.1
next reply other threads:[~2023-01-26 20:16 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-26 20:15 Matthew Wilcox (Oracle) [this message]
2023-01-26 23:41 ` Andrew Morton
2023-01-27 2:04 ` Matthew Wilcox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230126201552.1681588-1-willy@infradead.org \
--to=willy@infradead.org \
--cc=akpm@linux-foundation.org \
--cc=fmdefrancesco@gmail.com \
--cc=ira.weiny@intel.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-mm@kvack.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox