diff options
Diffstat (limited to 'fs/btrfs')
| -rw-r--r-- | fs/btrfs/Kconfig | 1 | ||||
| -rw-r--r-- | fs/btrfs/backref.c | 13 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
| -rw-r--r-- | fs/btrfs/delayed-inode.c | 8 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 6 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 14 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.c | 4 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 3 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 10 | ||||
| -rw-r--r-- | fs/btrfs/scrub.c | 6 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 14 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 1 |
13 files changed, 53 insertions, 30 deletions
diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig index a66768ebc8d1..80e9c18ea64f 100644 --- a/fs/btrfs/Kconfig +++ b/fs/btrfs/Kconfig | |||
| @@ -8,6 +8,7 @@ config BTRFS_FS | |||
| 8 | select LZO_DECOMPRESS | 8 | select LZO_DECOMPRESS |
| 9 | select RAID6_PQ | 9 | select RAID6_PQ |
| 10 | select XOR_BLOCKS | 10 | select XOR_BLOCKS |
| 11 | select SRCU | ||
| 11 | 12 | ||
| 12 | help | 13 | help |
| 13 | Btrfs is a general purpose copy-on-write filesystem with extents, | 14 | Btrfs is a general purpose copy-on-write filesystem with extents, |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 2d3e32ebfd15..8729cf68d2fe 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
| @@ -1552,7 +1552,6 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, | |||
| 1552 | { | 1552 | { |
| 1553 | int ret; | 1553 | int ret; |
| 1554 | int type; | 1554 | int type; |
| 1555 | struct btrfs_tree_block_info *info; | ||
| 1556 | struct btrfs_extent_inline_ref *eiref; | 1555 | struct btrfs_extent_inline_ref *eiref; |
| 1557 | 1556 | ||
| 1558 | if (*ptr == (unsigned long)-1) | 1557 | if (*ptr == (unsigned long)-1) |
| @@ -1573,9 +1572,17 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, | |||
| 1573 | } | 1572 | } |
| 1574 | 1573 | ||
| 1575 | /* we can treat both ref types equally here */ | 1574 | /* we can treat both ref types equally here */ |
| 1576 | info = (struct btrfs_tree_block_info *)(ei + 1); | ||
| 1577 | *out_root = btrfs_extent_inline_ref_offset(eb, eiref); | 1575 | *out_root = btrfs_extent_inline_ref_offset(eb, eiref); |
| 1578 | *out_level = btrfs_tree_block_level(eb, info); | 1576 | |
| 1577 | if (key->type == BTRFS_EXTENT_ITEM_KEY) { | ||
| 1578 | struct btrfs_tree_block_info *info; | ||
| 1579 | |||
| 1580 | info = (struct btrfs_tree_block_info *)(ei + 1); | ||
| 1581 | *out_level = btrfs_tree_block_level(eb, info); | ||
| 1582 | } else { | ||
| 1583 | ASSERT(key->type == BTRFS_METADATA_ITEM_KEY); | ||
| 1584 | *out_level = (u8)key->offset; | ||
| 1585 | } | ||
| 1579 | 1586 | ||
| 1580 | if (ret == 1) | 1587 | if (ret == 1) |
| 1581 | *ptr = (unsigned long)-1; | 1588 | *ptr = (unsigned long)-1; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 7e607416755a..0b180708bf79 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -1171,6 +1171,7 @@ struct btrfs_space_info { | |||
| 1171 | struct percpu_counter total_bytes_pinned; | 1171 | struct percpu_counter total_bytes_pinned; |
| 1172 | 1172 | ||
| 1173 | struct list_head list; | 1173 | struct list_head list; |
| 1174 | /* Protected by the spinlock 'lock'. */ | ||
| 1174 | struct list_head ro_bgs; | 1175 | struct list_head ro_bgs; |
| 1175 | 1176 | ||
| 1176 | struct rw_semaphore groups_sem; | 1177 | struct rw_semaphore groups_sem; |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 054577bddaf2..de4e70fb3cbb 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
| @@ -1857,6 +1857,14 @@ int btrfs_delayed_delete_inode_ref(struct inode *inode) | |||
| 1857 | { | 1857 | { |
| 1858 | struct btrfs_delayed_node *delayed_node; | 1858 | struct btrfs_delayed_node *delayed_node; |
| 1859 | 1859 | ||
| 1860 | /* | ||
| 1861 | * we don't do delayed inode updates during log recovery because it | ||
| 1862 | * leads to enospc problems. This means we also can't do | ||
| 1863 | * delayed inode refs | ||
| 1864 | */ | ||
| 1865 | if (BTRFS_I(inode)->root->fs_info->log_root_recovering) | ||
| 1866 | return -EAGAIN; | ||
| 1867 | |||
| 1860 | delayed_node = btrfs_get_or_create_delayed_node(inode); | 1868 | delayed_node = btrfs_get_or_create_delayed_node(inode); |
| 1861 | if (IS_ERR(delayed_node)) | 1869 | if (IS_ERR(delayed_node)) |
| 1862 | return PTR_ERR(delayed_node); | 1870 | return PTR_ERR(delayed_node); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8c63419a7f70..1afb18226da8 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1715,12 +1715,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) | |||
| 1715 | { | 1715 | { |
| 1716 | int err; | 1716 | int err; |
| 1717 | 1717 | ||
| 1718 | bdi->capabilities = BDI_CAP_MAP_COPY; | 1718 | err = bdi_setup_and_register(bdi, "btrfs"); |
| 1719 | err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY); | ||
| 1720 | if (err) | 1719 | if (err) |
| 1721 | return err; | 1720 | return err; |
| 1722 | 1721 | ||
| 1723 | bdi->ra_pages = default_backing_dev_info.ra_pages; | 1722 | bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE; |
| 1724 | bdi->congested_fn = btrfs_congested_fn; | 1723 | bdi->congested_fn = btrfs_congested_fn; |
| 1725 | bdi->congested_data = info; | 1724 | bdi->congested_data = info; |
| 1726 | return 0; | 1725 | return 0; |
| @@ -2319,7 +2318,6 @@ int open_ctree(struct super_block *sb, | |||
| 2319 | */ | 2318 | */ |
| 2320 | fs_info->btree_inode->i_size = OFFSET_MAX; | 2319 | fs_info->btree_inode->i_size = OFFSET_MAX; |
| 2321 | fs_info->btree_inode->i_mapping->a_ops = &btree_aops; | 2320 | fs_info->btree_inode->i_mapping->a_ops = &btree_aops; |
| 2322 | fs_info->btree_inode->i_mapping->backing_dev_info = &fs_info->bdi; | ||
| 2323 | 2321 | ||
| 2324 | RB_CLEAR_NODE(&BTRFS_I(fs_info->btree_inode)->rb_node); | 2322 | RB_CLEAR_NODE(&BTRFS_I(fs_info->btree_inode)->rb_node); |
| 2325 | extent_io_tree_init(&BTRFS_I(fs_info->btree_inode)->io_tree, | 2323 | extent_io_tree_init(&BTRFS_I(fs_info->btree_inode)->io_tree, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a80b97100d90..a684086c3c81 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -3139,9 +3139,11 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
| 3139 | struct extent_buffer *leaf; | 3139 | struct extent_buffer *leaf; |
| 3140 | 3140 | ||
| 3141 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); | 3141 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); |
| 3142 | if (ret < 0) | 3142 | if (ret) { |
| 3143 | if (ret > 0) | ||
| 3144 | ret = -ENOENT; | ||
| 3143 | goto fail; | 3145 | goto fail; |
| 3144 | BUG_ON(ret); /* Corruption */ | 3146 | } |
| 3145 | 3147 | ||
| 3146 | leaf = path->nodes[0]; | 3148 | leaf = path->nodes[0]; |
| 3147 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); | 3149 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); |
| @@ -3149,11 +3151,9 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
| 3149 | btrfs_mark_buffer_dirty(leaf); | 3151 | btrfs_mark_buffer_dirty(leaf); |
| 3150 | btrfs_release_path(path); | 3152 | btrfs_release_path(path); |
| 3151 | fail: | 3153 | fail: |
| 3152 | if (ret) { | 3154 | if (ret) |
| 3153 | btrfs_abort_transaction(trans, root, ret); | 3155 | btrfs_abort_transaction(trans, root, ret); |
| 3154 | return ret; | 3156 | return ret; |
| 3155 | } | ||
| 3156 | return 0; | ||
| 3157 | 3157 | ||
| 3158 | } | 3158 | } |
| 3159 | 3159 | ||
| @@ -9422,7 +9422,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
| 9422 | * are still on the list after taking the semaphore | 9422 | * are still on the list after taking the semaphore |
| 9423 | */ | 9423 | */ |
| 9424 | list_del_init(&block_group->list); | 9424 | list_del_init(&block_group->list); |
| 9425 | list_del_init(&block_group->ro_list); | ||
| 9426 | if (list_empty(&block_group->space_info->block_groups[index])) { | 9425 | if (list_empty(&block_group->space_info->block_groups[index])) { |
| 9427 | kobj = block_group->space_info->block_group_kobjs[index]; | 9426 | kobj = block_group->space_info->block_group_kobjs[index]; |
| 9428 | block_group->space_info->block_group_kobjs[index] = NULL; | 9427 | block_group->space_info->block_group_kobjs[index] = NULL; |
| @@ -9464,6 +9463,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
| 9464 | btrfs_remove_free_space_cache(block_group); | 9463 | btrfs_remove_free_space_cache(block_group); |
| 9465 | 9464 | ||
| 9466 | spin_lock(&block_group->space_info->lock); | 9465 | spin_lock(&block_group->space_info->lock); |
| 9466 | list_del_init(&block_group->ro_list); | ||
| 9467 | block_group->space_info->total_bytes -= block_group->key.offset; | 9467 | block_group->space_info->total_bytes -= block_group->key.offset; |
| 9468 | block_group->space_info->bytes_readonly -= block_group->key.offset; | 9468 | block_group->space_info->bytes_readonly -= block_group->key.offset; |
| 9469 | block_group->space_info->disk_total -= block_group->key.offset * factor; | 9469 | block_group->space_info->disk_total -= block_group->key.offset * factor; |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 4ebabd237153..c73df6a7c9b6 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -1407,8 +1407,8 @@ int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end) | |||
| 1407 | while (index <= end_index) { | 1407 | while (index <= end_index) { |
| 1408 | page = find_get_page(inode->i_mapping, index); | 1408 | page = find_get_page(inode->i_mapping, index); |
| 1409 | BUG_ON(!page); /* Pages should be in the extent_io_tree */ | 1409 | BUG_ON(!page); /* Pages should be in the extent_io_tree */ |
| 1410 | account_page_redirty(page); | ||
| 1411 | __set_page_dirty_nobuffers(page); | 1410 | __set_page_dirty_nobuffers(page); |
| 1411 | account_page_redirty(page); | ||
| 1412 | page_cache_release(page); | 1412 | page_cache_release(page); |
| 1413 | index++; | 1413 | index++; |
| 1414 | } | 1414 | } |
| @@ -2190,7 +2190,7 @@ void btrfs_free_io_failure_record(struct inode *inode, u64 start, u64 end) | |||
| 2190 | 2190 | ||
| 2191 | next = next_state(state); | 2191 | next = next_state(state); |
| 2192 | 2192 | ||
| 2193 | failrec = (struct io_failure_record *)state->private; | 2193 | failrec = (struct io_failure_record *)(unsigned long)state->private; |
| 2194 | free_extent_state(state); | 2194 | free_extent_state(state); |
| 2195 | kfree(failrec); | 2195 | kfree(failrec); |
| 2196 | 2196 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e4090259569b..b78bbbac900d 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1746,7 +1746,7 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, | |||
| 1746 | 1746 | ||
| 1747 | mutex_lock(&inode->i_mutex); | 1747 | mutex_lock(&inode->i_mutex); |
| 1748 | 1748 | ||
| 1749 | current->backing_dev_info = inode->i_mapping->backing_dev_info; | 1749 | current->backing_dev_info = inode_to_bdi(inode); |
| 1750 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); | 1750 | err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); |
| 1751 | if (err) { | 1751 | if (err) { |
| 1752 | mutex_unlock(&inode->i_mutex); | 1752 | mutex_unlock(&inode->i_mutex); |
| @@ -2081,7 +2081,6 @@ static const struct vm_operations_struct btrfs_file_vm_ops = { | |||
| 2081 | .fault = filemap_fault, | 2081 | .fault = filemap_fault, |
| 2082 | .map_pages = filemap_map_pages, | 2082 | .map_pages = filemap_map_pages, |
| 2083 | .page_mkwrite = btrfs_page_mkwrite, | 2083 | .page_mkwrite = btrfs_page_mkwrite, |
| 2084 | .remap_pages = generic_file_remap_pages, | ||
| 2085 | }; | 2084 | }; |
| 2086 | 2085 | ||
| 2087 | static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) | 2086 | static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e687bb0dc73a..54bcf639d1cf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -3608,7 +3608,6 @@ cache_acl: | |||
| 3608 | switch (inode->i_mode & S_IFMT) { | 3608 | switch (inode->i_mode & S_IFMT) { |
| 3609 | case S_IFREG: | 3609 | case S_IFREG: |
| 3610 | inode->i_mapping->a_ops = &btrfs_aops; | 3610 | inode->i_mapping->a_ops = &btrfs_aops; |
| 3611 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 3612 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 3611 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
| 3613 | inode->i_fop = &btrfs_file_operations; | 3612 | inode->i_fop = &btrfs_file_operations; |
| 3614 | inode->i_op = &btrfs_file_inode_operations; | 3613 | inode->i_op = &btrfs_file_inode_operations; |
| @@ -3623,7 +3622,6 @@ cache_acl: | |||
| 3623 | case S_IFLNK: | 3622 | case S_IFLNK: |
| 3624 | inode->i_op = &btrfs_symlink_inode_operations; | 3623 | inode->i_op = &btrfs_symlink_inode_operations; |
| 3625 | inode->i_mapping->a_ops = &btrfs_symlink_aops; | 3624 | inode->i_mapping->a_ops = &btrfs_symlink_aops; |
| 3626 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 3627 | break; | 3625 | break; |
| 3628 | default: | 3626 | default: |
| 3629 | inode->i_op = &btrfs_special_inode_operations; | 3627 | inode->i_op = &btrfs_special_inode_operations; |
| @@ -6088,7 +6086,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 6088 | inode->i_fop = &btrfs_file_operations; | 6086 | inode->i_fop = &btrfs_file_operations; |
| 6089 | inode->i_op = &btrfs_file_inode_operations; | 6087 | inode->i_op = &btrfs_file_inode_operations; |
| 6090 | inode->i_mapping->a_ops = &btrfs_aops; | 6088 | inode->i_mapping->a_ops = &btrfs_aops; |
| 6091 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 6092 | 6089 | ||
| 6093 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | 6090 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 6094 | if (err) | 6091 | if (err) |
| @@ -6255,8 +6252,10 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 6255 | 6252 | ||
| 6256 | out_fail: | 6253 | out_fail: |
| 6257 | btrfs_end_transaction(trans, root); | 6254 | btrfs_end_transaction(trans, root); |
| 6258 | if (drop_on_err) | 6255 | if (drop_on_err) { |
| 6256 | inode_dec_link_count(inode); | ||
| 6259 | iput(inode); | 6257 | iput(inode); |
| 6258 | } | ||
| 6260 | btrfs_balance_delayed_items(root); | 6259 | btrfs_balance_delayed_items(root); |
| 6261 | btrfs_btree_balance_dirty(root); | 6260 | btrfs_btree_balance_dirty(root); |
| 6262 | return err; | 6261 | return err; |
| @@ -9201,7 +9200,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 9201 | inode->i_fop = &btrfs_file_operations; | 9200 | inode->i_fop = &btrfs_file_operations; |
| 9202 | inode->i_op = &btrfs_file_inode_operations; | 9201 | inode->i_op = &btrfs_file_inode_operations; |
| 9203 | inode->i_mapping->a_ops = &btrfs_aops; | 9202 | inode->i_mapping->a_ops = &btrfs_aops; |
| 9204 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 9205 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 9203 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
| 9206 | 9204 | ||
| 9207 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | 9205 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| @@ -9245,7 +9243,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 9245 | 9243 | ||
| 9246 | inode->i_op = &btrfs_symlink_inode_operations; | 9244 | inode->i_op = &btrfs_symlink_inode_operations; |
| 9247 | inode->i_mapping->a_ops = &btrfs_symlink_aops; | 9245 | inode->i_mapping->a_ops = &btrfs_symlink_aops; |
| 9248 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 9249 | inode_set_bytes(inode, name_len); | 9246 | inode_set_bytes(inode, name_len); |
| 9250 | btrfs_i_size_write(inode, name_len); | 9247 | btrfs_i_size_write(inode, name_len); |
| 9251 | err = btrfs_update_inode(trans, root, inode); | 9248 | err = btrfs_update_inode(trans, root, inode); |
| @@ -9457,7 +9454,6 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 9457 | inode->i_op = &btrfs_file_inode_operations; | 9454 | inode->i_op = &btrfs_file_inode_operations; |
| 9458 | 9455 | ||
| 9459 | inode->i_mapping->a_ops = &btrfs_aops; | 9456 | inode->i_mapping->a_ops = &btrfs_aops; |
| 9460 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 9461 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 9457 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
| 9462 | 9458 | ||
| 9463 | ret = btrfs_init_inode_security(trans, inode, dir, NULL); | 9459 | ret = btrfs_init_inode_security(trans, inode, dir, NULL); |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index f2bb13a23f86..e427cb7ee12c 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
| @@ -2607,9 +2607,9 @@ static int scrub_extent_for_parity(struct scrub_parity *sparity, | |||
| 2607 | ret = scrub_pages_for_parity(sparity, logical, l, physical, dev, | 2607 | ret = scrub_pages_for_parity(sparity, logical, l, physical, dev, |
| 2608 | flags, gen, mirror_num, | 2608 | flags, gen, mirror_num, |
| 2609 | have_csum ? csum : NULL); | 2609 | have_csum ? csum : NULL); |
| 2610 | skip: | ||
| 2611 | if (ret) | 2610 | if (ret) |
| 2612 | return ret; | 2611 | return ret; |
| 2612 | skip: | ||
| 2613 | len -= l; | 2613 | len -= l; |
| 2614 | logical += l; | 2614 | logical += l; |
| 2615 | physical += l; | 2615 | physical += l; |
| @@ -3053,7 +3053,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, | |||
| 3053 | 3053 | ||
| 3054 | ppath = btrfs_alloc_path(); | 3054 | ppath = btrfs_alloc_path(); |
| 3055 | if (!ppath) { | 3055 | if (!ppath) { |
| 3056 | btrfs_free_path(ppath); | 3056 | btrfs_free_path(path); |
| 3057 | return -ENOMEM; | 3057 | return -ENOMEM; |
| 3058 | } | 3058 | } |
| 3059 | 3059 | ||
| @@ -3065,6 +3065,8 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, | |||
| 3065 | path->search_commit_root = 1; | 3065 | path->search_commit_root = 1; |
| 3066 | path->skip_locking = 1; | 3066 | path->skip_locking = 1; |
| 3067 | 3067 | ||
| 3068 | ppath->search_commit_root = 1; | ||
| 3069 | ppath->skip_locking = 1; | ||
| 3068 | /* | 3070 | /* |
| 3069 | * trigger the readahead for extent tree csum tree and wait for | 3071 | * trigger the readahead for extent tree csum tree and wait for |
| 3070 | * completion. During readahead, the scrub is officially paused | 3072 | * completion. During readahead, the scrub is officially paused |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 60f7cbe815e9..6f49b2872a64 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -1000,10 +1000,20 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
| 1000 | */ | 1000 | */ |
| 1001 | if (fs_info->pending_changes == 0) | 1001 | if (fs_info->pending_changes == 0) |
| 1002 | return 0; | 1002 | return 0; |
| 1003 | /* | ||
| 1004 | * A non-blocking test if the fs is frozen. We must not | ||
| 1005 | * start a new transaction here otherwise a deadlock | ||
| 1006 | * happens. The pending operations are delayed to the | ||
| 1007 | * next commit after thawing. | ||
| 1008 | */ | ||
| 1009 | if (__sb_start_write(sb, SB_FREEZE_WRITE, false)) | ||
| 1010 | __sb_end_write(sb, SB_FREEZE_WRITE); | ||
| 1011 | else | ||
| 1012 | return 0; | ||
| 1003 | trans = btrfs_start_transaction(root, 0); | 1013 | trans = btrfs_start_transaction(root, 0); |
| 1004 | } else { | ||
| 1005 | return PTR_ERR(trans); | ||
| 1006 | } | 1014 | } |
| 1015 | if (IS_ERR(trans)) | ||
| 1016 | return PTR_ERR(trans); | ||
| 1007 | } | 1017 | } |
| 1008 | return btrfs_commit_transaction(trans, root); | 1018 | return btrfs_commit_transaction(trans, root); |
| 1009 | } | 1019 | } |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index a605d4e2f2bc..e88b59d13439 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -2118,7 +2118,7 @@ void btrfs_apply_pending_changes(struct btrfs_fs_info *fs_info) | |||
| 2118 | unsigned long prev; | 2118 | unsigned long prev; |
| 2119 | unsigned long bit; | 2119 | unsigned long bit; |
| 2120 | 2120 | ||
| 2121 | prev = cmpxchg(&fs_info->pending_changes, 0, 0); | 2121 | prev = xchg(&fs_info->pending_changes, 0); |
| 2122 | if (!prev) | 2122 | if (!prev) |
| 2123 | return; | 2123 | return; |
| 2124 | 2124 | ||
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 9a02da16f2be..1a9585d4380a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -2591,6 +2591,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2591 | } | 2591 | } |
| 2592 | 2592 | ||
| 2593 | if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) { | 2593 | if (log_root_tree->log_transid_committed >= root_log_ctx.log_transid) { |
| 2594 | blk_finish_plug(&plug); | ||
| 2594 | mutex_unlock(&log_root_tree->log_mutex); | 2595 | mutex_unlock(&log_root_tree->log_mutex); |
| 2595 | ret = root_log_ctx.log_ret; | 2596 | ret = root_log_ctx.log_ret; |
| 2596 | goto out; | 2597 | goto out; |
