diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 5 | ||||
-rw-r--r-- | fs/btrfs/file.c | 6 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 4 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 14 | ||||
-rw-r--r-- | fs/btrfs/super.c | 5 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 4 |
6 files changed, 25 insertions, 13 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e9659e29d657..551faae77bc3 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -5461,7 +5461,10 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, ret = btrfs_dec_ref(trans, root, eb, 1); else ret = btrfs_dec_ref(trans, root, eb, 0); - BUG_ON(ret); /* -ENOMEM */ + if (ret) { + btrfs_abort_transaction(trans, ret); + return ret; + } if (is_fstree(root->root_key.objectid)) { ret = btrfs_qgroup_trace_leaf_items(trans, eb); if (ret) { diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 44160d4ad53e..0dd5a90feca3 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -731,7 +731,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, if (args->drop_cache) btrfs_drop_extent_cache(inode, args->start, args->end - 1, 0); - if (args->start >= inode->disk_i_size && !args->replace_extent) + if (data_race(args->start >= inode->disk_i_size) && !args->replace_extent) modify_tree = 0; update_refs = (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID); @@ -1607,7 +1607,6 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, loff_t pos = iocb->ki_pos; int ret; loff_t oldsize; - loff_t start_pos; if (iocb->ki_flags & IOCB_NOWAIT) { size_t nocow_bytes = count; @@ -1637,9 +1636,8 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, */ update_time_for_write(inode); - start_pos = round_down(pos, fs_info->sectorsize); oldsize = i_size_read(inode); - if (start_pos > oldsize) { + if (pos > oldsize) { /* Expand hole size to cover write data, preventing empty gap */ loff_t end_pos = round_up(pos + count, fs_info->sectorsize); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a6b1dd834060..d6e43c94436d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7698,8 +7698,6 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, ret = -EAGAIN; goto out; } - - cond_resched(); } btrfs_release_path(path); @@ -11033,6 +11031,8 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, } start += len; + + cond_resched(); } if (bsi.block_len) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 87f302a413f9..887ae4a9c50c 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -4414,8 +4414,18 @@ int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, WARN_ON(!first_cow && level == 0); node = rc->backref_cache.path[level]; - BUG_ON(node->bytenr != buf->start && - node->new_bytenr != buf->start); + + /* + * If node->bytenr != buf->start and node->new_bytenr != + * buf->start then we've got the wrong backref node for what we + * expected to see here and the cache is incorrect. + */ + if (unlikely(node->bytenr != buf->start && node->new_bytenr != buf->start)) { + btrfs_err(fs_info, +"bytenr %llu was found but our backref cache was expecting %llu or %llu", + buf->start, node->bytenr, node->new_bytenr); + return -EUCLEAN; + } btrfs_backref_drop_node_buffer(node); atomic_inc(&cow->refs); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 2fd0ee0e6e93..27994da46caa 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1386,7 +1386,7 @@ static int btrfs_fill_super(struct super_block *sb, err = open_ctree(sb, fs_devices, (char *)data); if (err) { - btrfs_err(fs_info, "open_ctree failed"); + btrfs_err(fs_info, "open_ctree failed: %d", err); return err; } @@ -1559,8 +1559,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) subvol_name = btrfs_get_subvol_name_from_objectid(info, BTRFS_I(d_inode(dentry))->root->root_key.objectid); if (!IS_ERR(subvol_name)) { - seq_puts(seq, ",subvol="); - seq_escape(seq, subvol_name, " \t\n\\"); + seq_show_option(seq, "subvol", subvol_name); kfree(subvol_name); } return 0; diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index a9b794c47159..4fb5e12c87d1 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -295,8 +295,10 @@ loop: cur_trans = fs_info->running_transaction; if (cur_trans) { if (TRANS_ABORTED(cur_trans)) { + const int abort_error = cur_trans->aborted; + spin_unlock(&fs_info->trans_lock); - return cur_trans->aborted; + return abort_error; } if (btrfs_blocked_trans_types[cur_trans->state] & type) { spin_unlock(&fs_info->trans_lock); |