Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp688972pxb; Mon, 25 Oct 2021 16:42:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw6yPeKOyndh6B72SlgQNQMqjnPsoEGNwsvoAmCgOGGG6TEad1GBMqcI7HP2xcQBqByM7ox X-Received: by 2002:a17:906:6088:: with SMTP id t8mr25635004ejj.537.1635205336872; Mon, 25 Oct 2021 16:42:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1635205336; cv=none; d=google.com; s=arc-20160816; b=mkbRghy+hR2sXWYAVnAHSoWtVODl9ewtDHOsTKAnHyA72mxlUWGWxmS2BpanBJ7YCk Ac6/6VHxzFGHUSuO+KRQaKAOyw6XSFYdzzZWjHVN1QYN57ZBDfaIJjTi+mMfTIIrrjWN ixi9VYA9xKlb0d935b0glU8VF7HPy34KP15DKxrMLNuQoXVGVjCDkKPFM4zGWU3N5iaw Me57NhP75dHTKkPCE4t8MEm9vwbyoynGufLoUngyTa5xUS+cnX1HD3F8ijZ8F4W7nA49 RfMLBkDcA3+31ksp7/ddU8e542UgCWiF5smH5uUBkh7ysUrPtDLjevhSE32kUQmQp77z 0DOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=TjWFAiylm+asEhaJ9edH7s0ISWpeNC/Q3yqLwFMFbPk=; b=HjFlwP1Fneqf+llik8nvL6nBHgFt8mcXUJXQLtV3IEzb5/WJkFoJ96kTAcoUXtuF+x Qkg4yINjG0Avm+KrQklmwyNXq4mr4im1aKPFRQh4FxuVRMfEORzQm7oh41Luo6O2cQhs 9sTf/vxw/QZQl5QYJwqwyEEtUbIWMMvLOX/W8KUsDsXoaEUaPeS4yXD2yHuthjejEvgT Jh6IwD7kx5za35YtN/trswUgU4uTYfG5hlGB8EkHtMxkJQJvbe3f0PxMsK0KLzW0+XCw 4yzOJYh+iRgEYeVK4lHkB6SZSeWKtcBqNqFQZVNgZWVY8p8Oy+L2kRx7T0QgGExDamPU Glhw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=D2YF4wTz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id gs7si2166067ejc.329.2021.10.25.16.41.53; Mon, 25 Oct 2021 16:42:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=D2YF4wTz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236282AbhJYTeH (ORCPT + 99 others); Mon, 25 Oct 2021 15:34:07 -0400 Received: from mail.kernel.org ([198.145.29.99]:48432 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235590AbhJYT2s (ORCPT ); Mon, 25 Oct 2021 15:28:48 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id B686261163; Mon, 25 Oct 2021 19:25:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1635189922; bh=moWcA6dpsVJM/wKHZ550zbatMX5CE/an+QAtwFM/0Sc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D2YF4wTzrRXmXH5pyBFydxncWXX3Fny9yNPRa3ZyuWUqqwvySd18Z65h82d5LY01M kCrUdRe7nyhT3ORKwCizwwcUSxOtagPjrAD+vMd6CIWOxOxlijj7y2nUjhO+PWdoly 1xaWhKZOxZsk+zIIvNP0IoY8l00tuPtwkhlFtlW8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Filipe Manana , David Sterba , Sasha Levin Subject: [PATCH 4.19 27/37] btrfs: deal with errors when checking if a dir entry exists during log replay Date: Mon, 25 Oct 2021 21:14:52 +0200 Message-Id: <20211025190933.679004667@linuxfoundation.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211025190926.680827862@linuxfoundation.org> References: <20211025190926.680827862@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Filipe Manana [ Upstream commit 77a5b9e3d14cbce49ceed2766b2003c034c066dc ] Currently inode_in_dir() ignores errors returned from btrfs_lookup_dir_index_item() and from btrfs_lookup_dir_item(), treating any errors as if the directory entry does not exists in the fs/subvolume tree, which is obviously not correct, as we can get errors such as -EIO when reading extent buffers while searching the fs/subvolume's tree. Fix that by making inode_in_dir() return the errors and making its only caller, add_inode_ref(), deal with returned errors as well. Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/tree-log.c | 47 ++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index e0fc8c094846..c856c32cc926 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -881,9 +881,11 @@ out: } /* - * helper function to see if a given name and sequence number found - * in an inode back reference are already in a directory and correctly - * point to this inode + * See if a given name and sequence number found in an inode back reference are + * already in a directory and correctly point to this inode. + * + * Returns: < 0 on error, 0 if the directory entry does not exists and 1 if it + * exists. */ static noinline int inode_in_dir(struct btrfs_root *root, struct btrfs_path *path, @@ -892,29 +894,35 @@ static noinline int inode_in_dir(struct btrfs_root *root, { struct btrfs_dir_item *di; struct btrfs_key location; - int match = 0; + int ret = 0; di = btrfs_lookup_dir_index_item(NULL, root, path, dirid, index, name, name_len, 0); - if (di && !IS_ERR(di)) { + if (IS_ERR(di)) { + if (PTR_ERR(di) != -ENOENT) + ret = PTR_ERR(di); + goto out; + } else if (di) { btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); if (location.objectid != objectid) goto out; - } else + } else { goto out; - btrfs_release_path(path); + } + btrfs_release_path(path); di = btrfs_lookup_dir_item(NULL, root, path, dirid, name, name_len, 0); - if (di && !IS_ERR(di)) { - btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); - if (location.objectid != objectid) - goto out; - } else + if (IS_ERR(di)) { + ret = PTR_ERR(di); goto out; - match = 1; + } else if (di) { + btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); + if (location.objectid == objectid) + ret = 1; + } out: btrfs_release_path(path); - return match; + return ret; } /* @@ -1421,10 +1429,12 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, if (ret) goto out; - /* if we already have a perfect match, we're done */ - if (!inode_in_dir(root, path, btrfs_ino(BTRFS_I(dir)), - btrfs_ino(BTRFS_I(inode)), ref_index, - name, namelen)) { + ret = inode_in_dir(root, path, btrfs_ino(BTRFS_I(dir)), + btrfs_ino(BTRFS_I(inode)), ref_index, + name, namelen); + if (ret < 0) { + goto out; + } else if (ret == 0) { /* * look for a conflicting back reference in the * metadata. if we find one we have to unlink that name @@ -1483,6 +1493,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, btrfs_update_inode(trans, root, inode); } + /* Else, ret == 1, we already have a perfect match, we're done. */ ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen; kfree(name); -- 2.33.0