Commit d64dab903fb3abb42ef2a3fc2d8aa064105e5dca

Authored by Linus Torvalds

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

Showing 6 changed files Side-by-side Diff

... ... @@ -1561,8 +1561,9 @@
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;
... ... @@ -1586,7 +1587,7 @@
1586 1587 again:
1587 1588 root = btrfs_lookup_fs_root(fs_info, location->objectid);
1588 1589 if (root) {
1589   - if (btrfs_root_refs(&root->root_item) == 0)
  1590 + if (check_ref && btrfs_root_refs(&root->root_item) == 0)
1590 1591 return ERR_PTR(-ENOENT);
1591 1592 return root;
1592 1593 }
... ... @@ -1595,7 +1596,7 @@
1595 1596 if (IS_ERR(root))
1596 1597 return root;
1597 1598  
1598   - if (btrfs_root_refs(&root->root_item) == 0) {
  1599 + if (check_ref && btrfs_root_refs(&root->root_item) == 0) {
1599 1600 ret = -ENOENT;
1600 1601 goto fail;
1601 1602 }
... ... @@ -68,8 +68,17 @@
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);
fs/btrfs/extent_io.c
... ... @@ -1490,10 +1490,8 @@
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 }
1500 1498  
... ... @@ -1635,10 +1633,9 @@
1635 1633  
1636 1634 /*
1637 1635 * make sure to limit the number of pages we try to lock down
1638   - * if we're looping.
1639 1636 */
1640   - if (delalloc_end + 1 - delalloc_start > max_bytes && loops)
1641   - delalloc_end = delalloc_start + PAGE_CACHE_SIZE - 1;
  1637 + if (delalloc_end + 1 - delalloc_start > max_bytes)
  1638 + delalloc_end = delalloc_start + max_bytes - 1;
1642 1639  
1643 1640 /* step two, lock all the pages after the page that has start */
1644 1641 ret = lock_delalloc_pages(inode, locked_page,
... ... @@ -1649,8 +1646,7 @@
1649 1646 */
1650 1647 free_extent_state(cached_state);
1651 1648 if (!loops) {
1652   - unsigned long offset = (*start) & (PAGE_CACHE_SIZE - 1);
1653   - max_bytes = PAGE_CACHE_SIZE - offset;
  1649 + max_bytes = PAGE_CACHE_SIZE;
1654 1650 loops = 1;
1655 1651 goto again;
1656 1652 } else {
... ... @@ -7986,7 +7986,7 @@
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  
fs/btrfs/relocation.c
... ... @@ -588,7 +588,7 @@
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
fs/btrfs/root-tree.c
... ... @@ -299,11 +299,6 @@
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);
... ... @@ -318,6 +313,9 @@
318 313 btrfs_free_fs_root(root);
319 314 break;
320 315 }
  316 +
  317 + if (btrfs_root_refs(&root->root_item) == 0)
  318 + btrfs_add_dead_root(root);
321 319 }
322 320  
323 321 btrfs_free_path(path);