From: Andrew Morton <akpm@linux-foundation.org>
To: akpm@linux-foundation.org, dchinner@redhat.com,
hannes@cmpxchg.org, hch@lst.de, hughd@google.com, jack@suse.cz,
kirill.shutemov@linux.intel.com, linux-mm@kvack.org,
mm-commits@vger.kernel.org, torvalds@linux-foundation.org,
william.kucharski@oracle.com, willy@infradead.org,
yang.shi@linux.alibaba.com
Subject: [patch 008/118] iomap: use mapping_seek_hole_data
Date: Thu, 25 Feb 2021 17:15:52 -0800 [thread overview]
Message-ID: <20210226011552.Z2dkn0jeY%akpm@linux-foundation.org> (raw)
In-Reply-To: <20210225171452.713967e96554bb6a53e44a19@linux-foundation.org>
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Subject: iomap: use mapping_seek_hole_data
Enhance mapping_seek_hole_data() to handle partially uptodate pages and
convert the iomap seek code to call it.
Link: https://lkml.kernel.org/r/20201112212641.27837-9-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Dave Chinner <dchinner@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: William Kucharski <william.kucharski@oracle.com>
Cc: Yang Shi <yang.shi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/iomap/seek.c | 125 ++++------------------------------------------
mm/filemap.c | 37 +++++++++++--
2 files changed, 43 insertions(+), 119 deletions(-)
--- a/fs/iomap/seek.c~iomap-use-mapping_seek_hole_data
+++ a/fs/iomap/seek.c
@@ -10,122 +10,17 @@
#include <linux/pagemap.h>
#include <linux/pagevec.h>
-/*
- * Seek for SEEK_DATA / SEEK_HOLE within @page, starting at @lastoff.
- * Returns true if found and updates @lastoff to the offset in file.
- */
-static bool
-page_seek_hole_data(struct inode *inode, struct page *page, loff_t *lastoff,
- int whence)
-{
- const struct address_space_operations *ops = inode->i_mapping->a_ops;
- unsigned int bsize = i_blocksize(inode), off;
- bool seek_data = whence == SEEK_DATA;
- loff_t poff = page_offset(page);
-
- if (WARN_ON_ONCE(*lastoff >= poff + PAGE_SIZE))
- return false;
-
- if (*lastoff < poff) {
- /*
- * Last offset smaller than the start of the page means we found
- * a hole:
- */
- if (whence == SEEK_HOLE)
- return true;
- *lastoff = poff;
- }
-
- /*
- * Just check the page unless we can and should check block ranges:
- */
- if (bsize == PAGE_SIZE || !ops->is_partially_uptodate)
- return PageUptodate(page) == seek_data;
-
- lock_page(page);
- if (unlikely(page->mapping != inode->i_mapping))
- goto out_unlock_not_found;
-
- for (off = 0; off < PAGE_SIZE; off += bsize) {
- if (offset_in_page(*lastoff) >= off + bsize)
- continue;
- if (ops->is_partially_uptodate(page, off, bsize) == seek_data) {
- unlock_page(page);
- return true;
- }
- *lastoff = poff + off + bsize;
- }
-
-out_unlock_not_found:
- unlock_page(page);
- return false;
-}
-
-/*
- * Seek for SEEK_DATA / SEEK_HOLE in the page cache.
- *
- * Within unwritten extents, the page cache determines which parts are holes
- * and which are data: uptodate buffer heads count as data; everything else
- * counts as a hole.
- *
- * Returns the resulting offset on successs, and -ENOENT otherwise.
- */
-static loff_t
-page_cache_seek_hole_data(struct inode *inode, loff_t offset, loff_t length,
- int whence)
-{
- pgoff_t index = offset >> PAGE_SHIFT;
- pgoff_t end = DIV_ROUND_UP(offset + length, PAGE_SIZE);
- loff_t lastoff = offset;
- struct pagevec pvec;
-
- if (length <= 0)
- return -ENOENT;
-
- pagevec_init(&pvec);
-
- do {
- unsigned nr_pages, i;
-
- nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping, &index,
- end - 1);
- if (nr_pages == 0)
- break;
-
- for (i = 0; i < nr_pages; i++) {
- struct page *page = pvec.pages[i];
-
- if (page_seek_hole_data(inode, page, &lastoff, whence))
- goto check_range;
- lastoff = page_offset(page) + PAGE_SIZE;
- }
- pagevec_release(&pvec);
- } while (index < end);
-
- /* When no page at lastoff and we are not done, we found a hole. */
- if (whence != SEEK_HOLE)
- goto not_found;
-
-check_range:
- if (lastoff < offset + length)
- goto out;
-not_found:
- lastoff = -ENOENT;
-out:
- pagevec_release(&pvec);
- return lastoff;
-}
-
-
static loff_t
-iomap_seek_hole_actor(struct inode *inode, loff_t offset, loff_t length,
+iomap_seek_hole_actor(struct inode *inode, loff_t start, loff_t length,
void *data, struct iomap *iomap, struct iomap *srcmap)
{
+ loff_t offset = start;
+
switch (iomap->type) {
case IOMAP_UNWRITTEN:
- offset = page_cache_seek_hole_data(inode, offset, length,
- SEEK_HOLE);
- if (offset < 0)
+ offset = mapping_seek_hole_data(inode->i_mapping, start,
+ start + length, SEEK_HOLE);
+ if (offset == start + length)
return length;
fallthrough;
case IOMAP_HOLE:
@@ -164,15 +59,17 @@ iomap_seek_hole(struct inode *inode, lof
EXPORT_SYMBOL_GPL(iomap_seek_hole);
static loff_t
-iomap_seek_data_actor(struct inode *inode, loff_t offset, loff_t length,
+iomap_seek_data_actor(struct inode *inode, loff_t start, loff_t length,
void *data, struct iomap *iomap, struct iomap *srcmap)
{
+ loff_t offset = start;
+
switch (iomap->type) {
case IOMAP_HOLE:
return length;
case IOMAP_UNWRITTEN:
- offset = page_cache_seek_hole_data(inode, offset, length,
- SEEK_DATA);
+ offset = mapping_seek_hole_data(inode->i_mapping, start,
+ start + length, SEEK_DATA);
if (offset < 0)
return length;
fallthrough;
--- a/mm/filemap.c~iomap-use-mapping_seek_hole_data
+++ a/mm/filemap.c
@@ -2553,11 +2553,36 @@ generic_file_read_iter(struct kiocb *ioc
}
EXPORT_SYMBOL(generic_file_read_iter);
-static inline bool page_seek_match(struct page *page, bool seek_data)
+static inline loff_t page_seek_hole_data(struct xa_state *xas,
+ struct address_space *mapping, struct page *page,
+ loff_t start, loff_t end, bool seek_data)
{
+ const struct address_space_operations *ops = mapping->a_ops;
+ size_t offset, bsz = i_blocksize(mapping->host);
+
if (xa_is_value(page) || PageUptodate(page))
- return seek_data;
- return !seek_data;
+ return seek_data ? start : end;
+ if (!ops->is_partially_uptodate)
+ return seek_data ? end : start;
+
+ xas_pause(xas);
+ rcu_read_unlock();
+ lock_page(page);
+ if (unlikely(page->mapping != mapping))
+ goto unlock;
+
+ offset = offset_in_thp(page, start) & ~(bsz - 1);
+
+ do {
+ if (ops->is_partially_uptodate(page, offset, bsz) == seek_data)
+ break;
+ start = (start + bsz) & ~(bsz - 1);
+ offset += bsz;
+ } while (offset < thp_size(page));
+unlock:
+ unlock_page(page);
+ rcu_read_lock();
+ return start;
}
static inline
@@ -2607,9 +2632,11 @@ loff_t mapping_seek_hole_data(struct add
start = pos;
}
- if (page_seek_match(page, seek_data))
+ pos += seek_page_size(&xas, page);
+ start = page_seek_hole_data(&xas, mapping, page, start, pos,
+ seek_data);
+ if (start < pos)
goto unlock;
- start = pos + seek_page_size(&xas, page);
if (!xa_is_value(page))
put_page(page);
}
_
next prev parent reply other threads:[~2021-02-26 1:16 UTC|newest]
Thread overview: 123+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-26 1:14 incoming Andrew Morton
2021-02-26 1:15 ` [patch 001/118] mm: make pagecache tagged lookups return only head pages Andrew Morton
2021-02-26 1:15 ` [patch 002/118] mm/shmem: use pagevec_lookup in shmem_unlock_mapping Andrew Morton
2021-02-26 1:15 ` [patch 003/118] mm/swap: optimise get_shadow_from_swap_cache Andrew Morton
2021-02-26 1:15 ` [patch 004/118] mm: add FGP_ENTRY Andrew Morton
2021-02-26 1:15 ` [patch 005/118] mm/filemap: rename find_get_entry to mapping_get_entry Andrew Morton
2021-02-26 1:15 ` [patch 006/118] mm/filemap: add helper for finding pages Andrew Morton
2021-02-26 1:15 ` [patch 007/118] mm/filemap: add mapping_seek_hole_data Andrew Morton
2021-02-26 1:15 ` Andrew Morton [this message]
2021-02-26 1:15 ` [patch 009/118] mm: add and use find_lock_entries Andrew Morton
2021-02-26 1:16 ` [patch 010/118] mm: add an 'end' parameter to find_get_entries Andrew Morton
2021-02-26 1:16 ` [patch 011/118] mm: add an 'end' parameter to pagevec_lookup_entries Andrew Morton
2021-02-26 1:16 ` [patch 012/118] mm: remove nr_entries parameter from pagevec_lookup_entries Andrew Morton
2021-02-26 1:16 ` [patch 013/118] mm: pass pvec directly to find_get_entries Andrew Morton
2021-02-26 1:16 ` [patch 014/118] mm: remove pagevec_lookup_entries Andrew Morton
2021-02-26 1:16 ` [patch 015/118] mm,thp,shmem: limit shmem THP alloc gfp_mask Andrew Morton
2021-02-26 1:16 ` [patch 016/118] mm,thp,shm: limit gfp mask to no more than specified Andrew Morton
2021-02-26 1:16 ` [patch 017/118] mm,thp,shmem: make khugepaged obey tmpfs mount flags Andrew Morton
2021-02-26 1:16 ` [patch 018/118] mm,shmem,thp: limit shmem THP allocations to requested zones Andrew Morton
2021-02-26 1:16 ` [patch 019/118] mm: cma: allocate cma areas bottom-up Andrew Morton
2021-02-26 1:16 ` [patch 020/118] mm/cma: expose all pages to the buddy if activation of an area fails Andrew Morton
2021-02-26 1:16 ` [patch 021/118] mm/page_alloc: count CMA pages per zone and print them in /proc/zoneinfo Andrew Morton
2021-02-26 1:16 ` [patch 022/118] mm: cma: print region name on failure Andrew Morton
2021-02-26 1:16 ` [patch 023/118] mm: vmstat: fix NOHZ wakeups for node stat changes Andrew Morton
2021-02-26 1:16 ` [patch 024/118] mm: vmstat: add some comments on internal storage of byte items Andrew Morton
2021-02-26 1:16 ` [patch 025/118] mm/vmstat.c: erase latency in vmstat_shepherd Andrew Morton
2021-02-26 1:16 ` [patch 026/118] mm: move pfn_to_online_page() out of line Andrew Morton
2021-02-26 1:17 ` [patch 027/118] mm: teach pfn_to_online_page() to consider subsection validity Andrew Morton
2021-02-26 1:17 ` [patch 028/118] mm: teach pfn_to_online_page() about ZONE_DEVICE section collisions Andrew Morton
2021-02-26 1:17 ` [patch 029/118] mm: fix memory_failure() handling of dax-namespace metadata Andrew Morton
2021-02-26 1:17 ` [patch 030/118] mm/memory_hotplug: rename all existing 'memhp' into 'mhp' Andrew Morton
2021-02-26 1:17 ` [patch 031/118] mm/memory_hotplug: MEMHP_MERGE_RESOURCE -> MHP_MERGE_RESOURCE Andrew Morton
2021-02-26 1:17 ` [patch 032/118] mm/memory_hotplug: use helper function zone_end_pfn() to get end_pfn Andrew Morton
2021-02-26 1:17 ` [patch 033/118] drivers/base/memory: don't store phys_device in memory blocks Andrew Morton
2021-02-26 1:17 ` [patch 034/118] Documentation: sysfs/memory: clarify some memory block device properties Andrew Morton
2021-02-26 1:17 ` [patch 035/118] mm/memory_hotplug: prevalidate the address range being added with platform Andrew Morton
2021-02-26 1:17 ` [patch 036/118] arm64/mm: define arch_get_mappable_range() Andrew Morton
2021-02-26 1:17 ` [patch 037/118] s390/mm: " Andrew Morton
2021-02-26 1:17 ` [patch 038/118] virtio-mem: check against mhp_get_pluggable_range() which memory we can hotplug Andrew Morton
2021-02-26 1:17 ` [patch 039/118] mm/mlock: stop counting mlocked pages when none vma is found Andrew Morton
2021-02-26 1:17 ` [patch 040/118] mm/rmap: correct some obsolete comments of anon_vma Andrew Morton
2021-02-26 1:17 ` [patch 041/118] mm/rmap: remove unneeded semicolon in page_not_mapped() Andrew Morton
2021-02-26 1:17 ` [patch 042/118] mm/rmap: fix obsolete comment in __page_check_anon_rmap() Andrew Morton
2021-02-26 1:18 ` [patch 043/118] mm/rmap: use page_not_mapped in try_to_unmap() Andrew Morton
2021-02-26 1:18 ` [patch 044/118] mm/rmap: correct obsolete comment of page_get_anon_vma() Andrew Morton
2021-02-26 1:18 ` [patch 045/118] mm/rmap: fix potential pte_unmap on an not mapped pte Andrew Morton
2021-02-26 1:18 ` [patch 046/118] mm: zswap: clean up confusing comment Andrew Morton
2021-02-26 1:18 ` [patch 047/118] mm/zswap: add the flag can_sleep_mapped Andrew Morton
2021-02-26 1:18 ` [patch 048/118] mm: set the sleep_mapped to true for zbud and z3fold Andrew Morton
2021-02-26 1:18 ` [patch 049/118] mm/zsmalloc.c: convert to use kmem_cache_zalloc in cache_alloc_zspage() Andrew Morton
2021-02-26 1:18 ` [patch 050/118] zsmalloc: account the number of compacted pages correctly Andrew Morton
2021-02-26 1:18 ` [patch 051/118] mm/zsmalloc.c: use page_private() to access page->private Andrew Morton
2021-02-26 1:18 ` [patch 052/118] mm: page-flags.h: Typo fix (It -> If) Andrew Morton
2021-02-26 1:18 ` [patch 053/118] mm/dmapool: use might_alloc() Andrew Morton
2021-02-26 1:18 ` [patch 054/118] mm/backing-dev.c: " Andrew Morton
2021-02-26 1:18 ` [patch 055/118] mm/early_ioremap.c: use __func__ instead of function name Andrew Morton
2021-02-26 1:18 ` [patch 056/118] mm: add Kernel Electric-Fence infrastructure Andrew Morton
2021-02-26 1:18 ` [patch 057/118] x86, kfence: enable KFENCE for x86 Andrew Morton
2021-02-26 1:19 ` [patch 058/118] arm64, kfence: enable KFENCE for ARM64 Andrew Morton
2021-02-26 1:19 ` [patch 059/118] kfence: use pt_regs to generate stack trace on faults Andrew Morton
2021-02-26 1:19 ` [patch 060/118] mm, kfence: insert KFENCE hooks for SLAB Andrew Morton
2021-02-26 1:19 ` [patch 061/118] mm, kfence: insert KFENCE hooks for SLUB Andrew Morton
2021-02-26 1:19 ` [patch 062/118] kfence, kasan: make KFENCE compatible with KASAN Andrew Morton
2021-02-26 1:19 ` [patch 063/118] kfence, Documentation: add KFENCE documentation Andrew Morton
2021-02-26 1:19 ` [patch 064/118] kfence: add test suite Andrew Morton
2021-02-26 1:19 ` [patch 065/118] MAINTAINERS: add entry for KFENCE Andrew Morton
2021-02-26 1:19 ` [patch 066/118] kfence: report sensitive information based on no_hash_pointers Andrew Morton
2021-02-26 1:19 ` [patch 067/118] tracing: add error_report_end trace point Andrew Morton
2021-02-26 14:03 ` Steven Rostedt
2021-02-26 1:19 ` [patch 068/118] kfence: use error_report_end tracepoint Andrew Morton
2021-02-26 1:19 ` [patch 069/118] kasan: " Andrew Morton
2021-02-26 1:19 ` [patch 070/118] kasan, mm: don't save alloc stacks twice Andrew Morton
2021-02-26 1:19 ` [patch 071/118] kasan, mm: optimize kmalloc poisoning Andrew Morton
2021-02-26 1:20 ` [patch 072/118] kasan: optimize large " Andrew Morton
2021-02-26 1:20 ` [patch 073/118] kasan: clean up setting free info in kasan_slab_free Andrew Morton
2021-02-26 1:20 ` [patch 074/118] kasan: unify large kfree checks Andrew Morton
2021-02-26 1:20 ` [patch 075/118] kasan: rework krealloc tests Andrew Morton
2021-02-26 1:20 ` [patch 076/118] kasan, mm: fail krealloc on freed objects Andrew Morton
2021-02-26 1:20 ` [patch 077/118] kasan, mm: optimize krealloc poisoning Andrew Morton
2021-02-26 1:20 ` [patch 078/118] kasan: ensure poisoning size alignment Andrew Morton
2021-02-26 1:20 ` [patch 079/118] arm64: kasan: simplify and inline MTE functions Andrew Morton
2021-02-26 1:20 ` [patch 080/118] kasan: inline HW_TAGS helper functions Andrew Morton
2021-02-26 1:20 ` [patch 081/118] kasan: clarify that only first bug is reported in HW_TAGS Andrew Morton
2021-02-26 1:20 ` [patch 082/118] alpha: remove CONFIG_EXPERIMENTAL from defconfigs Andrew Morton
2021-02-26 1:20 ` [patch 083/118] proc/wchan: use printk format instead of lookup_symbol_name() Andrew Morton
2021-02-26 1:20 ` [patch 084/118] proc: use kvzalloc for our kernel buffer Andrew Morton
2021-02-26 1:20 ` [patch 085/118] sysctl.c: fix underflow value setting risk in vm_table Andrew Morton
2021-02-26 1:20 ` [patch 086/118] include/linux: remove repeated words Andrew Morton
2021-02-26 1:21 ` [patch 087/118] treewide: Miguel has moved Andrew Morton
2021-02-26 1:21 ` [patch 088/118] groups: use flexible-array member in struct group_info Andrew Morton
2021-02-26 1:21 ` [patch 089/118] groups: simplify struct group_info allocation Andrew Morton
2021-02-26 1:21 ` [patch 090/118] kernel: delete repeated words in comments Andrew Morton
2021-02-26 1:21 ` [patch 091/118] MAINTAINERS: add uapi directories to API/ABI section Andrew Morton
2021-02-27 19:18 ` Michael Kerrisk (man-pages)
2021-02-26 1:21 ` [patch 092/118] lib/genalloc.c: change return type to unsigned long for bitmap_set_ll Andrew Morton
2021-02-26 1:21 ` [patch 093/118] string.h: move fortified functions definitions in a dedicated header Andrew Morton
2021-02-26 1:21 ` [patch 094/118] lib: stackdepot: add support to configure STACK_HASH_SIZE Andrew Morton
2021-02-26 1:21 ` [patch 095/118] lib: stackdepot: add support to disable stack depot Andrew Morton
2021-02-26 1:21 ` [patch 096/118] lib: stackdepot: fix ignoring return value warning Andrew Morton
2021-02-26 1:21 ` [patch 097/118] lib/cmdline: remove an unneeded local variable in next_arg() Andrew Morton
2021-02-26 1:21 ` [patch 098/118] include/linux/bitops.h: spelling s/synomyn/synonym/ Andrew Morton
2021-02-26 1:21 ` [patch 099/118] checkpatch: improve blank line after declaration test Andrew Morton
2021-02-26 1:21 ` [patch 100/118] checkpatch: ignore warning designated initializers using NR_CPUS Andrew Morton
2021-02-26 1:21 ` [patch 101/118] checkpatch: trivial style fixes Andrew Morton
2021-02-26 1:21 ` [patch 102/118] checkpatch: prefer ftrace over function entry/exit printks Andrew Morton
2021-02-26 1:21 ` [patch 103/118] checkpatch: improve TYPECAST_INT_CONSTANT test message Andrew Morton
2021-02-26 1:21 ` [patch 104/118] checkpatch: add warning for avoiding .L prefix symbols in assembly files Andrew Morton
2021-02-26 1:22 ` [patch 105/118] checkpatch: add kmalloc_array_node to unnecessary OOM message check Andrew Morton
2021-02-26 1:22 ` [patch 106/118] checkpatch: don't warn about colon termination in linker scripts Andrew Morton
2021-02-26 1:22 ` [patch 107/118] checkpatch: do not apply "initialise globals to 0" check to BPF progs Andrew Morton
2021-02-26 1:22 ` [patch 108/118] init/version.c: remove Version_<LINUX_VERSION_CODE> symbol Andrew Morton
2021-02-26 1:22 ` [patch 109/118] init: clean up early_param_on_off() macro Andrew Morton
2021-02-26 1:22 ` [patch 110/118] init/Kconfig: fix a typo in CC_VERSION_TEXT help text Andrew Morton
2021-02-26 1:22 ` [patch 111/118] fs/coredump: use kmap_local_page() Andrew Morton
2021-02-26 1:22 ` [patch 112/118] seq_file: document how per-entry resources are managed Andrew Morton
2021-02-26 1:22 ` [patch 113/118] x86: fix seq_file iteration for pat/memtype.c Andrew Morton
2021-02-26 1:22 ` [patch 114/118] scripts/gdb: fix list_for_each Andrew Morton
2021-02-26 1:22 ` [patch 115/118] kgdb: fix to kill breakpoints on initmem after boot Andrew Morton
2021-02-26 1:22 ` [patch 116/118] ubsan: remove overflow checks Andrew Morton
2021-02-26 1:22 ` [patch 117/118] initramfs: panic with memory information Andrew Morton
2021-02-26 1:22 ` [patch 118/118] MIPS: make userspace mapping young by default Andrew Morton
2021-02-26 17:55 ` incoming Linus Torvalds
2021-02-26 19:16 ` incoming Andrew Morton
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=20210226011552.Z2dkn0jeY%akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=dchinner@redhat.com \
--cc=hannes@cmpxchg.org \
--cc=hch@lst.de \
--cc=hughd@google.com \
--cc=jack@suse.cz \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mm-commits@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=william.kucharski@oracle.com \
--cc=willy@infradead.org \
--cc=yang.shi@linux.alibaba.com \
/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;
as well as URLs for NNTP newsgroup(s).