Commit 44b11874 authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 38478b24
...@@ -528,7 +528,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -528,7 +528,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
lock_kernel(); lock_kernel();
res = nfs_revalidate_inode(NFS_SERVER(inode), inode); res = nfs_revalidate_mapping(inode, filp->f_mapping);
if (res < 0) { if (res < 0) {
unlock_kernel(); unlock_kernel();
return res; return res;
......
...@@ -126,23 +126,6 @@ nfs_file_release(struct inode *inode, struct file *filp) ...@@ -126,23 +126,6 @@ nfs_file_release(struct inode *inode, struct file *filp)
return NFS_PROTO(inode)->file_release(inode, 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 * nfs_revalidate_size - Revalidate the file size
* @inode - pointer to inode struct * @inode - pointer to inode struct
...@@ -228,7 +211,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) ...@@ -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, dentry->d_parent->d_name.name, dentry->d_name.name,
(unsigned long) count, (unsigned long) pos); (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); nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
if (!result) if (!result)
result = generic_file_aio_read(iocb, buf, count, pos); 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, ...@@ -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, dentry->d_parent->d_name.name, dentry->d_name.name,
(unsigned long) count, (unsigned long long) *ppos); (unsigned long) count, (unsigned long long) *ppos);
res = nfs_revalidate_file(inode, filp); res = nfs_revalidate_mapping(inode, filp->f_mapping);
if (!res) if (!res)
res = generic_file_sendfile(filp, ppos, count, actor, target); res = generic_file_sendfile(filp, ppos, count, actor, target);
return res; return res;
...@@ -263,7 +246,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -263,7 +246,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
dfprintk(VFS, "nfs: mmap(%s/%s)\n", dfprintk(VFS, "nfs: mmap(%s/%s)\n",
dentry->d_parent->d_name.name, dentry->d_name.name); 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) if (!status)
status = generic_file_mmap(file, vma); status = generic_file_mmap(file, vma);
return status; return status;
...@@ -373,7 +356,6 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t ...@@ -373,7 +356,6 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
if (result) if (result)
goto out; goto out;
} }
nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
result = count; result = count;
if (!count) if (!count)
......
...@@ -1220,7 +1220,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) ...@@ -1220,7 +1220,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
status = -ESTALE; status = -ESTALE;
/* Do we trust the cached ESTALE? */ /* Do we trust the cached ESTALE? */
if (NFS_ATTRTIMEO(inode) != 0) { 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 */ /* no */
} else } else
goto out; goto out;
...@@ -1251,8 +1251,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) ...@@ -1251,8 +1251,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
} }
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
nfs_revalidate_mapping(inode, inode->i_mapping);
if (nfsi->cache_validity & NFS_INO_INVALID_ACL) if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
nfs_zap_acl_cache(inode); nfs_zap_acl_cache(inode);
...@@ -1287,7 +1285,7 @@ int nfs_attribute_timeout(struct inode *inode) ...@@ -1287,7 +1285,7 @@ int nfs_attribute_timeout(struct inode *inode)
int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
{ {
nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); 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)) && !nfs_attribute_timeout(inode))
return NFS_STALE(inode) ? -ESTALE : 0; return NFS_STALE(inode) ? -ESTALE : 0;
return __nfs_revalidate_inode(server, inode); return __nfs_revalidate_inode(server, inode);
...@@ -1298,9 +1296,16 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) ...@@ -1298,9 +1296,16 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
* @inode - pointer to host inode * @inode - pointer to host inode
* @mapping - pointer to mapping * @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); 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) { if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
...@@ -1321,6 +1326,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) ...@@ -1321,6 +1326,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
inode->i_sb->s_id, inode->i_sb->s_id,
(long long)NFS_FILEID(inode)); (long long)NFS_FILEID(inode));
} }
return ret;
} }
/** /**
......
...@@ -52,7 +52,7 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -52,7 +52,7 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct page *page; 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) if (err)
goto read_failed; goto read_failed;
page = read_cache_page(&inode->i_data, 0, page = read_cache_page(&inode->i_data, 0,
......
...@@ -301,7 +301,7 @@ extern int nfs_release(struct inode *, struct file *); ...@@ -301,7 +301,7 @@ extern int nfs_release(struct inode *, struct file *);
extern int nfs_attribute_timeout(struct inode *inode); 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 *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 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 int nfs_setattr(struct dentry *, struct iattr *);
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr); extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
extern void nfs_begin_attr_update(struct inode *); extern void nfs_begin_attr_update(struct inode *);
......
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