diff options
| -rw-r--r-- | fs/btrfs/file.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e4ff2d52ea23..3029925e96d7 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -780,6 +780,18 @@ next_slot: | |||
| 780 | extent_end = search_start; | 780 | extent_end = search_start; |
| 781 | } | 781 | } |
| 782 | 782 | ||
| 783 | /* | ||
| 784 | * Don't skip extent items representing 0 byte lengths. They | ||
| 785 | * used to be created (bug) if while punching holes we hit | ||
| 786 | * -ENOSPC condition. So if we find one here, just ensure we | ||
| 787 | * delete it, otherwise we would insert a new file extent item | ||
| 788 | * with the same key (offset) as that 0 bytes length file | ||
| 789 | * extent item in the call to setup_items_for_insert() later | ||
| 790 | * in this function. | ||
| 791 | */ | ||
| 792 | if (extent_end == key.offset && extent_end >= search_start) | ||
| 793 | goto delete_extent_item; | ||
| 794 | |||
| 783 | if (extent_end <= search_start) { | 795 | if (extent_end <= search_start) { |
| 784 | path->slots[0]++; | 796 | path->slots[0]++; |
| 785 | goto next_slot; | 797 | goto next_slot; |
| @@ -893,6 +905,7 @@ next_slot: | |||
| 893 | * | ------ extent ------ | | 905 | * | ------ extent ------ | |
| 894 | */ | 906 | */ |
| 895 | if (start <= key.offset && end >= extent_end) { | 907 | if (start <= key.offset && end >= extent_end) { |
| 908 | delete_extent_item: | ||
| 896 | if (del_nr == 0) { | 909 | if (del_nr == 0) { |
| 897 | del_slot = path->slots[0]; | 910 | del_slot = path->slots[0]; |
| 898 | del_nr = 1; | 911 | del_nr = 1; |
| @@ -2348,7 +2361,12 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
| 2348 | } | 2361 | } |
| 2349 | 2362 | ||
| 2350 | trans->block_rsv = &root->fs_info->trans_block_rsv; | 2363 | trans->block_rsv = &root->fs_info->trans_block_rsv; |
| 2351 | if (cur_offset < ino_size) { | 2364 | /* |
| 2365 | * Don't insert file hole extent item if it's for a range beyond eof | ||
| 2366 | * (because it's useless) or if it represents a 0 bytes range (when | ||
| 2367 | * cur_offset == drop_end). | ||
| 2368 | */ | ||
| 2369 | if (cur_offset < ino_size && cur_offset < drop_end) { | ||
| 2352 | ret = fill_holes(trans, inode, path, cur_offset, drop_end); | 2370 | ret = fill_holes(trans, inode, path, cur_offset, drop_end); |
| 2353 | if (ret) { | 2371 | if (ret) { |
| 2354 | err = ret; | 2372 | err = ret; |
