From patchwork Mon Dec 13 20:54:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 12674601 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8088C433FE for ; Mon, 13 Dec 2021 20:54:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241964AbhLMUyg (ORCPT ); Mon, 13 Dec 2021 15:54:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241566AbhLMUyf (ORCPT ); Mon, 13 Dec 2021 15:54:35 -0500 Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88BC6C061574 for ; Mon, 13 Dec 2021 12:54:35 -0800 (PST) Received: by mail-qv1-xf2f.google.com with SMTP id m17so15565135qvx.8 for ; Mon, 13 Dec 2021 12:54:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20210112.gappssmtp.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=rt6J1jl/aBxJbZk/jSZVRC1sIFyk2NwFobsEbPmutEo=; b=lkZZytoeY596h+r7PK8zYq8OZyHrAlTj5G6WLsrLxU0jJxfMlXD1wpIF5kac2tkrj9 WwKQn3sSzztsW0xCdLVRNNjwUbGtXOguu5/XPPx+lebDRBpvFDzKNNIemWgf2Rp39ExG 5J1H010FGCksgc3zHrWbNG99LwLjG972cirYkFgAkyzKSyI5lCvWI8satjQg8TAjGEs1 8paBNSXDEorg3xbAVpknjClkDBv84oaVbD5Rg5vOmTpgcMF6mSt9KbPtS8Dzn8ZSkhL9 9TXXDzGFolXMzWqpiRA3CtQG96bilSjt12QAE0TVPPExErongR+cxbL87ZsfAfFp+RvK l7vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rt6J1jl/aBxJbZk/jSZVRC1sIFyk2NwFobsEbPmutEo=; b=rXY1Ldtne+vFuHahhBYNQDksUZnrVkxpm+qeH2IXPxnKm9qe7WLp7NUA9nGCV8RoeB rN/2bSW4hFiXUKJA9kKdaR2LmJJFFXC+eLPC0TXpKMRlNiUAzjBuFrxIYJblP9c+Ofxq rYlzEM11VqShUVsSEvVXHm9yLLJyIhgj9TeMrsGHxNVjvABL+fiPu1aewP4XUk/yJ0ru Eq3Xh28PGUWZ+rhb3OVn2GQvwFOErRWfoJU1N+UwYuwmAKuN2tvA05Juiqi33vXSXhdB dX2DWEQBsBgbx0i3NrJKxcys/1G3HY9Tx27EcGMiNQdbBk4LoxqPpmt4CUhTlgmTDs6v gFog== X-Gm-Message-State: AOAM532CXEkCkEV4BnyGUDn640PiID2UhitjMP7xM+NF3vEEzn8UcPhG YQYjp1h+3rf45KW1bE0DHSMpG0XlzNIs0Q== X-Google-Smtp-Source: ABdhPJyr2CkaCjRIdKcxchaP9H3ZVvvHAcQKiMSRazgbGVGJXv1NCAef7TL0q/mCcVYSaK7qBeJqzQ== X-Received: by 2002:a0c:edca:: with SMTP id i10mr718444qvr.62.1639428874369; Mon, 13 Dec 2021 12:54:34 -0800 (PST) Received: from localhost (cpe-174-109-172-136.nc.res.rr.com. [174.109.172.136]) by smtp.gmail.com with ESMTPSA id u10sm10452733qtx.3.2021.12.13.12.54.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Dec 2021 12:54:32 -0800 (PST) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 1/2] btrfs-progs: handle orphan directories properly Date: Mon, 13 Dec 2021 15:54:28 -0500 Message-Id: <9386338b4e9f7b7c3a6667150ef1dab1773f8371.1639428656.git.josef@toxicpanda.com> X-Mailer: git-send-email 2.26.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org When implementing the GC tree I started getting btrfsck errors when a test rm -rf with files inside of it and immediately unmount, leaving behind orphaned directory items that have GC items for them. This made me realize that we don't actually handle this case currently for our normal orphan path. If we fail to clean everything up and leave behind the orphan items we'll fail fsck. Fix this by not processing any backrefs we find if we found an inode item and its nlink is 0. This allows us to pass the test case I've provided to validate this patch. Signed-off-by: Josef Bacik --- check/main.c | 15 ++++++++++++++- check/mode-lowmem.c | 6 ++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/check/main.c b/check/main.c index e67d2f72..966a68ab 100644 --- a/check/main.c +++ b/check/main.c @@ -1018,6 +1018,16 @@ static int merge_inode_recs(struct inode_record *src, struct inode_record *dst, int ret = 0; dst->merging = 1; + + /* + * If we wandered into a shared node while we were processing an inode + * we may have added backrefs for a directory that had nlink == 0, so + * skip adding these backrefs to our src inode if we have nlink == 0 and + * we actually found the inode item. + */ + if (src->found_inode_item && src->nlink == 0) + goto skip_backrefs; + list_for_each_entry(backref, &src->backrefs, list) { if (backref->found_dir_index) { add_inode_backref(dst_cache, dst->ino, backref->dir, @@ -1039,7 +1049,7 @@ static int merge_inode_recs(struct inode_record *src, struct inode_record *dst, backref->ref_type, backref->errors); } } - +skip_backrefs: if (src->found_dir_item) dst->found_dir_item = 1; if (src->found_file_extent) @@ -1394,6 +1404,9 @@ static int process_dir_item(struct extent_buffer *eb, rec = active_node->current; rec->found_dir_item = 1; + if (rec->found_inode_item && rec->nlink == 0) + return 0; + di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); total = btrfs_item_size_nr(eb, slot); while (cur < total) { diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c index 696ad215..66e291da 100644 --- a/check/mode-lowmem.c +++ b/check/mode-lowmem.c @@ -2726,6 +2726,8 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path) imode_to_type(mode), key.objectid, key.offset); } + if (has_orphan_item && key.type == BTRFS_DIR_INDEX_KEY) + break; ret = check_dir_item(root, &key, path, &size); err |= ret; break; @@ -2768,7 +2770,7 @@ out: &nlink); } - if (nlink != 1) { + if (nlink > 1) { err |= LINK_COUNT_ERROR; error("root %llu DIR INODE[%llu] shouldn't have more than one link(%llu)", root->objectid, inode_id, nlink); @@ -2784,7 +2786,7 @@ out: gfs_info->nodesize); } - if (isize != size) { + if (isize != size && !has_orphan_item) { if (repair) ret = repair_dir_isize_lowmem(root, path, inode_id, size); From patchwork Mon Dec 13 20:54:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 12674603 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E892AC433EF for ; Mon, 13 Dec 2021 20:54:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242790AbhLMUyi (ORCPT ); Mon, 13 Dec 2021 15:54:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46518 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241566AbhLMUyh (ORCPT ); Mon, 13 Dec 2021 15:54:37 -0500 Received: from mail-qt1-x835.google.com (mail-qt1-x835.google.com [IPv6:2607:f8b0:4864:20::835]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C41E1C061574 for ; Mon, 13 Dec 2021 12:54:36 -0800 (PST) Received: by mail-qt1-x835.google.com with SMTP id 8so16536400qtx.5 for ; Mon, 13 Dec 2021 12:54:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=toxicpanda-com.20210112.gappssmtp.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=HPWL2tmV+j/82fwrmbHL/o55oDNXP1BfYYdklwaVjY0=; b=jRvJkgyOThHm/pBwJEGJ99qeSrsbmfL5NGOaksxA7pgZFPQ6oDyhD14gdZGPg6OnXQ iDn/y/MGBp2OcWmVSUJMPNtbrEhgvLYIzpx/BmFlJ+YYZuuxwPewMl82Mc/z+9z9wyRR mz9bTS2/n7+GrTb+CpuRM+J6v4HEVa1XSHto+jpgwZrDyEwV+eXPJFPBfQydslnv7qlo BJqqVInrfciwm9GjzEj1Z271a7iszG/IKkR5hydQnlCyHYbAnRktYA4uD9W1AMhJiw+5 Krv8XVyxO4wynQ9mJFKlk8I8oNI6JCx4GZWlFLKsIn/BEMxbWl+gzwZj0akpcHrMKyNg 9yUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HPWL2tmV+j/82fwrmbHL/o55oDNXP1BfYYdklwaVjY0=; b=wOOdjMiHGI0CTWu7OpkrGljIfINabUlGlTf+TeZaQIYLq7HZoSMe0N5o0Lk5QQ093C 5RQS5ZxF4HZ1k7nspZm6BPZl0mkvgTDvDohgESlloqh1CPd4Welv63ASjQ6El1j52U9+ znaGtc2OqvtKKLQ3ILdax6edBILV0RyVJy++F5o8/gAQ4qR+RipsPwDm5crV7OaoaFyg rH4VGvZCewtmV4oTReZ9xdwU+rdg0CBLAogfKvDIBNldnoM5aCi2GqXtIaqFkyfdmpma 6Hc94mAOAa2BcqWVaoawKEEpNfIT0b1KmdFARZAT+yDud4pMtw1jigqDTXwb+tAqMZuc Mp7w== X-Gm-Message-State: AOAM532FrAFauQuRwWDRRwTpKLfTzkcahvjSIHu6yOWjlYKYGXuoiBO6 oZpWZMI4ZCAfl0nX05X4t4SL78cwxJEmBg== X-Google-Smtp-Source: ABdhPJzV9JUgZyjDQ+L5p8oyJRammGXR9pahgMFUxaXpxGsExngD82OvKkkQuuUzwFv5UIQMLayPZQ== X-Received: by 2002:ac8:5743:: with SMTP id 3mr938359qtx.440.1639428875644; Mon, 13 Dec 2021 12:54:35 -0800 (PST) Received: from localhost (cpe-174-109-172-136.nc.res.rr.com. [174.109.172.136]) by smtp.gmail.com with ESMTPSA id h16sm10340261qtx.20.2021.12.13.12.54.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Dec 2021 12:54:35 -0800 (PST) From: Josef Bacik To: linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 2/2] btrfs-progs: add a test to check orphaned directories Date: Mon, 13 Dec 2021 15:54:29 -0500 Message-Id: X-Mailer: git-send-email 2.26.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org When adding the GC support I noticed we were failing fsck when we had a directory that hadn't been cleaned up yet because of rm -rf. However this isn't limited to extent-tree-v2, we'll actually fail in the same way if we were unable to do the evict portion of the deletion and left the orphan items around for everybody. This is a valid file system, it'll be cleaned up properly at mount time, so fsck shouldn't fail in this case. Signed-off-by: Josef Bacik --- .../052-orphan-directory/default.img.xz | Bin 0 -> 1432 bytes tests/fsck-tests/052-orphan-directory/test.sh | 20 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/fsck-tests/052-orphan-directory/default.img.xz create mode 100755 tests/fsck-tests/052-orphan-directory/test.sh diff --git a/tests/fsck-tests/052-orphan-directory/default.img.xz b/tests/fsck-tests/052-orphan-directory/default.img.xz new file mode 100644 index 0000000000000000000000000000000000000000..4fac926c579034d29d51065f07ede7f1528f67f7 GIT binary patch literal 1432 zcmV;J1!wyGH+ooF000E$*0e?f03iVu0001VFXf}+Q~w23T>wRyj;C3^v%$$4d1rE0 zjjaF1$3^@a-*CI>b`;Xhem%7aGMP*V_w!KDE5R0R%IUtZRb^s9 zi6n6B>Al(Z6(ck4q8BzTqu}wwoMuwumm_b;EKiEFys%e}Wy|!(G_fi_h+~MXJ*v!* z@OLKOM3;uD5@h-)C*pAwm1MKZL8@)8Fx4fxHjW<>)`e6g5Zm!NQG2}Cra-*62)SQH>=$5N;D zLM%3pZc}+`?rkRWv6>4}Fn$cATpC3hqVBR=9q-6#R0-)Cv(^T!T^t|EJMyV#*Lx0$ zf$^BY!nwl}m6w4}rp>Bh;*?$D`Z0yB_~Xov?rO4k_j5?t8Q&*8i?W?!?mAmKZCuI` z%gJCR%)(WR?_bDW+`#$%Tt|AU_z6xe7R7ZS%%9Os&Lc?G$dNiKqoDnk;MffP4}V9N zd=6Jgv3s~w8vCXvoJMalb-txXc$zKKONI6HCiC3{T0XyE?KUar>YVQnbBIDW@3mph z+fJaSb-Bs2XRuNDn54yg<6>;z(;dbEEMA#YW?jQo?<7Z9tLF4#29`O%V)eC=fe{+@ zOTcDGQK~um*|~2NzP9juZ=P-Z4hvf^4+S(2(_}HP90h+E zUAt|w*rN(OiS2g_A_{WB!x!EI!)NN7AKz>y-4*7gusX@GuK)7rA^6nsyYhfmS=c2S zmTvHr3dg>OxD-C-0OH&hiler`!mpohSrQ zZ4_AJ-GO*{fJne0Aqn|}wma;<$xff>CSI8OA`{QC-tZAdFMafuQTWkEbU5qcPg@;n zB=?3LtMx2@lD@fV?V zp2$zK&{(*L`0ya5+$0hk=O~H)T}&J2bgEzK%`E=vRtkm2b_ZqBl9Hy3WWHN7ly#aWWD)V9wEY+vq6x* zK{I25VZCb|ex+OQdZj+Oe8nQ22S6r}qgqZH@Q^pivE*;Tyug)0=#sr;J=xb6AXkNK z4M-}MG^z0~YX(ExEW{9ZY`Vv%FW;{>7ZY?YmLY9Vb*ly4+t@btt*W$tHKqz2P(!(@ zLjby7n;YV$$h}qS-=*#5>AjJ zHZ+k~u~BE-A8o`$m>Aska*;l6_n{70@b{)EFyyUbN<*QPMB;FW4_|{Y)Nw+J5j?R+ z=H3KRTkCRE@D>im$ZO;&`*U@4M@Lo)0mP1T447cNe(|C=OY>X-?7%+G zrr;G*7ws0{$62R6#9Xmq m0001|VXy=UD-dA-0r3ies0jdS2iv@{#Ao{g000001X)_$1G{+u literal 0 HcmV?d00001 diff --git a/tests/fsck-tests/052-orphan-directory/test.sh b/tests/fsck-tests/052-orphan-directory/test.sh new file mode 100755 index 00000000..f3d380d9 --- /dev/null +++ b/tests/fsck-tests/052-orphan-directory/test.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# We could potentially have a directory and it's children with ORPHAN items left +# for them without having been cleaned up. +# +# fsck shouldn't complain about this or attempt to do anything about it, the +# orphan cleanup will do the correct thing. +# +# To create this image I simply modified the kernel to skip doing the +# btrfs_truncate_inode_items() and removing the orphan item at evict time, and +# then rm -rf'ed a directory. + +source "$TEST_TOP/common" + +check_prereq btrfs + +check_image() { + run_check "$TOP/btrfs" check "$1" +} + +check_all_images