From patchwork Wed Dec 18 22:20:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 11302325 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F22CA14E3 for ; Wed, 18 Dec 2019 22:20:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C59D1218AC for ; Wed, 18 Dec 2019 22:20:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=toxicpanda-com.20150623.gappssmtp.com header.i=@toxicpanda-com.20150623.gappssmtp.com header.b="wDOzv0OX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726695AbfLRWUf (ORCPT ); Wed, 18 Dec 2019 17:20:35 -0500 Received: from mail-qk1-f195.google.com ([209.85.222.195]:35607 "EHLO mail-qk1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726463AbfLRWUe (ORCPT ); Wed, 18 Dec 2019 17:20:34 -0500 Received: by mail-qk1-f195.google.com with SMTP id z76so3349250qka.2 for ; Wed, 18 Dec 2019 14:20:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=ZWYYHNPSb0eeg3q1ywcXRsInbeHmnCPUbkgYRnD6J6o=; b=wDOzv0OXjTKdttWjPB4bFej3YkhxpcPhwrd1oljaSiK/NokTLYn04oYRkYXzvbGQq/ o35JUUbgvf3Wsna5v9kg16DTTUAI5Iln46W92vdY4j8gOWJ5yfE6RSJE0z62zIPJASly FbTZGrNNUWpCjLFU4d2wSByZKtWd5fkMFFwmlWR8TUGoarbgV3DIzxsEb8w0qKMB5xNT y9aLzvdkkbzgWPLlytjMNGHQwecRuOF2WDMdn6dhqJ+9GcMnsaJtfxHLnAEuk8I1Gcxv Dl0rvtMJdOPdOqG/tvpfdfp1k6R7eQSm6WuahovtEUuB16rd4Zc0CJJM0Q36cPr0UDoh KjBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZWYYHNPSb0eeg3q1ywcXRsInbeHmnCPUbkgYRnD6J6o=; b=bo4TJd3Ul/+DUkBIpqtNk7SDdeVQ4MWriORMDEspYaX1v4xifvqh/dDuJVFZ2EEpU0 tl8ldVV3OsF0n991JHZEb3S00nhKRclk6VUYs6MRfsqx8c688aKenJh7rFgGK2MsLnmE XJEuTXf4Jy9ClIJsq1PRTtiUvPWtdaK/Rs1Oex5QRDSgUKAQQvporCEfdA8HmQc9GVKg PLikzZwxWnz9013B7sYRIiXR2QhKIbLAVNj9NBh82vmzezv1nEq4dKGcWj+wl0mxYIIl HfTovvvsPmb95/bsfQ4KT06D/AOz+1XE9c2Qs99cavRyfoQmZzfDsup2GZLKV4NJKBOt qFXA== X-Gm-Message-State: APjAAAWDGq4BKhLZAQcmBKO9LUT1ANQQD3u8PUqeLGZFqc5GrSEy28rC 3+yedDp6L2fGor4NQ+cu2aH7XeVPc6ooYA== X-Google-Smtp-Source: APXvYqxGu5HQZdMwQRD3xm8qZMV2Q/+poOxFpvlmO483VVpH7qY/maPg2qc7RDlL25Gw90x48RdPZg== X-Received: by 2002:a37:c24c:: with SMTP id j12mr5255954qkm.401.1576707633382; Wed, 18 Dec 2019 14:20:33 -0800 (PST) Received: from localhost ([107.15.81.208]) by smtp.gmail.com with ESMTPSA id p185sm1107379qkd.126.2019.12.18.14.20.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2019 14:20:32 -0800 (PST) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 1/3] btrfs: rework arguments for btrfs_unlink_subvol Date: Wed, 18 Dec 2019 17:20:27 -0500 Message-Id: <20191218222029.49178-2-josef@toxicpanda.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191218222029.49178-1-josef@toxicpanda.com> References: <20191218222029.49178-1-josef@toxicpanda.com> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org btrfs_unlink_subvol takes the name of the dentry and the root objectid based on what kind of inode this is, either a real subvolume link or a empty one that we inherited as a snapshot. We need to fix how we unlink in the case for BTRFS_EMPTY_SUBVOL_DIR_OBJECTID in the future, so rework btrfs_unlink_subvol to just take the dentry and handle getting the right objectid given the type of inode this is. There is no functional change here, simply pushing the work into btrfs_unlink_subvol() proper. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c1c6e6afa3bc..3cbdca2749bd 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4234,17 +4234,29 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) } static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, - struct inode *dir, u64 objectid, - const char *name, int name_len) + struct inode *dir, struct dentry *dentry) { struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_path *path; struct extent_buffer *leaf; struct btrfs_dir_item *di; + const char *name = dentry->d_name.name; + struct btrfs_inode *inode = BTRFS_I(d_inode(dentry)); struct btrfs_key key; + int name_len = dentry->d_name.len; u64 index; int ret; u64 dir_ino = btrfs_ino(BTRFS_I(dir)); + u64 objectid; + + if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) { + objectid = inode->root->root_key.objectid; + } else if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { + objectid = inode->location.objectid; + } else { + WARN_ON(1); + return -EINVAL; + } path = btrfs_alloc_path(); if (!path) @@ -4483,8 +4495,7 @@ int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry) btrfs_record_snapshot_destroy(trans, BTRFS_I(dir)); - ret = btrfs_unlink_subvol(trans, dir, dest->root_key.objectid, - dentry->d_name.name, dentry->d_name.len); + ret = btrfs_unlink_subvol(trans, dir, dentry); if (ret) { err = ret; btrfs_abort_transaction(trans, ret); @@ -4579,10 +4590,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) return PTR_ERR(trans); if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { - err = btrfs_unlink_subvol(trans, dir, - BTRFS_I(inode)->location.objectid, - dentry->d_name.name, - dentry->d_name.len); + err = btrfs_unlink_subvol(trans, dir, dentry); goto out; } @@ -9540,7 +9548,6 @@ static int btrfs_rename_exchange(struct inode *old_dir, u64 new_ino = btrfs_ino(BTRFS_I(new_inode)); u64 old_idx = 0; u64 new_idx = 0; - u64 root_objectid; int ret; bool root_log_pinned = false; bool dest_log_pinned = false; @@ -9646,10 +9653,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, /* src is a subvolume */ if (old_ino == BTRFS_FIRST_FREE_OBJECTID) { - root_objectid = BTRFS_I(old_inode)->root->root_key.objectid; - ret = btrfs_unlink_subvol(trans, old_dir, root_objectid, - old_dentry->d_name.name, - old_dentry->d_name.len); + ret = btrfs_unlink_subvol(trans, old_dir, old_dentry); } else { /* src is an inode */ ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir), BTRFS_I(old_dentry->d_inode), @@ -9665,10 +9669,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, /* dest is a subvolume */ if (new_ino == BTRFS_FIRST_FREE_OBJECTID) { - root_objectid = BTRFS_I(new_inode)->root->root_key.objectid; - ret = btrfs_unlink_subvol(trans, new_dir, root_objectid, - new_dentry->d_name.name, - new_dentry->d_name.len); + ret = btrfs_unlink_subvol(trans, new_dir, new_dentry); } else { /* dest is an inode */ ret = __btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir), BTRFS_I(new_dentry->d_inode), @@ -9974,10 +9975,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, BTRFS_I(old_inode), 1); if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) { - root_objectid = BTRFS_I(old_inode)->root->root_key.objectid; - ret = btrfs_unlink_subvol(trans, old_dir, root_objectid, - old_dentry->d_name.name, - old_dentry->d_name.len); + ret = btrfs_unlink_subvol(trans, old_dir, old_dentry); } else { ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir), BTRFS_I(d_inode(old_dentry)), @@ -9997,9 +9995,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (unlikely(btrfs_ino(BTRFS_I(new_inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { root_objectid = BTRFS_I(new_inode)->location.objectid; - ret = btrfs_unlink_subvol(trans, new_dir, root_objectid, - new_dentry->d_name.name, - new_dentry->d_name.len); + ret = btrfs_unlink_subvol(trans, new_dir, new_dentry); BUG_ON(new_inode->i_nlink == 0); } else { ret = btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir), From patchwork Wed Dec 18 22:20:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 11302327 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ADE2C14E3 for ; Wed, 18 Dec 2019 22:20:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8C1B324650 for ; Wed, 18 Dec 2019 22:20:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=toxicpanda-com.20150623.gappssmtp.com header.i=@toxicpanda-com.20150623.gappssmtp.com header.b="CuVWAfL6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726701AbfLRWUg (ORCPT ); Wed, 18 Dec 2019 17:20:36 -0500 Received: from mail-qt1-f195.google.com ([209.85.160.195]:32831 "EHLO mail-qt1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726463AbfLRWUg (ORCPT ); Wed, 18 Dec 2019 17:20:36 -0500 Received: by mail-qt1-f195.google.com with SMTP id d5so3308882qto.0 for ; Wed, 18 Dec 2019 14:20:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=wwpCBdz/UNy2gEku8xMraGS0RW7roLWFiOvYwKlPotU=; b=CuVWAfL6PRtkkpcYIzBixmT+v5g9HwKXcXn9J28iwLWqWZC0bxi3Z2COiKEPPvxAXn xuKJB1lBBTh4H3eICnUSYx2npjXm/STA/MhXoLPFDv4+F4e3aT3JDszQkeC0BCtYe3X+ Jyid3HxTwHpOL7tIzWM0m5oFzAgoP+1xx52p9CY3+LIH8Ttuk1jqe79Y1YOeE0WvLtnm ONGCGv/aceTh5Vs5yxsWJ6n9Zl/5XT46zq2LOcKcFFwjcVMPYKzOLKt+nVpqvNKw9y0m OCMcJJ03Az4F5PB+gm9QtmKiXpEMrWyPxv6GwbtBMV2J7q//d+cHa06l8ojwouqlM3/3 XUDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wwpCBdz/UNy2gEku8xMraGS0RW7roLWFiOvYwKlPotU=; b=Z7LHzGp33tyhwHXuGFDhd7iOJf5M+jko6DpRMjnDlDrfUnnu9Czosq29chH4u2CpRq JR5mt+HitMzbYvfEWEQbjaxfhi4c1WkbOWnCp78veOq94o2PZDsA6C3CSG9VDG0oR5lY omN5cMF+Wkz1DdQHjReklMJcxuHYkWNJY/dYCKWvHtcfuJ9TkK1TWaDGumMv5P4p58hK cH9E7oVgKKfeMy9SEHPFPZoG/C9IhqQ8pEjUu2CmymE+a13oCKo2ZOBYGnlT9kcOjIrW /23W+iTOWmLpr1Sktmi6yzdm5mV0L4TfOIdA2sfSp+7BC9i6I3TM6D2taA2lUIaQEZWf c3QA== X-Gm-Message-State: APjAAAWfGHnzkXDaQxJlnnVPplE4JPDoytzRoT5DdPkkk0085mS+TNPI 7wvi+xQjFvEnLUdXG2Gcu+rTZtp5LS3esw== X-Google-Smtp-Source: APXvYqzNt5X3EHIQY6J/26UKuPlCYjWwmQ80PzxGWvsLGLLWEEHKk4HIqID5ZgaD8OfIbmjdesBxLQ== X-Received: by 2002:ac8:4509:: with SMTP id q9mr4348841qtn.353.1576707635138; Wed, 18 Dec 2019 14:20:35 -0800 (PST) Received: from localhost ([107.15.81.208]) by smtp.gmail.com with ESMTPSA id s63sm1085062qkf.129.2019.12.18.14.20.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2019 14:20:34 -0800 (PST) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 2/3] btrfs: fix invalid removal of root ref Date: Wed, 18 Dec 2019 17:20:28 -0500 Message-Id: <20191218222029.49178-3-josef@toxicpanda.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191218222029.49178-1-josef@toxicpanda.com> References: <20191218222029.49178-1-josef@toxicpanda.com> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org If we have the following sequence of events btrfs sub create /a btrfs sub create /a/b btrfs sub snap /a /c mkdir /c/foo mv /a/b /mnt/test/c/foo rm -rf /mnt/test/* We will end up with a transaction abort. The reason for this is because we create a root ref for b pointing to a. When we create a snapshot of c we still have b in our tree, but because the root ref points to a and not c we will make it appear to be empty. The problem happens when we move b into c. This removes the root ref for b pointing to a and adds a ref of b pointing to c. When we rmdir c we'll see that we have a ref to our root and remove the root ref, despite not actually matching our reference name. Now btrfs_del_root_ref() allowing this to work is a bug as well, however we know that this inode does not actually point to a root ref in the first place, so we shouldn't be calling btrfs_del_root_ref() in the first place and instead simply look up our dir index for this item and do the rest of the removal. Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3cbdca2749bd..db67e1984c91 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4279,13 +4279,16 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, } btrfs_release_path(path); - ret = btrfs_del_root_ref(trans, objectid, root->root_key.objectid, - dir_ino, &index, name, name_len); - if (ret < 0) { - if (ret != -ENOENT) { - btrfs_abort_transaction(trans, ret); - goto out; - } + /* + * This is a placeholder inode for a subvolume we didn't have a + * reference to at the time of the snapshot creation. In the meantime + * we could have renamed the real subvol link into our snapshot, so + * depending on btrfs_del_root_ref to return -ENOENT here is incorret. + * Instead simply lookup the dir_index_item for this entry so we can + * remove it. Otherwise we know we have a ref to the root and we can + * call btrfs_del_root_ref, and it _shouldn't_ fail. + */ + if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { di = btrfs_search_dir_index_item(root, path, dir_ino, name, name_len); if (IS_ERR_OR_NULL(di)) { @@ -4300,8 +4303,16 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); index = key.offset; + btrfs_release_path(path); + } else { + ret = btrfs_del_root_ref(trans, objectid, + root->root_key.objectid, dir_ino, + &index, name, name_len); + if (ret) { + btrfs_abort_transaction(trans, ret); + goto out; + } } - btrfs_release_path(path); ret = btrfs_delete_delayed_dir_index(trans, BTRFS_I(dir), index); if (ret) { From patchwork Wed Dec 18 22:20:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 11302329 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E279614E3 for ; Wed, 18 Dec 2019 22:20:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BFD8924650 for ; Wed, 18 Dec 2019 22:20:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=toxicpanda-com.20150623.gappssmtp.com header.i=@toxicpanda-com.20150623.gappssmtp.com header.b="cjf9iuyb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726719AbfLRWUi (ORCPT ); Wed, 18 Dec 2019 17:20:38 -0500 Received: from mail-qv1-f68.google.com ([209.85.219.68]:32974 "EHLO mail-qv1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726463AbfLRWUh (ORCPT ); Wed, 18 Dec 2019 17:20:37 -0500 Received: by mail-qv1-f68.google.com with SMTP id z3so1432396qvn.0 for ; Wed, 18 Dec 2019 14:20:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=npYbZs/0MvOLk8eHQpDIgHq2hArzrfYft5Zmgh+wzjk=; b=cjf9iuybksC+27NqgZwlI7tvCXWRQle5w4LR6B/di+Q+CMZmvtccl/vVYzkOPG0iIF wQIOs0T3rmom0kJ0H1mMFLzl1U8iekNV8GMYc8DUwi+7zleYZMeBQkCWyz5XiRw/xDQq 44nCcTwhWMVzW+SBpm0YVLgU06SBn9lRkZApuen9rHzxEHhTz0GiqxJIOfbqT+Qbd+y7 DU3vvIpiBIm3SKR62LxNaZDcZV3e85ngtXFCMHVt+J+YpfLrCeq37Hr5Na1wMvFhc96c xO0uxXJTWUrSTs96E3JODm6zgUKapdFWpys63FtOcaKNKTviL7Y2trPdLRo9JkskuD0u dQ5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=npYbZs/0MvOLk8eHQpDIgHq2hArzrfYft5Zmgh+wzjk=; b=QniHQ14588ap7jT4hlRtdhjV/0nfxH9DXSQHV/oEfkgKBNQ6+3bmD4RdyBFL0lW2eJ l8M6GI1DlbGKo4a8UJgFrm+v/OAq0exJdkmweKog93UXTIPDpHoWk6Hn6znqtxlEY/KF 5reVRO0AZsZOUP2z3pcIyQUHyaxVR7dYAL1dwflzbgKHN2gOIdurllBo6I/eUupy1G9r 7ivIPsiP/+ybxTh4Y21gor7qLhnXuLMs0F5ACVGw/wiG3y8N3A6Q9LhK5I7P1bZI/QzM Mlja9rE9Ob9WFHzXX6520syQAmq7yXCi1VLDnKmEkDqYEvI4PH9Tyd2Lkh5bVg0MJHcB MOGg== X-Gm-Message-State: APjAAAUGYP1nz89rzqkZaRnZn5QOSYBLrDQYBE8aE0615Ixir1OT1dGi 8T2S9NKCN/egVIF3vzPitjtLFdfla9p1qA== X-Google-Smtp-Source: APXvYqw7ubTG7lZv5JVCiqFOLPSNEoLSB55iGdTr5bT2vbPbEmdeG1wrCmNIKNSNZcscafSB7jKtsg== X-Received: by 2002:a0c:c351:: with SMTP id j17mr4820178qvi.80.1576707636731; Wed, 18 Dec 2019 14:20:36 -0800 (PST) Received: from localhost ([107.15.81.208]) by smtp.gmail.com with ESMTPSA id f42sm1229613qta.0.2019.12.18.14.20.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Dec 2019 14:20:36 -0800 (PST) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 3/3] btrfs: do not delete mismatched root ref's Date: Wed, 18 Dec 2019 17:20:29 -0500 Message-Id: <20191218222029.49178-4-josef@toxicpanda.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191218222029.49178-1-josef@toxicpanda.com> References: <20191218222029.49178-1-josef@toxicpanda.com> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org btrfs_del_root_ref() will simply WARN_ON() if the ref doesn't match in any way, and then continue to delete the reference. This shouldn't happen, we have these values because there's more to the reference than the original root and the sub root. If any of these checks fail, return -ENOENT. Signed-off-by: Josef Bacik --- fs/btrfs/root-tree.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 0a455f116666..f2a59ec6c1ce 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -346,11 +346,13 @@ int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, leaf = path->nodes[0]; ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); - - WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid); - WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len); ptr = (unsigned long)(ref + 1); - WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len)); + if ((btrfs_root_ref_dirid(leaf, ref) != dirid) || + (btrfs_root_ref_name_len(leaf, ref) != name_len) || + memcmp_extent_buffer(leaf, name, ptr, name_len)) { + err = -ENOENT; + goto out; + } *sequence = btrfs_root_ref_sequence(leaf, ref); ret = btrfs_del_item(trans, tree_root, path);