* [PATCH 0/1] Is pagecache_isize_extended() compatible with large folios?
@ 2024-02-28 18:22 Matthew Wilcox (Oracle)
2024-02-28 18:22 ` [PATCH 1/1] mm: Convert pagecache_isize_extended to use a folio Matthew Wilcox (Oracle)
0 siblings, 1 reply; 3+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-02-28 18:22 UTC (permalink / raw)
To: linux-fsdevel, linux-mm; +Cc: Matthew Wilcox (Oracle)
I'd appreciate some filesystem people checking my work here (in that
pagecache_isize_extended() may already be broken and we didn't notice).
As far as I can tell (and it'd be nice to explain this in the kernel-doc
a little more thoroughly), the reason pagecache_isize_extended() exists
is that some filesystems rely on getting page_mkwrite() calls in order to
instantiate blocks. So if you have a filesystem using 512 byte blocks and
a 256 byte file mmaped, a store anywhere in the page will only result in
block 0 of the file being instantiated and the folio will now be marked
as dirty.
If we ftruncate the file to 2500 bytes before the folio gets written back,
then store to offset 2000, the filesystem will not be notified, so it
will not instantiate a block to store that information in. Therefore if
we truncate a file up, we need to mark the PTE that straddles the EOF
as read-only so that page_mkwrite() is called.
Now, I think this patch is safe because it's PAGE_SIZE that's important,
not the size of the folio. We mmap files on PAGE_SIZE boundaries and
we're only asking if there could be a new store which causes a block
to be instantiated. If the block size is >= PAGE_SIZE, there can't be.
If the folio size happens to be larger than PAGE_SIZE, it doesn't matter.
All that matters is that we protect the folio which crosses i_size if
block size < PAGE_SIZE.
Matthew Wilcox (Oracle) (1):
mm: Convert pagecache_isize_extended to use a folio
mm/truncate.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/1] mm: Convert pagecache_isize_extended to use a folio
2024-02-28 18:22 [PATCH 0/1] Is pagecache_isize_extended() compatible with large folios? Matthew Wilcox (Oracle)
@ 2024-02-28 18:22 ` Matthew Wilcox (Oracle)
2024-02-29 15:43 ` Pankaj Raghav (Samsung)
0 siblings, 1 reply; 3+ messages in thread
From: Matthew Wilcox (Oracle) @ 2024-02-28 18:22 UTC (permalink / raw)
To: linux-fsdevel, linux-mm; +Cc: Matthew Wilcox (Oracle)
Remove four hidden calls to compound_head(). Also exit early if the
filesystem block size is >= PAGE_SIZE instead of just equal to PAGE_SIZE.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
mm/truncate.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/mm/truncate.c b/mm/truncate.c
index 725b150e47ac..25776e1915b8 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -781,31 +781,29 @@ void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to)
{
int bsize = i_blocksize(inode);
loff_t rounded_from;
- struct page *page;
- pgoff_t index;
+ struct folio *folio;
WARN_ON(to > inode->i_size);
- if (from >= to || bsize == PAGE_SIZE)
+ if (from >= to || bsize >= PAGE_SIZE)
return;
/* Page straddling @from will not have any hole block created? */
rounded_from = round_up(from, bsize);
if (to <= rounded_from || !(rounded_from & (PAGE_SIZE - 1)))
return;
- index = from >> PAGE_SHIFT;
- page = find_lock_page(inode->i_mapping, index);
- /* Page not cached? Nothing to do */
- if (!page)
+ folio = filemap_lock_folio(inode->i_mapping, from / PAGE_SIZE);
+ /* Folio not cached? Nothing to do */
+ if (IS_ERR(folio))
return;
/*
- * See clear_page_dirty_for_io() for details why set_page_dirty()
+ * See folio_clear_dirty_for_io() for details why folio_mark_dirty()
* is needed.
*/
- if (page_mkclean(page))
- set_page_dirty(page);
- unlock_page(page);
- put_page(page);
+ if (folio_mkclean(folio))
+ folio_mark_dirty(folio);
+ folio_unlock(folio);
+ folio_put(folio);
}
EXPORT_SYMBOL(pagecache_isize_extended);
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 1/1] mm: Convert pagecache_isize_extended to use a folio
2024-02-28 18:22 ` [PATCH 1/1] mm: Convert pagecache_isize_extended to use a folio Matthew Wilcox (Oracle)
@ 2024-02-29 15:43 ` Pankaj Raghav (Samsung)
0 siblings, 0 replies; 3+ messages in thread
From: Pankaj Raghav (Samsung) @ 2024-02-29 15:43 UTC (permalink / raw)
To: Matthew Wilcox (Oracle); +Cc: linux-fsdevel, linux-mm, p.raghav
On Wed, Feb 28, 2024 at 06:22:28PM +0000, Matthew Wilcox (Oracle) wrote:
> Remove four hidden calls to compound_head(). Also exit early if the
> filesystem block size is >= PAGE_SIZE instead of just equal to PAGE_SIZE.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Look good to me.
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
> ---
> mm/truncate.c | 22 ++++++++++------------
> 1 file changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/mm/truncate.c b/mm/truncate.c
> index 725b150e47ac..25776e1915b8 100644
> --- a/mm/truncate.c
> +++ b/mm/truncate.c
> @@ -781,31 +781,29 @@ void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to)
> {
> int bsize = i_blocksize(inode);
> loff_t rounded_from;
> - struct page *page;
> - pgoff_t index;
> + struct folio *folio;
>
> WARN_ON(to > inode->i_size);
>
> - if (from >= to || bsize == PAGE_SIZE)
> + if (from >= to || bsize >= PAGE_SIZE)
> return;
> /* Page straddling @from will not have any hole block created? */
> rounded_from = round_up(from, bsize);
> if (to <= rounded_from || !(rounded_from & (PAGE_SIZE - 1)))
> return;
>
> - index = from >> PAGE_SHIFT;
> - page = find_lock_page(inode->i_mapping, index);
> - /* Page not cached? Nothing to do */
> - if (!page)
> + folio = filemap_lock_folio(inode->i_mapping, from / PAGE_SIZE);
> + /* Folio not cached? Nothing to do */
> + if (IS_ERR(folio))
> return;
> /*
> - * See clear_page_dirty_for_io() for details why set_page_dirty()
> + * See folio_clear_dirty_for_io() for details why folio_mark_dirty()
> * is needed.
> */
> - if (page_mkclean(page))
> - set_page_dirty(page);
> - unlock_page(page);
> - put_page(page);
> + if (folio_mkclean(folio))
> + folio_mark_dirty(folio);
> + folio_unlock(folio);
> + folio_put(folio);
> }
> EXPORT_SYMBOL(pagecache_isize_extended);
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-02-29 15:43 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-28 18:22 [PATCH 0/1] Is pagecache_isize_extended() compatible with large folios? Matthew Wilcox (Oracle)
2024-02-28 18:22 ` [PATCH 1/1] mm: Convert pagecache_isize_extended to use a folio Matthew Wilcox (Oracle)
2024-02-29 15:43 ` Pankaj Raghav (Samsung)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox