aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/file.c20
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) {
908delete_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;