Commit f003a717 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Trond Myklebust

nfs: Convert nfs_symlink() to use a folio

Use the folio APIs, saving about four calls to compound_head().
Convert back to a page in each of the individual protocol implementations.
Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent bfca5fb4
...@@ -2532,7 +2532,7 @@ EXPORT_SYMBOL_GPL(nfs_unlink); ...@@ -2532,7 +2532,7 @@ EXPORT_SYMBOL_GPL(nfs_unlink);
int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir, int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, const char *symname) struct dentry *dentry, const char *symname)
{ {
struct page *page; struct folio *folio;
char *kaddr; char *kaddr;
struct iattr attr; struct iattr attr;
unsigned int pathlen = strlen(symname); unsigned int pathlen = strlen(symname);
...@@ -2547,24 +2547,24 @@ int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir, ...@@ -2547,24 +2547,24 @@ int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
attr.ia_mode = S_IFLNK | S_IRWXUGO; attr.ia_mode = S_IFLNK | S_IRWXUGO;
attr.ia_valid = ATTR_MODE; attr.ia_valid = ATTR_MODE;
page = alloc_page(GFP_USER); folio = folio_alloc(GFP_USER, 0);
if (!page) if (!folio)
return -ENOMEM; return -ENOMEM;
kaddr = page_address(page); kaddr = folio_address(folio);
memcpy(kaddr, symname, pathlen); memcpy(kaddr, symname, pathlen);
if (pathlen < PAGE_SIZE) if (pathlen < PAGE_SIZE)
memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen); memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
trace_nfs_symlink_enter(dir, dentry); trace_nfs_symlink_enter(dir, dentry);
error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr); error = NFS_PROTO(dir)->symlink(dir, dentry, folio, pathlen, &attr);
trace_nfs_symlink_exit(dir, dentry, error); trace_nfs_symlink_exit(dir, dentry, error);
if (error != 0) { if (error != 0) {
dfprintk(VFS, "NFS: symlink(%s/%lu, %pd, %s) error %d\n", dfprintk(VFS, "NFS: symlink(%s/%lu, %pd, %s) error %d\n",
dir->i_sb->s_id, dir->i_ino, dir->i_sb->s_id, dir->i_ino,
dentry, symname, error); dentry, symname, error);
d_drop(dentry); d_drop(dentry);
__free_page(page); folio_put(folio);
return error; return error;
} }
...@@ -2574,18 +2574,13 @@ int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir, ...@@ -2574,18 +2574,13 @@ int nfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
* No big deal if we can't add this page to the page cache here. * No big deal if we can't add this page to the page cache here.
* READLINK will get the missing page from the server if needed. * READLINK will get the missing page from the server if needed.
*/ */
if (!add_to_page_cache_lru(page, d_inode(dentry)->i_mapping, 0, if (filemap_add_folio(d_inode(dentry)->i_mapping, folio, 0,
GFP_KERNEL)) { GFP_KERNEL) == 0) {
SetPageUptodate(page); folio_mark_uptodate(folio);
unlock_page(page); folio_unlock(folio);
/* }
* add_to_page_cache_lru() grabs an extra page refcount.
* Drop it here to avoid leaking this page later.
*/
put_page(page);
} else
__free_page(page);
folio_put(folio);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(nfs_symlink); EXPORT_SYMBOL_GPL(nfs_symlink);
......
...@@ -543,9 +543,10 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name) ...@@ -543,9 +543,10 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name)
} }
static int static int
nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct folio *folio,
unsigned int len, struct iattr *sattr) unsigned int len, struct iattr *sattr)
{ {
struct page *page = &folio->page;
struct nfs3_createdata *data; struct nfs3_createdata *data;
struct dentry *d_alias; struct dentry *d_alias;
int status = -ENOMEM; int status = -ENOMEM;
......
...@@ -5036,9 +5036,10 @@ static void nfs4_free_createdata(struct nfs4_createdata *data) ...@@ -5036,9 +5036,10 @@ static void nfs4_free_createdata(struct nfs4_createdata *data)
} }
static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
struct page *page, unsigned int len, struct iattr *sattr, struct folio *folio, unsigned int len, struct iattr *sattr,
struct nfs4_label *label) struct nfs4_label *label)
{ {
struct page *page = &folio->page;
struct nfs4_createdata *data; struct nfs4_createdata *data;
int status = -ENAMETOOLONG; int status = -ENAMETOOLONG;
...@@ -5063,7 +5064,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, ...@@ -5063,7 +5064,7 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
} }
static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
struct page *page, unsigned int len, struct iattr *sattr) struct folio *folio, unsigned int len, struct iattr *sattr)
{ {
struct nfs4_exception exception = { struct nfs4_exception exception = {
.interruptible = true, .interruptible = true,
...@@ -5074,7 +5075,7 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, ...@@ -5074,7 +5075,7 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
label = nfs4_label_init_security(dir, dentry, sattr, &l); label = nfs4_label_init_security(dir, dentry, sattr, &l);
do { do {
err = _nfs4_proc_symlink(dir, dentry, page, len, sattr, label); err = _nfs4_proc_symlink(dir, dentry, folio, len, sattr, label);
trace_nfs4_symlink(dir, &dentry->d_name, err); trace_nfs4_symlink(dir, &dentry->d_name, err);
err = nfs4_handle_exception(NFS_SERVER(dir), err, err = nfs4_handle_exception(NFS_SERVER(dir), err,
&exception); &exception);
......
...@@ -396,9 +396,10 @@ nfs_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name) ...@@ -396,9 +396,10 @@ nfs_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name)
} }
static int static int
nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct folio *folio,
unsigned int len, struct iattr *sattr) unsigned int len, struct iattr *sattr)
{ {
struct page *page = &folio->page;
struct nfs_fh *fh; struct nfs_fh *fh;
struct nfs_fattr *fattr; struct nfs_fattr *fattr;
struct nfs_symlinkargs arg = { struct nfs_symlinkargs arg = {
......
...@@ -1772,7 +1772,7 @@ struct nfs_rpc_ops { ...@@ -1772,7 +1772,7 @@ struct nfs_rpc_ops {
void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *); void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *);
int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir); int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir);
int (*link) (struct inode *, struct inode *, const struct qstr *); int (*link) (struct inode *, struct inode *, const struct qstr *);
int (*symlink) (struct inode *, struct dentry *, struct page *, int (*symlink) (struct inode *, struct dentry *, struct folio *,
unsigned int, struct iattr *); unsigned int, struct iattr *);
int (*mkdir) (struct inode *, struct dentry *, struct iattr *); int (*mkdir) (struct inode *, struct dentry *, struct iattr *);
int (*rmdir) (struct inode *, const struct qstr *); int (*rmdir) (struct inode *, const struct qstr *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment