Skip to content

Commit 76145cb

Browse files
committed
Merge patch series "Use folios for symlinks in the page cache"
Matthew Wilcox (Oracle) <[email protected]> says: FUSE already uses folios for its symlinks. Mirror that conversion in the generic code and the NFS code. That lets us get rid of a few folio->page->folio conversions in this path, and some of the few remaining users of read_cache_page() / read_mapping_page(). * patches from https://lore.kernel.org/[email protected]: fs: Pass a folio to page_put_link() nfs: Use a folio in nfs_get_link() fs: Convert __page_get_link() to use a folio Link: https://lore.kernel.org/[email protected] Signed-off-by: Christian Brauner <[email protected]>
2 parents 4fae90d + 4ec373b commit 76145cb

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

fs/fuse/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
16761676
goto out_err;
16771677
}
16781678

1679-
set_delayed_call(callback, page_put_link, &folio->page);
1679+
set_delayed_call(callback, page_put_link, folio);
16801680

16811681
return folio_address(folio);
16821682

fs/namei.c

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5371,25 +5371,25 @@ EXPORT_SYMBOL(vfs_get_link);
53715371
static char *__page_get_link(struct dentry *dentry, struct inode *inode,
53725372
struct delayed_call *callback)
53735373
{
5374-
struct page *page;
5374+
struct folio *folio;
53755375
struct address_space *mapping = inode->i_mapping;
53765376

53775377
if (!dentry) {
5378-
page = find_get_page(mapping, 0);
5379-
if (!page)
5378+
folio = filemap_get_folio(mapping, 0);
5379+
if (IS_ERR(folio))
53805380
return ERR_PTR(-ECHILD);
5381-
if (!PageUptodate(page)) {
5382-
put_page(page);
5381+
if (!folio_test_uptodate(folio)) {
5382+
folio_put(folio);
53835383
return ERR_PTR(-ECHILD);
53845384
}
53855385
} else {
5386-
page = read_mapping_page(mapping, 0, NULL);
5387-
if (IS_ERR(page))
5388-
return (char*)page;
5386+
folio = read_mapping_folio(mapping, 0, NULL);
5387+
if (IS_ERR(folio))
5388+
return ERR_CAST(folio);
53895389
}
5390-
set_delayed_call(callback, page_put_link, page);
5390+
set_delayed_call(callback, page_put_link, folio);
53915391
BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM);
5392-
return page_address(page);
5392+
return folio_address(folio);
53935393
}
53945394

53955395
const char *page_get_link_raw(struct dentry *dentry, struct inode *inode,
@@ -5399,6 +5399,17 @@ const char *page_get_link_raw(struct dentry *dentry, struct inode *inode,
53995399
}
54005400
EXPORT_SYMBOL_GPL(page_get_link_raw);
54015401

5402+
/**
5403+
* page_get_link() - An implementation of the get_link inode_operation.
5404+
* @dentry: The directory entry which is the symlink.
5405+
* @inode: The inode for the symlink.
5406+
* @callback: Used to drop the reference to the symlink.
5407+
*
5408+
* Filesystems which store their symlinks in the page cache should use
5409+
* this to implement the get_link() member of their inode_operations.
5410+
*
5411+
* Return: A pointer to the NUL-terminated symlink.
5412+
*/
54025413
const char *page_get_link(struct dentry *dentry, struct inode *inode,
54035414
struct delayed_call *callback)
54045415
{
@@ -5408,12 +5419,25 @@ const char *page_get_link(struct dentry *dentry, struct inode *inode,
54085419
nd_terminate_link(kaddr, inode->i_size, PAGE_SIZE - 1);
54095420
return kaddr;
54105421
}
5411-
54125422
EXPORT_SYMBOL(page_get_link);
54135423

5424+
/**
5425+
* page_put_link() - Drop the reference to the symlink.
5426+
* @arg: The folio which contains the symlink.
5427+
*
5428+
* This is used internally by page_get_link(). It is exported for use
5429+
* by filesystems which need to implement a variant of page_get_link()
5430+
* themselves. Despite the apparent symmetry, filesystems which use
5431+
* page_get_link() do not need to call page_put_link().
5432+
*
5433+
* The argument, while it has a void pointer type, must be a pointer to
5434+
* the folio which was retrieved from the page cache. The delayed_call
5435+
* infrastructure is used to drop the reference count once the caller
5436+
* is done with the symlink.
5437+
*/
54145438
void page_put_link(void *arg)
54155439
{
5416-
put_page(arg);
5440+
folio_put(arg);
54175441
}
54185442
EXPORT_SYMBOL(page_put_link);
54195443

fs/nfs/symlink.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,31 +40,31 @@ static const char *nfs_get_link(struct dentry *dentry,
4040
struct inode *inode,
4141
struct delayed_call *done)
4242
{
43-
struct page *page;
43+
struct folio *folio;
4444
void *err;
4545

4646
if (!dentry) {
4747
err = ERR_PTR(nfs_revalidate_mapping_rcu(inode));
4848
if (err)
4949
return err;
50-
page = find_get_page(inode->i_mapping, 0);
51-
if (!page)
50+
folio = filemap_get_folio(inode->i_mapping, 0);
51+
if (IS_ERR(folio))
5252
return ERR_PTR(-ECHILD);
53-
if (!PageUptodate(page)) {
54-
put_page(page);
53+
if (!folio_test_uptodate(folio)) {
54+
folio_put(folio);
5555
return ERR_PTR(-ECHILD);
5656
}
5757
} else {
5858
err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
5959
if (err)
6060
return err;
61-
page = read_cache_page(&inode->i_data, 0, nfs_symlink_filler,
61+
folio = read_cache_folio(&inode->i_data, 0, nfs_symlink_filler,
6262
NULL);
63-
if (IS_ERR(page))
64-
return ERR_CAST(page);
63+
if (IS_ERR(folio))
64+
return ERR_CAST(folio);
6565
}
66-
set_delayed_call(done, page_put_link, page);
67-
return page_address(page);
66+
set_delayed_call(done, page_put_link, folio);
67+
return folio_address(folio);
6868
}
6969

7070
/*

0 commit comments

Comments
 (0)