mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
mm/filemap: Add FGP_STABLE
Allow filemap_get_folio() to wait for writeback to complete (if the filesystem wants that behaviour). This is the folio equivalent of grab_cache_page_write_begin(), which is moved into the folio-compat file as a reminder to migrate all the code using it. This paves the way for getting rid of AOP_FLAG_NOFS once grab_cache_page_write_begin() is removed. Kernel grows by 11 bytes. filemap_get_folio() grows by 33 bytes but grab_cache_page_write_begin() shrinks by 22 bytes to make up for it. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: David Howells <dhowells@redhat.com> Acked-by: Vlastimil Babka <vbabka@suse.cz>
This commit is contained in:
parent
3f0c6a07fe
commit
b27652d935
@ -301,6 +301,7 @@ pgoff_t page_cache_prev_miss(struct address_space *mapping,
|
||||
#define FGP_FOR_MMAP 0x00000040
|
||||
#define FGP_HEAD 0x00000080
|
||||
#define FGP_ENTRY 0x00000100
|
||||
#define FGP_STABLE 0x00000200
|
||||
|
||||
struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
|
||||
int fgp_flags, gfp_t gfp);
|
||||
|
25
mm/filemap.c
25
mm/filemap.c
@ -1872,6 +1872,7 @@ static void *mapping_get_entry(struct address_space *mapping, pgoff_t index)
|
||||
* * %FGP_WRITE - The page will be written to by the caller.
|
||||
* * %FGP_NOFS - __GFP_FS will get cleared in gfp.
|
||||
* * %FGP_NOWAIT - Don't get blocked by page lock.
|
||||
* * %FGP_STABLE - Wait for the folio to be stable (finished writeback)
|
||||
*
|
||||
* If %FGP_LOCK or %FGP_CREAT are specified then the function may sleep even
|
||||
* if the %GFP flags specified for %FGP_CREAT are atomic.
|
||||
@ -1922,6 +1923,8 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,
|
||||
folio_clear_idle(folio);
|
||||
}
|
||||
|
||||
if (fgp_flags & FGP_STABLE)
|
||||
folio_wait_stable(folio);
|
||||
no_page:
|
||||
if (!folio && (fgp_flags & FGP_CREAT)) {
|
||||
int err;
|
||||
@ -3704,28 +3707,6 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from)
|
||||
}
|
||||
EXPORT_SYMBOL(generic_file_direct_write);
|
||||
|
||||
/*
|
||||
* Find or create a page at the given pagecache position. Return the locked
|
||||
* page. This function is specifically for buffered writes.
|
||||
*/
|
||||
struct page *grab_cache_page_write_begin(struct address_space *mapping,
|
||||
pgoff_t index, unsigned flags)
|
||||
{
|
||||
struct page *page;
|
||||
int fgp_flags = FGP_LOCK|FGP_WRITE|FGP_CREAT;
|
||||
|
||||
if (flags & AOP_FLAG_NOFS)
|
||||
fgp_flags |= FGP_NOFS;
|
||||
|
||||
page = pagecache_get_page(mapping, index, fgp_flags,
|
||||
mapping_gfp_mask(mapping));
|
||||
if (page)
|
||||
wait_for_stable_page(page);
|
||||
|
||||
return page;
|
||||
}
|
||||
EXPORT_SYMBOL(grab_cache_page_write_begin);
|
||||
|
||||
ssize_t generic_perform_write(struct file *file,
|
||||
struct iov_iter *i, loff_t pos)
|
||||
{
|
||||
|
@ -116,6 +116,7 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
|
||||
}
|
||||
EXPORT_SYMBOL(add_to_page_cache_lru);
|
||||
|
||||
noinline
|
||||
struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
|
||||
int fgp_flags, gfp_t gfp)
|
||||
{
|
||||
@ -127,3 +128,15 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t index,
|
||||
return folio_file_page(folio, index);
|
||||
}
|
||||
EXPORT_SYMBOL(pagecache_get_page);
|
||||
|
||||
struct page *grab_cache_page_write_begin(struct address_space *mapping,
|
||||
pgoff_t index, unsigned flags)
|
||||
{
|
||||
unsigned fgp_flags = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE;
|
||||
|
||||
if (flags & AOP_FLAG_NOFS)
|
||||
fgp_flags |= FGP_NOFS;
|
||||
return pagecache_get_page(mapping, index, fgp_flags,
|
||||
mapping_gfp_mask(mapping));
|
||||
}
|
||||
EXPORT_SYMBOL(grab_cache_page_write_begin);
|
||||
|
Loading…
Reference in New Issue
Block a user