NFS: Clean up cache validity checking

Consolidate the open-coded checking of NFS_I(inode)->cache_validity
into a couple of helper functions.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
Trond Myklebust 2016-12-08 18:18:38 -05:00
Родитель 58ff41842c
Коммит 61540bf6bb
3 изменённых файлов: 34 добавлений и 22 удалений

Просмотреть файл

@ -101,21 +101,11 @@ EXPORT_SYMBOL_GPL(nfs_file_release);
static int nfs_revalidate_file_size(struct inode *inode, struct file *filp) static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
{ {
struct nfs_server *server = NFS_SERVER(inode); struct nfs_server *server = NFS_SERVER(inode);
struct nfs_inode *nfsi = NFS_I(inode);
const unsigned long force_reval = NFS_INO_REVAL_PAGECACHE|NFS_INO_REVAL_FORCED;
unsigned long cache_validity = nfsi->cache_validity;
if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) &&
(cache_validity & force_reval) != force_reval)
goto out_noreval;
if (filp->f_flags & O_DIRECT) if (filp->f_flags & O_DIRECT)
goto force_reval; goto force_reval;
if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) if (nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE))
goto force_reval; goto force_reval;
if (nfs_attribute_timeout(inode))
goto force_reval;
out_noreval:
return 0; return 0;
force_reval: force_reval:
return __nfs_revalidate_inode(server, inode); return __nfs_revalidate_inode(server, inode);

Просмотреть файл

@ -160,6 +160,36 @@ int nfs_sync_mapping(struct address_space *mapping)
return ret; return ret;
} }
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) static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
{ {
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
@ -1116,17 +1146,8 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
bool nfs_mapping_need_revalidate_inode(struct inode *inode) bool nfs_mapping_need_revalidate_inode(struct inode *inode)
{ {
unsigned long cache_validity = NFS_I(inode)->cache_validity; return nfs_check_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE) ||
NFS_STALE(inode);
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);
} }
int nfs_revalidate_mapping_rcu(struct inode *inode) int nfs_revalidate_mapping_rcu(struct inode *inode)

Просмотреть файл

@ -381,6 +381,7 @@ extern int nfs_drop_inode(struct inode *);
extern void nfs_clear_inode(struct inode *); extern void nfs_clear_inode(struct inode *);
extern void nfs_evict_inode(struct inode *); extern void nfs_evict_inode(struct inode *);
void nfs_zap_acl_cache(struct inode *inode); void nfs_zap_acl_cache(struct inode *inode);
extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode); extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
extern int nfs_wait_atomic_killable(atomic_t *p); extern int nfs_wait_atomic_killable(atomic_t *p);