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: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
9998eb7034
commit
d98456fcaf
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user