diff options
-rw-r--r-- | fs/btrfs/inode.c | 20 |
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 | ||
1628 | error: | 1639 | error: |
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 | |