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
This commit is contained in:
commit
d64dab903f
@ -1561,8 +1561,9 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_key *location)
|
||||
struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_key *location,
|
||||
bool check_ref)
|
||||
{
|
||||
struct btrfs_root *root;
|
||||
int ret;
|
||||
@ -1586,7 +1587,7 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
|
||||
again:
|
||||
root = btrfs_lookup_fs_root(fs_info, location->objectid);
|
||||
if (root) {
|
||||
if (btrfs_root_refs(&root->root_item) == 0)
|
||||
if (check_ref && btrfs_root_refs(&root->root_item) == 0)
|
||||
return ERR_PTR(-ENOENT);
|
||||
return root;
|
||||
}
|
||||
@ -1595,7 +1596,7 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
|
||||
if (IS_ERR(root))
|
||||
return root;
|
||||
|
||||
if (btrfs_root_refs(&root->root_item) == 0) {
|
||||
if (check_ref && btrfs_root_refs(&root->root_item) == 0) {
|
||||
ret = -ENOENT;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -68,8 +68,17 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
|
||||
int btrfs_init_fs_root(struct btrfs_root *root);
|
||||
int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_root *root);
|
||||
struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_key *location);
|
||||
|
||||
struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_key *key,
|
||||
bool check_ref);
|
||||
static inline struct btrfs_root *
|
||||
btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_key *location)
|
||||
{
|
||||
return btrfs_get_fs_root(fs_info, location, true);
|
||||
}
|
||||
|
||||
int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info);
|
||||
void btrfs_btree_balance_dirty(struct btrfs_root *root);
|
||||
void btrfs_btree_balance_dirty_nodelay(struct btrfs_root *root);
|
||||
|
@ -1490,10 +1490,8 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
|
||||
cur_start = state->end + 1;
|
||||
node = rb_next(node);
|
||||
total_bytes += state->end - state->start + 1;
|
||||
if (total_bytes >= max_bytes) {
|
||||
*end = *start + max_bytes - 1;
|
||||
if (total_bytes >= max_bytes)
|
||||
break;
|
||||
}
|
||||
if (!node)
|
||||
break;
|
||||
}
|
||||
@ -1635,10 +1633,9 @@ static noinline u64 find_lock_delalloc_range(struct inode *inode,
|
||||
|
||||
/*
|
||||
* make sure to limit the number of pages we try to lock down
|
||||
* if we're looping.
|
||||
*/
|
||||
if (delalloc_end + 1 - delalloc_start > max_bytes && loops)
|
||||
delalloc_end = delalloc_start + PAGE_CACHE_SIZE - 1;
|
||||
if (delalloc_end + 1 - delalloc_start > max_bytes)
|
||||
delalloc_end = delalloc_start + max_bytes - 1;
|
||||
|
||||
/* step two, lock all the pages after the page that has start */
|
||||
ret = lock_delalloc_pages(inode, locked_page,
|
||||
@ -1649,8 +1646,7 @@ static noinline u64 find_lock_delalloc_range(struct inode *inode,
|
||||
*/
|
||||
free_extent_state(cached_state);
|
||||
if (!loops) {
|
||||
unsigned long offset = (*start) & (PAGE_CACHE_SIZE - 1);
|
||||
max_bytes = PAGE_CACHE_SIZE - offset;
|
||||
max_bytes = PAGE_CACHE_SIZE;
|
||||
loops = 1;
|
||||
goto again;
|
||||
} else {
|
||||
|
@ -7986,7 +7986,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
|
||||
|
||||
/* check for collisions, even if the name isn't there */
|
||||
ret = btrfs_check_dir_item_collision(root, new_dir->i_ino,
|
||||
ret = btrfs_check_dir_item_collision(dest, new_dir->i_ino,
|
||||
new_dentry->d_name.name,
|
||||
new_dentry->d_name.len);
|
||||
|
||||
|
@ -588,7 +588,7 @@ static struct btrfs_root *read_fs_root(struct btrfs_fs_info *fs_info,
|
||||
else
|
||||
key.offset = (u64)-1;
|
||||
|
||||
return btrfs_read_fs_root_no_name(fs_info, &key);
|
||||
return btrfs_get_fs_root(fs_info, &key, false);
|
||||
}
|
||||
|
||||
#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
|
||||
|
@ -299,11 +299,6 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (btrfs_root_refs(&root->root_item) == 0) {
|
||||
btrfs_add_dead_root(root);
|
||||
continue;
|
||||
}
|
||||
|
||||
err = btrfs_init_fs_root(root);
|
||||
if (err) {
|
||||
btrfs_free_fs_root(root);
|
||||
@ -318,6 +313,9 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
|
||||
btrfs_free_fs_root(root);
|
||||
break;
|
||||
}
|
||||
|
||||
if (btrfs_root_refs(&root->root_item) == 0)
|
||||
btrfs_add_dead_root(root);
|
||||
}
|
||||
|
||||
btrfs_free_path(path);
|
||||
|
Loading…
Reference in New Issue
Block a user