mirror of https://gitee.com/openkylin/linux.git
NFS: Separate metadata and page cache revalidation mechanisms
Separate out the function of revalidating the inode metadata, and revalidating the mapping. The former may be called by lookup(), and only really needs to check that permissions, ctime, etc haven't changed whereas the latter needs only done when we want to read data from the page cache, and may need to sync and then invalidate the mapping. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
38478b24e3
commit
44b11874ff
|
@ -528,7 +528,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||
|
||||
lock_kernel();
|
||||
|
||||
res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
|
||||
res = nfs_revalidate_mapping(inode, filp->f_mapping);
|
||||
if (res < 0) {
|
||||
unlock_kernel();
|
||||
return res;
|
||||
|
|
|
@ -126,23 +126,6 @@ nfs_file_release(struct inode *inode, struct file *filp)
|
|||
return NFS_PROTO(inode)->file_release(inode, filp);
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_revalidate_file - Revalidate the page cache & related metadata
|
||||
* @inode - pointer to inode struct
|
||||
* @file - pointer to file
|
||||
*/
|
||||
static int nfs_revalidate_file(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
int retval = 0;
|
||||
|
||||
if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR))
|
||||
|| nfs_attribute_timeout(inode))
|
||||
retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
|
||||
nfs_revalidate_mapping(inode, filp->f_mapping);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfs_revalidate_size - Revalidate the file size
|
||||
* @inode - pointer to inode struct
|
||||
|
@ -228,7 +211,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
|
|||
dentry->d_parent->d_name.name, dentry->d_name.name,
|
||||
(unsigned long) count, (unsigned long) pos);
|
||||
|
||||
result = nfs_revalidate_file(inode, iocb->ki_filp);
|
||||
result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
|
||||
nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
|
||||
if (!result)
|
||||
result = generic_file_aio_read(iocb, buf, count, pos);
|
||||
|
@ -247,7 +230,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count,
|
|||
dentry->d_parent->d_name.name, dentry->d_name.name,
|
||||
(unsigned long) count, (unsigned long long) *ppos);
|
||||
|
||||
res = nfs_revalidate_file(inode, filp);
|
||||
res = nfs_revalidate_mapping(inode, filp->f_mapping);
|
||||
if (!res)
|
||||
res = generic_file_sendfile(filp, ppos, count, actor, target);
|
||||
return res;
|
||||
|
@ -263,7 +246,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
|
|||
dfprintk(VFS, "nfs: mmap(%s/%s)\n",
|
||||
dentry->d_parent->d_name.name, dentry->d_name.name);
|
||||
|
||||
status = nfs_revalidate_file(inode, file);
|
||||
status = nfs_revalidate_mapping(inode, file->f_mapping);
|
||||
if (!status)
|
||||
status = generic_file_mmap(file, vma);
|
||||
return status;
|
||||
|
@ -373,7 +356,6 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
|
|||
if (result)
|
||||
goto out;
|
||||
}
|
||||
nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
|
||||
|
||||
result = count;
|
||||
if (!count)
|
||||
|
|
|
@ -1220,7 +1220,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
|
|||
status = -ESTALE;
|
||||
/* Do we trust the cached ESTALE? */
|
||||
if (NFS_ATTRTIMEO(inode) != 0) {
|
||||
if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) {
|
||||
if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME)) {
|
||||
/* no */
|
||||
} else
|
||||
goto out;
|
||||
|
@ -1251,8 +1251,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
|
|||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
|
||||
nfs_revalidate_mapping(inode, inode->i_mapping);
|
||||
|
||||
if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
|
||||
nfs_zap_acl_cache(inode);
|
||||
|
||||
|
@ -1287,7 +1285,7 @@ int nfs_attribute_timeout(struct inode *inode)
|
|||
int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
|
||||
{
|
||||
nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
|
||||
if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
|
||||
if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR)
|
||||
&& !nfs_attribute_timeout(inode))
|
||||
return NFS_STALE(inode) ? -ESTALE : 0;
|
||||
return __nfs_revalidate_inode(server, inode);
|
||||
|
@ -1298,9 +1296,16 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
|
|||
* @inode - pointer to host inode
|
||||
* @mapping - pointer to mapping
|
||||
*/
|
||||
void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
|
||||
int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
int ret = 0;
|
||||
|
||||
if (NFS_STALE(inode))
|
||||
ret = -ESTALE;
|
||||
if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
|
||||
|| nfs_attribute_timeout(inode))
|
||||
ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
|
||||
|
||||
if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
|
||||
nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
|
||||
|
@ -1321,6 +1326,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
|
|||
inode->i_sb->s_id,
|
||||
(long long)NFS_FILEID(inode));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,7 +52,7 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
|
|||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
struct page *page;
|
||||
void *err = ERR_PTR(nfs_revalidate_inode(NFS_SERVER(inode), inode));
|
||||
void *err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping));
|
||||
if (err)
|
||||
goto read_failed;
|
||||
page = read_cache_page(&inode->i_data, 0,
|
||||
|
|
|
@ -301,7 +301,7 @@ extern int nfs_release(struct inode *, struct file *);
|
|||
extern int nfs_attribute_timeout(struct inode *inode);
|
||||
extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
|
||||
extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
|
||||
extern void 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_setattr(struct dentry *, struct iattr *);
|
||||
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
|
||||
extern void nfs_begin_attr_update(struct inode *);
|
||||
|
|
Loading…
Reference in New Issue