소스 검색

Btrfs: just flush the delalloc inodes in the source tree before snapshot creation

Before applying this patch, we need flush all the delalloc inodes in
the fs when we want to create a snapshot, it wastes time, and make
the transaction commit be blocked for a long time. It means some other
user operation would also be blocked for a long time.

This patch improves this problem, we just flush the delalloc inodes that
in the source trees before snapshot creation, so the transaction commit
will complete quickly.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Miao Xie 12 년 전
부모
커밋
6a03843df4
2개의 변경된 파일7개의 추가작업 그리고 9개의 파일을 삭제
  1. 6 0
      fs/btrfs/ioctl.c
  2. 1 9
      fs/btrfs/transaction.c

+ 6 - 0
fs/btrfs/ioctl.c

@@ -555,6 +555,12 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 	if (!root->ref_cows)
 	if (!root->ref_cows)
 		return -EINVAL;
 		return -EINVAL;
 
 
+	ret = btrfs_start_delalloc_inodes(root, 0);
+	if (ret)
+		return ret;
+
+	btrfs_wait_ordered_extents(root, 0);
+
 	pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
 	pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
 	if (!pending_snapshot)
 	if (!pending_snapshot)
 		return -ENOMEM;
 		return -ENOMEM;

+ 1 - 9
fs/btrfs/transaction.c

@@ -1491,17 +1491,9 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans,
 					  struct btrfs_root *root)
 					  struct btrfs_root *root)
 {
 {
 	int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT);
 	int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT);
-	int snap_pending = 0;
 	int ret;
 	int ret;
 
 
-	if (!flush_on_commit) {
-		spin_lock(&root->fs_info->trans_lock);
-		if (!list_empty(&trans->transaction->pending_snapshots))
-			snap_pending = 1;
-		spin_unlock(&root->fs_info->trans_lock);
-	}
-
-	if (flush_on_commit || snap_pending) {
+	if (flush_on_commit) {
 		ret = btrfs_start_all_delalloc_inodes(root->fs_info, 1);
 		ret = btrfs_start_all_delalloc_inodes(root->fs_info, 1);
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;