Skip to content

Commit 00cdf76

Browse files
Matthew Wilcox (Oracle)akpm00
authored andcommitted
mm: add memcpy_from_file_folio()
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. [[email protected]: fix typo in comment] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> Cc: "Fabio M. De Francesco" <[email protected]> Cc: Ira Weiny <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 3222d8c commit 00cdf76

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

include/linux/highmem.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,35 @@ static inline void memzero_page(struct page *page, size_t offset, size_t len)
413413
kunmap_local(addr);
414414
}
415415

416+
/**
417+
* memcpy_from_file_folio - Copy some bytes from a file folio.
418+
* @to: The destination buffer.
419+
* @folio: The folio to copy from.
420+
* @pos: The position in the file.
421+
* @len: The maximum number of bytes to copy.
422+
*
423+
* Copy up to @len bytes from this folio. This may be limited by PAGE_SIZE
424+
* if the folio comes from HIGHMEM, and by the size of the folio.
425+
*
426+
* Return: The number of bytes copied from the folio.
427+
*/
428+
static inline size_t memcpy_from_file_folio(char *to, struct folio *folio,
429+
loff_t pos, size_t len)
430+
{
431+
size_t offset = offset_in_folio(folio, pos);
432+
char *from = kmap_local_folio(folio, offset);
433+
434+
if (folio_test_highmem(folio))
435+
len = min_t(size_t, len, PAGE_SIZE - offset);
436+
else
437+
len = min(len, folio_size(folio) - offset);
438+
439+
memcpy(to, from, len);
440+
kunmap_local(from);
441+
442+
return len;
443+
}
444+
416445
/**
417446
* folio_zero_segments() - Zero two byte ranges in a folio.
418447
* @folio: The folio to write to.

include/linux/page-flags.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ PAGEFLAG(Readahead, readahead, PF_NO_COMPOUND)
531531
* available at this point.
532532
*/
533533
#define PageHighMem(__p) is_highmem_idx(page_zonenum(__p))
534+
#define folio_test_highmem(__f) is_highmem_idx(folio_zonenum(__f))
534535
#else
535536
PAGEFLAG_FALSE(HighMem, highmem)
536537
#endif

0 commit comments

Comments
 (0)