diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/inode.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5b68330f8585..1eacc78f6614 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -5103,6 +5103,7 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
5103 | u64 mask = BTRFS_I(inode)->root->sectorsize - 1; | 5103 | u64 mask = BTRFS_I(inode)->root->sectorsize - 1; |
5104 | struct extent_map *em; | 5104 | struct extent_map *em; |
5105 | struct btrfs_trans_handle *trans; | 5105 | struct btrfs_trans_handle *trans; |
5106 | struct btrfs_root *root; | ||
5106 | int ret; | 5107 | int ret; |
5107 | 5108 | ||
5108 | alloc_start = offset & ~mask; | 5109 | alloc_start = offset & ~mask; |
@@ -5121,6 +5122,13 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
5121 | goto out; | 5122 | goto out; |
5122 | } | 5123 | } |
5123 | 5124 | ||
5125 | root = BTRFS_I(inode)->root; | ||
5126 | |||
5127 | ret = btrfs_check_data_free_space(root, inode, | ||
5128 | alloc_end - alloc_start); | ||
5129 | if (ret) | ||
5130 | goto out; | ||
5131 | |||
5124 | locked_end = alloc_end - 1; | 5132 | locked_end = alloc_end - 1; |
5125 | while (1) { | 5133 | while (1) { |
5126 | struct btrfs_ordered_extent *ordered; | 5134 | struct btrfs_ordered_extent *ordered; |
@@ -5128,7 +5136,7 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
5128 | trans = btrfs_start_transaction(BTRFS_I(inode)->root, 1); | 5136 | trans = btrfs_start_transaction(BTRFS_I(inode)->root, 1); |
5129 | if (!trans) { | 5137 | if (!trans) { |
5130 | ret = -EIO; | 5138 | ret = -EIO; |
5131 | goto out; | 5139 | goto out_free; |
5132 | } | 5140 | } |
5133 | 5141 | ||
5134 | /* the extent lock is ordered inside the running | 5142 | /* the extent lock is ordered inside the running |
@@ -5189,6 +5197,8 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
5189 | GFP_NOFS); | 5197 | GFP_NOFS); |
5190 | 5198 | ||
5191 | btrfs_end_transaction(trans, BTRFS_I(inode)->root); | 5199 | btrfs_end_transaction(trans, BTRFS_I(inode)->root); |
5200 | out_free: | ||
5201 | btrfs_free_reserved_data_space(root, inode, alloc_end - alloc_start); | ||
5192 | out: | 5202 | out: |
5193 | mutex_unlock(&inode->i_mutex); | 5203 | mutex_unlock(&inode->i_mutex); |
5194 | return ret; | 5204 | return ret; |