summaryrefslogtreecommitdiff
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-02-27 13:58:05 +0800
committerJosef Bacik <jbacik@fb.com>2014-03-10 15:17:00 -0400
commit7b2b70851f862b68714f357d2926adbb6c574fdd (patch)
treeb1f0715cb4140c4ddd63bf3c6e70f1900c8b9acf /fs/btrfs/file.c
parentc933956ddf80bc455d33cbcf39d35d935daf45a9 (diff)
Btrfs: fix preallocate vs double nocow write
We can not release the reserved metadata space for the first write if we find the write position is pre-allocated. Because the kernel might write the data on the disk before we do the second write but after the can-nocow check, if we release the space for the first write, we might fail to update the metadata because of no space. Fix this problem by end nocow write if there is dirty data in the range whose space is pre-allocated. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index fc2d21b0a022..d88f2dc4d045 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1427,16 +1427,11 @@ static noinline int check_can_nocow(struct inode *inode, loff_t pos,
num_bytes = lockend - lockstart + 1;
ret = can_nocow_extent(inode, lockstart, &num_bytes, NULL, NULL, NULL);
- if (ret <= 0) {
+ if (ret <= 0)
ret = 0;
- } else {
- clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend,
- EXTENT_DIRTY | EXTENT_DELALLOC |
- EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0,
- NULL, GFP_NOFS);
+ else
*write_bytes = min_t(size_t, *write_bytes ,
num_bytes - pos + lockstart);
- }
unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend);