Commit 5522d9f7 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Christian Brauner
Browse files

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: default avatar"Matthew Wilcox (Oracle)" <willy@infradead.org>
Message-Id: <20230821141322.2535459-1-willy@infradead.org>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 8c8e7dba
Loading
Loading
Loading
Loading
+20 −20
Original line number Diff line number Diff line
@@ -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 = page;
	*pagep = &folio->page;

	if (!PageUptodate(page) && (len != PAGE_SIZE)) {
		unsigned from = pos & (PAGE_SIZE - 1);
	if (!folio_test_uptodate(folio) && (len != folio_size(folio))) {
		size_t from = offset_in_folio(folio, pos);

		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;
}