shmem: convert shmem_get_link() to use a folio

Symlinks will never use a large folio, but using the folio API removes a
lot of unnecessary folio->page->folio conversions.

Link: https://lkml.kernel.org/r/20220902194653.1739778-31-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Matthew Wilcox (Oracle) 2022-09-02 20:46:26 +01:00 committed by Andrew Morton
parent 7ad0414bde
commit e4b57722d0

View File

@ -3143,40 +3143,41 @@ static int shmem_symlink(struct user_namespace *mnt_userns, struct inode *dir,
static void shmem_put_link(void *arg)
{
mark_page_accessed(arg);
put_page(arg);
folio_mark_accessed(arg);
folio_put(arg);
}
static const char *shmem_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{
struct page *page = NULL;
struct folio *folio = NULL;
int error;
if (!dentry) {
page = find_get_page(inode->i_mapping, 0);
if (!page)
folio = filemap_get_folio(inode->i_mapping, 0);
if (!folio)
return ERR_PTR(-ECHILD);
if (PageHWPoison(page) ||
!PageUptodate(page)) {
put_page(page);
if (PageHWPoison(&folio->page) ||
!folio_test_uptodate(folio)) {
folio_put(folio);
return ERR_PTR(-ECHILD);
}
} else {
error = shmem_getpage(inode, 0, &page, SGP_READ);
error = shmem_get_folio(inode, 0, &folio, SGP_READ);
if (error)
return ERR_PTR(error);
if (!page)
if (!folio)
return ERR_PTR(-ECHILD);
if (PageHWPoison(page)) {
unlock_page(page);
put_page(page);
if (PageHWPoison(&folio->page)) {
folio_unlock(folio);
folio_put(folio);
return ERR_PTR(-ECHILD);
}
unlock_page(page);
folio_unlock(folio);
}
set_delayed_call(done, shmem_put_link, page);
return page_address(page);
set_delayed_call(done, shmem_put_link, folio);
return folio_address(folio);
}
#ifdef CONFIG_TMPFS_XATTR