diff options
Diffstat (limited to 'fs/nfs/inode.c')
| -rw-r--r-- | fs/nfs/inode.c | 22 | 
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index e98ee7599eeb..222a28320e1c 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -606,7 +606,7 @@ EXPORT_SYMBOL_GPL(nfs_fhget);  #define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)  int -nfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, +nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,  	    struct iattr *attr)  {  	struct inode *inode = d_inode(dentry); @@ -825,10 +825,12 @@ static u32 nfs_get_valid_attrmask(struct inode *inode)  		reply_mask |= STATX_UID | STATX_GID;  	if (!(cache_validity & NFS_INO_INVALID_BLOCKS))  		reply_mask |= STATX_BLOCKS; +	if (!(cache_validity & NFS_INO_INVALID_CHANGE)) +		reply_mask |= STATX_CHANGE_COOKIE;  	return reply_mask;  } -int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path, +int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,  		struct kstat *stat, u32 request_mask, unsigned int query_flags)  {  	struct inode *inode = d_inode(path->dentry); @@ -843,7 +845,8 @@ int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,  	request_mask &= STATX_TYPE | STATX_MODE | STATX_NLINK | STATX_UID |  			STATX_GID | STATX_ATIME | STATX_MTIME | STATX_CTIME | -			STATX_INO | STATX_SIZE | STATX_BLOCKS; +			STATX_INO | STATX_SIZE | STATX_BLOCKS | STATX_BTIME | +			STATX_CHANGE_COOKIE;  	if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {  		if (readdirplus_enabled) @@ -851,8 +854,8 @@ int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,  		goto out_no_revalidate;  	} -	/* Flush out writes to the server in order to update c/mtime.  */ -	if ((request_mask & (STATX_CTIME | STATX_MTIME)) && +	/* Flush out writes to the server in order to update c/mtime/version.  */ +	if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_CHANGE_COOKIE)) &&  	    S_ISREG(inode->i_mode))  		filemap_write_and_wait(inode->i_mapping); @@ -872,7 +875,8 @@ int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,  	/* Is the user requesting attributes that might need revalidation? */  	if (!(request_mask & (STATX_MODE|STATX_NLINK|STATX_ATIME|STATX_CTIME|  					STATX_MTIME|STATX_UID|STATX_GID| -					STATX_SIZE|STATX_BLOCKS))) +					STATX_SIZE|STATX_BLOCKS| +					STATX_CHANGE_COOKIE)))  		goto out_no_revalidate;  	/* Check whether the cached attributes are stale */ @@ -908,8 +912,12 @@ out_no_revalidate:  	/* Only return attributes that were revalidated. */  	stat->result_mask = nfs_get_valid_attrmask(inode) | request_mask; -	generic_fillattr(&init_user_ns, inode, stat); +	generic_fillattr(&nop_mnt_idmap, inode, stat);  	stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); +	stat->change_cookie = inode_peek_iversion_raw(inode); +	stat->attributes_mask |= STATX_ATTR_CHANGE_MONOTONIC; +	if (server->change_attr_type != NFS4_CHANGE_TYPE_IS_UNDEFINED) +		stat->attributes |= STATX_ATTR_CHANGE_MONOTONIC;  	if (S_ISDIR(inode->i_mode))  		stat->blksize = NFS_SERVER(inode)->dtsize;  out:  |