aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-09-23 20:19:49 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:07 -0400
commit34353029534a08e41cfb8be647d734b9ce9ebff8 (patch)
tree00aaf0f34c2bf5e4a11541ec5f2fff7bc5473df4 /fs/btrfs/inode.c
parent31840ae1a6b433ca0e6a8d341756ff478bbf959e (diff)
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/inode.c')
-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:
608 add_pending_csums(trans, inode, ordered_extent->file_offset, 608 add_pending_csums(trans, inode, ordered_extent->file_offset,
609 &ordered_extent->list); 609 &ordered_extent->list);
610 610
611 mutex_lock(&BTRFS_I(inode)->extent_mutex);
611 btrfs_ordered_update_i_size(inode, ordered_extent); 612 btrfs_ordered_update_i_size(inode, ordered_extent);
612 btrfs_update_inode(trans, root, inode); 613 btrfs_update_inode(trans, root, inode);
613 btrfs_remove_ordered_extent(inode, ordered_extent); 614 btrfs_remove_ordered_extent(inode, ordered_extent);
615 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
614 616
615 /* once for us */ 617 /* once for us */
616 btrfs_put_ordered_extent(ordered_extent); 618 btrfs_put_ordered_extent(ordered_extent);