[Btrfs-devel] [PATCH] delay commit if work is done while we're asleep

Josef Bacik jwhiter at redhat.com
Thu Aug 9 08:07:39 PDT 2007


Hello,

Ok this one works I promise :).  Cleaned a few things up and such, but basically
same idea as before, I keep the waitqueue, I use schedule_timeout which keeps us
from deadlocking.  This speeds us up a decent amount, without the patch I
usually get 70-75 files/sec.  With this patch I get between 85-115 files/sec.
The reason there is such a wide spread depends mostly on when the transaction
cleaner runs while I'm running the test, as this is only single threaded.
Feedback is appreciated.  Thank you,

Josef

diff -r f6da57af2473 transaction.c
--- a/transaction.c	Wed Aug 08 20:17:12 2007 -0400
+++ b/transaction.c	Thu Aug 09 11:06:25 2007 -0400
@@ -55,7 +55,8 @@ static int join_transaction(struct btrfs
 		BUG_ON(!cur_trans);
 		root->fs_info->generation++;
 		root->fs_info->running_transaction = cur_trans;
-		cur_trans->num_writers = 0;
+		cur_trans->num_writers = 1;
+		cur_trans->num_joined = 0;
 		cur_trans->transid = root->fs_info->generation;
 		init_waitqueue_head(&cur_trans->writer_wait);
 		init_waitqueue_head(&cur_trans->commit_wait);
@@ -65,8 +66,11 @@ static int join_transaction(struct btrfs
 		cur_trans->start_time = get_seconds();
 		list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
 		init_bit_radix(&cur_trans->dirty_pages);
-	}
-	cur_trans->num_writers++;
+	} else {
+		cur_trans->num_writers++;
+		cur_trans->num_joined++;
+	}
+
 	return 0;
 }
 
@@ -426,7 +430,7 @@ int btrfs_commit_transaction(struct btrf
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 			     struct btrfs_root *root)
 {
-	int ret = 0;
+	int ret = 0, joined = 0;
 	struct btrfs_transaction *cur_trans;
 	struct btrfs_transaction *prev_trans = NULL;
 	struct list_head dirty_fs_roots;
@@ -467,19 +471,24 @@ int btrfs_commit_transaction(struct btrf
 			mutex_lock(&root->fs_info->trans_mutex);
 		}
 	}
-	while (trans->transaction->num_writers > 1) {
+	
+	do {
+		joined = cur_trans->num_joined;
 		WARN_ON(cur_trans != trans->transaction);
-		prepare_to_wait(&trans->transaction->writer_wait, &wait,
+		prepare_to_wait(&cur_trans->writer_wait, &wait,
 				TASK_UNINTERRUPTIBLE);
-		if (trans->transaction->num_writers <= 1)
+		if (cur_trans->num_writers <= 1 && 
+		    (cur_trans->num_joined != joined))
 			break;
 		mutex_unlock(&root->fs_info->fs_mutex);
 		mutex_unlock(&root->fs_info->trans_mutex);
-		schedule();
+		schedule_timeout(1);
 		mutex_lock(&root->fs_info->fs_mutex);
 		mutex_lock(&root->fs_info->trans_mutex);
-		finish_wait(&trans->transaction->writer_wait, &wait);
-	}
+		finish_wait(&cur_trans->writer_wait, &wait);
+	} while (cur_trans->num_writers > 1 || 
+		 (cur_trans->num_joined != joined));
+
 	finish_wait(&trans->transaction->writer_wait, &wait);
 	WARN_ON(cur_trans != trans->transaction);
 	ret = add_dirty_roots(trans, &root->fs_info->fs_roots_radix,
diff -r f6da57af2473 transaction.h
--- a/transaction.h	Wed Aug 08 20:17:12 2007 -0400
+++ b/transaction.h	Thu Aug 09 10:52:31 2007 -0400
@@ -23,6 +23,7 @@ struct btrfs_transaction {
 struct btrfs_transaction {
 	u64 transid;
 	unsigned long num_writers;
+	unsigned long num_joined;
 	int in_commit;
 	int use_count;
 	int commit_done;



More information about the Btrfs-devel mailing list