mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 22:24:11 +08:00
mm/truncate: Split invalidate_inode_page() into mapping_evict_folio()
Some of the callers already have the address_space and can avoid calling folio_mapping() and checking if the folio was already truncated. Also add kernel-doc and fix the return type (in case we ever support folios larger than 4TB). Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
This commit is contained in:
parent
5100da38ef
commit
d6c75dc22c
@ -1825,7 +1825,6 @@ extern void truncate_setsize(struct inode *inode, loff_t newsize);
|
|||||||
void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to);
|
void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to);
|
||||||
void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end);
|
void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end);
|
||||||
int generic_error_remove_page(struct address_space *mapping, struct page *page);
|
int generic_error_remove_page(struct address_space *mapping, struct page *page);
|
||||||
int invalidate_inode_page(struct page *page);
|
|
||||||
|
|
||||||
#ifdef CONFIG_MMU
|
#ifdef CONFIG_MMU
|
||||||
extern vm_fault_t handle_mm_fault(struct vm_area_struct *vma,
|
extern vm_fault_t handle_mm_fault(struct vm_area_struct *vma,
|
||||||
|
@ -95,6 +95,7 @@ void filemap_free_folio(struct address_space *mapping, struct folio *folio);
|
|||||||
int truncate_inode_folio(struct address_space *mapping, struct folio *folio);
|
int truncate_inode_folio(struct address_space *mapping, struct folio *folio);
|
||||||
bool truncate_inode_partial_folio(struct folio *folio, loff_t start,
|
bool truncate_inode_partial_folio(struct folio *folio, loff_t start,
|
||||||
loff_t end);
|
loff_t end);
|
||||||
|
long invalidate_inode_page(struct page *page);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* folio_evictable - Test whether a folio is evictable.
|
* folio_evictable - Test whether a folio is evictable.
|
||||||
|
@ -2139,7 +2139,7 @@ static bool isolate_page(struct page *page, struct list_head *pagelist)
|
|||||||
*/
|
*/
|
||||||
static int __soft_offline_page(struct page *page)
|
static int __soft_offline_page(struct page *page)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
long ret = 0;
|
||||||
unsigned long pfn = page_to_pfn(page);
|
unsigned long pfn = page_to_pfn(page);
|
||||||
struct page *hpage = compound_head(page);
|
struct page *hpage = compound_head(page);
|
||||||
char const *msg_page[] = {"page", "hugepage"};
|
char const *msg_page[] = {"page", "hugepage"};
|
||||||
@ -2196,7 +2196,7 @@ static int __soft_offline_page(struct page *page)
|
|||||||
if (!list_empty(&pagelist))
|
if (!list_empty(&pagelist))
|
||||||
putback_movable_pages(&pagelist);
|
putback_movable_pages(&pagelist);
|
||||||
|
|
||||||
pr_info("soft offline: %#lx: %s migration failed %d, type %pGp\n",
|
pr_info("soft offline: %#lx: %s migration failed %ld, type %pGp\n",
|
||||||
pfn, msg_page[huge], ret, &page->flags);
|
pfn, msg_page[huge], ret, &page->flags);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
@ -273,18 +273,9 @@ int generic_error_remove_page(struct address_space *mapping, struct page *page)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(generic_error_remove_page);
|
EXPORT_SYMBOL(generic_error_remove_page);
|
||||||
|
|
||||||
/*
|
static long mapping_evict_folio(struct address_space *mapping,
|
||||||
* Safely invalidate one page from its pagecache mapping.
|
struct folio *folio)
|
||||||
* It only drops clean, unused pages. The page must be locked.
|
|
||||||
*
|
|
||||||
* Returns 1 if the page is successfully invalidated, otherwise 0.
|
|
||||||
*/
|
|
||||||
int invalidate_inode_page(struct page *page)
|
|
||||||
{
|
{
|
||||||
struct folio *folio = page_folio(page);
|
|
||||||
struct address_space *mapping = folio_mapping(folio);
|
|
||||||
if (!mapping)
|
|
||||||
return 0;
|
|
||||||
if (folio_test_dirty(folio) || folio_test_writeback(folio))
|
if (folio_test_dirty(folio) || folio_test_writeback(folio))
|
||||||
return 0;
|
return 0;
|
||||||
/* The refcount will be elevated if any page in the folio is mapped */
|
/* The refcount will be elevated if any page in the folio is mapped */
|
||||||
@ -297,6 +288,27 @@ int invalidate_inode_page(struct page *page)
|
|||||||
return remove_mapping(mapping, folio);
|
return remove_mapping(mapping, folio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* invalidate_inode_page() - Remove an unused page from the pagecache.
|
||||||
|
* @page: The page to remove.
|
||||||
|
*
|
||||||
|
* Safely invalidate one page from its pagecache mapping.
|
||||||
|
* It only drops clean, unused pages.
|
||||||
|
*
|
||||||
|
* Context: Page must be locked.
|
||||||
|
* Return: The number of pages successfully removed.
|
||||||
|
*/
|
||||||
|
long invalidate_inode_page(struct page *page)
|
||||||
|
{
|
||||||
|
struct folio *folio = page_folio(page);
|
||||||
|
struct address_space *mapping = folio_mapping(folio);
|
||||||
|
|
||||||
|
/* The page may have been truncated before it was locked */
|
||||||
|
if (!mapping)
|
||||||
|
return 0;
|
||||||
|
return mapping_evict_folio(mapping, folio);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* truncate_inode_pages_range - truncate range of pages specified by start & end byte offsets
|
* truncate_inode_pages_range - truncate range of pages specified by start & end byte offsets
|
||||||
* @mapping: mapping to truncate
|
* @mapping: mapping to truncate
|
||||||
|
Loading…
Reference in New Issue
Block a user