Merge tag 'nfs-for-4.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull more NFS client updates from Trond Myklebust:
 "Highlights include:

   - further attribute cache improvements to make revalidation more fine
     grained

   - NFSv4 locking improvements

  Bugfixes:

   - nfs4_fl_prepare_ds must be careful about reporting success in files
     layout

   - pNFS/flexfiles: Instead of marking a device inactive, remove it
     from the cache"

* tag 'nfs-for-4.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFSv4: Retry the DELEGRETURN if the embedded GETATTR is rejected with EACCES
  NFS: Retry the CLOSE if the embedded GETATTR is rejected with EACCES
  NFSv4: Place the GETATTR operation before the CLOSE
  NFSv4: Also ask for attributes when downgrading to a READ-only state
  NFS: Don't abuse NFS_INO_REVAL_FORCED in nfs_post_op_update_inode_locked()
  pNFS: Return RW layouts on OPEN_DOWNGRADE
  NFSv4: Add encode/decode of the layoutreturn op in OPEN_DOWNGRADE
  NFS: Don't disconnect open-owner on NFS4ERR_BAD_SEQID
  NFSv4: ensure __nfs4_find_lock_state returns consistent result.
  NFSv4.1: nfs4_fl_prepare_ds must be careful about reporting success.
  pNFS/flexfiles: delete deviceid, don't mark inactive
  NFS: Clean up nfs_attribute_timeout()
  NFS: Remove unused function nfs_revalidate_inode_rcu()
  NFS: Fix and clean up the access cache validity checking
  NFS: Only look at the change attribute cache state in nfs_weak_revalidate()
  NFS: Clean up cache validity checking
  NFS: Don't revalidate the file on close if we hold a delegation
  NFSv4: Don't discard the attributes returned by asynchronous DELEGRETURN
  NFSv4: Update the attribute cache info in update_changeattr
This commit is contained in:
Linus Torvalds
2016-12-21 10:40:30 -08:00
12 changed files with 165 additions and 110 deletions

View File

@@ -160,6 +160,43 @@ int nfs_sync_mapping(struct address_space *mapping)
return ret;
}
static int nfs_attribute_timeout(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}
static bool nfs_check_cache_invalid_delegated(struct inode *inode, unsigned long flags)
{
unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
/* Special case for the pagecache or access cache */
if (flags == NFS_INO_REVAL_PAGECACHE &&
!(cache_validity & NFS_INO_REVAL_FORCED))
return false;
return (cache_validity & flags) != 0;
}
static bool nfs_check_cache_invalid_not_delegated(struct inode *inode, unsigned long flags)
{
unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
if ((cache_validity & flags) != 0)
return true;
if (nfs_attribute_timeout(inode))
return true;
return false;
}
bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
{
if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
return nfs_check_cache_invalid_delegated(inode, flags);
return nfs_check_cache_invalid_not_delegated(inode, flags);
}
static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
{
struct nfs_inode *nfsi = NFS_I(inode);
@@ -795,6 +832,8 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
if (!is_sync)
return;
inode = d_inode(ctx->dentry);
if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
return;
nfsi = NFS_I(inode);
if (inode->i_mapping->nrpages == 0)
return;
@@ -1044,13 +1083,6 @@ out:
return status;
}
int nfs_attribute_timeout(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}
int nfs_attribute_cache_expired(struct inode *inode)
{
if (nfs_have_delegated_attributes(inode))
@@ -1073,15 +1105,6 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
}
EXPORT_SYMBOL_GPL(nfs_revalidate_inode);
int nfs_revalidate_inode_rcu(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))
return NFS_STALE(inode) ? -ESTALE : 0;
return -ECHILD;
}
static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
{
struct nfs_inode *nfsi = NFS_I(inode);
@@ -1114,17 +1137,8 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
bool nfs_mapping_need_revalidate_inode(struct inode *inode)
{
unsigned long cache_validity = NFS_I(inode)->cache_validity;
if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) {
const unsigned long force_reval =
NFS_INO_REVAL_PAGECACHE|NFS_INO_REVAL_FORCED;
return (cache_validity & force_reval) == force_reval;
}
return (cache_validity & NFS_INO_REVAL_PAGECACHE)
|| nfs_attribute_timeout(inode)
|| NFS_STALE(inode);
return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
NFS_STALE(inode);
}
int nfs_revalidate_mapping_rcu(struct inode *inode)
@@ -1536,13 +1550,6 @@ static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr
{
unsigned long invalid = NFS_INO_INVALID_ATTR;
/*
* Don't revalidate the pagecache if we hold a delegation, but do
* force an attribute update
*/
if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
invalid = NFS_INO_INVALID_ATTR|NFS_INO_REVAL_FORCED;
if (S_ISDIR(inode->i_mode))
invalid |= NFS_INO_INVALID_DATA;
nfs_set_cache_invalid(inode, invalid);