Received: by 2002:ab2:604e:0:b0:1f4:60f3:cb4a with SMTP id a14csp10450lqm; Fri, 5 Apr 2024 07:24:22 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUlIPXXfMNbdfG1ZUngxKMaIu+6YKFLUXQGKMKrXL4YocmWmahwSBlG53rXz6xzL13bokzZR2oft3EzX49vZ6SQKnYQWL5Ln/xo2DjqMQ== X-Google-Smtp-Source: AGHT+IGCwJxEi+rPvDGqDV7WW+rGief0uAeUXod7bsDMu3nQd2erIYnJmMnVRbCBzLHfi02p9WaD X-Received: by 2002:a4a:a8c9:0:b0:5a4:ae86:118f with SMTP id r9-20020a4aa8c9000000b005a4ae86118fmr1389680oom.8.1712327061786; Fri, 05 Apr 2024 07:24:21 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712327061; cv=pass; d=google.com; s=arc-20160816; b=MPunLDTyzkiCbuAzMBCdwd4jQTGPU51S5ckxc9AeGP3TijZ3r+IGK/lKrqFGEwAdZK hJFpglf2afP+jiP7ftJSb45tyPO92V19w7NRtJ9lw/kYjt83metgYa/MnzjZir3PYUlA WCiQaB9ADKDjm6dFkenMEOOgaJ/m7/svPVEVwUQz5fHZjgfy9ceiR0oMqyhbvLmpRCxV 57K76raa53h0bnswMw8LPejD+7PrJ4A/wBpaI7RRlGxYyzwgklHvTbzTwXgm477q/Pgl p2z1wBInMsLFMdwrdPNKFVZEvPD8C5tJuSg/DvN0mWy+3FHEbmj/qAzwqYlRkzg+nhF3 XxuA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=+I/jBXYRJyhRcK8oWUV/079Yu4qPZYJRmaE9t+GmEsU=; fh=mFjBxWtsA9NPNe3Gkwd5L+dWph7pq0ADh54Ay2V+KKY=; b=wQgonV1U4KpDP8DFHXQhdSxgrwQLQsdUwf0e10NibFnisZRSC6NuzXp0LPvbpdBSvV +YEGXwI30abyu2BNnCOChWyoLVrx4tBoE/xrpk+Pz/cDlDAktScTpL2t06/jgDep3rPf griO6ejw3Z25z0bV6wWwUQpa6Z3Ql2SrFCR6dicmYR6ynYgGGP4QjS2VhoyUJ/jeDen6 l/4EDUqEgh3y1SMXzJrgaU2Uxm/P5FPip/mUMVtwjR0yJM4VhzBnGvlcodIgIdRcQLeD xIFvyjsZVGc29Wu3AiXsc+3X0tpSH2kKgnd04R+3Zn2F/f4QhcUQHNQBu6mQjuGHlt+A JeHw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=QQq15JCH; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-ext4+bounces-1901-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-ext4+bounces-1901-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id p15-20020a05622a00cf00b004314838f893si1870060qtw.558.2024.04.05.07.24.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Apr 2024 07:24:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-ext4+bounces-1901-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=QQq15JCH; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-ext4+bounces-1901-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-ext4+bounces-1901-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id BD0521C22B64 for ; Fri, 5 Apr 2024 14:24:20 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B75D616EC03; Fri, 5 Apr 2024 14:24:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="QQq15JCH" X-Original-To: linux-ext4@vger.kernel.org Received: from out-186.mta1.migadu.com (out-186.mta1.migadu.com [95.215.58.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ABB1216EBEB for ; Fri, 5 Apr 2024 14:24:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.186 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712327053; cv=none; b=gua6IhQEv7XdKFUEnL7iltNSPZ22wnjp+Opz/zA2k2H7p1IYCbkxco4QHSTlWk6yvtxNdEwwS/IVFWdUZ7rOgHziQN0QhnsinPvvLf1x7a5LAF1+z4ihESeEhybqoJgwK10PBK9UZDDfWmQWcm6Nq5ZogMYStt8i8GYx5PAhVFA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712327053; c=relaxed/simple; bh=62OJsOtg1s0aAYcd3xLjgyMBTelKu2nGtnU2O5fEY+A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tufn9cteegFz/FBKISMu445BS4cYBRqbaQrJgaoCFGsTKybKYrLyeE4t/e22+1mAdJYpRWpLD8qDTCbZX0WznRKdCOyhl74ZeTuU7GDXEhVJhvfuvv3aMXTjLn2JePdf6gyWI0WqONTjA8DxEtGGZOultuw/qgm1B9NUK0H/uc0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=QQq15JCH; arc=none smtp.client-ip=95.215.58.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1712327050; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+I/jBXYRJyhRcK8oWUV/079Yu4qPZYJRmaE9t+GmEsU=; b=QQq15JCHF7Gc3lFuSbNlpsaz1eL9G6bHtXOxUULXwidwm+DqBPxD3/+8km+trUFTmeC4Qc cWEYnjAcFZkSwnzbx1x5M4jRc/H6m0615UpCT22uw0xD7+zt62r3/aHqQk4zEGIX6xxttE zcNlgcyDJGk6RVWWSuQHc3ldhR4iD24= From: "Luis Henriques (SUSE)" To: Theodore Ts'o , Andreas Dilger Cc: linux-ext4@vger.kernel.org, "Luis Henriques (SUSE)" Subject: [PATCH v3 2/4] e2fsck: update quota when deallocating a bad inode Date: Fri, 5 Apr 2024 15:24:03 +0100 Message-ID: <20240405142405.12312-3-luis.henriques@linux.dev> In-Reply-To: <20240405142405.12312-1-luis.henriques@linux.dev> References: <20240405142405.12312-1-luis.henriques@linux.dev> Precedence: bulk X-Mailing-List: linux-ext4@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT If a bad inode is found it will be deallocated. However, if the filesystem has quota enabled, the quota information isn't being updated accordingly. This issue was detected by running fstest ext4/019. This patch fixes the issue by decreasing the inode count from the quota and, if blocks are also being released, also subtract them as well. While there, and as suggested by Andreas Dilger, the deallocate_inode() function documentation is also updated by this patch to make it clear what that function really does. Signed-off-by: Luis Henriques (SUSE) --- e2fsck/pass2.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index b91628567a7f..08ab40fa8ba1 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -1854,17 +1854,26 @@ static int deallocate_inode_block(ext2_filsys fs, } /* - * This function deallocates an inode + * This function reverts various counters and bitmaps incremented in + * pass1 for the inode, blocks, and quotas before it was decided the + * inode was corrupt and needed to be cleared. This avoids the need + * to run e2fsck a second time (or have it restart itself) to repair + * these counters. + * + * It does not modify any on-disk state, so even if the inode is bad + * it _should_ reset in-memory state to before the inode was first + * processed. */ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) { ext2_filsys fs = ctx->fs; - struct ext2_inode inode; + struct ext2_inode_large inode; struct problem_context pctx; __u32 count; struct del_block del_block; - e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode"); + e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&inode), + sizeof(inode), "deallocate_inode"); clear_problem_context(&pctx); pctx.ino = ino; @@ -1874,29 +1883,29 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) e2fsck_read_bitmaps(ctx); ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); - if (ext2fs_file_acl_block(fs, &inode) && + if (ext2fs_file_acl_block(fs, EXT2_INODE(&inode)) && ext2fs_has_feature_xattr(fs->super)) { pctx.errcode = ext2fs_adjust_ea_refcount3(fs, - ext2fs_file_acl_block(fs, &inode), + ext2fs_file_acl_block(fs, EXT2_INODE(&inode)), block_buf, -1, &count, ino); if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { pctx.errcode = 0; count = 1; } if (pctx.errcode) { - pctx.blk = ext2fs_file_acl_block(fs, &inode); + pctx.blk = ext2fs_file_acl_block(fs, EXT2_INODE(&inode)); fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx); ctx->flags |= E2F_FLAG_ABORT; return; } if (count == 0) { ext2fs_block_alloc_stats2(fs, - ext2fs_file_acl_block(fs, &inode), -1); + ext2fs_file_acl_block(fs, EXT2_INODE(&inode)), -1); } - ext2fs_file_acl_block_set(fs, &inode, 0); + ext2fs_file_acl_block_set(fs, EXT2_INODE(&inode), 0); } - if (!ext2fs_inode_has_valid_blocks2(fs, &inode)) + if (!ext2fs_inode_has_valid_blocks2(fs, EXT2_INODE(&inode))) goto clear_inode; /* Inline data inodes don't have blocks to iterate */ @@ -1921,10 +1930,22 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) ctx->flags |= E2F_FLAG_ABORT; return; } + + if ((ino != quota_type2inum(PRJQUOTA, fs->super)) && + (ino != fs->super->s_orphan_file_inum) && + (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) && + !(inode.i_flags & EXT4_EA_INODE_FL)) { + if (del_block.num > 0) + quota_data_sub(ctx->qctx, &inode, ino, + del_block.num * EXT2_CLUSTER_SIZE(fs->super)); + quota_data_inodes(ctx->qctx, (struct ext2_inode_large *)&inode, + ino, -1); + } + clear_inode: /* Inode may have changed by block_iterate, so reread it */ - e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode"); - e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode"); + e2fsck_read_inode(ctx, ino, EXT2_INODE(&inode), "deallocate_inode"); + e2fsck_clear_inode(ctx, ino, EXT2_INODE(&inode), 0, "deallocate_inode"); } /*