Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

Pull btrfs fixes from Chris Mason:
"We've got more bug fixes in my for-linus branch:

One of these fixes another corner of the compression oops from last
time. Miao nailed down some problems with concurrent snapshot
deletion and drive balancing.

I kept out one of his patches for more testing, but these are all
stable"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
Btrfs: fix oops caused by the space balance and dead roots
Btrfs: insert orphan roots into fs radix tree
Btrfs: limit delalloc pages outside of find_delalloc_range
Btrfs: use right root when checking for hash collision

+25 -21
+5 -4
fs/btrfs/disk-io.c
··· 1561 1561 return ret; 1562 1562 } 1563 1563 1564 - struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, 1565 - struct btrfs_key *location) 1564 + struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, 1565 + struct btrfs_key *location, 1566 + bool check_ref) 1566 1567 { 1567 1568 struct btrfs_root *root; 1568 1569 int ret; ··· 1587 1586 again: 1588 1587 root = btrfs_lookup_fs_root(fs_info, location->objectid); 1589 1588 if (root) { 1590 - if (btrfs_root_refs(&root->root_item) == 0) 1589 + if (check_ref && btrfs_root_refs(&root->root_item) == 0) 1591 1590 return ERR_PTR(-ENOENT); 1592 1591 return root; 1593 1592 } ··· 1596 1595 if (IS_ERR(root)) 1597 1596 return root; 1598 1597 1599 - if (btrfs_root_refs(&root->root_item) == 0) { 1598 + if (check_ref && btrfs_root_refs(&root->root_item) == 0) { 1600 1599 ret = -ENOENT; 1601 1600 goto fail; 1602 1601 }
+11 -2
fs/btrfs/disk-io.h
··· 68 68 int btrfs_init_fs_root(struct btrfs_root *root); 69 69 int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info, 70 70 struct btrfs_root *root); 71 - struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, 72 - struct btrfs_key *location); 71 + 72 + struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, 73 + struct btrfs_key *key, 74 + bool check_ref); 75 + static inline struct btrfs_root * 76 + btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, 77 + struct btrfs_key *location) 78 + { 79 + return btrfs_get_fs_root(fs_info, location, true); 80 + } 81 + 73 82 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info); 74 83 void btrfs_btree_balance_dirty(struct btrfs_root *root); 75 84 void btrfs_btree_balance_dirty_nodelay(struct btrfs_root *root);
+4 -8
fs/btrfs/extent_io.c
··· 1490 1490 cur_start = state->end + 1; 1491 1491 node = rb_next(node); 1492 1492 total_bytes += state->end - state->start + 1; 1493 - if (total_bytes >= max_bytes) { 1494 - *end = *start + max_bytes - 1; 1493 + if (total_bytes >= max_bytes) 1495 1494 break; 1496 - } 1497 1495 if (!node) 1498 1496 break; 1499 1497 } ··· 1633 1635 1634 1636 /* 1635 1637 * make sure to limit the number of pages we try to lock down 1636 - * if we're looping. 1637 1638 */ 1638 - if (delalloc_end + 1 - delalloc_start > max_bytes && loops) 1639 - delalloc_end = delalloc_start + PAGE_CACHE_SIZE - 1; 1639 + if (delalloc_end + 1 - delalloc_start > max_bytes) 1640 + delalloc_end = delalloc_start + max_bytes - 1; 1640 1641 1641 1642 /* step two, lock all the pages after the page that has start */ 1642 1643 ret = lock_delalloc_pages(inode, locked_page, ··· 1646 1649 */ 1647 1650 free_extent_state(cached_state); 1648 1651 if (!loops) { 1649 - unsigned long offset = (*start) & (PAGE_CACHE_SIZE - 1); 1650 - max_bytes = PAGE_CACHE_SIZE - offset; 1652 + max_bytes = PAGE_CACHE_SIZE; 1651 1653 loops = 1; 1652 1654 goto again; 1653 1655 } else {
+1 -1
fs/btrfs/inode.c
··· 7986 7986 7987 7987 7988 7988 /* check for collisions, even if the name isn't there */ 7989 - ret = btrfs_check_dir_item_collision(root, new_dir->i_ino, 7989 + ret = btrfs_check_dir_item_collision(dest, new_dir->i_ino, 7990 7990 new_dentry->d_name.name, 7991 7991 new_dentry->d_name.len); 7992 7992
+1 -1
fs/btrfs/relocation.c
··· 588 588 else 589 589 key.offset = (u64)-1; 590 590 591 - return btrfs_read_fs_root_no_name(fs_info, &key); 591 + return btrfs_get_fs_root(fs_info, &key, false); 592 592 } 593 593 594 594 #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
+3 -5
fs/btrfs/root-tree.c
··· 299 299 continue; 300 300 } 301 301 302 - if (btrfs_root_refs(&root->root_item) == 0) { 303 - btrfs_add_dead_root(root); 304 - continue; 305 - } 306 - 307 302 err = btrfs_init_fs_root(root); 308 303 if (err) { 309 304 btrfs_free_fs_root(root); ··· 313 318 btrfs_free_fs_root(root); 314 319 break; 315 320 } 321 + 322 + if (btrfs_root_refs(&root->root_item) == 0) 323 + btrfs_add_dead_root(root); 316 324 } 317 325 318 326 btrfs_free_path(path);