libfs: Convert simple_write_begin and simple_write_end to use a folio

Remove a number of implicit calls to compound_head() and various calls
to compatibility functions.  This is not sufficient to enable support
for large folios; generic_perform_write() must be converted first.

Signed-off-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Message-Id: <20230821141322.2535459-1-willy@infradead.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Matthew Wilcox (Oracle) 2023-08-21 15:13:22 +01:00 committed by Christian Brauner
parent 8c8e7dba10
commit 5522d9f7b2

View file

@ -548,21 +548,20 @@ int simple_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len,
struct page **pagep, void **fsdata)
{
struct page *page;
pgoff_t index;
struct folio *folio;
index = pos >> PAGE_SHIFT;
folio = __filemap_get_folio(mapping, pos / PAGE_SIZE, FGP_WRITEBEGIN,
mapping_gfp_mask(mapping));
if (IS_ERR(folio))
return PTR_ERR(folio);
page = grab_cache_page_write_begin(mapping, index);
if (!page)
return -ENOMEM;
*pagep = &folio->page;
*pagep = page;
if (!folio_test_uptodate(folio) && (len != folio_size(folio))) {
size_t from = offset_in_folio(folio, pos);
if (!PageUptodate(page) && (len != PAGE_SIZE)) {
unsigned from = pos & (PAGE_SIZE - 1);
zero_user_segments(page, 0, from, from + len, PAGE_SIZE);
folio_zero_segments(folio, 0, from,
from + len, folio_size(folio));
}
return 0;
}
@ -594,17 +593,18 @@ static int simple_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
{
struct inode *inode = page->mapping->host;
struct folio *folio = page_folio(page);
struct inode *inode = folio->mapping->host;
loff_t last_pos = pos + copied;
/* zero the stale part of the page if we did a short copy */
if (!PageUptodate(page)) {
/* zero the stale part of the folio if we did a short copy */
if (!folio_test_uptodate(folio)) {
if (copied < len) {
unsigned from = pos & (PAGE_SIZE - 1);
size_t from = offset_in_folio(folio, pos);
zero_user(page, from + copied, len - copied);
folio_zero_range(folio, from + copied, len - copied);
}
SetPageUptodate(page);
folio_mark_uptodate(folio);
}
/*
* No need to use i_size_read() here, the i_size
@ -613,9 +613,9 @@ static int simple_write_end(struct file *file, struct address_space *mapping,
if (last_pos > inode->i_size)
i_size_write(inode, last_pos);
set_page_dirty(page);
unlock_page(page);
put_page(page);
folio_mark_dirty(folio);
folio_unlock(folio);
folio_put(folio);
return copied;
}