From patchwork Wed Jan 29 15:32:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 3551991 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0844C9F2E9 for ; Wed, 29 Jan 2014 15:32:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E3D682018E for ; Wed, 29 Jan 2014 15:32:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9D92B2018B for ; Wed, 29 Jan 2014 15:32:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752573AbaA2Pce (ORCPT ); Wed, 29 Jan 2014 10:32:34 -0500 Received: from mail-pd0-f181.google.com ([209.85.192.181]:63201 "EHLO mail-pd0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752056AbaA2Pcd (ORCPT ); Wed, 29 Jan 2014 10:32:33 -0500 Received: by mail-pd0-f181.google.com with SMTP id y10so1816836pdj.40 for ; Wed, 29 Jan 2014 07:32:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=uqdjRCR/QtVQJst8ec9RUQt4+EVggn7Xr615NPIfc64=; b=niAQtZjMj1Zv7wkWp8ej0x21JBi5/AqeGMIZQy95bkNBBjzlalTsBhha3TScIbGYfm tEif7j0CB6BBUVM9EyAcP5bmtfc5p0zKYctby8EZl/cQ4HvZaxjvv4Ze6N/d4wV+e6AR d4SLSUhbHyuW1hzOw75gJmVFzu2xCuj0ZgGHcY7FOkjt1GKIJpzD0vKoH+VuvNyCI7SF VzIAxuPGq8FiwxDVtIQeovLA/Z3z80fdVE2kb1xYtXckPekh2HjEG9hahwsqNTKU7puZ 98LDjjInhe0Ipz8XoXQ+AuKCOOFFgC7puRm/S9alwXDKfX44Fd5vf5SZaDFPpJz+ZoFd Algg== X-Received: by 10.68.197.99 with SMTP id it3mr8535974pbc.37.1391009552810; Wed, 29 Jan 2014 07:32:32 -0800 (PST) Received: from linux-b0ol.localdomain ([36.58.227.58]) by mx.google.com with ESMTPSA id mo2sm8229156pbc.6.2014.01.29.07.32.27 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jan 2014 07:32:32 -0800 (PST) From: Wang Shilong To: linux-btrfs@vger.kernel.org Cc: Wang Shilong , Josef Bacik Subject: [PATCH] Btrfs: convert to add transaction protection for btrfs send Date: Wed, 29 Jan 2014 23:32:18 +0800 Message-Id: <1391009539-2326-1-git-send-email-wangshilong1991@gmail.com> X-Mailer: git-send-email 1.8.4 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wang Shilong I sent a patch to kick off transaction from btrfs send, however it gets a regression that btrfs send try to search extent commit root without transaction protection. To fix this regression, we have two ideas: 1. don't use extent commit root for sending. 2. add transaction protection to use extent commit root safely. Both approaches need transaction actually, however, the first approach will add extent tree lock contention, so we'd better adopt the second approach. Luckily, now we only need transaction protection when iterating extent root, the protection's *range* is smaller than before. Cc: Josef Bacik Signed-off-by: Wang Shilong --- fs/btrfs/send.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 04c07ed..8d5e151 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -4511,6 +4511,7 @@ static int process_extent(struct send_ctx *sctx, struct btrfs_key *key) { struct clone_root *found_clone = NULL; + struct btrfs_trans_handle *trans; int ret = 0; if (S_ISLNK(sctx->cur_inode_mode)) @@ -4551,10 +4552,24 @@ static int process_extent(struct send_ctx *sctx, } } } + /* + * We need to make sure the transaction does not get committed + * while we are walking backrefs on extent commit root. + */ + trans = btrfs_join_transaction(sctx->send_root); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out; + } ret = find_extent_clone(sctx, path, key->objectid, key->offset, sctx->cur_inode_size, &found_clone); - if (ret != -ENOENT && ret < 0) + if (ret != -ENOENT && ret < 0) { + btrfs_end_transaction(trans, sctx->send_root); + goto out; + } + ret = btrfs_end_transaction(trans, sctx->send_root); + if (ret) goto out; ret = send_write_or_clone(sctx, path, key, found_clone);