From patchwork Fri Dec 4 05:37:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naohiro Aota X-Patchwork-Id: 7765901 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 12A339F30B for ; Fri, 4 Dec 2015 08:11:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 32C87203B0 for ; Fri, 4 Dec 2015 08:11:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 11704203AB for ; Fri, 4 Dec 2015 08:11:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755253AbbLDIK7 (ORCPT ); Fri, 4 Dec 2015 03:10:59 -0500 Received: from mail-pa0-f46.google.com ([209.85.220.46]:33953 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751519AbbLDIK6 (ORCPT ); Fri, 4 Dec 2015 03:10:58 -0500 Received: by pacwq6 with SMTP id wq6so6101920pac.1 for ; Fri, 04 Dec 2015 00:10:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=PAaNzjsS44GCliTDowa+rOxI95fJ9nu93KmypATuPKA=; b=uAV1PYNNALdPBFv89RUm/nvAGLQKnNYe+3BLyKAElC43B1cId9c8Bq/eMQrCeqkJKE lI8qG5tSlS/UO6WyVL/Mh8z18naPCYGoP7k6gB3QIzVMkpn+M4AJ37hYv2M+PFMvIXnN l2vAvjSHS16jdgeLY/SddGitSY1Y+hfUW5kmgENo2qdMm7bzuqYKhARsxykFhxDFZfzk /WHf4pWLStxzyp13MUmh95NV6HwsM51bl/nvPSgPoHEVQcH1QfcOX43tBnctMsXJrArx gUvCPfO/TpMgTU+0f5sggoFXk1zpJr+ZLrdhhgaLqiimvK0kb+ZoElEzeguZkgLdp2A6 3bHQ== X-Received: by 10.66.158.129 with SMTP id wu1mr19658295pab.146.1449216657511; Fri, 04 Dec 2015 00:10:57 -0800 (PST) Received: from me (sslab-relay.ics.keio.ac.jp. [131.113.126.173]) by smtp.gmail.com with ESMTPSA id l20sm15241510pfi.10.2015.12.04.00.10.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Dec 2015 00:10:56 -0800 (PST) Received: (nullmailer pid 1503 invoked by uid 1000); Fri, 04 Dec 2015 05:37:37 -0000 From: Naohiro Aota To: linux-btrfs@vger.kernel.org Cc: quwenruo@cn.fujitsu.com, Naohiro Aota Subject: [PATCH 2/3] btrfs-progs: properly reset nlink of multi-linked file Date: Fri, 4 Dec 2015 14:37:26 +0900 Message-Id: <1449207447-1203-3-git-send-email-naota@elisp.net> X-Mailer: git-send-email 2.6.3 In-Reply-To: <1449207447-1203-1-git-send-email-naota@elisp.net> References: <1449207447-1203-1-git-send-email-naota@elisp.net> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,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 If a file is linked from more than one directory and only one of the links is corrupted, btrfs check dose not reset the nlink properly. Actually it can go into infinite loop to link the broken file into lost+found. This patch fix two part of the code. The first one delay the freeing valid (no error, found inode ref, directory index, and directory item) backrefs. Freeing valid backrefs earier prevent reset_nlink() to add back all valid links. The second fix is obvious: passing `ref_type' to btrfs_add_link() is just wrong. It should be `filetype' instead. The current code can break all valid file links. Signed-off-by: Naohiro Aota Reviewed-by: Qu Wenruo --- cmds-check.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmds-check.c b/cmds-check.c index 6a0b50a..11ff3fe 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -810,7 +810,8 @@ static void maybe_free_inode_rec(struct cache_tree *inode_cache, if (backref->found_dir_item && backref->found_dir_index) { if (backref->filetype != filetype) backref->errors |= REF_ERR_FILETYPE_UNMATCH; - if (!backref->errors && backref->found_inode_ref) { + if (!backref->errors && backref->found_inode_ref && + rec->nlink == rec->found_link) { list_del(&backref->list); free(backref); } @@ -2392,7 +2393,7 @@ static int reset_nlink(struct btrfs_trans_handle *trans, list_for_each_entry(backref, &rec->backrefs, list) { ret = btrfs_add_link(trans, root, rec->ino, backref->dir, backref->name, backref->namelen, - backref->ref_type, &backref->index, 1); + backref->filetype, &backref->index, 1); if (ret < 0) goto out; }