summaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-09-24 02:19:49 +0200
committerChris Mason <chris.mason@oracle.com>2008-09-25 17:04:07 +0200
commit34353029534a08e41cfb8be647d734b9ce9ebff8 (patch)
tree00aaf0f34c2bf5e4a11541ec5f2fff7bc5473df4 /fs/btrfs
parentBtrfs: Full back reference support (diff)
downloadlinux-34353029534a08e41cfb8be647d734b9ce9ebff8.tar.xz
linux-34353029534a08e41cfb8be647d734b9ce9ebff8.zip
Btrfs: Fix race against disk_i_size updates
The code to update the on disk i_size happens before the ordered_extent record is removed. So, it is possible for multiple ordered_extent completion routines to run at the same time, and to find each other in the ordered tree. The end result is they both decide not to update disk_i_size, leaving it too small. This temporary fix just puts the updates inside the extent_mutex. A real solution would be stronger ordering of disk_i_size updates against removing the ordered extent from the tree. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/inode.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2e7d82ec5d18..adb169d739ce 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -608,9 +608,11 @@ nocow:
add_pending_csums(trans, inode, ordered_extent->file_offset,
&ordered_extent->list);
+ mutex_lock(&BTRFS_I(inode)->extent_mutex);
btrfs_ordered_update_i_size(inode, ordered_extent);
btrfs_update_inode(trans, root, inode);
btrfs_remove_ordered_extent(inode, ordered_extent);
+ mutex_unlock(&BTRFS_I(inode)->extent_mutex);
/* once for us */
btrfs_put_ordered_extent(ordered_extent);