Skip to content

Commit

Permalink
Btrfs: account for space we may use in fallocate
Browse files Browse the repository at this point in the history
Using Eric Sandeen's xfstest for fallocate, you can easily trigger a ENOSPC
panic on btrfs.  This is because we do not account for data we may use when
doing the fallocate.  This patch fixes the problem by properly reserving space,
and then just freeing it when we are done.  The reservation stuff was made with
delalloc in mind, so its a little crude for this case, but it keeps the box
from panicing.

Signed-off-by: Josef Bacik <jbacik@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Josef Bacik authored and Chris Mason committed Jul 2, 2009
1 parent c8a894d commit a970b0a
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -5103,6 +5103,7 @@ static long btrfs_fallocate(struct inode *inode, int mode,
u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
struct extent_map *em;
struct btrfs_trans_handle *trans;
struct btrfs_root *root;
int ret;

alloc_start = offset & ~mask;
Expand All @@ -5121,14 +5122,21 @@ static long btrfs_fallocate(struct inode *inode, int mode,
goto out;
}

root = BTRFS_I(inode)->root;

ret = btrfs_check_data_free_space(root, inode,
alloc_end - alloc_start);
if (ret)
goto out;

locked_end = alloc_end - 1;
while (1) {
struct btrfs_ordered_extent *ordered;

trans = btrfs_start_transaction(BTRFS_I(inode)->root, 1);
if (!trans) {
ret = -EIO;
goto out;
goto out_free;
}

/* the extent lock is ordered inside the running
Expand Down Expand Up @@ -5189,6 +5197,8 @@ static long btrfs_fallocate(struct inode *inode, int mode,
GFP_NOFS);

btrfs_end_transaction(trans, BTRFS_I(inode)->root);
out_free:
btrfs_free_reserved_data_space(root, inode, alloc_end - alloc_start);
out:
mutex_unlock(&inode->i_mutex);
return ret;
Expand Down

0 comments on commit a970b0a

Please sign in to comment.