diff options
Diffstat (limited to 'fs/nfs/inode.c')
| -rw-r--r-- | fs/nfs/inode.c | 273 | 
1 files changed, 179 insertions, 94 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index eda8879171c..9927913c97c 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -122,13 +122,13 @@ void nfs_clear_inode(struct inode *inode)  	WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files));  	nfs_zap_acl_cache(inode);  	nfs_access_zap_cache(inode); -	nfs_fscache_release_inode_cookie(inode); +	nfs_fscache_clear_inode(inode);  }  EXPORT_SYMBOL_GPL(nfs_clear_inode);  void nfs_evict_inode(struct inode *inode)  { -	truncate_inode_pages(&inode->i_data, 0); +	truncate_inode_pages_final(&inode->i_data);  	clear_inode(inode);  	nfs_clear_inode(inode);  } @@ -147,6 +147,17 @@ int nfs_sync_mapping(struct address_space *mapping)  	return ret;  } +static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) +{ +	struct nfs_inode *nfsi = NFS_I(inode); + +	if (inode->i_mapping->nrpages == 0) +		flags &= ~NFS_INO_INVALID_DATA; +	nfsi->cache_validity |= flags; +	if (flags & NFS_INO_INVALID_DATA) +		nfs_fscache_invalidate(inode); +} +  /*   * Invalidate the local caches   */ @@ -162,19 +173,17 @@ static void nfs_zap_caches_locked(struct inode *inode)  	memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf));  	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { -		nfs_fscache_invalidate(inode); -		nfsi->cache_validity |= NFS_INO_INVALID_ATTR -					| NFS_INO_INVALID_LABEL +		nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR  					| NFS_INO_INVALID_DATA  					| NFS_INO_INVALID_ACCESS  					| NFS_INO_INVALID_ACL -					| NFS_INO_REVAL_PAGECACHE; +					| NFS_INO_REVAL_PAGECACHE);  	} else -		nfsi->cache_validity |= NFS_INO_INVALID_ATTR -					| NFS_INO_INVALID_LABEL +		nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR  					| NFS_INO_INVALID_ACCESS  					| NFS_INO_INVALID_ACL -					| NFS_INO_REVAL_PAGECACHE; +					| NFS_INO_REVAL_PAGECACHE); +	nfs_zap_label_cache_locked(nfsi);  }  void nfs_zap_caches(struct inode *inode) @@ -188,8 +197,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)  {  	if (mapping->nrpages != 0) {  		spin_lock(&inode->i_lock); -		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; -		nfs_fscache_invalidate(inode); +		nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);  		spin_unlock(&inode->i_lock);  	}  } @@ -210,7 +218,7 @@ EXPORT_SYMBOL_GPL(nfs_zap_acl_cache);  void nfs_invalidate_atime(struct inode *inode)  {  	spin_lock(&inode->i_lock); -	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; +	nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME);  	spin_unlock(&inode->i_lock);  }  EXPORT_SYMBOL_GPL(nfs_invalidate_atime); @@ -266,6 +274,13 @@ nfs_init_locked(struct inode *inode, void *opaque)  }  #ifdef CONFIG_NFS_V4_SECURITY_LABEL +static void nfs_clear_label_invalid(struct inode *inode) +{ +	spin_lock(&inode->i_lock); +	NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_LABEL; +	spin_unlock(&inode->i_lock); +} +  void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,  					struct nfs4_label *label)  { @@ -274,12 +289,6 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,  	if (label == NULL)  		return; -	if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL) == 0) -		return; - -	if (NFS_SERVER(inode)->nfs_client->cl_minorversion < 2) -		return; -  	if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) {  		error = security_inode_notifysecctx(inode, label->label,  				label->len); @@ -289,6 +298,7 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,  					__func__,  					(char *)label->label,  					label->len, error); +		nfs_clear_label_invalid(inode);  	}  } @@ -318,7 +328,7 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags)  }  EXPORT_SYMBOL_GPL(nfs4_label_alloc);  #else -void inline nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, +void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,  					struct nfs4_label *label)  {  } @@ -368,7 +378,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st  		inode->i_mode = fattr->mode;  		if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0  				&& nfs_server_capable(inode, NFS_CAP_MODE)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		/* Why so? Because we want revalidate for devices/FIFOs, and  		 * that's precisely what we have in nfs_file_inode_operations.  		 */ @@ -414,36 +424,36 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st  		if (fattr->valid & NFS_ATTR_FATTR_ATIME)  			inode->i_atime = fattr->atime;  		else if (nfs_server_capable(inode, NFS_CAP_ATIME)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		if (fattr->valid & NFS_ATTR_FATTR_MTIME)  			inode->i_mtime = fattr->mtime;  		else if (nfs_server_capable(inode, NFS_CAP_MTIME)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		if (fattr->valid & NFS_ATTR_FATTR_CTIME)  			inode->i_ctime = fattr->ctime;  		else if (nfs_server_capable(inode, NFS_CAP_CTIME)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		if (fattr->valid & NFS_ATTR_FATTR_CHANGE)  			inode->i_version = fattr->change_attr;  		else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		if (fattr->valid & NFS_ATTR_FATTR_SIZE)  			inode->i_size = nfs_size_to_loff_t(fattr->size);  		else -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR -				| NFS_INO_REVAL_PAGECACHE; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR +				| NFS_INO_REVAL_PAGECACHE);  		if (fattr->valid & NFS_ATTR_FATTR_NLINK)  			set_nlink(inode, fattr->nlink);  		else if (nfs_server_capable(inode, NFS_CAP_NLINK)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		if (fattr->valid & NFS_ATTR_FATTR_OWNER)  			inode->i_uid = fattr->uid;  		else if (nfs_server_capable(inode, NFS_CAP_OWNER)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		if (fattr->valid & NFS_ATTR_FATTR_GROUP)  			inode->i_gid = fattr->gid;  		else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) -			nfsi->cache_validity |= NFS_INO_INVALID_ATTR; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);  		if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)  			inode->i_blocks = fattr->du.nfs2.blocks;  		if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { @@ -459,14 +469,14 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st  		nfsi->attrtimeo_timestamp = now;  		nfsi->access_cache = RB_ROOT; -		nfs_fscache_init_inode_cookie(inode); +		nfs_fscache_init_inode(inode);  		unlock_new_inode(inode);  	} else  		nfs_refresh_inode(inode, fattr); -	dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", +	dprintk("NFS: nfs_fhget(%s/%Lu fh_crc=0x%08x ct=%d)\n",  		inode->i_sb->s_id, -		(long long)NFS_FILEID(inode), +		(unsigned long long)NFS_FILEID(inode),  		nfs_display_fhandle_hash(fh),  		atomic_read(&inode->i_count)); @@ -549,6 +559,9 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset)  	spin_lock(&inode->i_lock);  	i_size_write(inode, offset); +	/* Optimisation */ +	if (offset == 0) +		NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA;  	spin_unlock(&inode->i_lock);  	truncate_pagecache(inode, offset); @@ -577,7 +590,8 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)  			inode->i_uid = attr->ia_uid;  		if ((attr->ia_valid & ATTR_GID) != 0)  			inode->i_gid = attr->ia_gid; -		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; +		nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS +				| NFS_INO_INVALID_ACL);  		spin_unlock(&inode->i_lock);  	}  	if ((attr->ia_valid & ATTR_SIZE) != 0) { @@ -587,6 +601,25 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)  }  EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); +static void nfs_request_parent_use_readdirplus(struct dentry *dentry) +{ +	struct dentry *parent; + +	parent = dget_parent(dentry); +	nfs_force_use_readdirplus(parent->d_inode); +	dput(parent); +} + +static bool nfs_need_revalidate_inode(struct inode *inode) +{ +	if (NFS_I(inode)->cache_validity & +			(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) +		return true; +	if (nfs_attribute_cache_expired(inode)) +		return true; +	return false; +} +  int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)  {  	struct inode *inode = dentry->d_inode; @@ -615,10 +648,13 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)   	    ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))  		need_atime = 0; -	if (need_atime) -		err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); -	else -		err = nfs_revalidate_inode(NFS_SERVER(inode), inode); +	if (need_atime || nfs_need_revalidate_inode(inode)) { +		struct nfs_server *server = NFS_SERVER(inode); + +		if (server->caps & NFS_CAP_READDIRPLUS) +			nfs_request_parent_use_readdirplus(dentry); +		err = __nfs_revalidate_inode(server, inode); +	}  	if (!err) {  		generic_fillattr(inode, stat);  		stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); @@ -854,7 +890,7 @@ int nfs_open(struct inode *inode, struct file *filp)  		return PTR_ERR(ctx);  	nfs_file_set_open_context(filp, ctx);  	put_nfs_open_context(ctx); -	nfs_fscache_set_inode_cookie(inode, filp); +	nfs_fscache_open_file(inode, filp);  	return 0;  } @@ -876,8 +912,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  	struct nfs_fattr *fattr = NULL;  	struct nfs_inode *nfsi = NFS_I(inode); -	dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", -		inode->i_sb->s_id, (long long)NFS_FILEID(inode)); +	dfprintk(PAGECACHE, "NFS: revalidating (%s/%Lu)\n", +		inode->i_sb->s_id, (unsigned long long)NFS_FILEID(inode));  	trace_nfs_revalidate_inode_enter(inode); @@ -901,9 +937,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr, label);  	if (status != 0) { -		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", +		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n",  			 inode->i_sb->s_id, -			 (long long)NFS_FILEID(inode), status); +			 (unsigned long long)NFS_FILEID(inode), status);  		if (status == -ESTALE) {  			nfs_zap_caches(inode);  			if (!S_ISDIR(inode->i_mode)) @@ -914,18 +950,20 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  	status = nfs_refresh_inode(inode, fattr);  	if (status) { -		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", +		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) refresh failed, error=%d\n",  			 inode->i_sb->s_id, -			 (long long)NFS_FILEID(inode), status); +			 (unsigned long long)NFS_FILEID(inode), status);  		goto err_out;  	}  	if (nfsi->cache_validity & NFS_INO_INVALID_ACL)  		nfs_zap_acl_cache(inode); -	dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", +	nfs_setsecurity(inode, fattr, label); + +	dfprintk(PAGECACHE, "NFS: (%s/%Lu) revalidation complete\n",  		inode->i_sb->s_id, -		(long long)NFS_FILEID(inode)); +		(unsigned long long)NFS_FILEID(inode));  err_out:  	nfs4_label_free(label); @@ -958,9 +996,7 @@ int nfs_attribute_cache_expired(struct inode *inode)   */  int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)  { -	if (!(NFS_I(inode)->cache_validity & -			(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) -			&& !nfs_attribute_cache_expired(inode)) +	if (!nfs_need_revalidate_inode(inode))  		return NFS_STALE(inode) ? -ESTALE : 0;  	return __nfs_revalidate_inode(server, inode);  } @@ -981,16 +1017,17 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map  		if (ret < 0)  			return ret;  	} -	spin_lock(&inode->i_lock); -	nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; -	if (S_ISDIR(inode->i_mode)) +	if (S_ISDIR(inode->i_mode)) { +		spin_lock(&inode->i_lock);  		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); -	spin_unlock(&inode->i_lock); +		spin_unlock(&inode->i_lock); +	}  	nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);  	nfs_fscache_wait_on_invalidate(inode); -	dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", -			inode->i_sb->s_id, (long long)NFS_FILEID(inode)); +	dfprintk(PAGECACHE, "NFS: (%s/%Lu) data cache invalidated\n", +			inode->i_sb->s_id, +			(unsigned long long)NFS_FILEID(inode));  	return 0;  } @@ -1011,6 +1048,7 @@ static bool nfs_mapping_need_revalidate_inode(struct inode *inode)  int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)  {  	struct nfs_inode *nfsi = NFS_I(inode); +	unsigned long *bitlock = &nfsi->flags;  	int ret = 0;  	/* swapfiles are not supposed to be shared. */ @@ -1022,12 +1060,46 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)  		if (ret < 0)  			goto out;  	} -	if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { -		trace_nfs_invalidate_mapping_enter(inode); -		ret = nfs_invalidate_mapping(inode, mapping); -		trace_nfs_invalidate_mapping_exit(inode, ret); + +	/* +	 * We must clear NFS_INO_INVALID_DATA first to ensure that +	 * invalidations that come in while we're shooting down the mappings +	 * are respected. But, that leaves a race window where one revalidator +	 * can clear the flag, and then another checks it before the mapping +	 * gets invalidated. Fix that by serializing access to this part of +	 * the function. +	 * +	 * At the same time, we need to allow other tasks to see whether we +	 * might be in the middle of invalidating the pages, so we only set +	 * the bit lock here if it looks like we're going to be doing that. +	 */ +	for (;;) { +		ret = wait_on_bit(bitlock, NFS_INO_INVALIDATING, +				  nfs_wait_bit_killable, TASK_KILLABLE); +		if (ret) +			goto out; +		spin_lock(&inode->i_lock); +		if (test_bit(NFS_INO_INVALIDATING, bitlock)) { +			spin_unlock(&inode->i_lock); +			continue; +		} +		if (nfsi->cache_validity & NFS_INO_INVALID_DATA) +			break; +		spin_unlock(&inode->i_lock); +		goto out;  	} +	set_bit(NFS_INO_INVALIDATING, bitlock); +	smp_wmb(); +	nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; +	spin_unlock(&inode->i_lock); +	trace_nfs_invalidate_mapping_enter(inode); +	ret = nfs_invalidate_mapping(inode, mapping); +	trace_nfs_invalidate_mapping_exit(inode, ret); + +	clear_bit_unlock(NFS_INO_INVALIDATING, bitlock); +	smp_mb__after_atomic(); +	wake_up_bit(bitlock, NFS_INO_INVALIDATING);  out:  	return ret;  } @@ -1042,7 +1114,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr  			&& inode->i_version == fattr->pre_change_attr) {  		inode->i_version = fattr->change_attr;  		if (S_ISDIR(inode->i_mode)) -			nfsi->cache_validity |= NFS_INO_INVALID_DATA; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);  		ret |= NFS_INO_INVALID_ATTR;  	}  	/* If we have atomic WCC data, we may update some attributes */ @@ -1058,7 +1130,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr  			&& timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {  		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));  		if (S_ISDIR(inode->i_mode)) -			nfsi->cache_validity |= NFS_INO_INVALID_DATA; +			nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);  		ret |= NFS_INO_INVALID_ATTR;  	}  	if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) @@ -1069,9 +1141,6 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr  		ret |= NFS_INO_INVALID_ATTR;  	} -	if (nfsi->cache_validity & NFS_INO_INVALID_DATA) -		nfs_fscache_invalidate(inode); -  	return ret;  } @@ -1130,7 +1199,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat  		invalid |= NFS_INO_INVALID_ATIME;  	if (invalid != 0) -		nfsi->cache_validity |= invalid; +		nfs_set_cache_invalid(inode, invalid);  	nfsi->read_cache_jiffies = fattr->time_start;  	return 0; @@ -1209,6 +1278,7 @@ u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh)  	 * not on the result */  	return nfs_fhandle_hash(fh);  } +EXPORT_SYMBOL_GPL(_nfs_display_fhandle_hash);  /*   * _nfs_display_fhandle - display an NFS file handle on the console @@ -1253,6 +1323,7 @@ void _nfs_display_fhandle(const struct nfs_fh *fh, const char *caption)  		}  	}  } +EXPORT_SYMBOL_GPL(_nfs_display_fhandle);  #endif  /** @@ -1284,12 +1355,28 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n  		((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0);  } +/* + * Don't trust the change_attribute, mtime, ctime or size if + * a pnfs LAYOUTCOMMIT is outstanding + */ +static void nfs_inode_attrs_handle_layoutcommit(struct inode *inode, +		struct nfs_fattr *fattr) +{ +	if (pnfs_layoutcommit_outstanding(inode)) +		fattr->valid &= ~(NFS_ATTR_FATTR_CHANGE | +				NFS_ATTR_FATTR_MTIME | +				NFS_ATTR_FATTR_CTIME | +				NFS_ATTR_FATTR_SIZE); +} +  static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)  {  	int ret;  	trace_nfs_refresh_inode_enter(inode); +	nfs_inode_attrs_handle_layoutcommit(inode, fattr); +  	if (nfs_inode_attrs_need_update(inode, fattr))  		ret = nfs_update_inode(inode, fattr);  	else @@ -1325,13 +1412,11 @@ EXPORT_SYMBOL_GPL(nfs_refresh_inode);  static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)  { -	struct nfs_inode *nfsi = NFS_I(inode); +	unsigned long invalid = NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; -	nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; -	if (S_ISDIR(inode->i_mode)) { -		nfsi->cache_validity |= NFS_INO_INVALID_DATA; -		nfs_fscache_invalidate(inode); -	} +	if (S_ISDIR(inode->i_mode)) +		invalid |= NFS_INO_INVALID_DATA; +	nfs_set_cache_invalid(inode, invalid);  	if ((fattr->valid & NFS_ATTR_FATTR) == 0)  		return 0;  	return nfs_refresh_inode_locked(inode, fattr); @@ -1436,7 +1521,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  	unsigned long now = jiffies;  	unsigned long save_cache_validity; -	dfprintk(VFS, "NFS: %s(%s/%ld fh_crc=0x%08x ct=%d info=0x%x)\n", +	dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",  			__func__, inode->i_sb->s_id, inode->i_ino,  			nfs_display_fhandle_hash(NFS_FH(inode)),  			atomic_read(&inode->i_count), fattr->valid); @@ -1457,7 +1542,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  		/*  		* Big trouble! The inode has become a different object.  		*/ -		printk(KERN_DEBUG "NFS: %s: inode %ld mode changed, %07o to %07o\n", +		printk(KERN_DEBUG "NFS: %s: inode %lu mode changed, %07o to %07o\n",  				__func__, inode->i_ino, inode->i_mode, fattr->mode);  		goto out_err;  	} @@ -1498,18 +1583,20 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			inode->i_version = fattr->change_attr;  		}  	} else if (server->caps & NFS_CAP_CHANGE_ATTR) -		invalid |= save_cache_validity; +		nfsi->cache_validity |= save_cache_validity;  	if (fattr->valid & NFS_ATTR_FATTR_MTIME) {  		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));  	} else if (server->caps & NFS_CAP_MTIME) -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATTR  				| NFS_INO_REVAL_FORCED);  	if (fattr->valid & NFS_ATTR_FATTR_CTIME) {  		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));  	} else if (server->caps & NFS_CAP_CTIME) -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATTR  				| NFS_INO_REVAL_FORCED);  	/* Check if our cached file size is stale */ @@ -1519,10 +1606,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  		if (new_isize != cur_isize) {  			/* Do we perhaps have any outstanding writes, or has  			 * the file grown beyond our last write? */ -			if ((nfsi->npages == 0 && !test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) || -			     new_isize > cur_isize) { +			if ((nfsi->npages == 0) || new_isize > cur_isize) {  				i_size_write(inode, new_isize);  				invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; +				invalid &= ~NFS_INO_REVAL_PAGECACHE;  			}  			dprintk("NFS: isize change on server for file %s/%ld "  					"(%Ld to %Ld)\n", @@ -1532,7 +1619,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  					(long long)new_isize);  		}  	} else -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATTR  				| NFS_INO_REVAL_PAGECACHE  				| NFS_INO_REVAL_FORCED); @@ -1540,7 +1628,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  	if (fattr->valid & NFS_ATTR_FATTR_ATIME)  		memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));  	else if (server->caps & NFS_CAP_ATIME) -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATIME +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATIME  				| NFS_INO_REVAL_FORCED);  	if (fattr->valid & NFS_ATTR_FATTR_MODE) { @@ -1551,7 +1640,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;  		}  	} else if (server->caps & NFS_CAP_MODE) -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATTR  				| NFS_INO_INVALID_ACCESS  				| NFS_INO_INVALID_ACL  				| NFS_INO_REVAL_FORCED); @@ -1562,7 +1652,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			inode->i_uid = fattr->uid;  		}  	} else if (server->caps & NFS_CAP_OWNER) -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATTR  				| NFS_INO_INVALID_ACCESS  				| NFS_INO_INVALID_ACL  				| NFS_INO_REVAL_FORCED); @@ -1573,7 +1664,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			inode->i_gid = fattr->gid;  		}  	} else if (server->caps & NFS_CAP_OWNER_GROUP) -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATTR  				| NFS_INO_INVALID_ACCESS  				| NFS_INO_INVALID_ACL  				| NFS_INO_REVAL_FORCED); @@ -1586,7 +1678,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  			set_nlink(inode, fattr->nlink);  		}  	} else if (server->caps & NFS_CAP_NLINK) -		invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR +		nfsi->cache_validity |= save_cache_validity & +				(NFS_INO_INVALID_ATTR  				| NFS_INO_REVAL_FORCED);  	if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { @@ -1599,7 +1692,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  		inode->i_blocks = fattr->du.nfs2.blocks;  	/* Update attrtimeo value if we're out of the unstable period */ -	if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) { +	if (invalid & NFS_INO_INVALID_ATTR) {  		nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);  		nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);  		nfsi->attrtimeo_timestamp = now; @@ -1612,17 +1705,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  		}  	}  	invalid &= ~NFS_INO_INVALID_ATTR; -	invalid &= ~NFS_INO_INVALID_LABEL;  	/* Don't invalidate the data if we were to blame */  	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)  				|| S_ISLNK(inode->i_mode)))  		invalid &= ~NFS_INO_INVALID_DATA;  	if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) ||  			(save_cache_validity & NFS_INO_REVAL_FORCED)) -		nfsi->cache_validity |= invalid; - -	if (invalid & NFS_INO_INVALID_DATA) -		nfs_fscache_invalidate(inode); +		nfs_set_cache_invalid(inode, invalid);  	return 0;   out_err: @@ -1643,10 +1732,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb)  		return NULL;  	nfsi->flags = 0UL;  	nfsi->cache_validity = 0UL; -#ifdef CONFIG_NFS_V3_ACL -	nfsi->acl_access = ERR_PTR(-EAGAIN); -	nfsi->acl_default = ERR_PTR(-EAGAIN); -#endif  #if IS_ENABLED(CONFIG_NFS_V4)  	nfsi->nfs4_acl = NULL;  #endif /* CONFIG_NFS_V4 */  | 
