diff options
author | Liu Bo <bo.li.liu@oracle.com> | 2016-11-04 20:20:54 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-11-30 13:45:18 +0100 |
commit | a23eaa875f0f1d89eb866b8c9860e78273ff5daf (patch) | |
tree | b054482b1706390b6e5eefb435ba71393d505902 /fs/btrfs | |
parent | btrfs: return early from failed memory allocations in ioctl handlers (diff) | |
download | linux-a23eaa875f0f1d89eb866b8c9860e78273ff5daf.tar.xz linux-a23eaa875f0f1d89eb866b8c9860e78273ff5daf.zip |
Btrfs: adjust len of writes if following a preallocated extent
If we have
|0--hole--4095||4096--preallocate--12287|
instead of using preallocated space, a 8K direct write will just
create a new 8K extent and it'll end up with
|0--new extent--8191||8192--preallocate--12287|
It's because we find a hole em and then go to create a new 8K
extent directly without adjusting @len.
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Reviewed-by: Chris Mason <clm@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/inode.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 06dc95caa6f1..66c1d65bd476 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7782,10 +7782,12 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, } /* - * this will cow the extent, reset the len in case we changed - * it above + * this will cow the extent, if em is within [start, len], then + * probably we've found a preallocated/existing extent, let's + * give it a chance to use preallocated space. */ - len = bh_result->b_size; + len = min_t(u64, bh_result->b_size, em->len - (start - em->start)); + len = ALIGN(len, root->sectorsize); free_extent_map(em); em = btrfs_new_extent_direct(inode, start, len); if (IS_ERR(em)) { |