From patchwork Tue Oct 26 19:16:29 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sage Weil X-Patchwork-Id: 283282 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9QJGZZC023544 for ; Tue, 26 Oct 2010 19:16:36 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932309Ab0JZTQc (ORCPT ); Tue, 26 Oct 2010 15:16:32 -0400 Received: from cobra.newdream.net ([66.33.216.30]:35414 "EHLO cobra.newdream.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755731Ab0JZTQc (ORCPT ); Tue, 26 Oct 2010 15:16:32 -0400 Received: from localhost.localdomain (ip-66-33-206-8.dreamhost.com [66.33.206.8]) by cobra.newdream.net (Postfix) with ESMTPA id C786DBC749; Tue, 26 Oct 2010 12:19:43 -0700 (PDT) From: Sage Weil To: linux-btrfs@vger.kernel.org Cc: Sage Weil Subject: [PATCH v2] Btrfs: fix deadlock in btrfs_commit_transaction Date: Tue, 26 Oct 2010 12:16:29 -0700 Message-Id: <1288120589-31868-1-git-send-email-sage@newdream.net> X-Mailer: git-send-email 1.6.6.1 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 26 Oct 2010 19:16:36 +0000 (UTC) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 66e4c66..b461fe3 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -392,6 +392,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, WARN_ON(cur_trans->num_writers < 1); cur_trans->num_writers--; + smp_mb(); if (waitqueue_active(&cur_trans->writer_wait)) wake_up(&cur_trans->writer_wait); put_transaction(cur_trans); @@ -992,7 +993,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) { unsigned long joined = 0; - unsigned long timeout = 1; struct btrfs_transaction *cur_trans; struct btrfs_transaction *prev_trans = NULL; DEFINE_WAIT(wait); @@ -1063,11 +1063,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, snap_pending = 1; WARN_ON(cur_trans != trans->transaction); - if (cur_trans->num_writers > 1) - timeout = MAX_SCHEDULE_TIMEOUT; - else if (should_grow) - timeout = 1; - mutex_unlock(&root->fs_info->trans_mutex); if (flush_on_commit || snap_pending) { @@ -1089,8 +1084,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, TASK_UNINTERRUPTIBLE); smp_mb(); - if (cur_trans->num_writers > 1 || should_grow) - schedule_timeout(timeout); + if (cur_trans->num_writers > 1) + schedule_timeout(MAX_SCHEDULE_TIMEOUT); + else if (should_grow) + schedule_timeout(1); mutex_lock(&root->fs_info->trans_mutex); finish_wait(&cur_trans->writer_wait, &wait);