summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/inode.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 90c6a4813a19..b52282df8c4d 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1314,6 +1314,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1314 bool check_prev = true; 1314 bool check_prev = true;
1315 const bool freespace_inode = btrfs_is_free_space_inode(BTRFS_I(inode)); 1315 const bool freespace_inode = btrfs_is_free_space_inode(BTRFS_I(inode));
1316 u64 ino = btrfs_ino(BTRFS_I(inode)); 1316 u64 ino = btrfs_ino(BTRFS_I(inode));
1317 bool nocow = false;
1318 u64 disk_bytenr = 0;
1317 1319
1318 path = btrfs_alloc_path(); 1320 path = btrfs_alloc_path();
1319 if (!path) { 1321 if (!path) {
@@ -1333,12 +1335,12 @@ static noinline int run_delalloc_nocow(struct inode *inode,
1333 struct extent_buffer *leaf; 1335 struct extent_buffer *leaf;
1334 u64 extent_end; 1336 u64 extent_end;
1335 u64 extent_offset; 1337 u64 extent_offset;
1336 u64 disk_bytenr = 0;
1337 u64 num_bytes = 0; 1338 u64 num_bytes = 0;
1338 u64 disk_num_bytes; 1339 u64 disk_num_bytes;
1339 u64 ram_bytes; 1340 u64 ram_bytes;
1340 int extent_type; 1341 int extent_type;
1341 bool nocow = false; 1342
1343 nocow = false;
1342 1344
1343 ret = btrfs_lookup_file_extent(NULL, root, path, ino, 1345 ret = btrfs_lookup_file_extent(NULL, root, path, ino,
1344 cur_offset, 0); 1346 cur_offset, 0);
@@ -1572,16 +1574,25 @@ out_check:
1572 disk_bytenr, num_bytes, 1574 disk_bytenr, num_bytes,
1573 num_bytes, 1575 num_bytes,
1574 BTRFS_ORDERED_PREALLOC); 1576 BTRFS_ORDERED_PREALLOC);
1577 if (ret) {
1578 btrfs_drop_extent_cache(BTRFS_I(inode),
1579 cur_offset,
1580 cur_offset + num_bytes - 1,
1581 0);
1582 goto error;
1583 }
1575 } else { 1584 } else {
1576 ret = btrfs_add_ordered_extent(inode, cur_offset, 1585 ret = btrfs_add_ordered_extent(inode, cur_offset,
1577 disk_bytenr, num_bytes, 1586 disk_bytenr, num_bytes,
1578 num_bytes, 1587 num_bytes,
1579 BTRFS_ORDERED_NOCOW); 1588 BTRFS_ORDERED_NOCOW);
1589 if (ret)
1590 goto error;
1580 } 1591 }
1581 1592
1582 if (nocow) 1593 if (nocow)
1583 btrfs_dec_nocow_writers(fs_info, disk_bytenr); 1594 btrfs_dec_nocow_writers(fs_info, disk_bytenr);
1584 BUG_ON(ret); /* -ENOMEM */ 1595 nocow = false;
1585 1596
1586 if (root->root_key.objectid == 1597 if (root->root_key.objectid ==
1587 BTRFS_DATA_RELOC_TREE_OBJECTID) 1598 BTRFS_DATA_RELOC_TREE_OBJECTID)
@@ -1626,6 +1637,9 @@ out_check:
1626 } 1637 }
1627 1638
1628error: 1639error:
1640 if (nocow)
1641 btrfs_dec_nocow_writers(fs_info, disk_bytenr);
1642
1629 if (ret && cur_offset < end) 1643 if (ret && cur_offset < end)
1630 extent_clear_unlock_delalloc(inode, cur_offset, end, 1644 extent_clear_unlock_delalloc(inode, cur_offset, end,
1631 locked_page, EXTENT_LOCKED | 1645 locked_page, EXTENT_LOCKED |