summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-01-26 21:01:11 +0100
committerChris Mason <chris.mason@oracle.com>2012-01-26 21:01:11 +0100
commit6dd70ce4eb7429c2ba6dd9fa46f78a0a2a254038 (patch)
treed527b7a18a05183b9826d42f42e74811d5793cef /fs/btrfs/tree-log.c
parentBtrfs: make sure a bitmap has enough bytes (diff)
downloadlinux-6dd70ce4eb7429c2ba6dd9fa46f78a0a2a254038.tar.xz
linux-6dd70ce4eb7429c2ba6dd9fa46f78a0a2a254038.zip
btrfs: Fix busyloops in transaction waiting code
wait_log_commit() and wait_for_writer() were using slightly different conditions for deciding whether they should call schedule() and whether they should continue in the wait loop. Thus it could happen that we busylooped when the first condition was not true while the second one was. That is burning CPU cycles needlessly and is deadly on UP machines... Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to '')
-rw-r--r--fs/btrfs/tree-log.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index cb877e0886a7..966cc74f5d6c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1957,7 +1957,8 @@ static int wait_log_commit(struct btrfs_trans_handle *trans,
finish_wait(&root->log_commit_wait[index], &wait);
mutex_lock(&root->log_mutex);
- } while (root->log_transid < transid + 2 &&
+ } while (root->fs_info->last_trans_log_full_commit !=
+ trans->transid && root->log_transid < transid + 2 &&
atomic_read(&root->log_commit[index]));
return 0;
}
@@ -1966,7 +1967,8 @@ static int wait_for_writer(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
DEFINE_WAIT(wait);
- while (atomic_read(&root->log_writers)) {
+ while (root->fs_info->last_trans_log_full_commit !=
+ trans->transid && atomic_read(&root->log_writers)) {
prepare_to_wait(&root->log_writer_wait,
&wait, TASK_UNINTERRUPTIBLE);
mutex_unlock(&root->log_mutex);