diff options
Diffstat (limited to 'fs/nfs/inode.c')
| -rw-r--r-- | fs/nfs/inode.c | 43 | 
1 files changed, 36 insertions, 7 deletions
| diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 326d9e10d833..bdb4dc7b4ecd 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -75,11 +75,11 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)   * nfs_wait_bit_killable - helper for functions that are sleeping on bit locks   * @word: long word containing the bit lock   */ -int nfs_wait_bit_killable(struct wait_bit_key *key) +int nfs_wait_bit_killable(struct wait_bit_key *key, int mode)  { -	if (fatal_signal_pending(current)) -		return -ERESTARTSYS;  	freezable_schedule_unsafe(); +	if (signal_pending_state(mode, current)) +		return -ERESTARTSYS;  	return 0;  }  EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); @@ -408,9 +408,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st  				inode->i_fop = NULL;  				inode->i_flags |= S_AUTOMOUNT;  			} -		} else if (S_ISLNK(inode->i_mode)) +		} else if (S_ISLNK(inode->i_mode)) {  			inode->i_op = &nfs_symlink_inode_operations; -		else +			inode_nohighmem(inode); +		} else  			init_special_inode(inode, inode->i_mode, fattr->rdev);  		memset(&inode->i_atime, 0, sizeof(inode->i_atime)); @@ -618,7 +619,10 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,  		nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);  		nfs_vmtruncate(inode, attr->ia_size);  	} -	nfs_update_inode(inode, fattr); +	if (fattr->valid) +		nfs_update_inode(inode, fattr); +	else +		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;  	spin_unlock(&inode->i_lock);  }  EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); @@ -1083,6 +1087,27 @@ static bool nfs_mapping_need_revalidate_inode(struct inode *inode)  		|| NFS_STALE(inode);  } +int nfs_revalidate_mapping_rcu(struct inode *inode) +{ +	struct nfs_inode *nfsi = NFS_I(inode); +	unsigned long *bitlock = &nfsi->flags; +	int ret = 0; + +	if (IS_SWAPFILE(inode)) +		goto out; +	if (nfs_mapping_need_revalidate_inode(inode)) { +		ret = -ECHILD; +		goto out; +	} +	spin_lock(&inode->i_lock); +	if (test_bit(NFS_INO_INVALIDATING, bitlock) || +	    (nfsi->cache_validity & NFS_INO_INVALID_DATA)) +		ret = -ECHILD; +	spin_unlock(&inode->i_lock); +out: +	return ret; +} +  /**   * __nfs_revalidate_mapping - Revalidate the pagecache   * @inode - pointer to host inode @@ -1824,7 +1849,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)  		if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0)  			nfsi->attr_gencount = fattr->gencount;  	} -	invalid &= ~NFS_INO_INVALID_ATTR; + +	/* Don't declare attrcache up to date if there were no attrs! */ +	if (fattr->valid != 0) +		invalid &= ~NFS_INO_INVALID_ATTR; +  	/* 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))) | 
