Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+34 -6
+13
fs/btrfs/extent-tree.c
··· 2296 2296 static inline struct btrfs_delayed_ref_node * 2297 2297 select_delayed_ref(struct btrfs_delayed_ref_head *head) 2298 2298 { 2299 + struct btrfs_delayed_ref_node *ref; 2300 + 2299 2301 if (list_empty(&head->ref_list)) 2300 2302 return NULL; 2303 + 2304 + /* 2305 + * Select a delayed ref of type BTRFS_ADD_DELAYED_REF first. 2306 + * This is to prevent a ref count from going down to zero, which deletes 2307 + * the extent item from the extent tree, when there still are references 2308 + * to add, which would fail because they would not find the extent item. 2309 + */ 2310 + list_for_each_entry(ref, &head->ref_list, list) { 2311 + if (ref->action == BTRFS_ADD_DELAYED_REF) 2312 + return ref; 2313 + } 2301 2314 2302 2315 return list_entry(head->ref_list.next, struct btrfs_delayed_ref_node, 2303 2316 list);
+2 -3
fs/btrfs/inode.c
··· 4209 4209 u64 extent_num_bytes = 0; 4210 4210 u64 extent_offset = 0; 4211 4211 u64 item_end = 0; 4212 - u64 last_size = (u64)-1; 4212 + u64 last_size = new_size; 4213 4213 u32 found_type = (u8)-1; 4214 4214 int found_extent; 4215 4215 int del_item; ··· 4493 4493 btrfs_abort_transaction(trans, root, ret); 4494 4494 } 4495 4495 error: 4496 - if (last_size != (u64)-1 && 4497 - root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) 4496 + if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) 4498 4497 btrfs_ordered_update_i_size(inode, last_size, NULL); 4499 4498 4500 4499 btrfs_free_path(path);
+17 -1
fs/btrfs/ioctl.c
··· 3090 3090 static long btrfs_ioctl_file_extent_same(struct file *file, 3091 3091 struct btrfs_ioctl_same_args __user *argp) 3092 3092 { 3093 - struct btrfs_ioctl_same_args *same; 3093 + struct btrfs_ioctl_same_args *same = NULL; 3094 3094 struct btrfs_ioctl_same_extent_info *info; 3095 3095 struct inode *src = file_inode(file); 3096 3096 u64 off; ··· 3120 3120 3121 3121 if (IS_ERR(same)) { 3122 3122 ret = PTR_ERR(same); 3123 + same = NULL; 3123 3124 goto out; 3124 3125 } 3125 3126 ··· 3191 3190 3192 3191 out: 3193 3192 mnt_drop_write_file(file); 3193 + kfree(same); 3194 3194 return ret; 3195 3195 } 3196 3196 ··· 3587 3585 u64 skip = 0; 3588 3586 u64 trim = 0; 3589 3587 u64 aligned_end = 0; 3588 + 3589 + /* 3590 + * Don't copy an inline extent into an offset 3591 + * greater than zero. Having an inline extent 3592 + * at such an offset results in chaos as btrfs 3593 + * isn't prepared for such cases. Just skip 3594 + * this case for the same reasons as commented 3595 + * at btrfs_ioctl_clone(). 3596 + */ 3597 + if (last_dest_end > 0) { 3598 + ret = -EOPNOTSUPP; 3599 + btrfs_end_transaction(trans, root); 3600 + goto out; 3601 + } 3590 3602 3591 3603 if (off > key.offset) { 3592 3604 skip = off - key.offset;
+2 -2
fs/btrfs/transaction.c
··· 761 761 762 762 if (!list_empty(&trans->ordered)) { 763 763 spin_lock(&info->trans_lock); 764 - list_splice(&trans->ordered, &cur_trans->pending_ordered); 764 + list_splice_init(&trans->ordered, &cur_trans->pending_ordered); 765 765 spin_unlock(&info->trans_lock); 766 766 } 767 767 ··· 1866 1866 } 1867 1867 1868 1868 spin_lock(&root->fs_info->trans_lock); 1869 - list_splice(&trans->ordered, &cur_trans->pending_ordered); 1869 + list_splice_init(&trans->ordered, &cur_trans->pending_ordered); 1870 1870 if (cur_trans->state >= TRANS_STATE_COMMIT_START) { 1871 1871 spin_unlock(&root->fs_info->trans_lock); 1872 1872 atomic_inc(&cur_trans->use_count);