Commit d98456fc authored by Chris Mason's avatar Chris Mason

Btrfs: don't reserve data with extents locked in btrfs_fallocate

btrfs_fallocate tries to allocate space only if ranges in the file don't
already exist.  But the enospc checks it does are not allowed with
extents locked.
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 9998eb70
...@@ -1603,6 +1603,14 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1603,6 +1603,14 @@ static long btrfs_fallocate(struct file *file, int mode,
if (mode & ~FALLOC_FL_KEEP_SIZE) if (mode & ~FALLOC_FL_KEEP_SIZE)
return -EOPNOTSUPP; return -EOPNOTSUPP;
/*
* Make sure we have enough space before we do the
* allocation.
*/
ret = btrfs_check_data_free_space(inode, len);
if (ret)
return ret;
/* /*
* wait for ordered IO before we have any locks. We'll loop again * wait for ordered IO before we have any locks. We'll loop again
* below with the locks held. * below with the locks held.
...@@ -1666,27 +1674,12 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1666,27 +1674,12 @@ static long btrfs_fallocate(struct file *file, int mode,
if (em->block_start == EXTENT_MAP_HOLE || if (em->block_start == EXTENT_MAP_HOLE ||
(cur_offset >= inode->i_size && (cur_offset >= inode->i_size &&
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
/*
* Make sure we have enough space before we do the
* allocation.
*/
ret = btrfs_check_data_free_space(inode, last_byte -
cur_offset);
if (ret) {
free_extent_map(em);
break;
}
ret = btrfs_prealloc_file_range(inode, mode, cur_offset, ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
last_byte - cur_offset, last_byte - cur_offset,
1 << inode->i_blkbits, 1 << inode->i_blkbits,
offset + len, offset + len,
&alloc_hint); &alloc_hint);
/* Let go of our reservation. */
btrfs_free_reserved_data_space(inode, last_byte -
cur_offset);
if (ret < 0) { if (ret < 0) {
free_extent_map(em); free_extent_map(em);
break; break;
...@@ -1714,6 +1707,8 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1714,6 +1707,8 @@ static long btrfs_fallocate(struct file *file, int mode,
&cached_state, GFP_NOFS); &cached_state, GFP_NOFS);
out: out:
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
/* Let go of our reservation. */
btrfs_free_reserved_data_space(inode, len);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment