Skip to content

Commit

Permalink
NFS: Separate metadata and page cache revalidation mechanisms
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Jun 9, 2006
1 parent 38478b2 commit 44b1187
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 29 deletions.
2 changes: 1 addition & 1 deletion fs/nfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 3 additions & 21 deletions fs/nfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
16 changes: 11 additions & 5 deletions fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/symlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion include/linux/nfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down

0 comments on commit 44b1187

Please sign in to comment.