Btrfs: Add more synchronization before creating a snapshot

File data checksums are only done during writepage, so we have to make sure
all pages are written when the snapshot is taken.  This also adds some
locking so that new writes don't race in and add new dirty pages.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index acef8cb..77f1950 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -160,6 +160,7 @@
 	num_blocks = (write_bytes + pos - start_pos + root->blocksize - 1) >>
 			inode->i_blkbits;
 
+	down_read(&BTRFS_I(inode)->root->snap_sem);
 	end_of_last_block = start_pos + (num_blocks << inode->i_blkbits) - 1;
 	lock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS);
 	mutex_lock(&root->fs_info->fs_mutex);
@@ -250,6 +251,7 @@
 	mutex_unlock(&root->fs_info->fs_mutex);
 	unlock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS);
 	free_extent_map(em);
+	up_read(&BTRFS_I(inode)->root->snap_sem);
 	return err;
 }