NFS: Fix races in nfs_revalidate_mapping
Commit d529ef83c3
(NFS: fix the handling
of NFS_INO_INVALID_DATA flag in nfs_revalidate_mapping) introduces
a potential race, since it doesn't test the value of nfsi->cache_validity
and set the bitlock in nfsi->flags atomically.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Cc: Jeff Layton <jlayton@redhat.com>
This commit is contained in:
parent
0ea9de0ea6
commit
17dfeb9113
|
@ -1038,23 +1038,23 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
|
||||||
nfs_wait_bit_killable, TASK_KILLABLE);
|
nfs_wait_bit_killable, TASK_KILLABLE);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
if (!(nfsi->cache_validity & NFS_INO_INVALID_DATA))
|
spin_lock(&inode->i_lock);
|
||||||
goto out;
|
if (test_bit(NFS_INO_INVALIDATING, bitlock)) {
|
||||||
if (!test_and_set_bit_lock(NFS_INO_INVALIDATING, bitlock))
|
spin_unlock(&inode->i_lock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
|
||||||
break;
|
break;
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
set_bit(NFS_INO_INVALIDATING, bitlock);
|
||||||
if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
|
nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
|
||||||
nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
|
spin_unlock(&inode->i_lock);
|
||||||
spin_unlock(&inode->i_lock);
|
trace_nfs_invalidate_mapping_enter(inode);
|
||||||
trace_nfs_invalidate_mapping_enter(inode);
|
ret = nfs_invalidate_mapping(inode, mapping);
|
||||||
ret = nfs_invalidate_mapping(inode, mapping);
|
trace_nfs_invalidate_mapping_exit(inode, ret);
|
||||||
trace_nfs_invalidate_mapping_exit(inode, ret);
|
|
||||||
} else {
|
|
||||||
/* something raced in and cleared the flag */
|
|
||||||
spin_unlock(&inode->i_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_bit_unlock(NFS_INO_INVALIDATING, bitlock);
|
clear_bit_unlock(NFS_INO_INVALIDATING, bitlock);
|
||||||
smp_mb__after_clear_bit();
|
smp_mb__after_clear_bit();
|
||||||
|
|
Loading…
Reference in New Issue