mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 06:12:08 +00:00
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 <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
1a384eaac2
commit
0d0def49d0
@ -1087,6 +1087,27 @@ static bool nfs_mapping_need_revalidate_inode(struct inode *inode)
|
||||
|| NFS_STALE(inode);
|
||||
}
|
||||
|
||||
int nfs_revalidate_mapping_rcu(struct inode *inode)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
unsigned long *bitlock = &nfsi->flags;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_SWAPFILE(inode))
|
||||
goto out;
|
||||
if (nfs_mapping_need_revalidate_inode(inode)) {
|
||||
ret = -ECHILD;
|
||||
goto out;
|
||||
}
|
||||
spin_lock(&inode->i_lock);
|
||||
if (test_bit(NFS_INO_INVALIDATING, bitlock) ||
|
||||
(nfsi->cache_validity & NFS_INO_INVALID_DATA))
|
||||
ret = -ECHILD;
|
||||
spin_unlock(&inode->i_lock);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* __nfs_revalidate_mapping - Revalidate the pagecache
|
||||
* @inode - pointer to host inode
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -359,6 +359,7 @@ extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
|
||||
extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *inode);
|
||||
extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
|
||||
extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
|
||||
extern int nfs_revalidate_mapping_rcu(struct inode *inode);
|
||||
extern int nfs_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping);
|
||||
extern int nfs_setattr(struct dentry *, struct iattr *);
|
||||
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
|
||||
|
Loading…
Reference in New Issue
Block a user