From patchwork Fri Aug 24 22:44:27 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sage Weil X-Patchwork-Id: 1372691 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 85E923FC33 for ; Fri, 24 Aug 2012 22:44:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754454Ab2HXWoa (ORCPT ); Fri, 24 Aug 2012 18:44:30 -0400 Received: from cobra.newdream.net ([66.33.216.30]:35147 "EHLO cobra.newdream.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752496Ab2HXWo2 (ORCPT ); Fri, 24 Aug 2012 18:44:28 -0400 Received: from cobra.newdream.net (localhost [127.0.0.1]) by cobra.newdream.net (Postfix) with ESMTP id 006C980079 for ; Fri, 24 Aug 2012 15:44:28 -0700 (PDT) Received: by cobra.newdream.net (Postfix, from userid 1031) id DC2A380487; Fri, 24 Aug 2012 15:44:27 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by cobra.newdream.net (Postfix) with ESMTP id CB62480079 for ; Fri, 24 Aug 2012 15:44:27 -0700 (PDT) Date: Fri, 24 Aug 2012 15:44:27 -0700 (PDT) From: Sage Weil X-X-Sender: sage@cobra.newdream.net To: linux-btrfs@vger.kernel.org Subject: [PATCH] Btrfs: pass lockdep rwsem metadata to async commit transaction Message-ID: User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org The freeze rwsem is taken by sb_start_intwrite() and dropped during the commit_ or end_transaction(). In the async case, that happens in a worker thread. Tell lockdep the calling thread is releasing ownership of the rwsem and the async thread is picking it up. Josef and I worked out a more complicated solution that made the async commit thread join and potentially get a later transaction, but it failed my initial smoke test and Dave pointed out that XFS avoids the issue by just telling lockdep what's up. This is much simpler. XFS does the same thing in fs/xfs/xfs_aops.c. Signed-off-by: Sage Weil --- fs/btrfs/transaction.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 17be3de..efc41a5 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1228,6 +1228,14 @@ static void do_async_commit(struct work_struct *work) struct btrfs_async_commit *ac = container_of(work, struct btrfs_async_commit, work.work); + /* + * We've got freeze protection passed with the transaction. + * Tell lockdep about it. + */ + rwsem_acquire_read( + &ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], + 0, 1, _THIS_IP_); + btrfs_commit_transaction(ac->newtrans, ac->root); kfree(ac); } @@ -1257,6 +1265,14 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, atomic_inc(&cur_trans->use_count); btrfs_end_transaction(trans, root); + + /* + * Tell lockdep we've released the freeze rwsem, since the + * async commit thread will be the one to unlock it. + */ + rwsem_release(&root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], + 1, _THIS_IP_); + schedule_delayed_work(&ac->work, 0); /* wait for transaction to start and unblock */