for-5.3-rc1-tag

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAl07KzUACgkQxWXV+ddt
 WDs6Ow/+LQ4He5jW+xpgZ+5fSnSjervfSsYWxKARc4hYZog5l8e2ONASzrniKR0H
 aU2SWUyLF0Os1w++vp1FYYwa1xaPJJRTvlqTI6DSCFgEpu9DefXkCAFuP/+fXbhC
 Fx+ZDAbqgY2gUCEWcs4jQusSgz1sO0m97SJR7K4Vz+ZaBa+eneE5Hkm4kZd8AXg6
 ufKkjOD0+Vy+CUVBZdPg8RlU5KRJ+yAE7B2CRyuSeq6cF0LxTxoNeAtWz5KWd6Pn
 aNWDqa07na4kQz/p5s7Bw6qPC6i4hTdnNKVcc8N79iyz2TAetbjN8VXfbFFVCLZ9
 3+9O/kFCh+ZolgV1f9U8iLwSbg7V/8wu1uUdR3645cq2PQljluMJEHPSWOmm+LVw
 nOhm8VQiGsILbEYLRJbM3wI8dT4B0PtgP9IqYuk7TLV3qho6Pg8J2nyfpo5jehs5
 IP0gDanCBHYgsoCUwZwnJaKH3hIP2+5IJw6AqX0Lt6ge9aYA35+kWR4KE5459Pxw
 n0Eoiu+5y9QcfpgUuzb5EQIxHdRNlCjik70+n1yXBwwPtV9b6wDN9TlP3eI7p/Vx
 j+FUYcgrjwjfAP7Eh5a/ne/XEcq1R5UghM+2TWEWpqGh11NPnMDJS6d4OYyeCvA6
 yPLAhVvvqdbYM+PpALaNjvLxspxd6MSuKNLNk3pkJmkd69IXnXw=
 =RT/D
 -----END PGP SIGNATURE-----

Merge tag 'for-5.3-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:
 "Two regression fixes:

   - hangs caused by a missing barrier in the locking code

   - memory leaks of extent_state due to bad handling of a cached
     pointer"

* tag 'for-5.3-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix extent_state leak in btrfs_lock_and_flush_ordered_range
  btrfs: Fix deadlock caused by missing memory barrier
This commit is contained in:
Linus Torvalds 2019-07-26 11:08:37 -07:00
commit 4792ba1f1f
2 changed files with 12 additions and 8 deletions

View File

@ -346,9 +346,12 @@ void btrfs_tree_unlock(struct extent_buffer *eb)
if (blockers) { if (blockers) {
btrfs_assert_no_spinning_writers(eb); btrfs_assert_no_spinning_writers(eb);
eb->blocking_writers--; eb->blocking_writers--;
/* Use the lighter barrier after atomic */ /*
smp_mb__after_atomic(); * We need to order modifying blocking_writers above with
cond_wake_up_nomb(&eb->write_lock_wq); * actually waking up the sleepers to ensure they see the
* updated value of blocking_writers
*/
cond_wake_up(&eb->write_lock_wq);
} else { } else {
btrfs_assert_spinning_writers_put(eb); btrfs_assert_spinning_writers_put(eb);
write_unlock(&eb->lock); write_unlock(&eb->lock);

View File

@ -985,13 +985,14 @@ void btrfs_lock_and_flush_ordered_range(struct extent_io_tree *tree,
struct extent_state **cached_state) struct extent_state **cached_state)
{ {
struct btrfs_ordered_extent *ordered; struct btrfs_ordered_extent *ordered;
struct extent_state *cachedp = NULL; struct extent_state *cache = NULL;
struct extent_state **cachedp = &cache;
if (cached_state) if (cached_state)
cachedp = *cached_state; cachedp = cached_state;
while (1) { while (1) {
lock_extent_bits(tree, start, end, &cachedp); lock_extent_bits(tree, start, end, cachedp);
ordered = btrfs_lookup_ordered_range(inode, start, ordered = btrfs_lookup_ordered_range(inode, start,
end - start + 1); end - start + 1);
if (!ordered) { if (!ordered) {
@ -1001,10 +1002,10 @@ void btrfs_lock_and_flush_ordered_range(struct extent_io_tree *tree,
* aren't exposing it outside of this function * aren't exposing it outside of this function
*/ */
if (!cached_state) if (!cached_state)
refcount_dec(&cachedp->refs); refcount_dec(&cache->refs);
break; break;
} }
unlock_extent_cached(tree, start, end, &cachedp); unlock_extent_cached(tree, start, end, cachedp);
btrfs_start_ordered_extent(&inode->vfs_inode, ordered, 1); btrfs_start_ordered_extent(&inode->vfs_inode, ordered, 1);
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
} }