forked from luck/tmp_suning_uos_patched
Merge branch 'for-linus-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "These are all from Filipe, and cover a few problems we've had reported on the list recently (along with ones he found on his own)" * 'for-linus-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: fix file corruption after cloning inline extents Btrfs: fix order by which delayed references are run Btrfs: fix list transaction->pending_ordered corruption Btrfs: fix memory leak in the extent_same ioctl Btrfs: fix shrinking truncate when the no_holes feature is enabled
This commit is contained in:
commit
8be5701342
|
@ -2296,9 +2296,22 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
|
|||
static inline struct btrfs_delayed_ref_node *
|
||||
select_delayed_ref(struct btrfs_delayed_ref_head *head)
|
||||
{
|
||||
struct btrfs_delayed_ref_node *ref;
|
||||
|
||||
if (list_empty(&head->ref_list))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Select a delayed ref of type BTRFS_ADD_DELAYED_REF first.
|
||||
* This is to prevent a ref count from going down to zero, which deletes
|
||||
* the extent item from the extent tree, when there still are references
|
||||
* to add, which would fail because they would not find the extent item.
|
||||
*/
|
||||
list_for_each_entry(ref, &head->ref_list, list) {
|
||||
if (ref->action == BTRFS_ADD_DELAYED_REF)
|
||||
return ref;
|
||||
}
|
||||
|
||||
return list_entry(head->ref_list.next, struct btrfs_delayed_ref_node,
|
||||
list);
|
||||
}
|
||||
|
|
|
@ -4209,7 +4209,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
|
|||
u64 extent_num_bytes = 0;
|
||||
u64 extent_offset = 0;
|
||||
u64 item_end = 0;
|
||||
u64 last_size = (u64)-1;
|
||||
u64 last_size = new_size;
|
||||
u32 found_type = (u8)-1;
|
||||
int found_extent;
|
||||
int del_item;
|
||||
|
@ -4493,8 +4493,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
|
|||
btrfs_abort_transaction(trans, root, ret);
|
||||
}
|
||||
error:
|
||||
if (last_size != (u64)-1 &&
|
||||
root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
|
||||
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
|
||||
btrfs_ordered_update_i_size(inode, last_size, NULL);
|
||||
|
||||
btrfs_free_path(path);
|
||||
|
|
|
@ -3090,7 +3090,7 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
|
|||
static long btrfs_ioctl_file_extent_same(struct file *file,
|
||||
struct btrfs_ioctl_same_args __user *argp)
|
||||
{
|
||||
struct btrfs_ioctl_same_args *same;
|
||||
struct btrfs_ioctl_same_args *same = NULL;
|
||||
struct btrfs_ioctl_same_extent_info *info;
|
||||
struct inode *src = file_inode(file);
|
||||
u64 off;
|
||||
|
@ -3120,6 +3120,7 @@ static long btrfs_ioctl_file_extent_same(struct file *file,
|
|||
|
||||
if (IS_ERR(same)) {
|
||||
ret = PTR_ERR(same);
|
||||
same = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -3190,6 +3191,7 @@ static long btrfs_ioctl_file_extent_same(struct file *file,
|
|||
|
||||
out:
|
||||
mnt_drop_write_file(file);
|
||||
kfree(same);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3586,6 +3588,20 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
|
|||
u64 trim = 0;
|
||||
u64 aligned_end = 0;
|
||||
|
||||
/*
|
||||
* Don't copy an inline extent into an offset
|
||||
* greater than zero. Having an inline extent
|
||||
* at such an offset results in chaos as btrfs
|
||||
* isn't prepared for such cases. Just skip
|
||||
* this case for the same reasons as commented
|
||||
* at btrfs_ioctl_clone().
|
||||
*/
|
||||
if (last_dest_end > 0) {
|
||||
ret = -EOPNOTSUPP;
|
||||
btrfs_end_transaction(trans, root);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (off > key.offset) {
|
||||
skip = off - key.offset;
|
||||
new_key.offset += skip;
|
||||
|
|
|
@ -761,7 +761,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
|||
|
||||
if (!list_empty(&trans->ordered)) {
|
||||
spin_lock(&info->trans_lock);
|
||||
list_splice(&trans->ordered, &cur_trans->pending_ordered);
|
||||
list_splice_init(&trans->ordered, &cur_trans->pending_ordered);
|
||||
spin_unlock(&info->trans_lock);
|
||||
}
|
||||
|
||||
|
@ -1866,7 +1866,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
|||
}
|
||||
|
||||
spin_lock(&root->fs_info->trans_lock);
|
||||
list_splice(&trans->ordered, &cur_trans->pending_ordered);
|
||||
list_splice_init(&trans->ordered, &cur_trans->pending_ordered);
|
||||
if (cur_trans->state >= TRANS_STATE_COMMIT_START) {
|
||||
spin_unlock(&root->fs_info->trans_lock);
|
||||
atomic_inc(&cur_trans->use_count);
|
||||
|
|
Loading…
Reference in New Issue
Block a user