mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +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
3 changed files with 42 additions and 10 deletions
|
@ -1087,6 +1087,27 @@ static bool nfs_mapping_need_revalidate_inode(struct inode *inode)
|
||||||
|| NFS_STALE(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
|
* __nfs_revalidate_mapping - Revalidate the pagecache
|
||||||
* @inode - pointer to host inode
|
* @inode - pointer to host inode
|
||||||
|
|
|
@ -48,16 +48,26 @@ static const char *nfs_get_link(struct dentry *dentry,
|
||||||
struct page *page;
|
struct page *page;
|
||||||
void *err;
|
void *err;
|
||||||
|
|
||||||
if (!dentry)
|
if (!dentry) {
|
||||||
return ERR_PTR(-ECHILD);
|
err = ERR_PTR(nfs_revalidate_mapping_rcu(inode));
|
||||||
|
if (err)
|
||||||
err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
|
return err;
|
||||||
if (err)
|
page = find_get_page(inode->i_mapping, 0);
|
||||||
return err;
|
if (!page)
|
||||||
page = read_cache_page(&inode->i_data, 0,
|
return ERR_PTR(-ECHILD);
|
||||||
(filler_t *)nfs_symlink_filler, inode);
|
if (!PageUptodate(page)) {
|
||||||
if (IS_ERR(page))
|
put_page(page);
|
||||||
return ERR_CAST(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;
|
*cookie = page;
|
||||||
return page_address(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_rcu(struct nfs_server *server, struct inode *inode);
|
||||||
extern int __nfs_revalidate_inode(struct nfs_server *, struct 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(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_revalidate_mapping_protected(struct inode *inode, struct address_space *mapping);
|
||||||
extern int nfs_setattr(struct dentry *, struct iattr *);
|
extern int nfs_setattr(struct dentry *, struct iattr *);
|
||||||
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
|
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue