From 0d0def49d05ae988936268b0e57d19aeef8c3ad2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 17 Nov 2015 21:14:24 -0500 Subject: teach nfs_get_link() to work in RCU mode based upon the corresponding patch from Neil's March patchset, again with kmap-related horrors removed. Signed-off-by: Al Viro --- fs/nfs/symlink.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'fs/nfs/symlink.c') diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 8ade8a812607..95c69af7e4d0 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c @@ -48,16 +48,26 @@ static const char *nfs_get_link(struct dentry *dentry, struct page *page; void *err; - if (!dentry) - return ERR_PTR(-ECHILD); - - err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); - if (err) - return err; - page = read_cache_page(&inode->i_data, 0, - (filler_t *)nfs_symlink_filler, inode); - if (IS_ERR(page)) - return ERR_CAST(page); + if (!dentry) { + err = ERR_PTR(nfs_revalidate_mapping_rcu(inode)); + if (err) + return err; + page = find_get_page(inode->i_mapping, 0); + if (!page) + return ERR_PTR(-ECHILD); + if (!PageUptodate(page)) { + put_page(page); + return ERR_PTR(-ECHILD); + } + } else { + err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); + if (err) + return err; + page = read_cache_page(&inode->i_data, 0, + (filler_t *)nfs_symlink_filler, inode); + if (IS_ERR(page)) + return ERR_CAST(page); + } *cookie = page; return page_address(page); } -- cgit