Commit 960ea971 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle)
Browse files

filemap: Use a folio in filemap_page_mkwrite



This fixes a bug for tail pages.  They always have a NULL mapping, so
the check would fail and we would never mark the folio as dirty.
Ends up growing the kernel by 19 bytes although there will be fewer
calls to compound_head() dynamically.

Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarWilliam Kucharski <william.kucharski@oracle.com>
parent 820b05e9
Loading
Loading
Loading
Loading
+8 −8
Original line number Original line Diff line number Diff line
@@ -3349,24 +3349,24 @@ EXPORT_SYMBOL(filemap_map_pages);
vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
{
{
	struct address_space *mapping = vmf->vma->vm_file->f_mapping;
	struct address_space *mapping = vmf->vma->vm_file->f_mapping;
	struct page *page = vmf->page;
	struct folio *folio = page_folio(vmf->page);
	vm_fault_t ret = VM_FAULT_LOCKED;
	vm_fault_t ret = VM_FAULT_LOCKED;


	sb_start_pagefault(mapping->host->i_sb);
	sb_start_pagefault(mapping->host->i_sb);
	file_update_time(vmf->vma->vm_file);
	file_update_time(vmf->vma->vm_file);
	lock_page(page);
	folio_lock(folio);
	if (page->mapping != mapping) {
	if (folio->mapping != mapping) {
		unlock_page(page);
		folio_unlock(folio);
		ret = VM_FAULT_NOPAGE;
		ret = VM_FAULT_NOPAGE;
		goto out;
		goto out;
	}
	}
	/*
	/*
	 * We mark the page dirty already here so that when freeze is in
	 * We mark the folio dirty already here so that when freeze is in
	 * progress, we are guaranteed that writeback during freezing will
	 * progress, we are guaranteed that writeback during freezing will
	 * see the dirty page and writeprotect it again.
	 * see the dirty folio and writeprotect it again.
	 */
	 */
	set_page_dirty(page);
	folio_mark_dirty(folio);
	wait_for_stable_page(page);
	folio_wait_stable(folio);
out:
out:
	sb_end_pagefault(mapping->host->i_sb);
	sb_end_pagefault(mapping->host->i_sb);
	return ret;
	return ret;