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,
if (mode & ~FALLOC_FL_KEEP_SIZE)
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
* below with the locks held.
......@@ -1666,27 +1674,12 @@ static long btrfs_fallocate(struct file *file, int mode,
if (em->block_start == EXTENT_MAP_HOLE ||
(cur_offset >= inode->i_size &&
!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,
last_byte - cur_offset,
1 << inode->i_blkbits,
offset + len,
&alloc_hint);
/* Let go of our reservation. */
btrfs_free_reserved_data_space(inode, last_byte -
cur_offset);
if (ret < 0) {
free_extent_map(em);
break;
......@@ -1714,6 +1707,8 @@ static long btrfs_fallocate(struct file *file, int mode,
&cached_state, GFP_NOFS);
out:
mutex_unlock(&inode->i_mutex);
/* Let go of our reservation. */
btrfs_free_reserved_data_space(inode, len);
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