forked from luck/tmp_suning_uos_patched
[PATCH] NFS: Ensure that fstat() always returns the correct mtime
Even if the file is open for writes. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
7d52e86274
commit
fe51beecc5
|
@ -127,6 +127,21 @@ 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)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if ((NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) || 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
|
||||
|
@ -149,7 +164,8 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
|
|||
goto force_reval;
|
||||
if (nfsi->npages != 0)
|
||||
return 0;
|
||||
return nfs_revalidate_inode(server, inode);
|
||||
if (!(NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
|
||||
return 0;
|
||||
force_reval:
|
||||
return __nfs_revalidate_inode(server, inode);
|
||||
}
|
||||
|
@ -210,7 +226,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_inode(NFS_SERVER(inode), inode);
|
||||
result = nfs_revalidate_file(inode, iocb->ki_filp);
|
||||
if (!result)
|
||||
result = generic_file_aio_read(iocb, buf, count, pos);
|
||||
return result;
|
||||
|
@ -228,7 +244,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_inode(NFS_SERVER(inode), inode);
|
||||
res = nfs_revalidate_file(inode, filp);
|
||||
if (!res)
|
||||
res = generic_file_sendfile(filp, ppos, count, actor, target);
|
||||
return res;
|
||||
|
@ -244,7 +260,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_inode(NFS_SERVER(inode), inode);
|
||||
status = nfs_revalidate_file(inode, file);
|
||||
if (!status)
|
||||
status = generic_file_mmap(file, vma);
|
||||
return status;
|
||||
|
@ -340,8 +356,8 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
|
|||
result = nfs_revalidate_file_size(inode, iocb->ki_filp);
|
||||
if (result)
|
||||
goto out;
|
||||
} else
|
||||
nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
|
||||
}
|
||||
nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
|
||||
|
||||
result = count;
|
||||
if (!count)
|
||||
|
|
|
@ -620,9 +620,9 @@ nfs_zap_caches(struct inode *inode)
|
|||
|
||||
memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
|
||||
if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
|
||||
else
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
|
||||
}
|
||||
|
||||
static void nfs_zap_acl_cache(struct inode *inode)
|
||||
|
@ -1055,6 +1055,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
|
|||
goto out;
|
||||
}
|
||||
flags = nfsi->flags;
|
||||
nfsi->flags &= ~NFS_INO_REVAL_PAGECACHE;
|
||||
/*
|
||||
* We may need to keep the attributes marked as invalid if
|
||||
* we raced with nfs_end_attr_update().
|
||||
|
@ -1187,8 +1188,11 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||
if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
|
||||
&& nfsi->change_attr == fattr->pre_change_attr)
|
||||
nfsi->change_attr = fattr->change_attr;
|
||||
if (!data_unstable && nfsi->change_attr != fattr->change_attr)
|
||||
if (nfsi->change_attr != fattr->change_attr) {
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR;
|
||||
if (!data_unstable)
|
||||
nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fattr->valid & NFS_ATTR_FATTR) == 0)
|
||||
|
@ -1211,12 +1215,16 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||
}
|
||||
|
||||
/* Verify a few of the more important attributes */
|
||||
if (!data_unstable) {
|
||||
if (!timespec_equal(&inode->i_mtime, &fattr->mtime)
|
||||
|| cur_size != new_isize)
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR;
|
||||
} else if (new_isize != cur_size && nfsi->npages == 0)
|
||||
if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR;
|
||||
if (!data_unstable)
|
||||
nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
|
||||
}
|
||||
if (cur_size != new_isize) {
|
||||
nfsi->flags |= NFS_INO_INVALID_ATTR;
|
||||
if (nfsi->npages == 0)
|
||||
nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
|
||||
}
|
||||
|
||||
/* Have any file permissions changed? */
|
||||
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
|
||||
|
|
|
@ -198,6 +198,7 @@ struct nfs_inode {
|
|||
#define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */
|
||||
#define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */
|
||||
#define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */
|
||||
#define NFS_INO_REVAL_PAGECACHE 0x1000 /* must revalidate pagecache */
|
||||
|
||||
static inline struct nfs_inode *NFS_I(struct inode *inode)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user