Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d98456fc authored by Chris Mason's avatar Chris Mason
Browse files

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
Loading
Loading
Loading
Loading
+10 −15
Original line number Diff line number Diff line
@@ -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;
}