From patchwork Mon Dec 23 21:46:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919269 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4F6A21422AB for ; Mon, 23 Dec 2024 21:46:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990406; cv=none; b=DXERRmrXTl/LjDD2IA+ncMiKvJdq756UMJmM2A3L7bO1ERa9O0Ghx8DJrkxYSAhVSRaXcne3OZMr0zXld3OPtbYN8OcedBwKF9Y6Vk/+Nt8en55BxbJzXtsnslWgpYHaO5vzp/VW1SVOROpPgvPfOnxEyPP1onLS4C73gowj+fY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990406; c=relaxed/simple; bh=/i/xWxcxXw3UTLs4MnsDx/o6HRamgS1GdBGG0OGlxWc=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sKsaIGpwOHrnhXtSDxo4raHT0R+BgV04CYoHtudvZsfLFjk0564yZzarzK2g2lIwnm51lkcCQezsUJJDzOKybAoOz3B31VhgORHz7dC7ypPwoUUnZZyUtvAYbFgukPH25AIZPPW/KZU53foJk5+CCO9PEAh22FsMC5BTKm05fqY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PuFOouXF; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PuFOouXF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 272EAC4CED3; Mon, 23 Dec 2024 21:46:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990406; bh=/i/xWxcxXw3UTLs4MnsDx/o6HRamgS1GdBGG0OGlxWc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=PuFOouXFDD4Q7NmC1q9WsXyQV7oHxgNHlKl63L77BK8nwcqGN8lnggknEubO4+n+l oCxuuVJaz2/jOZ7ILeTGjPhtdDQMCvZU56NO7XsDZJTZz+UC18qqT/AjP0q03rvUTf ln6VX7UNbafznZcudGuvlZEY7M1fu1WSpz0mRo56FCYaIpRysa+UVsy4zEY4qtPiLF QNcV4wPiapxjZZyMvbnzYxK/nu7Fg2nRYyfZFTzvAYCSEsBN8fVgwTToXLlrirdb5E yT5DkUC6lGPL6Q3jJc610tvjz+VyeUjx0Jz6nDh8M81+hrPUPT4OJYouLtBNXJSiwL wj9ATqsEq29OA== Date: Mon, 23 Dec 2024 13:46:45 -0800 Subject: [PATCH 01/41] libxfs: constify the xfs_inode predicates From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498940981.2294268.10093164403078621177.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Change the xfs_inode predicates to take a const struct xfs_inode pointer because they do not change the inode. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- include/xfs_inode.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 6f2d23987d5f8a..30e171696c80e2 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -248,7 +248,7 @@ typedef struct xfs_inode { struct inode i_vnode; } xfs_inode_t; -static inline bool xfs_inode_has_attr_fork(struct xfs_inode *ip) +static inline bool xfs_inode_has_attr_fork(const struct xfs_inode *ip) { return ip->i_forkoff > 0; } @@ -372,17 +372,17 @@ static inline void drop_nlink(struct inode *inode) inode->i_nlink--; } -static inline bool xfs_is_reflink_inode(struct xfs_inode *ip) +static inline bool xfs_is_reflink_inode(const struct xfs_inode *ip) { return ip->i_diflags2 & XFS_DIFLAG2_REFLINK; } -static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip) +static inline bool xfs_inode_has_bigtime(const struct xfs_inode *ip) { return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME; } -static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip) +static inline bool xfs_inode_has_large_extent_counts(const struct xfs_inode *ip) { return ip->i_diflags2 & XFS_DIFLAG2_NREXT64; } @@ -392,12 +392,12 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip) * Decide if this file is a realtime file whose data allocation unit is larger * than a single filesystem block. */ -static inline bool xfs_inode_has_bigrtalloc(struct xfs_inode *ip) +static inline bool xfs_inode_has_bigrtalloc(const struct xfs_inode *ip) { return XFS_IS_REALTIME_INODE(ip) && ip->i_mount->m_sb.sb_rextsize > 1; } -static inline bool xfs_is_always_cow_inode(struct xfs_inode *ip) +static inline bool xfs_is_always_cow_inode(const struct xfs_inode *ip) { return false; } From patchwork Mon Dec 23 21:47:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919270 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2B8C21422AB for ; Mon, 23 Dec 2024 21:47:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990422; cv=none; b=k36gNRBOd+vg7WYJ6XtBpn5zO/V0VhPsqL9xov5Rv3Xrlk5d2GZj/QF6tHgPxZuXOY7LfaSwwqHtWavnx+wTJHZXFrFFRec+YAScMgsHIVS6krInNnf2E6Uq8XrknV9CClZ4F156ZIgwJCu1xkA8K/jxVPut1Or7RfVMd4r0nyA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990422; c=relaxed/simple; bh=gj7qpNWm8NxrkEGVdzdTQTZ3XWqiMDdL7/2QKqUWsL8=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OzvtM+nuOKuDgcaePwaU7w/FSk0oj2/ztqe7xoIMglkm1qR0xJQ4ueVTZ33LtdhJpsBl/RgSo8UHW4v5/S8/qkzLYvk53v4pc1h35WS0qMMiJhBtRPJTvnLJlpcfrgdVcPmwA5Sz/iTHglQlon2QaVxP3t8lUn6IQnSzhlU1gGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F4QM4Qmf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="F4QM4Qmf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B77EEC4CED3; Mon, 23 Dec 2024 21:47:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990421; bh=gj7qpNWm8NxrkEGVdzdTQTZ3XWqiMDdL7/2QKqUWsL8=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=F4QM4QmfCzMaF5uJ1WmiA4bdljc/kLirQscZlTJDyyAn7QfOi0rg0nqhvchvoTn3i cA0IY2Ca8r6dMvuHxxFaGY36we5sNx4T+DiA1WN+iec/6ONnYJYssQYd7AAHJ5+Lau S//ch936PVQ1Kw0qy6GJxDtKm5M/hp8JYgF6CEa9HmIi15QQZKdP714bLRyivy+tGm TJLatnEmSzkHVc5iAwsON5u9tF+upPsMnanCvvEntlCpNBd1yBIL5wDSZSBeVt370W 9REg+dtCcZrYEIf/oqXaHdfCV1oqv/hQgQEyxjkxC2YXK2urbXnK1fbL2DQnrOFC4u RteYM0Vdjv+aA== Date: Mon, 23 Dec 2024 13:47:01 -0800 Subject: [PATCH 02/41] libxfs: load metadata directory root at mount time From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498940997.2294268.1014315135749449830.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Load the metadata directory root inode into memory at mount time and release it at unmount time. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- include/xfs_mount.h | 1 + libxfs/init.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/xfs_mount.h b/include/xfs_mount.h index c7fada9e2a6d70..6daf3f01ffa9cf 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -91,6 +91,7 @@ typedef struct xfs_mount { uint8_t *m_rsum_cache; struct xfs_inode *m_rbmip; /* pointer to bitmap inode */ struct xfs_inode *m_rsumip; /* pointer to summary inode */ + struct xfs_inode *m_metadirip; /* ptr to metadata directory */ struct xfs_buftarg *m_ddev_targp; struct xfs_buftarg *m_logdev_targp; struct xfs_buftarg *m_rtdev_targp; diff --git a/libxfs/init.c b/libxfs/init.c index beb58706629d23..bf488c5d8533b1 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -619,6 +619,27 @@ libxfs_compute_all_maxlevels( } +/* Mount the metadata files under the metadata directory tree. */ +STATIC void +libxfs_mount_setup_metadir( + struct xfs_mount *mp) +{ + int error; + + /* Ignore filesystems that are under construction. */ + if (mp->m_sb.sb_inprogress) + return; + + error = -libxfs_metafile_iget(mp, mp->m_sb.sb_metadirino, + XFS_METAFILE_DIR, &mp->m_metadirip); + if (error) { + fprintf(stderr, + _("%s: Failed to load metadir root directory, error %d\n"), + progname, error); + return; + } +} + /* * precalculate the low space thresholds for dynamic speculative preallocation. */ @@ -800,6 +821,9 @@ libxfs_mount( } xfs_set_perag_data_loaded(mp); + if (xfs_has_metadir(mp)) + libxfs_mount_setup_metadir(mp); + return mp; out_da: xfs_da_unmount(mp); @@ -918,6 +942,8 @@ libxfs_umount( int error; libxfs_rtmount_destroy(mp); + if (mp->m_metadirip) + libxfs_irele(mp->m_metadirip); /* * Purge the buffer cache to write all dirty buffers to disk and free From patchwork Mon Dec 23 21:47:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919271 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 802DC1D7982 for ; Mon, 23 Dec 2024 21:47:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990437; cv=none; b=QeVlrQZkgePT/a1THdf/ifPMMZkCZrdmsdcTVZGvPRqreJO2MR5W1x01fQ719om5BQVJ+mkHQ4HoJzXmTzlaI32MSRNQ0lMpp4UKHOp361fph6Qks4FHR5pg6/UhpPUcxkTlH7aDD4I6xDtnbdIMx2yG1+uMTe5B40sW+6o5NIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990437; c=relaxed/simple; bh=kWE442pT3RSOyEdCIrLuZKELUQVa+ZtuM6POBwDpYms=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MGLNGvPaFikIUM9hj8cGdfVVdJdZv6Xt0Yan8VYZ/B49ahSZTG/fxxFBENh8uAs/6WTD+tPcTsFS6wJd5YQjDD3BmpTqMbzF9tKzVBYS8qV0a46Plu9CPRrYwS212eQMGwNnIoF0mVhet9/T9pHbaTGZG6Z4iMgkK+T3efHyVJ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F1eSpHWS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="F1eSpHWS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58718C4CED6; Mon, 23 Dec 2024 21:47:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990437; bh=kWE442pT3RSOyEdCIrLuZKELUQVa+ZtuM6POBwDpYms=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=F1eSpHWSB2UsqvH0tHpZRG9EAa0YBpResCQaKMW6U/2ST61urUpBErJMxdBVQPvn5 kuIC/V11EvBdjSFbuHLXm7gtNixoGVkEInpsF6fwFJ69JWgu7Sm04x27fFdTUr9e7s HWGxWPhXi0sM43A9abR6o/ZzZFOeG2ODBCrlyPkELe8c72SAZP1399EJvdVMPL5Aqm Nv5qAH90XomeIQwIYHL78u20YaxdsIgKqFyNS0BVIjmseDSAYXh+kWk6WXvqJ9SD7g z1pCsxTuScYwOIRTmQS/ahS/OqkIhas7WYFKlFzTrk2yNBkQphomsAWNwzApwkqkqF +XFqzkE9ltSPw== Date: Mon, 23 Dec 2024 13:47:16 -0800 Subject: [PATCH 03/41] libxfs: enforce metadata inode flag From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941012.2294268.4220474805447112535.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Add checks for the metadata inode flag so that we don't ever leak metadata inodes out to userspace, and we don't ever try to read a regular inode as metadata. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- libxfs/inode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libxfs/inode.c b/libxfs/inode.c index 1eb0bccae48906..0598a70ff504a4 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -208,7 +208,8 @@ libxfs_iget( /* * Get a metadata inode. * - * The metafile type must match the file mode exactly. + * The metafile type must match the file mode exactly, and for files in the + * metadata directory tree, it must match the inode's metatype exactly. */ int libxfs_trans_metafile_iget( @@ -232,6 +233,12 @@ libxfs_trans_metafile_iget( mode = S_IFREG; if (inode_wrong_type(VFS_I(ip), mode)) goto bad_rele; + if (xfs_has_metadir(mp)) { + if (!xfs_is_metadir_inode(ip)) + goto bad_rele; + if (metafile_type != ip->i_metatype) + goto bad_rele; + } *ipp = ip; return 0; From patchwork Mon Dec 23 21:47:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919272 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2C0571C3F3B for ; Mon, 23 Dec 2024 21:47:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990453; cv=none; b=hpktmYa1nanHiI6+xswnmq7HbfGOcHz1Mp0n3nrFFmV7TsNzf8nTdNrHzPFeMHW/8fZ6KlypnQAVzkgK55OcW6fCn+2A8DOWHz3xaM6367sOI+2Fa/tyres+Q+uyhlvfZUgtjHNYAO2RBkf9ReJGdhFWi9gM3167SrCWLg5F9oc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990453; c=relaxed/simple; bh=pXhYa2gE5pPlF/6ULKSW+UCWJjWyrGPD9Q/kjczkelQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=syRg4jSkl9TeDbUPKdlCwxyD+R+PEf8ufGwfMSqIeUEfWoDGXR7Ci3o/efS5EUSKgkgKBWIgygZ3dOa1cjDDwoBhUuU2lZwYbkdn7CjnstIuJnKYRm7OaXBtbTXTSk86Gj5sywS9WjWu1MQ/QilrdqxCxeuPdMU8e+w5qcmyJ8A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AwamiJja; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AwamiJja" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1F19C4CED3; Mon, 23 Dec 2024 21:47:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990453; bh=pXhYa2gE5pPlF/6ULKSW+UCWJjWyrGPD9Q/kjczkelQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=AwamiJja8GCqyo0OgKkqcVHhAZ+t53nBez34OWl6mlaZ5foeP2AI+K/lGHhTukocw JL1k45EpQhQRSwXfGS87S4uKilLITyZcNzcvfMsM8LdsphbuCozLsT++c3YL9mL3fm yYfmASg/mUewq32YEbHMQF/91SofQspPnyZJeolFm2fS1Nk7emUMpuWdYPFqu/olUl gNjFkhP3mzz8XOcvkRWLntkbpTU4AiWwseRBk4ug1Sak/1UN7auTTFmttYl+vfKa23 aIlHkYYhwO9seQIKz2iqe8Q+49nr9D5+KS+nJPEITef4C7pEtF0zq6l5hIBr3NVFvU aPwb/hevm/DaA== Date: Mon, 23 Dec 2024 13:47:32 -0800 Subject: [PATCH 04/41] man2: document metadata directory flag in fsgeom ioctl From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941028.2294268.16295120792966671511.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Document the additions to the fsgeometry ioctl for metadata directory trees. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- man/man2/ioctl_xfs_fsgeometry.2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man/man2/ioctl_xfs_fsgeometry.2 b/man/man2/ioctl_xfs_fsgeometry.2 index db7698fa922b87..c808ad5b8b9190 100644 --- a/man/man2/ioctl_xfs_fsgeometry.2 +++ b/man/man2/ioctl_xfs_fsgeometry.2 @@ -214,6 +214,9 @@ .SH FILESYSTEM FEATURE FLAGS .TP .B XFS_FSOP_GEOM_FLAGS_EXCHANGE_RANGE Filesystem can exchange file contents atomically via XFS_IOC_EXCHANGE_RANGE. +.TP +.B XFS_FSOP_GEOM_FLAGS_METADIR +Filesystem contains a metadata directory tree. .RE .SH XFS METADATA HEALTH REPORTING .PP From patchwork Mon Dec 23 21:47:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919273 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 0447519048A for ; Mon, 23 Dec 2024 21:47:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990469; cv=none; b=hvpGi8RA/z0/9HQ53iDe1VSAAcDE6yqVQjUVP5YPuE3q9DY/lMz4ZMdByUg1lhPcyF6KFuvePeICjSI1vCQw1xL2+hsIJC5ifemYhILvw/uGg7bjFAbUYNw3ebtkwzN14o3BpXIRU9ljc174wUQVmRkvr/NdSQAMe7qNdlEke68= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990469; c=relaxed/simple; bh=akE/wcExpLX95MMF+L9aQW6VQ++Jq3oAyIOZT9m0rVQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ROnwqr2dCgIjO4Hi+gn2EcTbovpSH3w/2o/LqioYO9wUwmNXoC3d8SBx4By1y6VC5+/yAVJk4CLHxhC+ArBW/s/UYWCCzcBzDcm0GyvDfo8koTQtfuBWS0Ss3gRVhp/U1Gs4eF9W+fwErgJw+rD/vMM8uD4+0LO12vW7cVzexNU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ilXBBNLG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ilXBBNLG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8D0D8C4CED3; Mon, 23 Dec 2024 21:47:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990468; bh=akE/wcExpLX95MMF+L9aQW6VQ++Jq3oAyIOZT9m0rVQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ilXBBNLG9H91H/ujK31IFvmPWw8cLHYTwoMYRDUN6qNY1rseJu5JfUKBne45X3G7m B7WEqH+NZJUDtqpq6oBAou5t4QsXIBF6w5mH416yKS96uqyi7QGHi5pKAEpdwSsEOv jqbHADwoht/YJH+hb6DqooIwJxJOKOqmTrRSSv50qO9lMHjPoFqZ4FHjnCWxh4wg4o lDfBu9GJdc/xvEUqv5DjApFAszKvAV8lkvL3X/CKtKNLTic09hN+RCTCkulquRkiT0 Qvq8MWpPA7TBNiu1q4InEK+p54DuVPlXMuID4zOpSPtebeT4ZLXzeBB9a0hp6q/UGC ldZX9z57jtOUw== Date: Mon, 23 Dec 2024 13:47:48 -0800 Subject: [PATCH 05/41] man: update scrub ioctl documentation for metadir From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941044.2294268.13829508656235306083.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Update the scrub ioctl manpage to reflect the new metadir path scrubber. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- man/man2/ioctl_xfs_scrub_metadata.2 | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/man/man2/ioctl_xfs_scrub_metadata.2 b/man/man2/ioctl_xfs_scrub_metadata.2 index 44aa139b297a3b..1e7e327b37d226 100644 --- a/man/man2/ioctl_xfs_scrub_metadata.2 +++ b/man/man2/ioctl_xfs_scrub_metadata.2 @@ -200,6 +200,50 @@ .SH DESCRIPTION Mark everything healthy after a clean scrub run. This clears out all the indirect health problem markers that might remain in the system. + +.TP +.B XFS_SCRUB_TYPE_METAPATH +Check that a metadata directory path actually points to the active metadata +inode. +Metadata inodes are usually cached for the duration of the mount, so this +scrubber ensures that the same inode will still be reachable after an unmount +and mount cycle. +Discrepancies can happen if the directory or parent pointer scrubbers rebuild +a metadata directory but lose a link in the process. +The +.B sm_ino +field should be passed one of the following special values to communicate which +path to check: + +.RS 7 +.TP +.B XFS_SCRUB_METAPATH_RTDIR +Realtime metadata file subdirectory. +.TP +.B XFS_SCRUB_METAPATH_RTBITMAP +Realtime bitmap file. +.TP +.B XFS_SCRUB_METAPATH_RTSUMMARY +Realtime summary file. +.TP +.B XFS_SCRUB_METAPATH_QUOTADIR +Quota metadata file subdirectory. +.TP +.B XFS_SCRUB_METAPATH_USRQUOTA +User quota file. +.TP +.B XFS_SCRUB_METAPATH_GRPQUOTA +Group quota file. +.TP +.B XFS_SCRUB_METAPATH_PRJQUOTA +Project quota file. +.RE + +The values of +.I sm_agno +and +.I sm_gen +must be zero. .RE .PD 1 From patchwork Mon Dec 23 21:48:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919274 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 551CA1BEF82 for ; Mon, 23 Dec 2024 21:48:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990484; cv=none; b=hPenoJPv6wvAVLRyQfz9PWOQTNKRUevKeaFfVqr2JgtV26KAy1nMmvC3QZJz2AVKcB7AATTcSsmx10JsAGPmCKef7xk3YL8KZXwrZicBIwvLo5Zx/qDLo0Ngl+7gW7diWw0UIXNsWf/qcLCwpQiiOgh5p6VzuoCHa9i16LXN0bA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990484; c=relaxed/simple; bh=W8bhfVdWK9yKQzEud1e5pZ+bRh6V44J6gLhVwOguJoc=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=k+0Ufwq0Gr+TxFpi9J/M3E7KMfpoowDeWjfWELSyGzPrMvZywKJhI/N25c8wBYbhiMvLaW39CdkEp/PeB3qZCslUiNBs+7cmMFOBb822NOTE6FxZ2/ajEvoiYUa8EDqJqgkKi/BioDCXwvgO9fF6N/A2H9ZIsG2hGjBtv4YkZbc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MEY6OEVY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MEY6OEVY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2A48BC4CED3; Mon, 23 Dec 2024 21:48:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990484; bh=W8bhfVdWK9yKQzEud1e5pZ+bRh6V44J6gLhVwOguJoc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=MEY6OEVYwy8f9hxxjb6nuSV7yE5VgjJgIJCMAXl/YInENyJmMOaTdgamQ6c0xYa52 UsUwXlAHeMG0x1uVWZUl7A4x4u8HYAYJ27/3vTPhNmfLI6/LOuuyA0NNdTOArk3wi4 W7T1Quv6Wb5eiOPYmVyrBiKle9YkMyF2f/IpU5QEzHWZ6CUuG+vePh/Opwy4BA6d1D YOHj19iOuqn2aXblFNkiygJ2YCMShtWlEQpdI7zC4iaO7MhYwwbYo9iKfBsaqcYlmI 7DwZTP7kD6ad8KDokB363kyuGEjsygw7k22RQfe+ZwDcmBZEijYvYUhulG8wymZc6p fysaxtn+rrFww== Date: Mon, 23 Dec 2024 13:48:03 -0800 Subject: [PATCH 06/41] libfrog: report metadata directories in the geometry report From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941059.2294268.4436654414999820175.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Report the presence of a metadata directory tree in the geometry report. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- libfrog/fsgeom.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c index 597c38b1140250..67b4e65713be5b 100644 --- a/libfrog/fsgeom.c +++ b/libfrog/fsgeom.c @@ -33,6 +33,7 @@ xfs_report_geom( int nrext64; int exchangerange; int parent; + int metadir; isint = geo->logstart > 0; lazycount = geo->flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0; @@ -53,13 +54,14 @@ xfs_report_geom( nrext64 = geo->flags & XFS_FSOP_GEOM_FLAGS_NREXT64 ? 1 : 0; exchangerange = geo->flags & XFS_FSOP_GEOM_FLAGS_EXCHANGE_RANGE ? 1 : 0; parent = geo->flags & XFS_FSOP_GEOM_FLAGS_PARENT ? 1 : 0; + metadir = geo->flags & XFS_FSOP_GEOM_FLAGS_METADIR ? 1 : 0; printf(_( "meta-data=%-22s isize=%-6d agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n" " =%-22s reflink=%-4u bigtime=%u inobtcount=%u nrext64=%u\n" -" =%-22s exchange=%-3u\n" +" =%-22s exchange=%-3u metadir=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d, ftype=%d, parent=%d\n" @@ -70,7 +72,7 @@ xfs_report_geom( "", geo->sectsize, attrversion, projid32bit, "", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled, "", reflink_enabled, bigtime_enabled, inobtcount, nrext64, - "", exchangerange, + "", exchangerange, metadir, "", geo->blocksize, (unsigned long long)geo->datablocks, geo->imaxpct, "", geo->sunit, geo->swidth, From patchwork Mon Dec 23 21:48:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919275 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 F388F19259D for ; Mon, 23 Dec 2024 21:48:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990500; cv=none; b=AcM+ozT7XYIoa70DfL+NXdOO5pY0N0VT5jVH4lLKtNQiSJe4KhiYdO6xXyG4AX++yANIsNjzerbbo/1yl8vEy8aUmeJtzUL2x+bcyctRJi0CKJhA/Xzu63XmYG+6cu3cLwf96MyKBRiWCEBLN+AUQrLy58HOHWwk/szOpF2qg1Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990500; c=relaxed/simple; bh=px8gqbE8jCVa8R9TGm/mMoCBtya3uZX7RMJnMJrYs/4=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=B2lTXwXz5I6mAH3yTEMN5cLgxMzGOs7U7F8KBm8py/swDp5hpj0E+DR8qLi5uRX/5G45WL3nOIczmRG120r4I3acorIwMcn7CV5o+BKppPQd7z3NuP2wQPcQkQcnIT0x1JSGojOV/GuriWHK2vUJpXb1xxW8+hjYRNCTeD4k39w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=o1dw7m3G; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="o1dw7m3G" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CF3A0C4CED3; Mon, 23 Dec 2024 21:48:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990499; bh=px8gqbE8jCVa8R9TGm/mMoCBtya3uZX7RMJnMJrYs/4=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=o1dw7m3GtAw4L/mkh9E7SFgjWuoaYungIyFm05xYrAxw96/4NMW18iyMhwW8ucNng 3k7MAILG8HOiPgbjpS5zny2l+xP4vhWWCVjnBzvJNCMVH7OVe40QgvCxB+qYSr6E9Z B5AkLRFvMgsjwUlC4PyQrlWsKGbsCadiCm80jTZ9pHg+ZYcAtXKHkiSGNUb+K9K2AD +k3hbY5tPTMGhoE7TVmHPG703y1VgYkkXRYWTGZ1aBAcuR8jfF1P3BFidCLWUJQKCK YLNOH6CD3YxReh6qL+QqK4qCC8l+h8l1T5zLMnqckSwDLr3LyqETP3f9Yoe9Rqqxs2 YRDI+Js2pACOw== Date: Mon, 23 Dec 2024 13:48:19 -0800 Subject: [PATCH 07/41] libfrog: allow METADIR in xfrog_bulkstat_single5 From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941074.2294268.6364367114782702645.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong This is a valid flag for a single-file bulkstat, so add that to the filter. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- libfrog/bulkstat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c index c863bcb6bf89b8..6eceef2a8fa6b9 100644 --- a/libfrog/bulkstat.c +++ b/libfrog/bulkstat.c @@ -53,7 +53,8 @@ xfrog_bulkstat_single5( struct xfs_bulkstat_req *req; int ret; - if (flags & ~(XFS_BULK_IREQ_SPECIAL | XFS_BULK_IREQ_NREXT64)) + if (flags & ~(XFS_BULK_IREQ_SPECIAL | XFS_BULK_IREQ_NREXT64 | + XFS_BULK_IREQ_METADIR)) return -EINVAL; if (xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_NREXT64) From patchwork Mon Dec 23 21:48:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919276 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E03EF19048A for ; Mon, 23 Dec 2024 21:48:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990516; cv=none; b=B/wSlU9erKKr8jWRxNyeCgr2z4JBBtk1vp0M5z2kjb9X0mVe59O8auAFuLZ0sCXJENHLdeyetC1A9JC+AddUAQ2gi3U5ICTBskgHDyC5TsTVmQbPssValLOLShahRDJK8NMlfJLPLfECSvfYHNaMpY9ZFr+3kdFPmKt5UIM1mIg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990516; c=relaxed/simple; bh=u4VGsM8ngB0B3hDN54rJQ9YgmCLjUJ8WJVh/7na0sEo=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GudIkrSn/RnYM1FYol2wOippW5doE9DYCxz4tJ4wQhy82NmvU5H8MX242PSG+pBjKBL1fnWM8rrQuDEfwA8P4nQ4uroDXgrOWr7Y+fExHTm0fEh6hVhP6wAX/LWTUrxIJIhcMs5uums8NkM6IpAG6vtzOnqqYSRgc5gZ8e1iDa8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=URcFkfSD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="URcFkfSD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73AE8C4CED3; Mon, 23 Dec 2024 21:48:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990515; bh=u4VGsM8ngB0B3hDN54rJQ9YgmCLjUJ8WJVh/7na0sEo=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=URcFkfSD/DibVe9x9QU0DaZDND/fr7Tt7SzJB8Y6iRopMrEeP8zsQ3k2mmgwwi2Qf o1dVSB3RpRZW1KnC3c256m/za3WdBc99RZEFQnQ/8QbUG9l6TacSBUatg7Rn1x/+Co 8OCTucGRPEGW0Ef6mlMc0Gm4kFUJWfuxdTvN7flLWR/7YD49iTZrVpzZmLOY2RCrk5 jJC0F4vm2lAnlnfqWu1MhScdpKZcIbnGGBUjgHE+Yfv7uefxDtJG9wGS4uujOMkvlw H2vn+SY67ur07CXLbhu0wSgf/gvVCYtIvcCuOJsDNGQFRXlDZyRgXzQICvSiZwKndv ar2Od9Q1ACApg== Date: Mon, 23 Dec 2024 13:48:34 -0800 Subject: [PATCH 08/41] xfs_io: support scrubbing metadata directory paths From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941090.2294268.13647827378022473290.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Support invoking the metadata directory path scrubber from xfs_io for testing. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- libfrog/scrub.c | 14 +++++++++++++- libfrog/scrub.h | 2 ++ scrub/scrub.c | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/libfrog/scrub.c b/libfrog/scrub.c index e233c0f9c8e1e6..b2d58c7a966b0d 100644 --- a/libfrog/scrub.c +++ b/libfrog/scrub.c @@ -154,8 +154,20 @@ const struct xfrog_scrub_descr xfrog_scrubbers[XFS_SCRUB_TYPE_NR] = { .descr = "directory tree structure", .group = XFROG_SCRUB_GROUP_INODE, }, + [XFS_SCRUB_TYPE_METAPATH] = { + .name = "metapath", + .descr = "metadata directory paths", + .group = XFROG_SCRUB_GROUP_METAPATH, + }, +}; + +const struct xfrog_scrub_descr xfrog_metapaths[XFS_SCRUB_METAPATH_NR] = { + [XFS_SCRUB_METAPATH_PROBE] = { + .name = "probe", + .descr = "metapath", + .group = XFROG_SCRUB_GROUP_NONE, + }, }; -#undef DEP /* Invoke the scrub ioctl. Returns zero or negative error code. */ int diff --git a/libfrog/scrub.h b/libfrog/scrub.h index b564c0d7bd0f55..a35d3e9c293fe5 100644 --- a/libfrog/scrub.h +++ b/libfrog/scrub.h @@ -15,6 +15,7 @@ enum xfrog_scrub_group { XFROG_SCRUB_GROUP_INODE, /* per-inode metadata */ XFROG_SCRUB_GROUP_ISCAN, /* metadata requiring full inode scan */ XFROG_SCRUB_GROUP_SUMMARY, /* summary metadata */ + XFROG_SCRUB_GROUP_METAPATH, /* metadata directory path */ }; /* Catalog of scrub types and names, indexed by XFS_SCRUB_TYPE_* */ @@ -25,6 +26,7 @@ struct xfrog_scrub_descr { }; extern const struct xfrog_scrub_descr xfrog_scrubbers[XFS_SCRUB_TYPE_NR]; +extern const struct xfrog_scrub_descr xfrog_metapaths[XFS_SCRUB_METAPATH_NR]; int xfrog_scrub_metadata(struct xfs_fd *xfd, struct xfs_scrub_metadata *meta); diff --git a/scrub/scrub.c b/scrub/scrub.c index 44c4049899d29e..bcd63eea1030a6 100644 --- a/scrub/scrub.c +++ b/scrub/scrub.c @@ -53,6 +53,22 @@ static const unsigned int scrub_deps[XFS_SCRUB_TYPE_NR] = { }; #undef DEP +static int +format_metapath_descr( + char *buf, + size_t buflen, + struct xfs_scrub_vec_head *vhead) +{ + const struct xfrog_scrub_descr *sc; + + if (vhead->svh_ino >= XFS_SCRUB_METAPATH_NR) + return snprintf(buf, buflen, _("unknown metadir path %llu"), + (unsigned long long)vhead->svh_ino); + + sc = &xfrog_metapaths[vhead->svh_ino]; + return snprintf(buf, buflen, "%s", _(sc->descr)); +} + /* Describe the current state of a vectored scrub. */ int format_scrubv_descr( @@ -89,6 +105,8 @@ format_scrubv_descr( case XFROG_SCRUB_GROUP_ISCAN: case XFROG_SCRUB_GROUP_NONE: return snprintf(buf, buflen, _("%s"), _(sc->descr)); + case XFROG_SCRUB_GROUP_METAPATH: + return format_metapath_descr(buf, buflen, vhead); } return -1; } From patchwork Mon Dec 23 21:48:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919277 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 3D8751422AB for ; Mon, 23 Dec 2024 21:48:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990531; cv=none; b=ExZROAKRCKgkBQP7KgD8t8/p0lTt5/ogG5tvZtZ217x2dHu0LLfWC4KNEPluDeq2FFJWoDWzYE+XTeHLHamauXozvNKkV8AUWrq2QOJsOL4Xx1fTuzSrL9LEJM0SFEY/1/aWaMrW02UwuIcHk2mUzZLYlyhw8bRfQnhYBI5boSQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990531; c=relaxed/simple; bh=voXgngq/bwGPPRW3vqkvRgXGV+PFRu/J9E94Egb20yw=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VP+I4ZGQ8usLxn7j7v7EtwMCLWEMIdqTHQcjqB+fRV6Z0BZorCq8/OiVm+UyINGoul+4mzqKI98wXHqzo0/yV8rk2PfEZVGfvnTYqSoiMf1HrXGTkIr9lpgDnWoiFgHgxnKXGGxf7oI6ulUhd3CHHUwKW/aCGfL0GPiXOtWzEvY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H+PsOsL0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="H+PsOsL0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14C61C4CED3; Mon, 23 Dec 2024 21:48:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990531; bh=voXgngq/bwGPPRW3vqkvRgXGV+PFRu/J9E94Egb20yw=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=H+PsOsL0fav/Pa49ABndHNypNOTzwsy6mPPyhSfHLAMTFAVeh4YHDskUAyd69rcxf gH/n54C+gmMIiE7HHK7qT7/+vIMU38pdXZIiKOTvI0XnPIWHqVI/KEV2wB0D9KuSs+ LAne4DDBvk0TIVPd5auSSQ5AvxXYFTvJgfxfFt6M/5jbHTyL6bEIK28cG5kaXsuf30 Ej1VArzTBJ0xRc0/UuSK9reoJc+bekHB/3S/korgqX4SLVc9VHlQQOl8o3YDcLpX+h Ob9GHbqAhAIpmTI59If97ZNlU8Kj2TBCUNyIe3AQ9HRwQRoFXtRNiGaI/Wkcam24Er P7NN/E71qLw+A== Date: Mon, 23 Dec 2024 13:48:50 -0800 Subject: [PATCH 09/41] xfs_db: disable xfs_check when metadir is enabled From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941106.2294268.4061755876736342352.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong As of July 2024, xfs_repair can detect more types of corruptions than xfs_check does. I don't think it makes sense to maintain the xfs_check code anymore, so let's just turn it off for any filesystem that has metadata directory trees. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- db/check.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/db/check.c b/db/check.c index fb7b6cb41a3fbf..37306bd7a6ac2d 100644 --- a/db/check.c +++ b/db/check.c @@ -831,6 +831,12 @@ blockget_f( dbprefix = oldprefix; return 0; } + + if (xfs_has_metadir(mp)) { + dbprefix = oldprefix; + return 0; + } + check_rootdir(); /* * Check that there are no blocks either From patchwork Mon Dec 23 21:49:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919278 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 3FB431422AB for ; Mon, 23 Dec 2024 21:49:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990547; cv=none; b=aLOojJYRTYrVoq7RYEzuDK1hIFtV/lIZS4fZXuRvC3i1hqjww7ewK3TVPtszgZc8JHbBcO3yrcY3cAqsSRhYpRerZr1snFmMBtepR8EMAVHlWiuPGbEznyV1SnqayJtcPbSelJ0GUu9KXQRtboQ87HNk8iVgYa6k95f/8S71rME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990547; c=relaxed/simple; bh=nziJQXVtNGQWDTn/nOrd+uzhPF2xU9JGJeIpLMT9bDo=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EOUNNF4MlDa9T+versDl8Ro0j5yL3ERtStROUUTh5KWunuvNVxc/hP2ipjoTIakTFWMxty+mkHC+rg17ErsaJi/3ZAkl2qiZGUQGrwDna8H9y/9YcTowDz+wz37xkaA7BQMMSibjj5ame5QasZYtqSlw8IPePOI02G91gpW5azg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lnDn3dRH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lnDn3dRH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AC3D5C4CED3; Mon, 23 Dec 2024 21:49:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990546; bh=nziJQXVtNGQWDTn/nOrd+uzhPF2xU9JGJeIpLMT9bDo=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=lnDn3dRHGV0OkfuX3u53j1FDOjg0Ew0I22ZJWUFeUUoxYdo1XEBFtwdFfJ8Og5eeH QIKQ2tolt+eSXu795lOKUxchnd1Xk5zqqv8jDSo3ZjpNnTXQt5tuOg0SdKv1iQt+nf ds3rA5C7d7cXIL1e7Xu+xYpvaSVlwhC8lC4BNHC4nWk+g+LtoIHmi6cwZ2lTnnrCB1 dKSYo7951HijXbGPZYwJtKoaXTQhhOKd+fkL/gn6mvxDb+zO4SfAXDYd07O3iVgsc+ OP+6nNnK0EUTxwSUyIr48Six7CDTfUQR5xp/YXosOpPZCwJlat7K6ROajIfSr2fkc6 IdQCr+IbEZiOA== Date: Mon, 23 Dec 2024 13:49:06 -0800 Subject: [PATCH 10/41] xfs_db: report metadir support for version command From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941121.2294268.1474501519126070613.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Report metadir support if we have it enabled. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- db/inode.c | 3 +++ db/sb.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/db/inode.c b/db/inode.c index 246febb5929aa1..0aff68083508cb 100644 --- a/db/inode.c +++ b/db/inode.c @@ -207,6 +207,9 @@ const field_t inode_v3_flds[] = { { "nrext64", FLDT_UINT1, OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_NREXT64_BIT - 1), C1, 0, TYP_NONE }, + { "metadata", FLDT_UINT1, + OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_METADATA_BIT-1), C1, + 0, TYP_NONE }, { NULL } }; diff --git a/db/sb.c b/db/sb.c index 9fcb7340f8b02f..4f115650e1283f 100644 --- a/db/sb.c +++ b/db/sb.c @@ -710,6 +710,8 @@ version_string( strcat(s, ",EXCHANGE"); if (xfs_has_parent(mp)) strcat(s, ",PARENT"); + if (xfs_has_metadir(mp)) + strcat(s, ",METADIR"); return s; } From patchwork Mon Dec 23 21:49:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919279 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8925B1422AB for ; Mon, 23 Dec 2024 21:49:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990562; cv=none; b=b2GpaQ2bvLKW9fdqBuAkFBl3iPubwDli8uJOoWWLG2+PtcTQ3KRTnmJ7TwJFZ9JhgsdWDw7J2CF1kgzZ+7fNB06gEOvmV4B1DQTaptEXBpQZbzTdDGYnGRxlOtvT6NJSBbRbSBS9rQwrPr5onlLVVAlcIc72drYHFFLGL6e2Tl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990562; c=relaxed/simple; bh=HbuJ2XWtW/6GfNknfVpMEnk+GidFtv2xMi5j3Xtqf0s=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=AdpeS9RFCYP/ODitzyh2j9/42M2jUpa5yGbGvJcDdalAQ+alaZBDb6orfnJho69Ct0Pb2b7ytdCwmD0X/4Y4p3bs16HekuWlv3JIQkYdaWB5N0wimLVRqIQssHtN7bCboSlibQFwbFdY96atxAb+a3DnVfTl3IoE1i6Spch0Y4M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UP+212rx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UP+212rx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E56BC4CED3; Mon, 23 Dec 2024 21:49:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990562; bh=HbuJ2XWtW/6GfNknfVpMEnk+GidFtv2xMi5j3Xtqf0s=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=UP+212rx056wwZ0R9gvrfllACR2CBUj4IE9Eh05Inc/UmhbPi3bwMEFVMjfAp0qp0 jmiYSMq2OSipezueGPoVzxLdU49+mIcvefztSNnUC7FAYtGkxIfPnFBYg1lAfbZE8H TsHdOfiK6zMZ/3GLQCP6F6z5FNwDG8V/rZQMhmtnL6xkUk7V2SsdkBw4btopYdZVC+ 9oSmRIozdB2zkLpA6XZVdCasKVuEOnqaZVLkAe5ZZ42EOY4FlU1+gJPYPK59sCMQ2Q w1cdS3pMYrXTTrhRL88KAUQmcOXMcBN0ENb4lzBqLokF1B5o9jniX+yR7UJmmQ2B5/ AQXDyjNXwM8Sg== Date: Mon, 23 Dec 2024 13:49:21 -0800 Subject: [PATCH 11/41] xfs_db: don't obfuscate metadata directories and attributes From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941137.2294268.13704149813177314948.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Don't obfuscate the directory and attribute names of metadata inodes. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- db/metadump.c | 385 +++++++++++++++++++++++++++------------------------------ 1 file changed, 183 insertions(+), 202 deletions(-) diff --git a/db/metadump.c b/db/metadump.c index 5c57c1293a53cb..144ebfbfe2a90e 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -1056,10 +1056,26 @@ generate_obfuscated_name( free(orig_name); } +static inline bool +is_metadata_ino( + struct xfs_dinode *dip) +{ + if (!xfs_has_metadir(mp) || dip->di_version < 3) + return false; + return dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA); +} + +static inline bool +want_obfuscate_dirents(bool is_meta) +{ + return metadump.obfuscate && !is_meta; +} + static void process_sf_dir( struct xfs_dinode *dip) { + bool is_meta = is_metadata_ino(dip); struct xfs_dir2_sf_hdr *sfp; xfs_dir2_sf_entry_t *sfep; uint64_t ino_dir_size; @@ -1105,7 +1121,7 @@ process_sf_dir( (char *)sfp); } - if (metadump.obfuscate) + if (want_obfuscate_dirents(is_meta)) generate_obfuscated_name( libxfs_dir2_sf_get_ino(mp, sfp, sfep), namelen, &sfep->name[0]); @@ -1201,7 +1217,8 @@ maybe_obfuscate_pptr( uint8_t *name, int namelen, const void *value, - int valuelen) + int valuelen, + bool is_meta) { unsigned char old_name[MAXNAMELEN]; struct remap_ent *remap; @@ -1210,7 +1227,7 @@ maybe_obfuscate_pptr( xfs_ino_t parent_ino; int error; - if (!metadump.obfuscate) + if (!metadump.obfuscate || is_meta) return; if (!(attr_flags & XFS_ATTR_PARENT)) @@ -1274,9 +1291,10 @@ want_obfuscate_attr( const void *name, unsigned int namelen, const void *value, - unsigned int valuelen) + unsigned int valuelen, + bool is_meta) { - if (!metadump.obfuscate) + if (!metadump.obfuscate || is_meta) return false; /* @@ -1289,15 +1307,15 @@ want_obfuscate_attr( return true; } +/* + * Obfuscate the attr names and fill the actual values with 'v' (to see a valid + * string length, as opposed to NULLs). + */ static void process_sf_attr( struct xfs_dinode *dip) { - /* - * with extended attributes, obfuscate the names and fill the actual - * values with 'v' (to see a valid string length, as opposed to NULLs) - */ - + bool is_meta = is_metadata_ino(dip); struct xfs_attr_sf_hdr *hdr = XFS_DFORK_APTR(dip); struct xfs_attr_sf_entry *asfep = libxfs_attr_sf_firstentry(hdr); int ino_attr_size; @@ -1338,9 +1356,9 @@ process_sf_attr( if (asfep->flags & XFS_ATTR_PARENT) { maybe_obfuscate_pptr(asfep->flags, name, namelen, - value, asfep->valuelen); + value, asfep->valuelen, is_meta); } else if (want_obfuscate_attr(asfep->flags, name, namelen, - value, asfep->valuelen)) { + value, asfep->valuelen, is_meta)) { generate_obfuscated_name(0, asfep->namelen, name); memset(value, 'v', asfep->valuelen); } @@ -1442,7 +1460,8 @@ static void process_dir_data_block( char *block, xfs_fileoff_t offset, - int is_block_format) + int is_block_format, + bool is_meta) { /* * we have to rely on the fileoffset and signature of the block to @@ -1549,7 +1568,7 @@ process_dir_data_block( dir_offset) return; - if (metadump.obfuscate) + if (want_obfuscate_dirents(is_meta)) generate_obfuscated_name(be64_to_cpu(dep->inumber), dep->namelen, &dep->name[0]); dir_offset += length; @@ -1574,7 +1593,8 @@ process_symlink_block( xfs_fsblock_t s, xfs_filblks_t c, typnm_t btype, - xfs_fileoff_t last) + xfs_fileoff_t last, + bool is_meta) { struct bbmap map; char *link; @@ -1599,7 +1619,7 @@ process_symlink_block( if (xfs_has_crc((mp))) link += sizeof(struct xfs_dsymlink_hdr); - if (metadump.obfuscate) + if (want_obfuscate_dirents(is_meta)) obfuscate_path_components(link, XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize)); if (metadump.zero_stale_data) { @@ -1650,7 +1670,8 @@ add_remote_vals( static void process_attr_block( char *block, - xfs_fileoff_t offset) + xfs_fileoff_t offset, + bool is_meta) { struct xfs_attr_leafblock *leaf; struct xfs_attr3_icleaf_hdr hdr; @@ -1730,10 +1751,10 @@ process_attr_block( if (entry->flags & XFS_ATTR_PARENT) { maybe_obfuscate_pptr(entry->flags, name, local->namelen, value, - valuelen); + valuelen, is_meta); } else if (want_obfuscate_attr(entry->flags, name, local->namelen, value, - valuelen)) { + valuelen, is_meta)) { generate_obfuscated_name(0, local->namelen, name); memset(value, 'v', valuelen); @@ -1759,7 +1780,7 @@ process_attr_block( /* do not obfuscate obviously busted pptr */ add_remote_vals(be32_to_cpu(remote->valueblk), be32_to_cpu(remote->valuelen)); - } else if (metadump.obfuscate) { + } else if (want_obfuscate_dirents(is_meta)) { generate_obfuscated_name(0, remote->namelen, &remote->name[0]); add_remote_vals(be32_to_cpu(remote->valueblk), @@ -1792,7 +1813,8 @@ process_single_fsb_objects( xfs_fsblock_t s, xfs_filblks_t c, typnm_t btype, - xfs_fileoff_t last) + xfs_fileoff_t last, + bool is_meta) { int rval = 1; char *dp; @@ -1862,12 +1884,13 @@ process_single_fsb_objects( process_dir_leaf_block(dp); } else { process_dir_data_block(dp, o, - last == mp->m_dir_geo->fsbcount); + last == mp->m_dir_geo->fsbcount, + is_meta); } iocur_top->need_crc = 1; break; case TYP_ATTR: - process_attr_block(dp, o); + process_attr_block(dp, o, is_meta); iocur_top->need_crc = 1; break; default: @@ -1900,7 +1923,8 @@ process_multi_fsb_dir( xfs_fsblock_t s, xfs_filblks_t c, typnm_t btype, - xfs_fileoff_t last) + xfs_fileoff_t last, + bool is_meta) { char *dp; int rval = 1; @@ -1944,7 +1968,8 @@ process_multi_fsb_dir( process_dir_leaf_block(dp); } else { process_dir_data_block(dp, o, - last == mp->m_dir_geo->fsbcount); + last == mp->m_dir_geo->fsbcount, + is_meta); } iocur_top->need_crc = 1; write: @@ -1963,6 +1988,38 @@ process_multi_fsb_dir( return rval; } +static typnm_t +ifork_data_type( + struct xfs_dinode *dip, + int whichfork) +{ + xfs_ino_t ino = be64_to_cpu(dip->di_ino); + + if (whichfork == XFS_ATTR_FORK) + return TYP_ATTR; + + switch (be16_to_cpu(dip->di_mode) & S_IFMT) { + case S_IFDIR: + return TYP_DIR2; + case S_IFLNK: + return TYP_SYMLINK; + case S_IFREG: + if (ino == mp->m_sb.sb_rbmino) + return TYP_RTBITMAP; + if (ino == mp->m_sb.sb_rsumino) + return TYP_RTSUMMARY; + if (ino == mp->m_sb.sb_uquotino) + return TYP_DQBLK; + if (ino == mp->m_sb.sb_gquotino) + return TYP_DQBLK; + if (ino == mp->m_sb.sb_pquotino) + return TYP_DQBLK; + return TYP_DATA; + default: + return TYP_NONE; + } +} + static bool is_multi_fsb_object( struct xfs_mount *mp, @@ -1981,13 +2038,14 @@ process_multi_fsb_objects( xfs_fsblock_t s, xfs_filblks_t c, typnm_t btype, - xfs_fileoff_t last) + xfs_fileoff_t last, + bool is_meta) { switch (btype) { case TYP_DIR2: - return process_multi_fsb_dir(o, s, c, btype, last); + return process_multi_fsb_dir(o, s, c, btype, last, is_meta); case TYP_SYMLINK: - return process_symlink_block(o, s, c, btype, last); + return process_symlink_block(o, s, c, btype, last, is_meta); default: print_warning("bad type for multi-fsb object %d", btype); return 1; @@ -1997,10 +2055,13 @@ process_multi_fsb_objects( /* inode copy routines */ static int process_bmbt_reclist( - xfs_bmbt_rec_t *rp, - int numrecs, - typnm_t btype) + struct xfs_dinode *dip, + int whichfork, + struct xfs_bmbt_rec *rp, + int numrecs) { + bool is_meta = is_metadata_ino(dip); + typnm_t btype = ifork_data_type(dip, whichfork); int i; xfs_fileoff_t o, op = NULLFILEOFF; xfs_fsblock_t s; @@ -2009,7 +2070,6 @@ process_bmbt_reclist( xfs_fileoff_t last; xfs_agnumber_t agno; xfs_agblock_t agbno; - bool is_multi_fsb = is_multi_fsb_object(mp, btype); int rval = 1; if (btype == TYP_DATA) @@ -2077,12 +2137,12 @@ process_bmbt_reclist( } /* multi-extent blocks require special handling */ - if (is_multi_fsb) + if (is_multi_fsb_object(mp, btype)) rval = process_multi_fsb_objects(o, s, c, btype, - last); + last, is_meta); else rval = process_single_fsb_objects(o, s, c, btype, - last); + last, is_meta); if (!rval) break; } @@ -2090,6 +2150,11 @@ process_bmbt_reclist( return rval; } +struct scan_bmap { + struct xfs_dinode *dip; + int whichfork; +}; + static int scanfunc_bmap( struct xfs_btree_block *block, @@ -2097,8 +2162,9 @@ scanfunc_bmap( xfs_agblock_t agbno, int level, typnm_t btype, - void *arg) /* ptr to itype */ + void *arg) { + struct scan_bmap *sbm = arg; int i; xfs_bmbt_ptr_t *pp; int nrecs; @@ -2113,8 +2179,8 @@ scanfunc_bmap( typtab[btype].name, agno, agbno); return 1; } - return process_bmbt_reclist(xfs_bmbt_rec_addr(mp, block, 1), - nrecs, *(typnm_t*)arg); + return process_bmbt_reclist(sbm->dip, sbm->whichfork, + xfs_bmbt_rec_addr(mp, block, 1), nrecs); } if (nrecs > mp->m_bmap_dmxr[1]) { @@ -2149,23 +2215,17 @@ scanfunc_bmap( static int process_btinode( struct xfs_dinode *dip, - typnm_t itype) + int whichfork) { - xfs_bmdr_block_t *dib; - int i; - xfs_bmbt_ptr_t *pp; - int level; - int nrecs; + struct xfs_bmdr_block *dib = + (struct xfs_bmdr_block *)XFS_DFORK_PTR(dip, whichfork); + int level = be16_to_cpu(dib->bb_level); + int nrecs = be16_to_cpu(dib->bb_numrecs); int maxrecs; - int whichfork; - typnm_t btype; - - whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK; - btype = (itype == TYP_ATTR) ? TYP_BMAPBTA : TYP_BMAPBTD; - - dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); - level = be16_to_cpu(dib->bb_level); - nrecs = be16_to_cpu(dib->bb_numrecs); + typnm_t btype = (whichfork == XFS_ATTR_FORK) ? + TYP_BMAPBTA : TYP_BMAPBTD; + xfs_bmbt_ptr_t *pp; + int i; if (level > XFS_BM_MAXLEVELS(mp, whichfork)) { if (metadump.show_warnings) @@ -2176,8 +2236,8 @@ process_btinode( } if (level == 0) { - return process_bmbt_reclist(xfs_bmdr_rec_addr(dib, 1), - nrecs, itype); + return process_bmbt_reclist(dip, whichfork, + xfs_bmdr_rec_addr(dib, 1), nrecs); } maxrecs = libxfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0); @@ -2204,6 +2264,10 @@ process_btinode( } for (i = 0; i < nrecs; i++) { + struct scan_bmap sbm = { + .dip = dip, + .whichfork = whichfork, + }; xfs_agnumber_t ag; xfs_agblock_t bno; @@ -2220,7 +2284,7 @@ process_btinode( continue; } - if (!scan_btree(ag, bno, level, btype, &itype, scanfunc_bmap)) + if (!scan_btree(ag, bno, level, btype, &sbm, scanfunc_bmap)) return 0; } return 1; @@ -2229,19 +2293,13 @@ process_btinode( static int process_exinode( struct xfs_dinode *dip, - typnm_t itype) + int whichfork) { - int whichfork; - int used; - xfs_extnum_t nex, max_nex; + xfs_extnum_t max_nex = xfs_iext_max_nextents( + xfs_dinode_has_large_extent_counts(dip), whichfork); + xfs_extnum_t nex = xfs_dfork_nextents(dip, whichfork); + int used = nex * sizeof(struct xfs_bmbt_rec); - whichfork = (itype == TYP_ATTR) ? XFS_ATTR_FORK : XFS_DATA_FORK; - - nex = xfs_dfork_nextents(dip, whichfork); - max_nex = xfs_iext_max_nextents( - xfs_dinode_has_large_extent_counts(dip), - whichfork); - used = nex * sizeof(xfs_bmbt_rec_t); if (nex > max_nex || used > XFS_DFORK_SIZE(dip, mp, whichfork)) { if (metadump.show_warnings) print_warning("bad number of extents %llu in inode %lld", @@ -2257,52 +2315,52 @@ process_exinode( XFS_DFORK_SIZE(dip, mp, whichfork) - used); - return process_bmbt_reclist((xfs_bmbt_rec_t *)XFS_DFORK_PTR(dip, - whichfork), nex, itype); + return process_bmbt_reclist(dip, whichfork, + (struct xfs_bmbt_rec *)XFS_DFORK_PTR(dip, whichfork), + nex); } static int process_inode_data( - struct xfs_dinode *dip, - typnm_t itype) + struct xfs_dinode *dip) { switch (dip->di_format) { - case XFS_DINODE_FMT_LOCAL: - if (!(metadump.obfuscate || metadump.zero_stale_data)) - break; + case XFS_DINODE_FMT_LOCAL: + if (!(metadump.obfuscate || metadump.zero_stale_data)) + break; - /* - * If the fork size is invalid, we can't safely do - * anything with this fork. Leave it alone to preserve - * the information for diagnostic purposes. - */ - if (XFS_DFORK_DSIZE(dip, mp) > XFS_LITINO(mp)) { - print_warning( + /* + * If the fork size is invalid, we can't safely do anything + * with this fork. Leave it alone to preserve the information + * for diagnostic purposes. + */ + if (XFS_DFORK_DSIZE(dip, mp) > XFS_LITINO(mp)) { + print_warning( "Invalid data fork size (%d) in inode %llu, preserving contents!", - XFS_DFORK_DSIZE(dip, mp), - (long long)metadump.cur_ino); - break; - } + XFS_DFORK_DSIZE(dip, mp), + (long long)metadump.cur_ino); + break; + } - switch (itype) { - case TYP_DIR2: - process_sf_dir(dip); - break; + switch (be16_to_cpu(dip->di_mode) & S_IFMT) { + case S_IFDIR: + process_sf_dir(dip); + break; - case TYP_SYMLINK: - process_sf_symlink(dip); - break; + case S_IFLNK: + process_sf_symlink(dip); + break; - default: - break; - } + default: break; + } + break; - case XFS_DINODE_FMT_EXTENTS: - return process_exinode(dip, itype); + case XFS_DINODE_FMT_EXTENTS: + return process_exinode(dip, XFS_DATA_FORK); - case XFS_DINODE_FMT_BTREE: - return process_btinode(dip, itype); + case XFS_DINODE_FMT_BTREE: + return process_btinode(dip, XFS_DATA_FORK); } return 1; } @@ -2375,28 +2433,22 @@ process_inode( /* copy appropriate data fork metadata */ switch (be16_to_cpu(dip->di_mode) & S_IFMT) { - case S_IFDIR: - rval = process_inode_data(dip, TYP_DIR2); - if (dip->di_format == XFS_DINODE_FMT_LOCAL) - need_new_crc = true; - break; - case S_IFLNK: - rval = process_inode_data(dip, TYP_SYMLINK); - if (dip->di_format == XFS_DINODE_FMT_LOCAL) - need_new_crc = true; - break; - case S_IFREG: - rval = process_inode_data(dip, TYP_DATA); - break; - case S_IFIFO: - case S_IFCHR: - case S_IFBLK: - case S_IFSOCK: - process_dev_inode(dip); + case S_IFDIR: + case S_IFLNK: + case S_IFREG: + rval = process_inode_data(dip); + if (dip->di_format == XFS_DINODE_FMT_LOCAL) need_new_crc = true; - break; - default: - break; + break; + case S_IFIFO: + case S_IFCHR: + case S_IFBLK: + case S_IFSOCK: + process_dev_inode(dip); + need_new_crc = true; + break; + default: + break; } nametable_clear(); if (!rval) @@ -2406,20 +2458,17 @@ process_inode( if (XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp)) { attr_data.remote_val_count = 0; switch (dip->di_aformat) { - case XFS_DINODE_FMT_LOCAL: - need_new_crc = true; - if (metadump.obfuscate || - metadump.zero_stale_data) - process_sf_attr(dip); - break; - - case XFS_DINODE_FMT_EXTENTS: - rval = process_exinode(dip, TYP_ATTR); - break; - - case XFS_DINODE_FMT_BTREE: - rval = process_btinode(dip, TYP_ATTR); - break; + case XFS_DINODE_FMT_LOCAL: + need_new_crc = true; + if (metadump.obfuscate || metadump.zero_stale_data) + process_sf_attr(dip); + break; + case XFS_DINODE_FMT_EXTENTS: + rval = process_exinode(dip, XFS_ATTR_FORK); + break; + case XFS_DINODE_FMT_BTREE: + rval = process_btinode(dip, XFS_ATTR_FORK); + break; } nametable_clear(); } @@ -2796,70 +2845,6 @@ scan_ag( return rval; } -static int -copy_ino( - xfs_ino_t ino, - typnm_t itype) -{ - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_agino_t agino; - int offset; - int rval = 1; - - if (ino == 0 || ino == NULLFSINO) - return 1; - - agno = XFS_INO_TO_AGNO(mp, ino); - agino = XFS_INO_TO_AGINO(mp, ino); - agbno = XFS_AGINO_TO_AGBNO(mp, agino); - offset = XFS_AGINO_TO_OFFSET(mp, agino); - - if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || - offset >= mp->m_sb.sb_inopblock) { - if (metadump.show_warnings) - print_warning("invalid %s inode number (%lld)", - typtab[itype].name, (long long)ino); - return 1; - } - - push_cur(); - set_cur(&typtab[TYP_INODE], XFS_AGB_TO_DADDR(mp, agno, agbno), - blkbb, DB_RING_IGN, NULL); - if (iocur_top->data == NULL) { - print_warning("cannot read %s inode %lld", - typtab[itype].name, (long long)ino); - rval = !metadump.stop_on_read_error; - goto pop_out; - } - off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); - - metadump.cur_ino = ino; - rval = process_inode_data(iocur_top->data, itype); -pop_out: - pop_cur(); - return rval; -} - - -static int -copy_sb_inodes(void) -{ - if (!copy_ino(mp->m_sb.sb_rbmino, TYP_RTBITMAP)) - return 0; - - if (!copy_ino(mp->m_sb.sb_rsumino, TYP_RTSUMMARY)) - return 0; - - if (!copy_ino(mp->m_sb.sb_uquotino, TYP_DQBLK)) - return 0; - - if (!copy_ino(mp->m_sb.sb_gquotino, TYP_DQBLK)) - return 0; - - return copy_ino(mp->m_sb.sb_pquotino, TYP_DQBLK); -} - static int copy_log(void) { @@ -3296,10 +3281,6 @@ metadump_f( } } - /* copy realtime and quota inode contents */ - if (!exitcode) - exitcode = !copy_sb_inodes(); - /* copy log */ if (!exitcode && !(metadump.version == 1 && metadump.external_log)) exitcode = !copy_log(); From patchwork Mon Dec 23 21:49:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919280 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2B31D1422AB for ; Mon, 23 Dec 2024 21:49:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990578; cv=none; b=imTtlmJRZjGrxArOF72DNL2n+AfaPUMt5MuBpDnqnse9Mgr1gqqBc1zrVyd/PIlrB4XSKbm12nEIjRULqvvxMC0hXDSm6P7IZLF9+WAahsfS2YYhAr/EN50OsezHH/e0HJEYoIc75AzbwR78VwIEY94cXBiZoHe9CsQNKEDb1Ps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990578; c=relaxed/simple; bh=2/LpO6eeGlLSzIXJagOneP9csxmrYp+BLRLF/BCLbu8=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gMNT6VK4u9ii5YlUYwzkBzEEiavxdm1tRrYMVOSmoYGp3XaiM+NiDlazaW4fCQ3vsIbqsuUWmab9g2Vkrf/vHyumvwndH8EhVySH7Mf5tN9i1Fkdnvv0NlFPltGl1sjIRYpOp7D6PGW+kcdLADGdf4J/aPTvmaopqhazVrNgtnI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QIcjmuHB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QIcjmuHB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 002CEC4CED3; Mon, 23 Dec 2024 21:49:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990578; bh=2/LpO6eeGlLSzIXJagOneP9csxmrYp+BLRLF/BCLbu8=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=QIcjmuHBmDlnXaAQ2ORghF3uetENH7DUHF3k3tA2YH2ZssPx+5JfydiDLnVvn8l09 w/YK9ONsEFKFneN2C0wZvb34jTW6vmLydFmKDTy0kDKrliFyhGc4nxWkd7L+Dri6hu oxsMxTMYOmi2XaD/aXRIhTP7EtfV/4+mmcr1grFYCDKkTtQxjPRdKymI2uJ/EGXEnI w83WghjxdnZkJpH8ehfPkreBa9aYIuGiqjy7Ns6xdLW1G9Mid03KIS7bPaPVUJGm+6 nmHyV8VSqVcRjjvTRh2/STYB+qW5HZaAqi6WayxDWWhb79wmyBk2kprv+IOjPRp2QF wfYUEoRKzNQ4Q== Date: Mon, 23 Dec 2024 13:49:37 -0800 Subject: [PATCH 12/41] xfs_db: support metadata directories in the path command From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941152.2294268.1905536511412544802.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Teach various directory tree debugger commands to traverse the metadata directory tree by adding a -m switch to select that tree. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- db/namei.c | 71 ++++++++++++++++++++++++++++++++++++++++++++--------- man/man8/xfs_db.8 | 23 ++++++++++++++--- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/db/namei.c b/db/namei.c index 8c7f4932fce4a3..4eae4e8fd3232c 100644 --- a/db/namei.c +++ b/db/namei.c @@ -139,11 +139,11 @@ path_navigate( /* Walk a directory path to an inode and set the io cursor to that inode. */ static int path_walk( + xfs_ino_t rootino, char *path) { struct dirpath *dirpath; char *p = path; - xfs_ino_t rootino = mp->m_sb.sb_rootino; int error = 0; if (*p == '/') { @@ -173,6 +173,9 @@ path_help(void) dbprintf(_( "\n" " Navigate to an inode via directory path.\n" +"\n" +" Options:\n" +" -m -- Walk an absolute path down the metadata directory tree.\n" )); } @@ -181,18 +184,34 @@ path_f( int argc, char **argv) { + xfs_ino_t rootino = mp->m_sb.sb_rootino; int c; int error; - while ((c = getopt(argc, argv, "")) != -1) { + while ((c = getopt(argc, argv, "m")) != -1) { switch (c) { + case 'm': + /* Absolute path, start from metadata rootdir. */ + if (!xfs_has_metadir(mp)) { + dbprintf( + _("filesystem does not support metadata directories.\n")); + exitcode = 1; + return 0; + } + rootino = mp->m_sb.sb_metadirino; + break; default: path_help(); return 0; } } - error = path_walk(argv[optind]); + if (argc == optind || argc > optind + 1) { + dbprintf(_("Only supply one path.\n")); + return -1; + } + + error = path_walk(rootino, argv[optind]); if (error) { dbprintf("%s: %s\n", argv[optind], strerror(error)); exitcode = 1; @@ -206,7 +225,7 @@ static struct cmdinfo path_cmd = { .altname = NULL, .cfunc = path_f, .argmin = 1, - .argmax = 1, + .argmax = -1, .canpush = 0, .args = "", .help = path_help, @@ -519,6 +538,7 @@ ls_help(void) " Options:\n" " -i -- Resolve the given paths to their corresponding inode numbers.\n" " If no paths are given, display the current inode number.\n" +" -m -- Walk an absolute path down the metadata directory tree.\n" "\n" " Directory contents will be listed in the format:\n" " dir_cookie inode_number type hash name_length name\n" @@ -530,15 +550,26 @@ ls_f( int argc, char **argv) { + xfs_ino_t rootino = mp->m_sb.sb_rootino; bool inum_only = false; int c; int error = 0; - while ((c = getopt(argc, argv, "i")) != -1) { + while ((c = getopt(argc, argv, "im")) != -1) { switch (c) { case 'i': inum_only = true; break; + case 'm': + /* Absolute path, start from metadata rootdir. */ + if (!xfs_has_metadir(mp)) { + dbprintf( + _("filesystem does not support metadata directories.\n")); + exitcode = 1; + return 0; + } + rootino = mp->m_sb.sb_metadirino; + break; default: ls_help(); return 0; @@ -561,7 +592,7 @@ ls_f( for (c = optind; c < argc; c++) { push_cur(); - error = path_walk(argv[c]); + error = path_walk(rootino, argv[c]); if (error) goto err_cur; @@ -860,11 +891,22 @@ parent_f( int argc, char **argv) { + xfs_ino_t rootino = mp->m_sb.sb_rootino; int c; int error = 0; - while ((c = getopt(argc, argv, "")) != -1) { + while ((c = getopt(argc, argv, "m")) != -1) { switch (c) { + case 'm': + /* Absolute path, start from metadata rootdir. */ + if (!xfs_has_metadir(mp)) { + dbprintf( + _("filesystem does not support metadata directories.\n")); + exitcode = 1; + return 0; + } + rootino = mp->m_sb.sb_metadirino; + break; default: ls_help(); return 0; @@ -884,7 +926,7 @@ parent_f( for (c = optind; c < argc; c++) { push_cur(); - error = path_walk(argv[c]); + error = path_walk(rootino, argv[c]); if (error) goto err_cur; @@ -912,7 +954,7 @@ static struct cmdinfo parent_cmd = { .argmin = 0, .argmax = -1, .canpush = 0, - .args = "[paths...]", + .args = "[-m] [paths...]", .help = parent_help, }; @@ -926,6 +968,7 @@ link_help(void) "\n" " Options:\n" " -i -- Point to this specific inode number.\n" +" -m -- Select the metadata directory tree.\n" " -p -- Point to the inode given by this path.\n" " -t -- Set the file type to this value.\n" " name -- Create this directory entry with this name.\n" @@ -1039,11 +1082,12 @@ link_f( { xfs_ino_t child_ino = NULLFSINO; int ftype = XFS_DIR3_FT_UNKNOWN; + xfs_ino_t rootino = mp->m_sb.sb_rootino; unsigned int i; int c; int error = 0; - while ((c = getopt(argc, argv, "i:p:t:")) != -1) { + while ((c = getopt(argc, argv, "i:mp:t:")) != -1) { switch (c) { case 'i': errno = 0; @@ -1054,9 +1098,12 @@ link_f( return 0; } break; + case 'm': + rootino = mp->m_sb.sb_metadirino; + break; case 'p': push_cur(); - error = path_walk(optarg); + error = path_walk(rootino, optarg); if (error) { printf("%s: %s\n", optarg, strerror(error)); exitcode = 1; @@ -1126,7 +1173,7 @@ static struct cmdinfo link_cmd = { .argmin = 0, .argmax = -1, .canpush = 0, - .args = "[-i ino] [-p path] [-t ftype] name", + .args = "[-i ino] [-m] [-p path] [-t ftype] name", .help = link_help, }; diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 998553684586c7..066f124458b286 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -992,7 +992,7 @@ .SH COMMANDS .I label is given, the current filesystem label is printed. .TP -.BI "link [-i " ino "] [-p " path "] [-t " ftype "] name" +.BI "link [-i " ino "] [-m] [-p " path "] [-t " ftype "] name" In the current directory, create a directory entry with the given .I name pointing to a file. @@ -1005,6 +1005,10 @@ .SH COMMANDS child file unless the .I ftype option is given. +The +.B -m +option specifies that the path lookup should be done in the metadata directory +tree. The file being targetted must not be on the iunlink list. .TP .BI "log [stop | start " filename ] @@ -1039,7 +1043,7 @@ .SH COMMANDS between xfsprogs and the kernel, which will help when diagnosing minimum log size calculation errors. .TP -.BI "ls [\-i] [" paths "]..." +.BI "ls [\-im] [" paths "]..." List the contents of a directory. If a path resolves to a directory, the directory will be listed. If no paths are supplied and the IO cursor points at a directory inode, @@ -1053,6 +1057,9 @@ .SH COMMANDS Resolve each of the given paths to an inode number and print that number. If no paths are given and the IO cursor points to an inode, print the inode number. +.TP +.B \-m +Absolute paths should be walked from the root of the metadata directory tree. .RE .TP .BI "metadump [\-egow] " filename @@ -1080,18 +1087,26 @@ .SH COMMANDS .B print command. .TP -.BI "parent [" paths "]..." +.BI "parent [\-m] [" paths "]..." List the parents of a file. If a path resolves to a file, the parents of that file will be listed. If no paths are supplied and the IO cursor points at an inode, the parents of that file will be listed. +The +.B \-m +option causes absolute paths to be walked from the root of the metadata +directory tree. The output format is: inode number, inode generation, ondisk namehash, namehash, name length, name. .TP -.BI "path " dir_path +.BI "path [\-m] " dir_path Walk the directory tree to an inode using the supplied path. Absolute and relative paths are supported. +The +.B \-m +option causes absolute paths to be walked from the root of the metadata +directory tree. .TP .B pop Pop location from the stack. From patchwork Mon Dec 23 21:49:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919281 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 248041422AB for ; Mon, 23 Dec 2024 21:49:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990594; cv=none; b=IVdrcMhuUrh9fjHaNYXaK/WmR/kHeTZiK9+Y4HuKu9xvAuFhkhygxQFgYxWY3VSvyEaUH+IzSGlAS4Ju/uYgwh5QL8Zc6H8XF6zRgt2fkDMOyY135hRsi7sIoWFsjMef7MSVePIzNGwbMau+NqF9P8ZsXw71AnsgA1yPpdJOB1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990594; c=relaxed/simple; bh=0EAHsWuDhDfz813bb6+vGEmq/XEbzVBHqo9x2nj7a1k=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LOZ6yu+tutI/j4SRxZ7O7xNNjk1y1Ggyu58N6C2se4MjFyu8At3usymhJTIAbl7ZG2BnPVAnjYaNnZqqgly0DOjXLG/FpsogQ+N2ZYWKtM+mt8p7toJ0yVImJmn9ljsfJjnWJMSGHTnT7hsjSaewug8FnUUX3ccGu9uVVuCzRiI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mgoqVvy0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mgoqVvy0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 99C3CC4CED3; Mon, 23 Dec 2024 21:49:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990593; bh=0EAHsWuDhDfz813bb6+vGEmq/XEbzVBHqo9x2nj7a1k=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=mgoqVvy0EgWYM0eGOHOhOxeT28IdamVdqXgOpXTNUBYJieAboMg8+eOvPHGtuiNKp egFqyeWVdgq7Pc62Jyh4+9kHSfpw6sk/o/3NF+5S/VDfJ+JBM68e0QlRzYvRLnU3uY mKBG4FygZvDMRfq1/vQIGgBEPiT6PCBWO82jAjqK8gnW0J+rHdV2MALH2U1BpJlU39 NbVVbLGsILFoyY3WCLyCF29U41AjnS6EgchWIa35ty3usOdLgGF9OJP2LiIKukxo+F FADu+C5b9RLzukhjkhpELMGuxg/0NKBG2uFm0qX1AQKjF+OZYR9vObAa2P/UDbhFLZ J1Sa5eALrAB4w== Date: Mon, 23 Dec 2024 13:49:53 -0800 Subject: [PATCH 13/41] xfs_db: show the metadata root directory when dumping superblocks From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941167.2294268.16997793666566296649.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Show the metadirino field when appropriate. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- db/sb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/db/sb.c b/db/sb.c index 4f115650e1283f..fa15b429ecbefa 100644 --- a/db/sb.c +++ b/db/sb.c @@ -50,6 +50,18 @@ sb_init(void) add_command(&version_cmd); } +/* + * Counts superblock fields that only exist when the metadata directory feature + * is enabled. + */ +static int +metadirfld_count( + void *obj, + int startoff) +{ + return xfs_has_metadir(mp) ? 1 : 0; +} + #define OFF(f) bitize(offsetof(struct xfs_dsb, sb_ ## f)) #define SZC(f) szcount(struct xfs_dsb, sb_ ## f) const field_t sb_flds[] = { @@ -113,6 +125,8 @@ const field_t sb_flds[] = { { "pquotino", FLDT_INO, OI(OFF(pquotino)), C1, 0, TYP_INODE }, { "lsn", FLDT_UINT64X, OI(OFF(lsn)), C1, 0, TYP_NONE }, { "meta_uuid", FLDT_UUID, OI(OFF(meta_uuid)), C1, 0, TYP_NONE }, + { "metadirino", FLDT_INO, OI(OFF(metadirino)), metadirfld_count, + FLD_COUNT, TYP_INODE }, { NULL } }; From patchwork Mon Dec 23 21:50:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919282 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 AAA9019259D for ; Mon, 23 Dec 2024 21:50:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990609; cv=none; b=gCtVSTyhgpSUTXzLI4XUJVCK8a76OHvtI3S+STs5//WeiC6FlHdwNQ/ZC9YOgk7S07hzm3ZHMb0B5m52TQBQOedremaDwmi/9gz3P06NxFsLMBZlIPNGv3AqVZ6E6rI685zeACfvvuMf1E1noaBb9+PJNOHcQ3dkaySZmGKyFsI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990609; c=relaxed/simple; bh=oh4eEtAFCG6K8IpP8LVr1KnIvGdWDS/2xeB9Fh5V5X0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=URhEXsR91GuDc+2WfSC/fasPP//iFXKzTv5Ip9BIcBg1qMK5h3vM6/PadXw9zdN4sogkKBZgY8kykqbVeoNfggihOQL1Sk80+WWABYUtGp4fZH0bHJPxf/O6LyEKItMpxH69r7+T1pYKwBnr159w6TwXXmUG5Z1mWo+9bjeWdDs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eqIo97XU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eqIo97XU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 43901C4CED3; Mon, 23 Dec 2024 21:50:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990609; bh=oh4eEtAFCG6K8IpP8LVr1KnIvGdWDS/2xeB9Fh5V5X0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=eqIo97XUHrJWRbrvhyNjr8WCjBxml81lLDY8d7f5fB+LwDXHIf4mUCmTHwn6WSmqz 6t8cFK+dM7Mebpg8fPQKRsBQmVpk4U3F67/rGZnzD70naWja1730evY6kkMCz16AVC Jt88QY3PHgFvmAv8YLFs8Auzm4GQCkWZVmOrCxhuEzgNJLKb+oLlzaeeQH45RgFHiw zowO0yL8QZBTk9bNDbtwlwnTKm/JG89kqcpcIZ8IQ1Uj/dS1SyTmFN2N6xsbdfelWn v28OjcLWdAXGfYkK1EX2f64m8W2g9F9wWS7UZnc12ntiCpdsHvgZ2Sdnf8YLTp/M+3 R1C9NQ2/Z0YuA== Date: Mon, 23 Dec 2024 13:50:08 -0800 Subject: [PATCH 14/41] xfs_db: display di_metatype From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941183.2294268.15927941912459455353.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Print the metadata file type if available. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- db/field.c | 2 + db/field.h | 1 + db/inode.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- db/inode.h | 2 + 4 files changed, 78 insertions(+), 10 deletions(-) diff --git a/db/field.c b/db/field.c index a61ccc9ef6d072..946684415f65d3 100644 --- a/db/field.c +++ b/db/field.c @@ -212,6 +212,8 @@ const ftattr_t ftattrtab[] = { SI(bitsz(struct xfs_dinode)), 0, NULL, inode_core_flds }, { FLDT_DINODE_FMT, "dinode_fmt", fp_dinode_fmt, NULL, SI(bitsz(int8_t)), 0, NULL, NULL }, + { FLDT_DINODE_METATYPE, "metatype", fp_metatype, NULL, + SI(bitsz(uint16_t)), 0, NULL, NULL }, { FLDT_DINODE_U, "dinode_u", NULL, (char *)inode_u_flds, inode_u_size, FTARG_SIZE|FTARG_OKEMPTY, NULL, inode_u_flds }, { FLDT_DINODE_V3, "dinode_v3", NULL, (char *)inode_v3_flds, diff --git a/db/field.h b/db/field.h index b1bfdbed19cea3..9746676a6c7ac9 100644 --- a/db/field.h +++ b/db/field.h @@ -95,6 +95,7 @@ typedef enum fldt { FLDT_DINODE_A, FLDT_DINODE_CORE, FLDT_DINODE_FMT, + FLDT_DINODE_METATYPE, FLDT_DINODE_U, FLDT_DINODE_V3, diff --git a/db/inode.c b/db/inode.c index 0aff68083508cb..07efbb4902be08 100644 --- a/db/inode.c +++ b/db/inode.c @@ -25,6 +25,7 @@ static int inode_a_offset(void *obj, int startoff, int idx); static int inode_a_sfattr_count(void *obj, int startoff); static int inode_core_nlinkv2_count(void *obj, int startoff); static int inode_core_onlink_count(void *obj, int startoff); +static int inode_core_metatype_count(void *obj, int startoff); static int inode_core_projid_count(void *obj, int startoff); static int inode_core_nlinkv1_count(void *obj, int startoff); static int inode_core_v3_pad_count(void *obj, int startoff); @@ -94,6 +95,8 @@ const field_t inode_core_flds[] = { FLD_COUNT, TYP_NONE }, { "onlink", FLDT_UINT16D, OI(COFF(metatype)), inode_core_onlink_count, FLD_COUNT, TYP_NONE }, + { "metatype", FLDT_DINODE_METATYPE, OI(COFF(metatype)), + inode_core_metatype_count, FLD_COUNT, TYP_NONE }, { "uid", FLDT_UINT32D, OI(COFF(uid)), C1, 0, TYP_NONE }, { "gid", FLDT_UINT32D, OI(COFF(gid)), C1, 0, TYP_NONE }, { "nlinkv2", FLDT_UINT32D, OI(COFF(nlink)), inode_core_nlinkv2_count, @@ -247,9 +250,8 @@ static const char *dinode_fmt_name[] = static const int dinode_fmt_name_size = sizeof(dinode_fmt_name) / sizeof(dinode_fmt_name[0]); -/*ARGSUSED*/ -int -fp_dinode_fmt( +static int +fp_enum_fmt( void *obj, int bit, int count, @@ -257,26 +259,65 @@ fp_dinode_fmt( int size, int arg, int base, - int array) + int array, + const char **names, + unsigned int nr_names) { int bitpos; - enum xfs_dinode_fmt f; + int f; int i; for (i = 0, bitpos = bit; i < count; i++, bitpos += size) { - f = (enum xfs_dinode_fmt)getbitval(obj, bitpos, size, BVUNSIGNED); + f = getbitval(obj, bitpos, size, BVUNSIGNED); if (array) dbprintf("%d:", i + base); - if (f < 0 || f >= dinode_fmt_name_size) - dbprintf("%d", (int)f); + if (f < 0 || f >= nr_names) + dbprintf("%d", f); else - dbprintf("%d (%s)", (int)f, dinode_fmt_name[(int)f]); + dbprintf("%d (%s)", f, names[f]); if (i < count - 1) dbprintf(" "); } return 1; } +/*ARGSUSED*/ +int +fp_dinode_fmt( + void *obj, + int bit, + int count, + char *fmtstr, + int size, + int arg, + int base, + int array) +{ + return fp_enum_fmt(obj, bit, count, fmtstr, size, arg, base, array, + dinode_fmt_name, dinode_fmt_name_size); +} + +static const char *metatype_name[] = + { "unknown", "dir", "usrquota", "grpquota", "prjquota", "rtbitmap", + "rtsummary" + }; +static const int metatype_name_size = ARRAY_SIZE(metatype_name); + +int +fp_metatype( + void *obj, + int bit, + int count, + char *fmtstr, + int size, + int arg, + int base, + int array) +{ + return fp_enum_fmt(obj, bit, count, fmtstr, size, arg, base, array, + metatype_name, metatype_name_size); +} + static int inode_a_bmbt_count( void *obj, @@ -414,7 +455,29 @@ inode_core_onlink_count( ASSERT(startoff == 0); ASSERT(obj == iocur_top->data); dic = obj; - return dic->di_version >= 2; + if (dic->di_version < 2) + return 0; + if (dic->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA)) + return 0; + return 1; +} + +static int +inode_core_metatype_count( + void *obj, + int startoff) +{ + struct xfs_dinode *dic; + + ASSERT(startoff == 0); + ASSERT(obj == iocur_top->data); + dic = obj; + + if (dic->di_version < 3) + return 0; + if (dic->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA)) + return 1; + return 0; } static int diff --git a/db/inode.h b/db/inode.h index 31a2ebbba6a175..9e4ec1b3833716 100644 --- a/db/inode.h +++ b/db/inode.h @@ -16,6 +16,8 @@ extern const struct field timestamp_flds[]; extern int fp_dinode_fmt(void *obj, int bit, int count, char *fmtstr, int size, int arg, int base, int array); +int fp_metatype(void *obj, int bit, int count, char *fmtstr, + int size, int arg, int base, int array); extern int inode_a_size(void *obj, int startoff, int idx); extern void inode_init(void); extern typnm_t inode_next_type(void); From patchwork Mon Dec 23 21:50:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919283 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 51E971C3C0C for ; Mon, 23 Dec 2024 21:50:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990625; cv=none; b=XW2+ZHAPYIjRJG7Lrud3M50K6zXPTPN4JQ6iteSsXgNJlDqJhVgoasK3pnxTvIPCyRHPJoE+wLmptsSpvOpAJ3Ftqc1bnckYtLI+OTEMUEW+VUKtu+kmDE+aBj9eVwR1boEkaA8maX4YQvuxkSxdydtUpjG3VTFo6kvT/3xZqrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990625; c=relaxed/simple; bh=2/qQYtXxwLeQQBf6NujhinMTFv/wz8H+mrpO1jlXooU=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=K3iFW+DxVoSlO6KGyUhuFuUNgsvOofKpMASgt0xEZxAMchzJLsgR1vJOyU24SN9KPcsrIBCAFSwMpgtW4Vh0tETTj6Ij0TBWismH/prv265bf3BNwzIP/yqq9YGhBpS6H4mWXZZcd2Q3VRgKs4/eEBzu60nJWigEHjnXokUuzn8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JpV/Iiok; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JpV/Iiok" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2A1EC4CED3; Mon, 23 Dec 2024 21:50:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990624; bh=2/qQYtXxwLeQQBf6NujhinMTFv/wz8H+mrpO1jlXooU=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=JpV/IiokPHPs3RhjJVN61oUV56s6H67U9InhDpi09FDV5W0PnsxphNAXwCJfoDCVq m5QZIMHQkop1Ma3+CiXTaDGvX2Ml0Y8RUn3+8fyrwQVYqR0IZlGdnJYEedLr3ZDj+t p61uJmCCaay/VozFaBx9t5Dlyzrg2s3zZylaFOXBKOba2ogqEqPsQPG2dLbnWfxINV 0Z/afDCqygS6YFF1xQ5/L2Eo8N4h0yZ6N5slsnL5eitbJFFO8rok7U1EWr4IHK1tNp cIrGd/43LtS/7t4Fa6+EWDzc8ThkMdLl1xQfUjgOccifTYX7uWhC+ubGL1fkuHgXl+ 3kcKKqzWr5HeA== Date: Mon, 23 Dec 2024 13:50:24 -0800 Subject: [PATCH 15/41] xfs_db: drop the metadata checking code from blockget From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941198.2294268.3459139823957282491.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Drop the check subcommand and all the metadata checking code from xfs_db. We haven't shipped xfs_check in xfsprogs in a decade and the last known user (fstests) stopped calling it back in July 2024. Signed-off-by: "Darrick J. Wong" Reviewed-by: Andrey Albershteyn Reviewed-by: Christoph Hellwig --- db/check.c | 294 ----------------------------------------------------- man/man8/xfs_db.8 | 12 +- 2 files changed, 5 insertions(+), 301 deletions(-) diff --git a/db/check.c b/db/check.c index 37306bd7a6ac2d..4f7785c64f5b49 100644 --- a/db/check.c +++ b/db/check.c @@ -236,14 +236,12 @@ static void check_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, int ignore_reflink); static int check_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, xfs_ino_t c_ino); -static void check_linkcounts(xfs_agnumber_t agno); static int check_range(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len); static void check_rdbmap(xfs_rfsblock_t bno, xfs_extlen_t len, dbm_t type); static int check_rinomap(xfs_rfsblock_t bno, xfs_extlen_t len, xfs_ino_t c_ino); -static void check_rootdir(void); static int check_rrange(xfs_rfsblock_t bno, xfs_extlen_t len); static void check_set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, @@ -252,11 +250,6 @@ static void check_set_dbmap(xfs_agnumber_t agno, xfs_agblock_t c_agbno); static void check_set_rdbmap(xfs_rfsblock_t bno, xfs_extlen_t len, dbm_t type1, dbm_t type2); -static void check_summary(void); -static void checknot_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, - xfs_extlen_t len, int typemask); -static void checknot_rdbmap(xfs_rfsblock_t bno, xfs_extlen_t len, - int typemask); static void dir_hash_add(xfs_dahash_t hash, xfs_dir2_dataptr_t addr); static void dir_hash_check(inodata_t *id, int v); @@ -323,7 +316,6 @@ static void quota_add(xfs_dqid_t *p, xfs_dqid_t *g, xfs_dqid_t *u, static void quota_add1(qdata_t **qt, xfs_dqid_t id, int dq, xfs_qcnt_t bc, xfs_qcnt_t ic, xfs_qcnt_t rc); -static void quota_check(char *s, qdata_t **qt); static void quota_init(void); static void scan_ag(xfs_agnumber_t agno); static void scan_freelist(xfs_agf_t *agf); @@ -376,7 +368,7 @@ static const cmdinfo_t blockfree_cmd = { "blockfree", NULL, blockfree_f, 0, 0, 0, NULL, N_("free block usage information"), NULL }; static const cmdinfo_t blockget_cmd = - { "blockget", "check", blockget_f, 0, -1, 0, + { "blockget", NULL, blockget_f, 0, -1, 0, N_("[-s|-v] [-n] [-t] [-b bno]... [-i ino] ..."), N_("get block usage and check consistency"), NULL }; static const cmdinfo_t blocktrash_cmd = @@ -826,107 +818,9 @@ blockget_f( blist = NULL; blist_size = 0; } - if (serious_error) { + if (serious_error) exitcode = 2; - dbprefix = oldprefix; - return 0; - } - if (xfs_has_metadir(mp)) { - dbprefix = oldprefix; - return 0; - } - - check_rootdir(); - /* - * Check that there are no blocks either - * a) unaccounted for or - * b) bno-free but not cnt-free - */ - if (!tflag) { /* are we in test mode, faking out freespace? */ - for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) - checknot_dbmap(agno, 0, mp->m_sb.sb_agblocks, - (1 << DBM_UNKNOWN) | (1 << DBM_FREE1)); - } - for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) - check_linkcounts(agno); - if (mp->m_sb.sb_rblocks) { - checknot_rdbmap(0, - (xfs_extlen_t)(mp->m_sb.sb_rextents * - mp->m_sb.sb_rextsize), - 1 << DBM_UNKNOWN); - check_summary(); - } - if (mp->m_sb.sb_icount != icount) { - if (!sflag) - dbprintf(_("sb_icount %lld, counted %lld\n"), - mp->m_sb.sb_icount, icount); - error++; - } - if (mp->m_sb.sb_ifree != ifree) { - if (!sflag) - dbprintf(_("sb_ifree %lld, counted %lld\n"), - mp->m_sb.sb_ifree, ifree); - error++; - } - if (mp->m_sb.sb_fdblocks != fdblocks) { - if (!sflag) - dbprintf(_("sb_fdblocks %lld, counted %lld\n"), - mp->m_sb.sb_fdblocks, fdblocks); - error++; - } - if (lazycount && mp->m_sb.sb_fdblocks != agf_aggr_freeblks) { - if (!sflag) - dbprintf(_("sb_fdblocks %lld, aggregate AGF count %lld\n"), - mp->m_sb.sb_fdblocks, agf_aggr_freeblks); - error++; - } - if (mp->m_sb.sb_frextents != frextents) { - if (!sflag) - dbprintf(_("sb_frextents %lld, counted %lld\n"), - mp->m_sb.sb_frextents, frextents); - error++; - } - if (mp->m_sb.sb_bad_features2 != 0 && - mp->m_sb.sb_bad_features2 != mp->m_sb.sb_features2) { - if (!sflag) - dbprintf(_("sb_features2 (0x%x) not same as " - "sb_bad_features2 (0x%x)\n"), - mp->m_sb.sb_features2, - mp->m_sb.sb_bad_features2); - error++; - } - if ((sbversion & XFS_SB_VERSION_ATTRBIT) && - !xfs_has_attr(mp)) { - if (!sflag) - dbprintf(_("sb versionnum missing attr bit %x\n"), - XFS_SB_VERSION_ATTRBIT); - error++; - } - if ((sbversion & XFS_SB_VERSION_QUOTABIT) && - !xfs_has_quota(mp)) { - if (!sflag) - dbprintf(_("sb versionnum missing quota bit %x\n"), - XFS_SB_VERSION_QUOTABIT); - error++; - } - if (!(sbversion & XFS_SB_VERSION_ALIGNBIT) && - xfs_has_align(mp)) { - if (!sflag) - dbprintf(_("sb versionnum extra align bit %x\n"), - XFS_SB_VERSION_ALIGNBIT); - error++; - } - if (qudo) - quota_check("user", qudata); - if (qpdo) - quota_check("project", qpdata); - if (qgdo) - quota_check("group", qgdata); - if (sbver_err > mp->m_sb.sb_agcount / 2) - dbprintf(_("WARNING: this may be a newer XFS filesystem.\n")); - if (error) - exitcode = 3; dbprefix = oldprefix; return 0; } @@ -1388,58 +1282,6 @@ check_inomap( return rval; } -static void -check_linkcounts( - xfs_agnumber_t agno) -{ - inodata_t *ep; - inodata_t **ht; - int idx; - char *path; - - ht = inodata[agno]; - for (idx = 0; idx < inodata_hash_size; ht++, idx++) { - ep = *ht; - while (ep) { - if (ep->link_set != ep->link_add || ep->link_set == 0) { - path = inode_name(ep->ino, NULL); - if (!path && ep->link_add) - path = xstrdup("?"); - if (!sflag || ep->ilist) { - if (ep->link_add) - dbprintf(_("link count mismatch " - "for inode %lld (name " - "%s), nlink %d, " - "counted %d\n"), - ep->ino, path, - ep->link_set, - ep->link_add); - else if (ep->link_set) - dbprintf(_("disconnected inode " - "%lld, nlink %d\n"), - ep->ino, ep->link_set); - else - dbprintf(_("allocated inode %lld " - "has 0 link count\n"), - ep->ino); - } - if (path) - xfree(path); - error++; - } else if (verbose || ep->ilist) { - path = inode_name(ep->ino, NULL); - if (path) { - dbprintf(_("inode %lld name %s\n"), - ep->ino, path); - xfree(path); - } - } - ep = ep->next; - } - } - -} - static int check_range( xfs_agnumber_t agno, @@ -1556,25 +1398,6 @@ check_rinomap( return rval; } -static void -check_rootdir(void) -{ - inodata_t *id; - - id = find_inode(mp->m_sb.sb_rootino, 0); - if (id == NULL) { - if (!sflag) - dbprintf(_("root inode %lld is missing\n"), - mp->m_sb.sb_rootino); - error++; - } else if (!id->isdir) { - if (!sflag || id->ilist) - dbprintf(_("root inode %lld is not a directory\n"), - mp->m_sb.sb_rootino); - error++; - } -} - static inline void report_rrange( xfs_rfsblock_t low, @@ -1718,77 +1541,6 @@ get_suminfo( return raw->old; } -static void -check_summary(void) -{ - xfs_rfsblock_t bno; - union xfs_suminfo_raw *csp; - union xfs_suminfo_raw *fsp; - int log; - - csp = sumcompute; - fsp = sumfile; - for (log = 0; log < mp->m_rsumlevels; log++) { - for (bno = 0; - bno < mp->m_sb.sb_rbmblocks; - bno++, csp++, fsp++) { - if (csp->old != fsp->old) { - if (!sflag) - dbprintf(_("rt summary mismatch, size %d " - "block %llu, file: %d, " - "computed: %d\n"), - log, bno, - get_suminfo(mp, fsp), - get_suminfo(mp, csp)); - error++; - } - } - } -} - -static void -checknot_dbmap( - xfs_agnumber_t agno, - xfs_agblock_t agbno, - xfs_extlen_t len, - int typemask) -{ - xfs_extlen_t i; - char *p; - - if (!check_range(agno, agbno, len)) - return; - for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) { - if ((1 << *p) & typemask) { - if (!sflag || CHECK_BLISTA(agno, agbno + i)) - dbprintf(_("block %u/%u type %s not expected\n"), - agno, agbno + i, typename[(dbm_t)*p]); - error++; - } - } -} - -static void -checknot_rdbmap( - xfs_rfsblock_t bno, - xfs_extlen_t len, - int typemask) -{ - xfs_extlen_t i; - char *p; - - if (!check_rrange(bno, len)) - return; - for (i = 0, p = &dbmap[mp->m_sb.sb_agcount][bno]; i < len; i++, p++) { - if ((1 << *p) & typemask) { - if (!sflag || CHECK_BLIST(bno + i)) - dbprintf(_("rtblock %llu type %s not expected\n"), - bno + i, typename[(dbm_t)*p]); - error++; - } - } -} - static void dir_hash_add( xfs_dahash_t hash, @@ -3923,48 +3675,6 @@ quota_add1( qt[qh] = qe; } -static void -quota_check( - char *s, - qdata_t **qt) -{ - int i; - qdata_t *next; - qdata_t *qp; - - for (i = 0; i < QDATA_HASH_SIZE; i++) { - qp = qt[i]; - while (qp) { - next = qp->next; - if (qp->count.bc != qp->dq.bc || - qp->count.ic != qp->dq.ic || - qp->count.rc != qp->dq.rc) { - if (!sflag) { - dbprintf(_("%s quota id %u, have/exp"), - s, qp->id); - if (qp->count.bc != qp->dq.bc) - dbprintf(_(" bc %lld/%lld"), - qp->dq.bc, - qp->count.bc); - if (qp->count.ic != qp->dq.ic) - dbprintf(_(" ic %lld/%lld"), - qp->dq.ic, - qp->count.ic); - if (qp->count.rc != qp->dq.rc) - dbprintf(_(" rc %lld/%lld"), - qp->dq.rc, - qp->count.rc); - dbprintf("\n"); - } - error++; - } - xfree(qp); - qp = next; - } - } - xfree(qt); -} - static void quota_init(void) { diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 066f124458b286..2325ef169ddc1b 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -345,7 +345,7 @@ .SH COMMANDS command can be given, presumably with different arguments than the previous one. .TP .BI "blockget [\-npvs] [\-b " bno "] ... [\-i " ino "] ..." -Get block usage and check filesystem consistency. +Get block usage. The information is saved for use by a subsequent .BR blockuse ", " ncheck ", or " blocktrash command. @@ -564,11 +564,6 @@ .SH COMMANDS half full. .RE .TP -.B check -See the -.B blockget -command. -.TP .BI "convert " "type number" " [" "type number" "] ... " type Convert from one address form to another. The known @@ -2635,8 +2630,7 @@ .SH TYPES and printable ASCII chars. .SH DIAGNOSTICS Many messages can come from the -.B check -.RB ( blockget ) +.B blockget command. If the filesystem is completely corrupt, a core dump might be produced instead of the message @@ -2646,7 +2640,7 @@ .SH DIAGNOSTICS .RE .PP If the filesystem is very large (has many files) then -.B check +.B blockget might run out of memory. In this case the message .RS .B out of memory From patchwork Mon Dec 23 21:50:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919284 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B582A19259D for ; Mon, 23 Dec 2024 21:50:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990640; cv=none; b=oVnCo5dflbWMxInVSeHTevgrDKsA0YJF/iajL+Sk1cY8B0ujxqcuWRPCjc5k9lGmFF7mHGOtrgHZn+lx6ofiHaX44VydS1sUT3XGSzNK2S7E7z//cVxjz48gBPKs0FGNAizEDon2v6eCiRdin1+gRPYPcTPiwyRusJDLVLyHBJI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990640; c=relaxed/simple; bh=w4cPHE75WmiMvt1KsVlCPtrrimVYEdCY5WpRejjyRHY=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Oh9tglHmNnqQ7A0Y+bSo25IHtCLRzggofYulvi0zi1fznLfgC/cg/NF/7jyhtB2VMbt58emCmf9n4FVMD5GzOdUB51FdVgGMbCNrfTumzePG8Ra81OxsSUb8ZRDqvbs4wVZ+UWjxZGf95iLjaob29lGt210aXdXll1KUj3O6f/k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZkoOi9gW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZkoOi9gW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 802CFC4CED3; Mon, 23 Dec 2024 21:50:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990640; bh=w4cPHE75WmiMvt1KsVlCPtrrimVYEdCY5WpRejjyRHY=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ZkoOi9gWJ/65cAFl/heOx3Tloj54+sLlSb66xj0fmzak0F+5WJgyQjXhPmgTPYchU i+qqKB7a6Pu7jlvCa4R4rEDw6Wr/vVf35rFT+fjLv/7S+TKyRROvZZwnheGuLYsKmf g+bTsY0QsOUdQdl826EbeW72nbJVpFPdlnUNHLkpqp42iXvP0qm91AjIFo9T2uxPVK I43AWeSe8OXL6JC0IhYI6uLrZCmwHShvK5iaVyqLRxakUK6ztRLMpcJlytzwnuExxe +swvxRfhs9ck1hF1boQ4vPW9HU1gxSQf3Qq4OL5VHCGPUzfd6fpif3ER6A2iw9XK66 bB6gFR8FnWrWg== Date: Mon, 23 Dec 2024 13:50:40 -0800 Subject: [PATCH 16/41] xfs_io: support flag for limited bulkstat of the metadata directory From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941213.2294268.10575337506816934722.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Support the new XFS_BULK_IREQ_METADIR flag for bulkstat commands. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- io/bulkstat.c | 16 +++++++++++++++- man/man8/xfs_io.8 | 10 +++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/io/bulkstat.c b/io/bulkstat.c index 06023e1289e420..f312c6d55f47bc 100644 --- a/io/bulkstat.c +++ b/io/bulkstat.c @@ -70,6 +70,7 @@ bulkstat_help(void) " -d Print debugging output.\n" " -q Be quiet, no output.\n" " -e Stop after this inode.\n" +" -m Include metadata directories.\n" " -n Ask for this many results at once.\n" " -s Inode to start with.\n" " -v Use this version of the ioctl (1 or 5).\n")); @@ -107,11 +108,12 @@ bulkstat_f( bool has_agno = false; bool debug = false; bool quiet = false; + bool metadir = false; unsigned int i; int c; int ret; - while ((c = getopt(argc, argv, "a:de:n:qs:v:")) != -1) { + while ((c = getopt(argc, argv, "a:de:mn:qs:v:")) != -1) { switch (c) { case 'a': agno = cvt_u32(optarg, 10); @@ -131,6 +133,9 @@ bulkstat_f( return 1; } break; + case 'm': + metadir = true; + break; case 'n': batch_size = cvt_u32(optarg, 10); if (errno) { @@ -185,6 +190,8 @@ bulkstat_f( if (has_agno) xfrog_bulkstat_set_ag(breq, agno); + if (metadir) + breq->hdr.flags |= XFS_BULK_IREQ_METADIR; set_xfd_flags(&xfd, ver); @@ -253,6 +260,7 @@ bulkstat_single_f( unsigned long ver = 0; unsigned int i; bool debug = false; + bool metadir = false; int c; int ret; @@ -261,6 +269,9 @@ bulkstat_single_f( case 'd': debug = true; break; + case 'm': + metadir = true; + break; case 'v': errno = 0; ver = strtoull(optarg, NULL, 10); @@ -313,6 +324,9 @@ bulkstat_single_f( } } + if (metadir) + flags |= XFS_BULK_IREQ_METADIR; + ret = -xfrog_bulkstat_single(&xfd, ino, flags, &bulkstat); if (ret) { xfrog_perror(ret, "xfrog_bulkstat_single"); diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index eb2201fca74380..fb7a026224fda7 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -1243,7 +1243,7 @@ .SH MEMORY MAPPED I/O COMMANDS .SH FILESYSTEM COMMANDS .TP -.BI "bulkstat [ \-a " agno " ] [ \-d ] [ \-e " endino " ] [ \-n " batchsize " ] [ \-q ] [ \-s " startino " ] [ \-v " version" ] +.BI "bulkstat [ \-a " agno " ] [ \-d ] [ \-e " endino " ] [ \-m ] [ \-n " batchsize " ] [ \-q ] [ \-s " startino " ] [ \-v " version" ] Display raw stat information about a bunch of inodes in an XFS filesystem. Options are as follows: .RS 1.0i @@ -1260,6 +1260,9 @@ .SH FILESYSTEM COMMANDS Stop displaying records when this inode number is reached. Defaults to stopping when the system call stops returning results. .TP +.BI \-m +Include metadata directories in the output. +.TP .BI \-n " batchsize" Retrieve at most this many records per call. Defaults to 4,096. @@ -1280,10 +1283,11 @@ .SH FILESYSTEM COMMANDS .RE .PD .TP -.BI "bulkstat_single [ \-d ] [ \-v " version " ] [ " inum... " | " special... " ] +.BI "bulkstat_single [ \-d ] [ \-m ] [ \-v " version " ] [ " inum... " | " special... " ] Display raw stat information about individual inodes in an XFS filesystem. The -.B \-d +.BR \-d , +.BR \-m , and .B \-v options are the same as the From patchwork Mon Dec 23 21:50:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919285 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 5451A1422AB for ; Mon, 23 Dec 2024 21:50:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990656; cv=none; b=PGDwXLYTsWJp5nm595XMf5pLvruMvCT4pLse4PhaN+BmIWIRbH1ib3ujSDX+xKYi3pfo8eJQ1SARSAH8E0QznyrpWjW0pHsgr722T5pAMq/HTnkSdYAkU+sSpVIxXJirITdXm05FChcAd0W/NpKtUxz2ZJ6HAX2/JriGUfuatH4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990656; c=relaxed/simple; bh=1uYFW+FmgceaORNAYe53w7ng0XVL2zWulfhkiOGas4Q=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WgNbhrBNkcSZjahhB3qBrOW3cQJglsRdne0E8Jeg+mZ62YG8MqnnvnJ77AJnuRngDlXmcwIJEw3nmiriGXMyRFK2I4HM5+djN/rMSRKzhJIuNQQkNfR9V36eDJJvezB7TfykbD6wVmMchxyYeyT/bRiSpdDtsJGaG+g8lYNFJlc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IohBJGXN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IohBJGXN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 28D0AC4CED3; Mon, 23 Dec 2024 21:50:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990656; bh=1uYFW+FmgceaORNAYe53w7ng0XVL2zWulfhkiOGas4Q=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=IohBJGXNFUn6B9DcnOd96Rl/JfThu3jKW5nebG9GV5W6omGZzQIQePA9O9pYSWhtv VtbnjuFKQ3utAtdEwdKdo39ZDCRcIZvh0ok7313ATYhY8rCGEAkLSW2Djeqfh9R7Pr aGe6PDr1c0Q4jYZ16blDAdOjN8SRD/lbTaSUYPYfWmyxakKHh1z95OtCuMZczQ/WUI yvxqQlWiqrNFIcmkykG8acVwi0zgsTpik0VELTPA2YdOyEH3dr1RFVnpdD/zw8VjWK 6uRVJuK9o5/XjVJAf0VeZH7HHvi091VTUaJlFrQRi8l3YgDAxQdibO8YW0ArZoQRpW qe1J66XrIvGzQ== Date: Mon, 23 Dec 2024 13:50:55 -0800 Subject: [PATCH 17/41] xfs_io: support scrubbing metadata directory paths From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941228.2294268.440032311520694618.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Support invoking the metadata directory path scrubber from xfs_io for testing. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- io/scrub.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++-- man/man8/xfs_io.8 | 3 ++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/io/scrub.c b/io/scrub.c index e03c1d0eaf1db8..45229a8ae81099 100644 --- a/io/scrub.c +++ b/io/scrub.c @@ -41,6 +41,12 @@ scrub_help(void) " Known metadata scrub types are:")); for (i = 0, d = xfrog_scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++) printf(" %s", d->name); + printf(_( +"\n" +"\n" +" Known metapath scrub arguments are:")); + for (i = 0, d = xfrog_metapaths; i < XFS_SCRUB_METAPATH_NR; i++, d++) + printf(" %s", d->name); printf("\n"); } @@ -125,6 +131,40 @@ parse_none( return true; } +static bool +parse_metapath( + int argc, + char **argv, + int optind, + __u64 *ino) +{ + char *p; + unsigned long long control; + int i; + + if (optind != argc - 1) { + fprintf(stderr, _("Must specify metapath number.\n")); + return false; + } + + for (i = 0; i < XFS_SCRUB_METAPATH_NR; i++) { + if (!strcmp(argv[optind], xfrog_metapaths[i].name)) { + *ino = i; + return true; + } + } + + control = strtoll(argv[optind], &p, 0); + if (*p != '\0') { + fprintf(stderr, _("Bad metapath number '%s'.\n"), + argv[optind]); + return false; + } + + *ino = control; + return true; +} + static int parse_args( int argc, @@ -170,6 +210,12 @@ parse_args( meta->sm_flags = flags; switch (d->group) { + case XFROG_SCRUB_GROUP_METAPATH: + if (!parse_metapath(argc, argv, optind, &meta->sm_ino)) { + exitcode = 1; + return command_usage(cmdinfo); + } + break; case XFROG_SCRUB_GROUP_INODE: if (!parse_inode(argc, argv, optind, &meta->sm_ino, &meta->sm_gen)) { @@ -244,7 +290,7 @@ scrub_init(void) scrub_cmd.argmin = 1; scrub_cmd.argmax = -1; scrub_cmd.flags = CMD_NOMAP_OK; - scrub_cmd.args = _("type [agno|ino gen]"); + scrub_cmd.args = _("type [agno|ino gen|metapath]"); scrub_cmd.oneline = _("scrubs filesystem metadata"); scrub_cmd.help = scrub_help; @@ -275,6 +321,12 @@ repair_help(void) " Known metadata repair types are:")); for (i = 0, d = xfrog_scrubbers; i < XFS_SCRUB_TYPE_NR; i++, d++) printf(" %s", d->name); + printf(_( +"\n" +"\n" +" Known metapath repair arguments are:")); + for (i = 0, d = xfrog_metapaths; i < XFS_SCRUB_METAPATH_NR; i++, d++) + printf(" %s", d->name); printf("\n"); } @@ -327,7 +379,7 @@ repair_init(void) repair_cmd.argmin = 1; repair_cmd.argmax = -1; repair_cmd.flags = CMD_NOMAP_OK; - repair_cmd.args = _("type [agno|ino gen]"); + repair_cmd.args = _("type [agno|ino gen|metapath]"); repair_cmd.oneline = _("repairs filesystem metadata"); repair_cmd.help = repair_help; @@ -495,6 +547,12 @@ scrubv_f( optind++; switch (group) { + case XFROG_SCRUB_GROUP_METAPATH: + if (!parse_metapath(argc, argv, optind, &scrubv.head.svh_ino)) { + exitcode = 1; + return command_usage(&scrubv_cmd); + } + break; case XFROG_SCRUB_GROUP_INODE: if (!parse_inode(argc, argv, optind, &scrubv.head.svh_ino, &scrubv.head.svh_gen)) { diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index fb7a026224fda7..c73fee7c2780c6 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -1425,13 +1425,14 @@ .SH FILESYSTEM COMMANDS .RE .PD .TP -.BI "scrub " type " [ " agnumber " | " "ino" " " "gen" " ]" +.BI "scrub " type " [ " agnumber " | " "ino" " " "gen" " | " metapath " ]" Scrub internal XFS filesystem metadata. The .BI type parameter specifies which type of metadata to scrub. For AG metadata, one AG number must be specified. For file metadata, the scrub is applied to the open file unless the inode number and generation number are specified. +For metapath, the name of a file or a raw number must be specified. .RE .PD .TP From patchwork Mon Dec 23 21:51:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919286 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E39D81422AB for ; Mon, 23 Dec 2024 21:51:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990672; cv=none; b=O3XnEGYfuhZ2J9O1u9ppYUTHmXAmZOjB1aPAOwOhSClOLqUkt81d1qyi9HRq8+H3+QU4r7oFbUmhYvwy/UBHC0lQL7FFZlnGtnY3KLvmaPgVVeWKNagb2gPHLSHIUqCkbER/kDl9ST7srYTX2XR0bnGPMViw3Kf3xOFerscJI1s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990672; c=relaxed/simple; bh=yZFjOm1lE6ybdMQsEpXqpGqL/tUAsmWxE1ewC+nR35w=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ArIMPUwgV18QGzP3kU1vj0LhPLCsmidgo2HmyNvLADY1gfa4p1DedydtSJZayZVYJY2ra38mAJGJHHxftgbHLBv2UxmNw3xmXp4xZH1WlfC+2M1ovNxp5RgueYycqjPfAiIDVbKnwFYxG8Swf/bqGy3vjbLwzuB0sRJdDZwsCwo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=frs47lf1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="frs47lf1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B81E2C4CED3; Mon, 23 Dec 2024 21:51:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990671; bh=yZFjOm1lE6ybdMQsEpXqpGqL/tUAsmWxE1ewC+nR35w=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=frs47lf1q47GTzZCBbh3YG4G5Spj6B2mxJ5Aj2jOQSJBNcpmiywIGeA0+YkD6XuEW UIJtSCrMgp1IVM5w1WWnDbFowoNSYtq4W1dV3LVsAmq65wsg4qgmV58D5STOnuDJf4 MJaWrkc6WHEjzSRfgZF3J9DIDMU7TOWfx37ZVt2m+VElHjN2du+wnmkMUY7bMOwDhr Xz3er5UtuiO9/0LSGFjyB4PEN+SDmSCbZtv/xiy0N+x6CrGq75ob78FAW9bQBtIH6i hTrzxj/HDHtGdi9Rb8icSGizfMjrXJRukyx3j1n1fan/mIVf9hE89sGvfsHpW+z5wv CPWngwscYQGFA== Date: Mon, 23 Dec 2024 13:51:11 -0800 Subject: [PATCH 18/41] xfs_spaceman: report health of metadir inodes too From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941244.2294268.3005435014722968067.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong If the filesystem has a metadata directory tree, we should include those inodes in the health report. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- spaceman/health.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spaceman/health.c b/spaceman/health.c index d88a7f6c6e53f2..c4d570363fbbf1 100644 --- a/spaceman/health.c +++ b/spaceman/health.c @@ -324,6 +324,8 @@ report_bulkstat_health( if (agno != NULLAGNUMBER) xfrog_bulkstat_set_ag(breq, agno); + if (file->xfd.fsgeom.flags & XFS_FSOP_GEOM_FLAGS_METADIR) + breq->hdr.flags |= XFS_BULK_IREQ_METADIR; do { error = -xfrog_bulkstat(&file->xfd, breq); From patchwork Mon Dec 23 21:51:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919287 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8AC431422AB for ; Mon, 23 Dec 2024 21:51:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990687; cv=none; b=RwjM9SkgYMvnJywxMSf22AlAmvx73xveBze60NfHbgU7q2HSCieUHQiwdOZiITqYyAZOWZEenw01g9fOG7ASImhoaUBzru3zel0C0r0SGuIFhuv9s2EUnDU9DBhqN19sV4+lWn0HVIiHElL0fBZfW+I0eKS8a6ZT10obwwJnIUo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990687; c=relaxed/simple; bh=dRrTkaUo7KfbtybU+pDZVmYawbYfTTNszCIPdIkxY8U=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=H+ZZvwIzY6/u1G/NXJIDUtz49iDlBXZwsAecu2E0oKvL2pJZ5uRC2qu7h0IItDRDO0bmLbtO0KnzrWoLMhOwvEOK+4YC4H6uKnKv7Xw2hT1WX14/GOeFdVzxb/IO/+rS3oKKvBoZotucD/W4AXCVfvtZ2M+A69eZRbsjJSX+ABQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fEGYJ3O3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fEGYJ3O3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5CA86C4CED3; Mon, 23 Dec 2024 21:51:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990687; bh=dRrTkaUo7KfbtybU+pDZVmYawbYfTTNszCIPdIkxY8U=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=fEGYJ3O34kZjfH7cDGT4X1Lu3tvyQhX7eWB0zPFgvbYIxeAnnosyd22JsSYhQlnVy xb0QKCGb474Orermq5JCFdf6ff1JaP1A8oqxbZhAXjvxfozMNnMTTe1Xop0CpJPc/s Rfhcn/ZCZjSGEfMnWorS2kX7kfHAnH6KCBIkmeI1kzSG6TlZx8Vcz56vzM9U4a/8t+ USup377WDVkdS6jYWkRInptavowxXkujaQlbQGKdOGQ2Hehdqet0Qc/TaeoprXZhZH YuCznggGqslRjH9QsKSB9tfj34VWnzQUEIwpHR2Zmhv/nuD7b/FyR9ib0wvoQYKLoK WQbc9Q8pIjn/g== Date: Mon, 23 Dec 2024 13:51:26 -0800 Subject: [PATCH 19/41] xfs_scrub: tread zero-length read verify as an IO error From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: linux-xfs@vger.kernel.org, hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941259.2294268.12717372688725284669.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong While doing some chaos testing on the xfs_scrub read verify code, I noticed that if the device under a live filesystem gets resized while scrub is running a media scan, reads will start returning 0. This causes read_verify() to run around in an infinite loop instead of erroring out like it should. Cc: # v5.3.0 Fixes: 27464242956fac ("xfs_scrub: fix read verify disk error handling strategy") Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- scrub/phase6.c | 22 ++++++++++++++++++++++ scrub/read_verify.c | 8 ++++++++ 2 files changed, 30 insertions(+) diff --git a/scrub/phase6.c b/scrub/phase6.c index a61853019e290c..54d21820a722a6 100644 --- a/scrub/phase6.c +++ b/scrub/phase6.c @@ -44,6 +44,9 @@ struct media_verify_state { struct read_verify_pool *rvp_realtime; struct bitmap *d_bad; /* bytes */ struct bitmap *r_bad; /* bytes */ + bool d_trunc:1; + bool r_trunc:1; + bool l_trunc:1; }; /* Find the fd for a given device identifier. */ @@ -544,6 +547,13 @@ report_all_media_errors( { int ret; + if (vs->d_trunc) + str_corrupt(ctx, ctx->mntpoint, _("data device truncated")); + if (vs->l_trunc) + str_corrupt(ctx, ctx->mntpoint, _("log device truncated")); + if (vs->r_trunc) + str_corrupt(ctx, ctx->mntpoint, _("rt device truncated")); + ret = report_disk_ioerrs(ctx, ctx->datadev, vs); if (ret) { str_liberror(ctx, ret, _("walking datadev io errors")); @@ -663,6 +673,18 @@ remember_ioerr( struct bitmap *tree; int ret; + if (!length) { + dev_t dev = disk_to_dev(ctx, disk); + + if (dev == ctx->fsinfo.fs_datadev) + vs->d_trunc = true; + else if (dev == ctx->fsinfo.fs_rtdev) + vs->r_trunc = true; + else if (dev == ctx->fsinfo.fs_logdev) + vs->l_trunc = true; + return; + } + tree = bitmap_for_disk(ctx, disk, vs); if (!tree) { str_liberror(ctx, ENOENT, _("finding bad block bitmap")); diff --git a/scrub/read_verify.c b/scrub/read_verify.c index 52348274be2c25..1219efe2590182 100644 --- a/scrub/read_verify.c +++ b/scrub/read_verify.c @@ -245,6 +245,14 @@ read_verify( read_error); rvp->ioerr_fn(rvp->ctx, rvp->disk, rv->io_start, sz, read_error, rv->io_end_arg); + } else if (sz == 0) { + /* No bytes at all? Did we hit the end of the disk? */ + dbg_printf("EOF %d @ %"PRIu64" %zu err %d\n", + rvp->disk->d_fd, rv->io_start, sz, + read_error); + rvp->ioerr_fn(rvp->ctx, rvp->disk, rv->io_start, sz, + read_error, rv->io_end_arg); + break; } else if (sz < len) { /* * A short direct read suggests that we might have hit From patchwork Mon Dec 23 21:51:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919288 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2E9821422AB for ; Mon, 23 Dec 2024 21:51:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990703; cv=none; b=CKFOoW+wQzh4+5BppaEhTsfzipCoYjnqJQ0CKsxwFK+0XPFlS2AZnddL+dl31diJsskg2VDgd+EoEtTQyquefgbS2LXaYg8uWCgpCJi/V5N5OaMnpyq1VuT1gCEBe4ryfvZa1CmfKdaX1DQ0Gaj5K9LMe17WQ3Ciuwdts8Pccus= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990703; c=relaxed/simple; bh=tZpDW9vlIKk3sOz7rWcXXwY5l9LLFEZkYLI03EehAac=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=X1jiWMTH03xwuWtnUwhbRu34VjVgt1Mut1DhOByVZ+3HjBmfs1hI2BsU1ZTHpRO1pbvJ4Qir69VZ1YatqT/SjCOGKt/svHVoquYmqJE9V+Oj0SB7NcSWK6e7/i4xxO/bCA1FqYRO/5pxcmRnLdpvIrTA0BP/JVagnK+DvrEMG58= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GHwX4itG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GHwX4itG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 035A3C4CED3; Mon, 23 Dec 2024 21:51:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990703; bh=tZpDW9vlIKk3sOz7rWcXXwY5l9LLFEZkYLI03EehAac=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=GHwX4itGfBD2ZlqkHhGVVDJW3OjZxkwmIjAU6ghzKz//oxjycJMPB1LJV7kaTY6ja vbOjJeQxW55bQzZPTR++nT1GrA4Lj7KpPoR10VfyPiZTAlkzUcSkXLu2vNyZDhYUfX UnU8lDNsIdYFEDwbrnCSHn4I7HzsCV25sgVVtvtfLvXMEKkZXGRa8oy81ipiQc4dYT OpwCkfMI3iWJ1tCbHrVHrz9XW1mapv6LqF4lkgCOsxE4GZoyJMqSuVuTJibqB/KQCf /4XVYhtkqeEsKSx0KyH/Nd3yr7EFFhQOlfHvqQqqNX88MbwmO0yGMGLmjaodnS97WB 0FSpCZ6m44OHw== Date: Mon, 23 Dec 2024 13:51:42 -0800 Subject: [PATCH 20/41] xfs_scrub: scan metadata directories during phase 3 From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941274.2294268.7199394885221456745.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Scan metadata directories for correctness during phase 3. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- scrub/inodes.c | 11 ++++++++++- scrub/inodes.h | 5 ++++- scrub/phase3.c | 7 ++++++- scrub/phase5.c | 5 ++++- scrub/phase6.c | 2 +- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/scrub/inodes.c b/scrub/inodes.c index 16c79cf495c793..3fe759e8f4867d 100644 --- a/scrub/inodes.c +++ b/scrub/inodes.c @@ -56,6 +56,7 @@ bulkstat_for_inumbers( { struct xfs_bulkstat *bstat = breq->bulkstat; struct xfs_bulkstat *bs; + unsigned int flags = 0; int i; int error; @@ -70,6 +71,9 @@ bulkstat_for_inumbers( strerror_r(error, errbuf, DESCR_BUFSZ)); } + if (breq->hdr.flags & XFS_BULK_IREQ_METADIR) + flags |= XFS_BULK_IREQ_METADIR; + /* * Check each of the stats we got back to make sure we got the inodes * we asked for. @@ -84,7 +88,7 @@ bulkstat_for_inumbers( /* Load the one inode. */ error = -xfrog_bulkstat_single(&ctx->mnt, - inumbers->xi_startino + i, 0, bs); + inumbers->xi_startino + i, flags, bs); if (error || bs->bs_ino != inumbers->xi_startino + i) { memset(bs, 0, sizeof(struct xfs_bulkstat)); bs->bs_ino = inumbers->xi_startino + i; @@ -100,6 +104,7 @@ struct scan_inodes { scrub_inode_iter_fn fn; void *arg; unsigned int nr_threads; + unsigned int flags; bool aborted; }; @@ -158,6 +163,8 @@ alloc_ichunk( breq = ichunk_to_bulkstat(ichunk); breq->hdr.icount = LIBFROG_BULKSTAT_CHUNKSIZE; + if (si->flags & SCRUB_SCAN_METADIR) + breq->hdr.flags |= XFS_BULK_IREQ_METADIR; *ichunkp = ichunk; return 0; @@ -380,10 +387,12 @@ int scrub_scan_all_inodes( struct scrub_ctx *ctx, scrub_inode_iter_fn fn, + unsigned int flags, void *arg) { struct scan_inodes si = { .fn = fn, + .flags = flags, .arg = arg, .nr_threads = scrub_nproc_workqueue(ctx), }; diff --git a/scrub/inodes.h b/scrub/inodes.h index 9447fb56aa62e7..7a0b275e575ead 100644 --- a/scrub/inodes.h +++ b/scrub/inodes.h @@ -17,8 +17,11 @@ typedef int (*scrub_inode_iter_fn)(struct scrub_ctx *ctx, struct xfs_handle *handle, struct xfs_bulkstat *bs, void *arg); +/* Return metadata directories too. */ +#define SCRUB_SCAN_METADIR (1 << 0) + int scrub_scan_all_inodes(struct scrub_ctx *ctx, scrub_inode_iter_fn fn, - void *arg); + unsigned int flags, void *arg); int scrub_open_handle(struct xfs_handle *handle); diff --git a/scrub/phase3.c b/scrub/phase3.c index 046a42c1da8beb..c90da78439425a 100644 --- a/scrub/phase3.c +++ b/scrub/phase3.c @@ -312,6 +312,7 @@ phase3_func( struct scrub_inode_ctx ictx = { .ctx = ctx }; uint64_t val; xfs_agnumber_t agno; + unsigned int scan_flags = 0; int err; err = -ptvar_alloc(scrub_nproc(ctx), sizeof(struct action_list), @@ -328,6 +329,10 @@ phase3_func( goto out_ptvar; } + /* Scan the metadata directory tree too. */ + if (ctx->mnt.fsgeom.flags & XFS_FSOP_GEOM_FLAGS_METADIR) + scan_flags |= SCRUB_SCAN_METADIR; + /* * If we already have ag/fs metadata to repair from previous phases, * we would rather not try to repair file metadata until we've tried @@ -338,7 +343,7 @@ phase3_func( ictx.always_defer_repairs = true; } - err = scrub_scan_all_inodes(ctx, scrub_inode, &ictx); + err = scrub_scan_all_inodes(ctx, scrub_inode, scan_flags, &ictx); if (!err && ictx.aborted) err = ECANCELED; if (err) diff --git a/scrub/phase5.c b/scrub/phase5.c index e1d94f9a3568b1..69b1cae5c5e2c0 100644 --- a/scrub/phase5.c +++ b/scrub/phase5.c @@ -462,6 +462,9 @@ retry_deferred_inode( unsigned int flags = 0; int error; + if (ctx->mnt.fsgeom.flags & XFS_FSOP_GEOM_FLAGS_METADIR) + flags |= XFS_BULK_IREQ_METADIR; + error = -xfrog_bulkstat_single(&ctx->mnt, ino, flags, &bstat); if (error == ENOENT) { /* Directory is gone, mark it clear. */ @@ -772,7 +775,7 @@ _("Filesystem has errors, skipping connectivity checks.")); pthread_mutex_init(&ncs.lock, NULL); - ret = scrub_scan_all_inodes(ctx, check_inode_names, &ncs); + ret = scrub_scan_all_inodes(ctx, check_inode_names, 0, &ncs); if (ret) goto out_lock; if (ncs.aborted) { diff --git a/scrub/phase6.c b/scrub/phase6.c index 54d21820a722a6..e4f26e7f1dd93e 100644 --- a/scrub/phase6.c +++ b/scrub/phase6.c @@ -578,7 +578,7 @@ report_all_media_errors( } /* Scan for unlinked files. */ - return scrub_scan_all_inodes(ctx, report_inode_loss, vs); + return scrub_scan_all_inodes(ctx, report_inode_loss, 0, vs); } /* Schedule a read-verify of a (data block) extent. */ From patchwork Mon Dec 23 21:51:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919289 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 C0B5819259D for ; Mon, 23 Dec 2024 21:51:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990718; cv=none; b=oE0huP3NgyZkwk9TA0tZe1CXO2Yct982bnzYNzuX0UuICfH4jdZVayfytu/0Q1QFFbalgqFCY45AoK+486qAFeqqhbgvxu9K3T9GjZcF/vFNRisNQIjM45mDooQG98LxhOMlOfM23Tm+E+hgSf4ElDBbRUpPxyMrDmbWbVdgZjM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990718; c=relaxed/simple; bh=FgzZpeR99ojtU5dEYF7oxzk1+nbCCYqfKmkQMWZwstI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=B/XIxRG4qE7IgBUuq45xUSp6iF8tEtDyQ08+vMwIbdQCJT+fvpllFWxu1TGebTcLGNFl1NqWlbYVZw/slCvQN2aKMD2eO1Eg5mZIFJvlze3GA4q6e/939ndg1hisL1iMjod6ilyRU7iTOQu6SUuUWuWBDYSMxvpB4hutlPVxkc0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=McJqj4WU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="McJqj4WU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 96D74C4CED3; Mon, 23 Dec 2024 21:51:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990718; bh=FgzZpeR99ojtU5dEYF7oxzk1+nbCCYqfKmkQMWZwstI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=McJqj4WUlIui5dNhPV1LQ57ESrEQyHUstvNIBglpJMWEUDeJn3u0Cx2ySzf5CVTLe y1jfBMX6oxTD6jKMNTAX2Ahwdk2mh3Ls1v+cYbDewO/i9KO2p8LVHxByXZggDhEd9d j49gULPDk/OjJYoELZSmVTmBvxuXCOJ7gknd22IvM8z/eMpwvASIklZlSxRtpuAv3a 2WSz3QTItknLWzUDftzHMnHQUUTojC91j3rgwmNljOo5rNIolZDCTCa/KNF+qZp9vC 1YUfU7ILzODJvtcYiW1aa0MscAucVD4itCF7uYN5hO20WDpTh0MsIllZ5WJ/GVTJ0B ePYrv80HyNEAg== Date: Mon, 23 Dec 2024 13:51:58 -0800 Subject: [PATCH 21/41] xfs_scrub: re-run metafile scrubbers during phase 5 From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941290.2294268.4112620871848234004.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong For metadata files on a metadir filesystem, re-run the scrubbers during phase 5 to ensure that the metadata files are still connected. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- scrub/phase5.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- scrub/scrub.h | 7 ++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/scrub/phase5.c b/scrub/phase5.c index 69b1cae5c5e2c0..4d0a76a529b55d 100644 --- a/scrub/phase5.c +++ b/scrub/phase5.c @@ -745,6 +745,87 @@ run_kernel_fs_scan_scrubbers( return ret; } +/* Queue one metapath scrubber. */ +static int +queue_metapath_scan( + struct workqueue *wq, + bool *abortedp, + uint64_t type) +{ + struct fs_scan_item *item; + struct scrub_ctx *ctx = wq->wq_ctx; + int ret; + + item = malloc(sizeof(struct fs_scan_item)); + if (!item) { + ret = ENOMEM; + str_liberror(ctx, ret, _("setting up metapath scan")); + return ret; + } + scrub_item_init_metapath(&item->sri, type); + scrub_item_schedule(&item->sri, XFS_SCRUB_TYPE_METAPATH); + item->abortedp = abortedp; + + ret = -workqueue_add(wq, fs_scan_worker, 0, item); + if (ret) + str_liberror(ctx, ret, _("queuing metapath scan work")); + + return ret; +} + +/* + * Scrub metadata directory file paths to ensure that fs metadata are still + * connected where the fs needs to find them. + */ +static int +run_kernel_metadir_path_scrubbers( + struct scrub_ctx *ctx) +{ + struct workqueue wq; + const struct xfrog_scrub_descr *sc; + uint64_t type; + unsigned int nr_threads = scrub_nproc_workqueue(ctx); + bool aborted = false; + int ret, ret2; + + ret = -workqueue_create(&wq, (struct xfs_mount *)ctx, nr_threads); + if (ret) { + str_liberror(ctx, ret, _("setting up metapath scan workqueue")); + return ret; + } + + /* + * Scan all the metadata files in parallel if metadata directories + * are enabled, because the phase 3 scrubbers might have taken out + * parts of the metadir tree. + */ + for (type = 0; type < XFS_SCRUB_METAPATH_NR; type++) { + sc = &xfrog_metapaths[type]; + if (sc->group != XFROG_SCRUB_GROUP_FS) + continue; + + ret = queue_metapath_scan(&wq, &aborted, type); + if (ret) { + str_liberror(ctx, ret, + _("queueing metapath scrub work")); + goto wait; + } + } + +wait: + ret2 = -workqueue_terminate(&wq); + if (ret2) { + str_liberror(ctx, ret2, _("joining metapath scan workqueue")); + if (!ret) + ret = ret2; + } + if (aborted && !ret) + ret = ECANCELED; + + workqueue_destroy(&wq); + return ret; +} + /* Check directory connectivity. */ int phase5_func( @@ -753,6 +834,16 @@ phase5_func( struct ncheck_state ncs = { .ctx = ctx }; int ret; + /* + * Make sure metadata files are still connected to the metadata + * directory tree now that phase 3 pruned all corrupt directory tree + * links. + */ + if (ctx->mnt.fsgeom.flags & XFS_FSOP_GEOM_FLAGS_METADIR) { + ret = run_kernel_metadir_path_scrubbers(ctx); + if (ret) + return ret; + } /* * Check and fix anything that requires a full filesystem scan. We do @@ -805,8 +896,12 @@ phase5_estimate( unsigned int *nr_threads, int *rshift) { + unsigned int scans = 2; + *items = scrub_estimate_iscan_work(ctx); - *nr_threads = scrub_nproc(ctx) * 2; + if (ctx->mnt.fsgeom.flags & XFS_FSOP_GEOM_FLAGS_METADIR) + scans++; + *nr_threads = scrub_nproc(ctx) * scans; *rshift = 0; return 0; } diff --git a/scrub/scrub.h b/scrub/scrub.h index c3eed1b261d511..3bb3ea1d07bf40 100644 --- a/scrub/scrub.h +++ b/scrub/scrub.h @@ -108,6 +108,13 @@ scrub_item_init_file(struct scrub_item *sri, const struct xfs_bulkstat *bstat) sri->sri_gen = bstat->bs_gen; } +static inline void +scrub_item_init_metapath(struct scrub_item *sri, uint64_t metapath) +{ + memset(sri, 0, sizeof(*sri)); + sri->sri_ino = metapath; +} + void scrub_item_dump(struct scrub_item *sri, unsigned int group_mask, const char *tag); From patchwork Mon Dec 23 21:52:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919290 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6028A19048A for ; Mon, 23 Dec 2024 21:52:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990734; cv=none; b=AMpYXp0RucF803hR2QoNVjvr31Tkao/61aLcn/xKUh+kkchwT9kc27y6TNY5Y36SZ2M8KauQQ162B++pYzkkJ1lDBit26/XuUAoS5troOInT9Kr999v1f1WXtOlwXuJ79kLEFOPlUKRVd1eYYgVskbg51oQsTUpo0dWlZ86BS78= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990734; c=relaxed/simple; bh=bkVLn4E9uBYa03y5YwaB0CJcAc+t8TO017deArzGzPY=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MXtoiVblEa1TLA66p4eSu8c6x1lzvbg6O3nbcuRMlj+3Z3DR4SxQfVjJxZ2ktrvbtyYQUHGo+KD4MtB2wEeyyat2r+HXr549/OCnL0u5cI02VF1L4U4MjSDWnYuPsLGTOSep8RDLLJO1TcowVvBda6j2Hnf1UID/Bl7u1SfWrQE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cDxELLpJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cDxELLpJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30F51C4CED3; Mon, 23 Dec 2024 21:52:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990734; bh=bkVLn4E9uBYa03y5YwaB0CJcAc+t8TO017deArzGzPY=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=cDxELLpJiqKsYfXI/t1YowY+S+K3QqDzYQ9QXSqpxSVQuJUX8+0IxJkhh4KdQRVrK Auecz6859Lg98M7TytpQISrckOCIGuyx5f12FPp99ejw01S3cQjLdw9NL1VMEZMNUQ XWq5XTPTqtCz0MoXS3zNpX3m2SQIgbA/IV5VtUasqXFIqxRxq2opfLJB7D/rnQ92G1 xxf/tfIE1oRW7P8Bu3BagPCm7GsWZ3fNBdiXcROl2GxwjYNsA95WgTXMkPqXBlFld3 Vd5fqNsLUQ3KbxjCPsLWHbq5k6sMb7TM2LQh/9pDvaS4+XYrCr4lS9hXr0Yw7npuGK pJ+6qT6XIKNtg== Date: Mon, 23 Dec 2024 13:52:13 -0800 Subject: [PATCH 22/41] xfs_repair: handle sb_metadirino correctly when zeroing supers From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941305.2294268.16758078118636673556.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong The metadata directory root inumber is now the last field in the superblock, so extend the zeroing code to know about that. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/agheader.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/repair/agheader.c b/repair/agheader.c index 3930a0ac0919b4..fe58d833b8bafa 100644 --- a/repair/agheader.c +++ b/repair/agheader.c @@ -319,6 +319,12 @@ check_v5_feature_mismatch( return XR_AG_SB_SEC; } +static inline bool xfs_sb_version_hasmetadir(const struct xfs_sb *sbp) +{ + return xfs_sb_is_v5(sbp) && + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR); +} + /* * Possible fields that may have been set at mkfs time, * sb_inoalignmt, sb_unit, sb_width and sb_dirblklog. @@ -357,7 +363,10 @@ secondary_sb_whack( * * size is the size of data which is valid for this sb. */ - if (xfs_sb_version_hasmetauuid(sb)) + if (xfs_sb_version_hasmetadir(sb)) + size = offsetof(struct xfs_dsb, sb_metadirino) + + sizeof(sb->sb_metadirino); + else if (xfs_sb_version_hasmetauuid(sb)) size = offsetof(struct xfs_dsb, sb_meta_uuid) + sizeof(sb->sb_meta_uuid); else if (xfs_sb_version_hascrc(sb)) From patchwork Mon Dec 23 21:52:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919291 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4D95519048A for ; Mon, 23 Dec 2024 21:52:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990750; cv=none; b=ryhtkkeQuZ0klC26/6utsFB4Z1oM7w3VkSg9W3FOTJu26d73PlZlcCHAHIlLMYT6DUYcIRpO32muHH1zaR54IXOn8xOpWyEiV1aWODAV52Xd20P+Z/gHr1o7hMywq+wlCz/gwMYoJLBGC7QfjsV76S3+cnCOJtSGwTKfoH21fLE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990750; c=relaxed/simple; bh=t/sx01/1fjwkg5rUp6DGW6xn/kO2KypnUArrpi11oV0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=V5lJkcvHzSjz2uQJBnJIQC+aYX1anzeTwOTHmwHXT3jt+qxxyQ0oRobr/y9TTbXibE51ne7jrHVUdbPDz9tUNiM3s6I2neG8hVBv+sJFp+pAjaSxUvQyr3XjS8fRyikD5wJYdrkMNhiT3bAy2RuXafrs9cdG2LpvFyXzKmBk1iY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UXlS8CyR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UXlS8CyR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D36B9C4CED3; Mon, 23 Dec 2024 21:52:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990749; bh=t/sx01/1fjwkg5rUp6DGW6xn/kO2KypnUArrpi11oV0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=UXlS8CyROf7uzGLJcvUYf2QGidRnFuSLGMdNGg46j63GpEDsGM80Cd3GjJR4KEF32 2T60g34uVzz/9Od3AgHXp1k68+FygLl0mnf8D+Qjn9k4F9paL15bKyUUrw7Gvu6TJ+ kSFZZKPMMviIYhahY/RhyCt2KWbioFkH2ofaTimHnho8clkeKkPM1zNSqlvaS8XcNM aaYZDv1NI8iPoq5sZLWXMn63SafmYB3rTfhyGCiiodpqEsiNeuvcttZEuBARO9ZuCy HGn1a4Jns8bJGDaQ0RYPyOvUAV39GRT0455jxUe7VkO14RQIPXd6cK0jafk42winBC jqaN1kosIg15g== Date: Mon, 23 Dec 2024 13:52:29 -0800 Subject: [PATCH 23/41] xfs_repair: dont check metadata directory dirent inumbers From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941321.2294268.11909021874949153958.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Phase 6 always rebuilds the entire metadata directory tree, and repair quietly ignores all the DIFLAG2_METADATA directory inodes that it finds. As a result, none of the metadata directories are marked inuse in the incore data. Therefore, the is_inode_free checks are not valid for anything we find in a metadata directory. Therefore, avoid checking is_inode_free when scanning metadata directory dirents. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- libxfs/libxfs_api_defs.h | 1 + repair/dir2.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index dd163709fe07df..d2611d7a764259 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -121,6 +121,7 @@ #define xfs_dinode_calc_crc libxfs_dinode_calc_crc #define xfs_dinode_good_version libxfs_dinode_good_version #define xfs_dinode_verify libxfs_dinode_verify +#define xfs_dinode_verify_metadir libxfs_dinode_verify_metadir #define xfs_dir2_data_bestfree_p libxfs_dir2_data_bestfree_p #define xfs_dir2_data_entry_tag_p libxfs_dir2_data_entry_tag_p diff --git a/repair/dir2.c b/repair/dir2.c index bfeaddd07d2058..dab6523f676a34 100644 --- a/repair/dir2.c +++ b/repair/dir2.c @@ -136,6 +136,29 @@ process_sf_dir2_fixoff( } } +static inline bool +is_metadata_directory( + struct xfs_mount *mp, + struct xfs_dinode *dip) +{ + xfs_failaddr_t fa; + uint16_t mode; + uint16_t flags; + uint64_t flags2; + + if (!xfs_has_metadir(mp)) + return false; + if (dip->di_version < 3 || + !(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA))) + return false; + + mode = be16_to_cpu(dip->di_mode); + flags = be16_to_cpu(dip->di_flags); + flags2 = be64_to_cpu(dip->di_flags2); + fa = libxfs_dinode_verify_metadir(mp, dip, mode, flags, flags2); + return fa == NULL; +} + /* * this routine performs inode discovery and tries to fix things * in place. available redundancy -- inode data size should match @@ -227,6 +250,12 @@ process_sf_dir2( } else if (!libxfs_verify_dir_ino(mp, lino)) { junkit = 1; junkreason = _("invalid"); + } else if (is_metadata_directory(mp, dip)) { + /* + * Metadata directories are always rebuilt, so don't + * bother checking if the child inode is free or not. + */ + junkit = 0; } else if (lino == mp->m_sb.sb_rbmino) { junkit = 1; junkreason = _("realtime bitmap"); @@ -698,6 +727,12 @@ process_dir2_data( * directory since it's still structurally intact. */ clearreason = _("invalid"); + } else if (is_metadata_directory(mp, dip)) { + /* + * Metadata directories are always rebuilt, so don't + * bother checking if the child inode is free or not. + */ + clearino = 0; } else if (ent_ino == mp->m_sb.sb_rbmino) { clearreason = _("realtime bitmap"); } else if (ent_ino == mp->m_sb.sb_rsumino) { From patchwork Mon Dec 23 21:52:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919292 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E945219259D for ; Mon, 23 Dec 2024 21:52:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990766; cv=none; b=XFwwVi/UHNy/i7kOVurhwsdWNOSfRbajZfhWkfSfMLwfggj4UrPhNc8V4a0bw7G57gIoGBx51XmMc4FNIFHYNnQT/VI3SbTCIAF6dgpkUxeRsdYiQ5o4erT+480QphFiN8B6CkSRshBREK6OBeoMjMHpuH75ErZZZlcMr7U6gN8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990766; c=relaxed/simple; bh=pvt0XcwIyNnLxndZkhwgb27IbzRJWK1zm+fnjYezAm0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=S3gDg14fnqCokRBgofqLrmVHaoMibe+aexgq1tEKYY/nud9z/u0rpNlnPbg0DIL0IHNdzZPIaTZ9bSnb3P1adt+05ua8VrGxG1Llf6hdLywWBchnFXbdzp+zFXIvZxkZeK2MZoPvCz4yFICgORcA+s5qslrFeJbujc4Hmvje8Wc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bDOfv2Lc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bDOfv2Lc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74FAAC4CED3; Mon, 23 Dec 2024 21:52:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990765; bh=pvt0XcwIyNnLxndZkhwgb27IbzRJWK1zm+fnjYezAm0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=bDOfv2LcO71j7529XzROnkEMy0QE8+ZGPIMRNQJ20SIb5EItQUNgvdfpB4s8v05Gz 7Aii4lLsWaEDC+Oud4/VBBhoWDhP05w/lNQAOo5M6ggPJEiSKsI34uwG6TnzKiEB8O ZY7pr7/LK+o2ekU+Kr93twOBK3WYR9NY9wFeGl6sV5jTLblYtFMfTzx90O6HWrf2VS EIUqThNxeMoTgIeXASIBI9x2IXd8L++Sqg+0eE0DLgZefxEqMMNdvFhpB8fMF4WrC6 o8CFy9n3TCPytcSzBHIHkJt5oDqrD64DZjnkgMbCn0vRKE5gtgP/NUajrypLjAzlOH XsiC7C//i8aNg== Date: Mon, 23 Dec 2024 13:52:45 -0800 Subject: [PATCH 24/41] xfs_repair: refactor fixing dotdot From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941336.2294268.5709516863667328479.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Pull the code that fixes a directory's dot-dot entry into a separate helper function so that we can call it on the rootdir and (later) the metadir. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase6.c | 96 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index 630617ef8ab8fe..0f13d996fe726a 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2649,6 +2649,62 @@ dir_hash_add_parent_ptrs( } } +/* + * If we have to create a .. for /, do it now *before* we delete the bogus + * entries, otherwise the directory could transform into a shortform dir which + * would probably cause the simulation to choke. Even if the illegal entries + * get shifted around, it's ok because the entries are structurally intact and + * in in hash-value order so the simulation won't get confused if it has to + * move them around. + */ +static void +fix_dotdot( + struct xfs_mount *mp, + xfs_ino_t ino, + struct xfs_inode *ip, + xfs_ino_t rootino, + const char *tag, + int *need_dotdot) +{ + struct xfs_trans *tp; + int nres; + int error; + + if (ino != rootino || !*need_dotdot) + return; + + if (no_modify) { + do_warn(_("would recreate %s directory .. entry\n"), tag); + return; + } + + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_LOCAL); + + do_warn(_("recreating %s directory .. entry\n"), tag); + + nres = libxfs_mkdir_space_res(mp, 2); + error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir, nres, 0, 0, &tp); + if (error) + res_failed(error); + + libxfs_trans_ijoin(tp, ip, 0); + + error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot, ip->i_ino, + nres); + if (error) + do_error( +_("can't make \"..\" entry in %s inode %" PRIu64 ", createname error %d\n"), + tag ,ino, error); + + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + error = -libxfs_trans_commit(tp); + if (error) + do_error( +_("%s inode \"..\" entry recreation failed (%d)\n"), tag, error); + + *need_dotdot = 0; +} + /* * processes all reachable inodes in directories */ @@ -2778,45 +2834,7 @@ _("error %d fixing shortform directory %llu\n"), dir_hash_add_parent_ptrs(ip, hashtab); dir_hash_done(hashtab); - /* - * if we have to create a .. for /, do it now *before* - * we delete the bogus entries, otherwise the directory - * could transform into a shortform dir which would - * probably cause the simulation to choke. Even - * if the illegal entries get shifted around, it's ok - * because the entries are structurally intact and in - * in hash-value order so the simulation won't get confused - * if it has to move them around. - */ - if (!no_modify && need_root_dotdot && ino == mp->m_sb.sb_rootino) { - ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_LOCAL); - - do_warn(_("recreating root directory .. entry\n")); - - nres = libxfs_mkdir_space_res(mp, 2); - error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir, - nres, 0, 0, &tp); - if (error) - res_failed(error); - - libxfs_trans_ijoin(tp, ip, 0); - - error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot, - ip->i_ino, nres); - if (error) - do_error( - _("can't make \"..\" entry in root inode %" PRIu64 ", createname error %d\n"), ino, error); - - libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - error = -libxfs_trans_commit(tp); - if (error) - do_error( - _("root inode \"..\" entry recreation failed (%d)\n"), error); - - need_root_dotdot = 0; - } else if (need_root_dotdot && ino == mp->m_sb.sb_rootino) { - do_warn(_("would recreate root directory .. entry\n")); - } + fix_dotdot(mp, ino, ip, mp->m_sb.sb_rootino, "root", &need_root_dotdot); /* * if we need to create the '.' entry, do so only if From patchwork Mon Dec 23 21:53:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919293 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4D0871422AB for ; Mon, 23 Dec 2024 21:53:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990781; cv=none; b=coiRce63h/SNoxfEZI2LXVi5NMWgm9O3tab5iD9NSBX+WGOXOAZwf2Ve5IT6uJ2x3/9KiRC90KcBS1VfceMwvjUHr17no/BOhXxKdjAXOH0Nm0YM2FCeoh5Iytvaj1K9ygvufl3xAl3bkYc4JeYIkCESkD21LYwkIJex6JdUfA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990781; c=relaxed/simple; bh=ACl0Kkc8NpsP+6AficLSiaIm0xW/HNXq3sRa5o08+v0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=swDgfuVDFQDYxk+PfT7Qc/lvYBQTTWfRpHYt7nvtFpq5HBMfHqdQ3StD5ffdeTgAHv9B6gVdTm8cjtyrn8dqvbXRmOHggytdLoUjzR3dErZ9YM0zqMSMScHwV3Mvik1jg0IrGtrbmSiHzqIIv8BU2DPdCcwF71L0WGy/WH52sbk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=u5pvAJrG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="u5pvAJrG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 20A17C4CED3; Mon, 23 Dec 2024 21:53:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990781; bh=ACl0Kkc8NpsP+6AficLSiaIm0xW/HNXq3sRa5o08+v0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=u5pvAJrG8jVYlQPCEEdD2WOJnix4pPM3MfioE6/XL/GDLkNsE/49KXsa/wjmEjl7X YX6dWlVX5ztn3ePf86O6niJpJJLLuqabei3pTOmUy7rv7vcrhxQljQeMAd9m13zOgy Q/LMLp+mwfOoa0rI4PZ9ZeLfGhyK8pdpkljJhj0E1HwvhnkLdvRs/jkdceI54MAlpD ohT55UZ0PACfNgE10zc5NsXs0OuwD/mEITDdLE9wf6f2MMIFXsZcxhY930f9/+atvI 8U7OpYPhS487cK8xecjhN2id1VFxJT/jn1qQWoTPoLBmhmf9MqMKE3ThGTOBmj4MEM ye8RPMU4FDqiQ== Date: Mon, 23 Dec 2024 13:53:00 -0800 Subject: [PATCH 25/41] xfs_repair: refactor marking of metadata inodes From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941352.2294268.5169144370427381066.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Refactor the mechanics of marking a metadata inode into a helper function so that we don't have to open-code that for every single metadata inode. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase6.c | 72 ++++++++++++++++++------------------------------------- 1 file changed, 24 insertions(+), 48 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index 0f13d996fe726a..79c8226110a890 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2891,6 +2891,18 @@ _("error %d fixing shortform directory %llu\n"), libxfs_irele(ip); } +static void +mark_inode( + struct xfs_mount *mp, + xfs_ino_t ino) +{ + struct ino_tree_node *irec = + find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ino), + XFS_INO_TO_AGINO(mp, ino)); + + add_inode_reached(irec, XFS_INO_TO_AGINO(mp, ino) - irec->ino_startnum); +} + /* * mark realtime bitmap and summary inodes as reached. * quota inode will be marked here as well @@ -2898,54 +2910,18 @@ _("error %d fixing shortform directory %llu\n"), static void mark_standalone_inodes(xfs_mount_t *mp) { - ino_tree_node_t *irec; - int offset; - - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rbmino), - XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino)); - - offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rbmino) - - irec->ino_startnum; - - add_inode_reached(irec, offset); - - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rsumino), - XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rsumino)); - - offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rsumino) - - irec->ino_startnum; - - add_inode_reached(irec, offset); - - if (fs_quotas) { - if (mp->m_sb.sb_uquotino - && mp->m_sb.sb_uquotino != NULLFSINO) { - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, - mp->m_sb.sb_uquotino), - XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino)); - offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_uquotino) - - irec->ino_startnum; - add_inode_reached(irec, offset); - } - if (mp->m_sb.sb_gquotino - && mp->m_sb.sb_gquotino != NULLFSINO) { - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, - mp->m_sb.sb_gquotino), - XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino)); - offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_gquotino) - - irec->ino_startnum; - add_inode_reached(irec, offset); - } - if (mp->m_sb.sb_pquotino - && mp->m_sb.sb_pquotino != NULLFSINO) { - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, - mp->m_sb.sb_pquotino), - XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino)); - offset = XFS_INO_TO_AGINO(mp, mp->m_sb.sb_pquotino) - - irec->ino_startnum; - add_inode_reached(irec, offset); - } - } + mark_inode(mp, mp->m_sb.sb_rbmino); + mark_inode(mp, mp->m_sb.sb_rsumino); + + if (!fs_quotas) + return; + + if (mp->m_sb.sb_uquotino && mp->m_sb.sb_uquotino != NULLFSINO) + mark_inode(mp, mp->m_sb.sb_uquotino); + if (mp->m_sb.sb_gquotino && mp->m_sb.sb_gquotino != NULLFSINO) + mark_inode(mp, mp->m_sb.sb_gquotino); + if (mp->m_sb.sb_pquotino && mp->m_sb.sb_pquotino != NULLFSINO) + mark_inode(mp, mp->m_sb.sb_pquotino); } static void From patchwork Mon Dec 23 21:53:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919294 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E09F81422AB for ; Mon, 23 Dec 2024 21:53:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990797; cv=none; b=DVxwTBt6X8C4H0M35OHryLBtiLyPEl9Xp/tG3kId0gYcMiZJKkdw10pelqtRs3+c+suLMsKppkjU14KvfCBPNmQKOOuk3ta6WNbAHOJq9cr/PRIwsf8NPIGXDOmJdbh47a5MC5ZM3fM1Prh+clnm8UmUdGaLsWX37sj6hCODJ+I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990797; c=relaxed/simple; bh=imZXq9QKF4kvk9pelvkd/wue14kpx3uV99MtwOvPozI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WclujlhOtN8vL5ihM4cg/vI6Zp84Yn7m9qtLOTkHjEszJDUq6CN8j6lb6ImDpPTHNRQ1I6TJpnChK9asPSZ000W8UNILP1pYpFWBBy+3xVRc4OiPMto/bXwFxAIiqZq0VePHrV1OHXY5mfeeVqc+I/dBqWjPnHB/WDUH8xqJDDo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PKQ+yOqu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PKQ+yOqu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B7196C4CED3; Mon, 23 Dec 2024 21:53:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990796; bh=imZXq9QKF4kvk9pelvkd/wue14kpx3uV99MtwOvPozI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=PKQ+yOquqy9Re3QbYakVprwzTF7D3gX1LcXDmLxlkqT4CdQLTepc6Blyg+g/QVmWu 8W0c8QmZthE/PwOEx61qPhJIQL+dpkFlyrrW/xpNPi9mvhTkrIqpDe8rx0+HDYmIoo xGKvQrmXuHVNIoMoW8gVMTHUk/+Q0nZ++IOwDdRc6i/HP0PDI7xzv3SPQEGKcgJ9Uk 6Q5AUcUTrGuEPuYghFxOoKVX7PTExvhX7ErhqGZBpnm35jW+kAXWNEk2fG9SCgk4vg FLq5A+y/5D2MVfpRoN9JYAzl4zA0cI0qLaID2y5N6t+PcATluiV9H7SPq3kZER3a7L J2cMCK8XAPPRQ== Date: Mon, 23 Dec 2024 13:53:16 -0800 Subject: [PATCH 26/41] xfs_repair: refactor root directory initialization From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941367.2294268.7228312364539892994.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Refactor root directory initialization into a separate function we can call for both the root dir and the metadir. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase6.c | 63 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index 79c8226110a890..b3c013138be6c8 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -587,27 +587,27 @@ mk_rsumino(xfs_mount_t *mp) libxfs_irele(ip); } -/* - * makes a new root directory. - */ -static void -mk_root_dir(xfs_mount_t *mp) +/* Initialize a root directory. */ +static int +init_fs_root_dir( + struct xfs_mount *mp, + xfs_ino_t ino, + mode_t mode, + struct xfs_inode **ipp) { - xfs_trans_t *tp; - xfs_inode_t *ip; - int i; - int error; - const mode_t mode = 0755; - ino_tree_node_t *irec; + struct xfs_trans *tp; + struct xfs_inode *ip = NULL; + struct ino_tree_node *irec; + int error; - ip = NULL; - i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp); - if (i) - res_failed(i); + error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp); + if (error) + return error; - error = -libxfs_iget(mp, tp, mp->m_sb.sb_rootino, 0, &ip); + error = -libxfs_iget(mp, tp, ino, 0, &ip); if (error) { - do_error(_("could not iget root inode -- error - %d\n"), error); + libxfs_trans_cancel(tp); + return error; } /* Reset the root directory. */ @@ -616,14 +616,31 @@ mk_root_dir(xfs_mount_t *mp) error = -libxfs_trans_commit(tp); if (error) - do_error(_("%s: commit failed, error %d\n"), __func__, error); + return error; + + irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ino), + XFS_INO_TO_AGINO(mp, ino)); + set_inode_isadir(irec, XFS_INO_TO_AGINO(mp, ino) - irec->ino_startnum); + *ipp = ip; + return 0; +} + +/* + * makes a new root directory. + */ +static void +mk_root_dir(xfs_mount_t *mp) +{ + struct xfs_inode *ip = NULL; + int error; + + error = init_fs_root_dir(mp, mp->m_sb.sb_rootino, 0755, &ip); + if (error) + do_error( + _("Could not reinitialize root directory inode, error %d\n"), + error); libxfs_irele(ip); - - irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), - XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); - set_inode_isadir(irec, XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino) - - irec->ino_startnum); } /* From patchwork Mon Dec 23 21:53:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919295 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 819AF1422AB for ; Mon, 23 Dec 2024 21:53:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990812; cv=none; b=MOJrByKlzkETenPBAYMT89XlfQ8ZoU5okt/265UofEacL9xtLhJ5b+hYP8eoox2bQ6/nwMpzxgZzSLdMmFXOtXNJolFtCGpfYpuQBQIgNaSxhv3bQgqru+ivPCkq9QikUTDI2ZLiK6r2FUBKMEtEOlrsmdMNnEKMsNO5QTh4Gs0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990812; c=relaxed/simple; bh=nlKdakrj9YPbtnIN9/CWeNbT0nxicy6fP+nObhMf/B4=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tCcR1QSFTMRMnPt/kMeYixPHSMSc42WHg2PtXs4hJVjvkep+xUK1H0ZL+whDq7eO/QlfHa797S4SV6I+Tc3WhffCD2kn/kAbykhUcLR3r4ebbk4IVjtaZXA5COkQqFvF7CiLzN2qIi3UBCFklvV9/coC76xKBhz59quOnlsxKVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BKeSeazz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BKeSeazz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 55EFFC4CED3; Mon, 23 Dec 2024 21:53:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990812; bh=nlKdakrj9YPbtnIN9/CWeNbT0nxicy6fP+nObhMf/B4=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=BKeSeazzJOG77eYRmz6f8nD/pqAbU92Vzu2idNAPaDZ9x3uxO9o2vdHzMl2M6wK9D h16lZGocyBhzBgzCjDkasWcd5RjBXI30PPkHbc3DlbZZ+NR4q2266YgMPYb/2Qt+H9 HI0xv9KIm1J+0pjgu7Vcw8QY9QHj8sqesNFfz7+YQoCDXMeSIctk5LeMKuiwknHtTZ asUXsE6NdDvDRMOEPfZHiH9q8hPSvVBGG2vH7y8m9pFw7bUv+3ju0U4td5oZYfMjBx okYg+ViXbOVhG/MuIKfSJTMfVRI/oYMkSlTgBQ8N4r6tXZVNhu1R+0EH75rmnLJEMy mLjuMCR1JHPLw== Date: Mon, 23 Dec 2024 13:53:31 -0800 Subject: [PATCH 27/41] xfs_repair: refactor grabbing realtime metadata inodes From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941382.2294268.17205149313239172434.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Create a helper function to grab a realtime metadata inode. When metadir arrives, the bitmap and summary inodes can float, so we'll turn this function into a "load or allocate" function. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase6.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index b3c013138be6c8..1decfe2286fa47 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -474,6 +474,24 @@ reset_sbroot_ino( libxfs_inode_init(tp, &args, ip); } +/* Load a realtime freespace metadata inode from disk and reset it. */ +static int +ensure_rtino( + struct xfs_trans *tp, + xfs_ino_t ino, + struct xfs_inode **ipp) +{ + struct xfs_mount *mp = tp->t_mountp; + int error; + + error = -libxfs_iget(mp, tp, ino, 0, ipp); + if (error) + return error; + + reset_sbroot_ino(tp, S_IFREG, *ipp); + return 0; +} + static void mk_rbmino( struct xfs_mount *mp) @@ -486,15 +504,14 @@ mk_rbmino( if (error) res_failed(error); - error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip); - if (error) { - do_error( - _("couldn't iget realtime bitmap inode -- error - %d\n"), - error); - } - /* Reset the realtime bitmap inode. */ - reset_sbroot_ino(tp, S_IFREG, ip); + error = ensure_rtino(tp, mp->m_sb.sb_rbmino, &ip); + if (error) { + do_error( + _("couldn't iget realtime bitmap inode -- error - %d\n"), + error); + } + ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize; libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = -libxfs_trans_commit(tp); @@ -560,7 +577,8 @@ _("couldn't re-initialize realtime summary inode, error %d\n"), error); } static void -mk_rsumino(xfs_mount_t *mp) +mk_rsumino( + struct xfs_mount *mp) { struct xfs_trans *tp; struct xfs_inode *ip; @@ -570,15 +588,14 @@ mk_rsumino(xfs_mount_t *mp) if (error) res_failed(error); - error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip); - if (error) { - do_error( - _("couldn't iget realtime summary inode -- error - %d\n"), - error); - } - /* Reset the rt summary inode. */ - reset_sbroot_ino(tp, S_IFREG, ip); + error = ensure_rtino(tp, mp->m_sb.sb_rsumino, &ip); + if (error) { + do_error( + _("couldn't iget realtime summary inode -- error - %d\n"), + error); + } + ip->i_disk_size = mp->m_rsumblocks * mp->m_sb.sb_blocksize; libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = -libxfs_trans_commit(tp); From patchwork Mon Dec 23 21:53:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919296 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6D11C19048A for ; Mon, 23 Dec 2024 21:53:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990828; cv=none; b=dm/xT+RT9WNeM3Ck6yw2Vuwlzaq7ayMsoLJKD6IYNElbMTQXyjfS2rzUsSowkp8KFDQr7EHh1y4aoGamFt7YImEtxPuwBTZaShwJYmNeGPmUB/cWCnEA8BMZbz+bagIknuQMnuZ4Zsymp59O4UQntaTHq+Y9NgxBNzZ3mqHCamQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990828; c=relaxed/simple; bh=2PrKCYZ4oW7FWPRrXs0ud2cF1JDf4Np78gjxr8b1cyY=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JwaMf/vfkSgt310Ml5xAvo128ztdpz5iePRbNMmpYIxB7B1B6YW1mN4N5GWx+7tDDgKj6GQTHN1o5KcJDtDbOZz/GT3fxVuaZtpwYdrva18li24UrWskHkRdxcnuGKkfovAYwkUKW9kidI3ZErhjBLkJRv2O+FtDrtLdwiJEJvQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bk926N69; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bk926N69" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E6097C4CED3; Mon, 23 Dec 2024 21:53:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990828; bh=2PrKCYZ4oW7FWPRrXs0ud2cF1JDf4Np78gjxr8b1cyY=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=bk926N6927kg29gjpskTNnsFKUeLDLSItx48JA76f4x3cgQdz54tbTIk0IeHKZhwH phRARo0y+y0aINVq7V6lP4pjY6sjXnWmSJp8yUcVwbbwKiWfkq7NxmbVkDZiVpTzYD 4Ro6d/C7gbjRGbnOrkXed60mS31oRL8XXbyq1caGeFuvGn8HukFdFkcjNzDyP8WbQX dfiZU0nu1prf71kCpe09iBHRuKJJDThafbyVC0zYeyo6pz1Psth2ARW4r7XaoDAZkE ptjAgW7Ras7vE5Y4TS0YLmj4fj2uMex8lPTFgUfuo6SCX+/fisytK7yBrC/+l/hFwC i+TpUtqUeOnGg== Date: Mon, 23 Dec 2024 13:53:47 -0800 Subject: [PATCH 28/41] xfs_repair: check metadata inode flag From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941398.2294268.14575894511791481918.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Check whether or not the metadata inode flag is set appropriately. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/dinode.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/repair/dinode.c b/repair/dinode.c index e217e037f8862d..5dd7edfa36aed0 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2331,6 +2331,26 @@ _("Bad extent size hint %u on inode %" PRIu64 ", "), } } +static inline bool +should_have_metadir_iflag( + struct xfs_mount *mp, + xfs_ino_t ino) +{ + if (ino == mp->m_sb.sb_metadirino) + return true; + if (ino == mp->m_sb.sb_rbmino) + return true; + if (ino == mp->m_sb.sb_rsumino) + return true; + if (ino == mp->m_sb.sb_uquotino) + return true; + if (ino == mp->m_sb.sb_gquotino) + return true; + if (ino == mp->m_sb.sb_pquotino) + return true; + return false; +} + /* * returns 0 if the inode is ok, 1 if the inode is corrupt * check_dups can be set to 1 *only* when called by the @@ -2680,6 +2700,27 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), } } + if (flags2 & XFS_DIFLAG2_METADATA) { + xfs_failaddr_t fa; + + fa = libxfs_dinode_verify_metadir(mp, dino, di_mode, + be16_to_cpu(dino->di_flags), flags2); + if (fa) { + if (!uncertain) + do_warn( + _("inode %" PRIu64 " is incorrectly marked as metadata\n"), + lino); + goto clear_bad_out; + } + } else if (xfs_has_metadir(mp) && + should_have_metadir_iflag(mp, lino)) { + if (!uncertain) + do_warn( + _("inode %" PRIu64 " should be marked as metadata\n"), + lino); + goto clear_bad_out; + } + if ((flags2 & XFS_DIFLAG2_REFLINK) && !xfs_has_reflink(mp)) { if (!uncertain) { From patchwork Mon Dec 23 21:54:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919297 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 AD93919259D for ; Mon, 23 Dec 2024 21:54:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990843; cv=none; b=QYBoMw6XhzTf6IUuwO6/aHmDqIh+SyNkO6w+TLihCdr4b/IOxEExPgH1/8bahqcnD7SC/sxe5gM/4/29DuABQVIGHL9XHfsBhP9VIJQj65RFJWjUtys/ClRiGMyX1u2Dony7Qh7Tdv5S8BJCdkX0Y6g6tjUD+bGzi9fuTAE3bfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990843; c=relaxed/simple; bh=q1/JjIWG/v1XWbkNICI8bovSVG1b6e7EDOxyLSyn9YU=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UdnhHfBc2TTUVaCiDORJYNvJx/xtFwxJd7u+A32YlOC2FBXjug7l7ufhDPzYj39zd5SPGFV5M3HfdMgZhjyogZuzGwE0HPt0Ev9JPkeqhcZH4lTaLakCAXNrEbO4Dfm7rCjCSP5rX4dUGWNi8Jszmjd0G6hgnqIIM0Ap2qthdqk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NTmPoYYE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NTmPoYYE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8B67BC4CED3; Mon, 23 Dec 2024 21:54:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990843; bh=q1/JjIWG/v1XWbkNICI8bovSVG1b6e7EDOxyLSyn9YU=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=NTmPoYYExOZKuLFlFRk4VaxncOH/C27U622VIbhwyZ2RkkywPqY4Xcz+BH65b7tyr rk0tgJR8GAcP63FdybC9VWxNg8i0X/gjAA08N5W6qoXhAUZZAMO5b80TX7kXj7faCP C4UgcbW+QQRmuHN3QgKJ68iPATsCgmMy+l1H4xlLNEC9T9e8BG+mO5PvutU5bN7WTA ZlLPXcjPCpWC+7HGfh9QlLIFyVd5DijgYgYEbp8EvgSbt28/GnnFkS5UjJs2+A/+tu seSNwh+Vl14Dt0rWjb9/o99sDTpHrtqx5+UvRncj7VBHm6ET9DenrxfODtmXUn5/zk f3g7giw76lK2A== Date: Mon, 23 Dec 2024 13:54:03 -0800 Subject: [PATCH 29/41] xfs_repair: use libxfs_metafile_iget for quota/rt inodes From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941413.2294268.3995795656525060421.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Use the new iget function for these metadata files so that we can check types, etc. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase6.c | 23 +++++++++-------------- repair/quotacheck.c | 17 ++++++++++++++--- repair/rt.c | 29 ++++++++++++++++++++++------- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index 1decfe2286fa47..82e1687f9b278d 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -484,6 +484,11 @@ ensure_rtino( struct xfs_mount *mp = tp->t_mountp; int error; + /* + * Don't use metafile iget here because we're resetting sb-rooted + * inodes that live at fixed inumbers, but these inodes could be in + * an arbitrary state. + */ error = -libxfs_iget(mp, tp, ino, 0, ipp); if (error) return error; @@ -524,16 +529,11 @@ static void fill_rbmino( struct xfs_mount *mp) { - struct xfs_trans *tp; struct xfs_inode *ip; int error; - error = -libxfs_trans_alloc_rollable(mp, 10, &tp); - if (error) - res_failed(error); - - error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip); - libxfs_trans_cancel(tp); + error = -libxfs_metafile_iget(mp, mp->m_sb.sb_rbmino, + XFS_METAFILE_RTBITMAP, &ip); if (error) do_error( _("couldn't iget realtime bitmap inode, error %d\n"), error); @@ -551,16 +551,11 @@ static void fill_rsumino( struct xfs_mount *mp) { - struct xfs_trans *tp; struct xfs_inode *ip; int error; - error = -libxfs_trans_alloc_rollable(mp, 10, &tp); - if (error) - res_failed(error); - - error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip); - libxfs_trans_cancel(tp); + error = -libxfs_metafile_iget(mp, mp->m_sb.sb_rsumino, + XFS_METAFILE_RTSUMMARY, &ip); if (error) do_error( _("couldn't iget realtime summary inode, error %d\n"), error); diff --git a/repair/quotacheck.c b/repair/quotacheck.c index 4cb38db3ddd6d7..d9e08059927f80 100644 --- a/repair/quotacheck.c +++ b/repair/quotacheck.c @@ -403,21 +403,26 @@ quotacheck_verify( struct xfs_ifork *ifp; struct qc_dquots *dquots = NULL; struct avl64node *node, *n; + struct xfs_trans *tp; xfs_ino_t ino = NULLFSINO; + enum xfs_metafile_type metafile_type; int error; switch (type) { case XFS_DQTYPE_USER: ino = mp->m_sb.sb_uquotino; dquots = user_dquots; + metafile_type = XFS_METAFILE_USRQUOTA; break; case XFS_DQTYPE_GROUP: ino = mp->m_sb.sb_gquotino; dquots = group_dquots; + metafile_type = XFS_METAFILE_GRPQUOTA; break; case XFS_DQTYPE_PROJ: ino = mp->m_sb.sb_pquotino; dquots = proj_dquots; + metafile_type = XFS_METAFILE_PRJQUOTA; break; } @@ -429,17 +434,21 @@ quotacheck_verify( if (!dquots || !chkd_flags) return; - error = -libxfs_iget(mp, NULL, ino, 0, &ip); + error = -libxfs_trans_alloc_empty(mp, &tp); + if (error) + do_error(_("could not alloc transaction to open quota file\n")); + + error = -libxfs_trans_metafile_iget(tp, ino, metafile_type, &ip); if (error) { do_warn( _("could not open %s inode %"PRIu64" for quotacheck, err=%d\n"), qflags_typestr(type), ino, error); chkd_flags = 0; - return; + goto out_trans; } ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK); - error = -libxfs_iread_extents(NULL, ip, XFS_DATA_FORK); + error = -libxfs_iread_extents(tp, ip, XFS_DATA_FORK); if (error) { do_warn( _("could not read %s inode %"PRIu64" extents, err=%d\n"), @@ -477,6 +486,8 @@ _("%s record for id %u not found on disk (bcount %"PRIu64" rtbcount %"PRIu64" ic } err: libxfs_irele(ip); +out_trans: + libxfs_trans_cancel(tp); } /* diff --git a/repair/rt.c b/repair/rt.c index 721c363cc1dd10..9ae421168e84b4 100644 --- a/repair/rt.c +++ b/repair/rt.c @@ -144,18 +144,34 @@ generate_rtinfo( static void check_rtfile_contents( struct xfs_mount *mp, - const char *filename, - xfs_ino_t ino, - void *buf, + enum xfs_metafile_type metafile_type, xfs_fileoff_t filelen) { struct xfs_bmbt_irec map; struct xfs_buf *bp; struct xfs_inode *ip; + const char *filename; + void *buf; + xfs_ino_t ino; xfs_fileoff_t bno = 0; int error; - error = -libxfs_iget(mp, NULL, ino, 0, &ip); + switch (metafile_type) { + case XFS_METAFILE_RTBITMAP: + ino = mp->m_sb.sb_rbmino; + filename = "rtbitmap"; + buf = btmcompute; + break; + case XFS_METAFILE_RTSUMMARY: + ino = mp->m_sb.sb_rsumino; + filename = "rtsummary"; + buf = sumcompute; + break; + default: + return; + } + + error = -libxfs_metafile_iget(mp, ino, metafile_type, &ip); if (error) { do_warn(_("unable to open %s file, err %d\n"), filename, error); return; @@ -216,7 +232,7 @@ check_rtbitmap( if (need_rbmino) return; - check_rtfile_contents(mp, "rtbitmap", mp->m_sb.sb_rbmino, btmcompute, + check_rtfile_contents(mp, XFS_METAFILE_RTBITMAP, mp->m_sb.sb_rbmblocks); } @@ -227,6 +243,5 @@ check_rtsummary( if (need_rsumino) return; - check_rtfile_contents(mp, "rtsummary", mp->m_sb.sb_rsumino, sumcompute, - mp->m_rsumblocks); + check_rtfile_contents(mp, XFS_METAFILE_RTSUMMARY, mp->m_rsumblocks); } From patchwork Mon Dec 23 21:54:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919298 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 5C46E19259D for ; Mon, 23 Dec 2024 21:54:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990859; cv=none; b=jRqXKk1b8fGCxwWN/nBfUvYXG8W3VvRCw3G/b1A03JFdoaZZu4DezOzklcfQlVygR7VVAKI4r7pBjmrUgDWw6Yggmlq+uQuMVWsFBGaR7lRQLOucFBocoMmLXCI3JLYZTb+uCPv0dyvX2625kpBR1Jw+6NMkl2TppvlcxWuq/Vc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990859; c=relaxed/simple; bh=1wTV0udIAYbBIwPBfSN5YdEHJQhZfEag/L1YW7oB2LU=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ne3/DsgOUtgMcVtO7zHskTTnnVjD7NTC07GM1me3soRNmWdu4oOGG5ixm+FwqQxLqQjdoUITCDmIl5xiO+dfG7rdRKIR3pcAJ177jv4YoYVLwVjNCTgyYloEPJ+29BXTP00vYduT5xK91fuEbTMwo+GhLcQ9Ad1timVM1OyOmaw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YU6Ru2LA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YU6Ru2LA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 21A9CC4CED3; Mon, 23 Dec 2024 21:54:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990859; bh=1wTV0udIAYbBIwPBfSN5YdEHJQhZfEag/L1YW7oB2LU=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=YU6Ru2LAb0Pl7dymrRLpno0ab12OSq2KR7qEg8TbcivcTLSOYoWt6vLMTjl5NHym0 8jvRt5YFq8tbb/dCNsxE6SI/llAhnid0CSgzXDfndgURavFzXcsTx+jWZBDLiA4qCv YoKru5Q907FEZLQ+xud8OTpQG6p360eVxrHfT0/IGpL68deBxwUP8jJrkAaaK+c7VE vkAyJmVkGwKhhLy02rslAE+V5Ek7nIsw90yHtEXtRrlMlalWh+beRjcKiaB98MhFns Rf8W5EUx6R9RbFyPe2UOPjqilwieqawmoXZNJRGKbTqjPCeQEVv0fNlQnjKrZ6YnqL nOivWcrufGfYA== Date: Mon, 23 Dec 2024 13:54:18 -0800 Subject: [PATCH 30/41] xfs_repair: rebuild the metadata directory From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941428.2294268.3851251919592701079.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Check the dirents in metadata directories for problems and repair them if necessary. Also make sure that the sb-rooted inodes (root, metadir root, rt bitmap, rt summary) are always allocated in that order. Note that xfs_repair will always rebuild the metadata directory tree itself, so we only need to report problems, not fix them. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- libxfs/libxfs_api_defs.h | 1 repair/dino_chunks.c | 12 ++++++ repair/dir2.c | 16 +++++++- repair/globals.c | 3 + repair/globals.h | 3 + repair/incore.h | 13 ++++++ repair/phase1.c | 2 + repair/phase2.c | 53 +++++++++++++++++++------- repair/phase4.c | 16 ++++++++ repair/phase6.c | 73 ++++++++++++++++++++++++++++++++++-- repair/pptr.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++ repair/pptr.h | 2 + repair/sb.c | 3 + repair/xfs_repair.c | 50 ++++++++++++++++++++++++ 14 files changed, 320 insertions(+), 21 deletions(-) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index d2611d7a764259..e79aa0e06e4f90 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -214,6 +214,7 @@ #define xfs_metafile_iget libxfs_metafile_iget #define xfs_trans_metafile_iget libxfs_trans_metafile_iget +#define xfs_metafile_set_iflag libxfs_metafile_set_iflag #define xfs_metadir_link libxfs_metadir_link #define xfs_metadir_lookup libxfs_metadir_lookup #define xfs_metadir_start_create libxfs_metadir_start_create diff --git a/repair/dino_chunks.c b/repair/dino_chunks.c index 49d57948c7eca8..0d9b3a01bc298d 100644 --- a/repair/dino_chunks.c +++ b/repair/dino_chunks.c @@ -932,6 +932,18 @@ process_inode_chunk( _("would clear root inode %" PRIu64 "\n"), ino); } + } else if (mp->m_sb.sb_metadirino == ino) { + need_metadir_inode = true; + + if (!no_modify) { + do_warn( + _("cleared metadata directory %" PRIu64 "\n"), + ino); + } else { + do_warn( + _("would clear metadata directory %" PRIu64 "\n"), + ino); + } } else if (mp->m_sb.sb_rbmino == ino) { need_rbmino = 1; diff --git a/repair/dir2.c b/repair/dir2.c index dab6523f676a34..d233c724488182 100644 --- a/repair/dir2.c +++ b/repair/dir2.c @@ -271,6 +271,9 @@ process_sf_dir2( } else if (lino == mp->m_sb.sb_pquotino) { junkit = 1; junkreason = _("project quota"); + } else if (lino == mp->m_sb.sb_metadirino) { + junkit = 1; + junkreason = _("metadata directory root"); } else if ((irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, lino), XFS_INO_TO_AGINO(mp, lino))) != NULL) { @@ -564,7 +567,8 @@ _("corrected root directory %" PRIu64 " .. entry, was %" PRIu64 ", now %" PRIu64 _("would have corrected root directory %" PRIu64 " .. entry from %" PRIu64" to %" PRIu64 "\n"), ino, *parent, ino); } - } else if (ino == *parent && ino != mp->m_sb.sb_rootino) { + } else if (ino == *parent && ino != mp->m_sb.sb_rootino && + ino != mp->m_sb.sb_metadirino) { /* * likewise, non-root directories can't have .. pointing * to . @@ -743,6 +747,8 @@ process_dir2_data( clearreason = _("group quota"); } else if (ent_ino == mp->m_sb.sb_pquotino) { clearreason = _("project quota"); + } else if (ent_ino == mp->m_sb.sb_metadirino) { + clearreason = _("metadata directory root"); } else { irec_p = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ent_ino), @@ -864,7 +870,8 @@ _("entry at block %u offset %" PRIdPTR " in directory inode %" PRIu64 " has ille * NULLFSINO otherwise. */ if (ino == ent_ino && - ino != mp->m_sb.sb_rootino) { + ino != mp->m_sb.sb_rootino && + ino != mp->m_sb.sb_metadirino) { *parent = NULLFSINO; do_warn( _("bad .. entry in directory inode %" PRIu64 ", points to self: "), @@ -1519,9 +1526,14 @@ process_dir2( } else if (dotdot == 0 && ino == mp->m_sb.sb_rootino) { do_warn(_("no .. entry for root directory %" PRIu64 "\n"), ino); need_root_dotdot = 1; + } else if (dotdot == 0 && ino == mp->m_sb.sb_metadirino) { + do_warn(_("no .. entry for metaino directory %" PRIu64 "\n"), ino); + need_metadir_dotdot = 1; } ASSERT((ino != mp->m_sb.sb_rootino && ino != *parent) || + (ino == mp->m_sb.sb_metadirino && + (ino == *parent || need_metadir_dotdot == 1)) || (ino == mp->m_sb.sb_rootino && (ino == *parent || need_root_dotdot == 1))); diff --git a/repair/globals.c b/repair/globals.c index 7388090a7d39f3..b63931be9fdb70 100644 --- a/repair/globals.c +++ b/repair/globals.c @@ -66,6 +66,9 @@ int fs_is_dirty; int need_root_inode; int need_root_dotdot; +bool need_metadir_inode; +int need_metadir_dotdot; + int need_rbmino; int need_rsumino; diff --git a/repair/globals.h b/repair/globals.h index fa53502f98bbcd..1dc85ce7f8114c 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -107,6 +107,9 @@ extern int fs_is_dirty; extern int need_root_inode; extern int need_root_dotdot; +extern bool need_metadir_inode; +extern int need_metadir_dotdot; + extern int need_rbmino; extern int need_rsumino; diff --git a/repair/incore.h b/repair/incore.h index 9ad5f1972d3dee..4f32ad3377faed 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -661,4 +661,17 @@ inorec_set_freecount( rp->ir_u.f.ir_freecount = cpu_to_be32(freecount); } +/* + * Number of inodes assumed to be always allocated because they are created + * by mkfs. + */ +static inline unsigned int +xfs_rootrec_inodes_inuse( + struct xfs_mount *mp) +{ + if (xfs_has_metadir(mp)) + return 4; /* sb_rootino, sb_rbmino, sb_rsumino, sb_metadirino */ + return 3; /* sb_rootino, sb_rbmino, sb_rsumino */ +} + #endif /* XFS_REPAIR_INCORE_H */ diff --git a/repair/phase1.c b/repair/phase1.c index 00b98584eed429..40e7f164c55158 100644 --- a/repair/phase1.c +++ b/repair/phase1.c @@ -48,6 +48,8 @@ phase1(xfs_mount_t *mp) primary_sb_modified = 0; need_root_inode = 0; need_root_dotdot = 0; + need_metadir_inode = false; + need_metadir_dotdot = 0; need_rbmino = 0; need_rsumino = 0; lost_quotas = 0; diff --git a/repair/phase2.c b/repair/phase2.c index 17966bb54db09d..17c16e94a600c2 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -496,8 +496,8 @@ phase2( struct xfs_mount *mp, int scan_threads) { - int j; ino_tree_node_t *ino_rec; + unsigned int inuse = xfs_rootrec_inodes_inuse(mp), j; /* now we can start using the buffer cache routines */ set_mp(mp); @@ -541,58 +541,81 @@ phase2( * make sure we know about the root inode chunk */ if ((ino_rec = find_inode_rec(mp, 0, mp->m_sb.sb_rootino)) == NULL) { - ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 && - mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2); + struct xfs_sb *sb = &mp->m_sb; + + if (xfs_has_metadir(mp)) + ASSERT(sb->sb_metadirino == sb->sb_rootino + 1 && + sb->sb_rbmino == sb->sb_rootino + 2 && + sb->sb_rsumino == sb->sb_rootino + 3); + else + ASSERT(sb->sb_rbmino == sb->sb_rootino + 1 && + sb->sb_rsumino == sb->sb_rootino + 2); do_warn(_("root inode chunk not found\n")); /* - * mark the first 3 used, the rest are free + * mark the first 3-4 inodes used, the rest are free */ ino_rec = set_inode_used_alloc(mp, 0, - (xfs_agino_t) mp->m_sb.sb_rootino); - set_inode_used(ino_rec, 1); - set_inode_used(ino_rec, 2); + XFS_INO_TO_AGINO(mp, sb->sb_rootino)); + for (j = 1; j < inuse; j++) + set_inode_used(ino_rec, j); - for (j = 3; j < XFS_INODES_PER_CHUNK; j++) + for (j = inuse; j < XFS_INODES_PER_CHUNK; j++) set_inode_free(ino_rec, j); /* * also mark blocks */ - set_bmap_ext(0, XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino), + set_bmap_ext(0, XFS_INO_TO_AGBNO(mp, sb->sb_rootino), M_IGEO(mp)->ialloc_blks, XR_E_INO); } else { do_log(_(" - found root inode chunk\n")); + j = 0; /* * blocks are marked, just make sure they're in use */ - if (is_inode_free(ino_rec, 0)) { + if (is_inode_free(ino_rec, j)) { do_warn(_("root inode marked free, ")); - set_inode_used(ino_rec, 0); + set_inode_used(ino_rec, j); if (!no_modify) do_warn(_("correcting\n")); else do_warn(_("would correct\n")); } + j++; - if (is_inode_free(ino_rec, 1)) { + if (xfs_has_metadir(mp)) { + if (is_inode_free(ino_rec, j)) { + do_warn(_("metadata root inode marked free, ")); + set_inode_used(ino_rec, j); + if (!no_modify) + do_warn(_("correcting\n")); + else + do_warn(_("would correct\n")); + } + j++; + } + + if (is_inode_free(ino_rec, j)) { do_warn(_("realtime bitmap inode marked free, ")); - set_inode_used(ino_rec, 1); + set_inode_used(ino_rec, j); if (!no_modify) do_warn(_("correcting\n")); else do_warn(_("would correct\n")); } + j++; - if (is_inode_free(ino_rec, 2)) { + if (is_inode_free(ino_rec, j)) { do_warn(_("realtime summary inode marked free, ")); - set_inode_used(ino_rec, 2); + set_inode_used(ino_rec, j); if (!no_modify) do_warn(_("correcting\n")); else do_warn(_("would correct\n")); } + j++; } /* diff --git a/repair/phase4.c b/repair/phase4.c index 071f20ed736e4b..7efef86245fbe7 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -264,6 +264,22 @@ phase4(xfs_mount_t *mp) do_warn(_("root inode lost\n")); } + /* + * If metadata directory trees are enabled, the metadata root directory + * always comes immediately after the regular root directory, even if + * it's free. + */ + if (xfs_has_metadir(mp) && + (is_inode_free(irec, 1) || !inode_isadir(irec, 1))) { + need_metadir_inode = true; + if (no_modify) + do_warn( + _("metadata directory root inode would be lost\n")); + else + do_warn( + _("metadata directory root inode lost\n")); + } + for (i = 0; i < mp->m_sb.sb_agcount; i++) { ag_end = (i < mp->m_sb.sb_agcount - 1) ? mp->m_sb.sb_agblocks : mp->m_sb.sb_dblocks - diff --git a/repair/phase6.c b/repair/phase6.c index 82e1687f9b278d..7a8edbad2ebfc2 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -478,12 +478,25 @@ reset_sbroot_ino( static int ensure_rtino( struct xfs_trans *tp, - xfs_ino_t ino, + enum xfs_metafile_type metafile_type, struct xfs_inode **ipp) { struct xfs_mount *mp = tp->t_mountp; + xfs_ino_t ino; int error; + switch (metafile_type) { + case XFS_METAFILE_RTBITMAP: + ino = mp->m_sb.sb_rbmino; + break; + case XFS_METAFILE_RTSUMMARY: + ino = mp->m_sb.sb_rsumino; + break; + default: + ASSERT(0); + return -EFSCORRUPTED; + } + /* * Don't use metafile iget here because we're resetting sb-rooted * inodes that live at fixed inumbers, but these inodes could be in @@ -494,6 +507,8 @@ ensure_rtino( return error; reset_sbroot_ino(tp, S_IFREG, *ipp); + if (xfs_has_metadir(mp)) + libxfs_metafile_set_iflag(tp, *ipp, metafile_type); return 0; } @@ -510,7 +525,7 @@ mk_rbmino( res_failed(error); /* Reset the realtime bitmap inode. */ - error = ensure_rtino(tp, mp->m_sb.sb_rbmino, &ip); + error = ensure_rtino(tp, XFS_METAFILE_RTBITMAP, &ip); if (error) { do_error( _("couldn't iget realtime bitmap inode -- error - %d\n"), @@ -584,7 +599,7 @@ mk_rsumino( res_failed(error); /* Reset the rt summary inode. */ - error = ensure_rtino(tp, mp->m_sb.sb_rsumino, &ip); + error = ensure_rtino(tp, XFS_METAFILE_RTSUMMARY, &ip); if (error) { do_error( _("couldn't iget realtime summary inode -- error - %d\n"), @@ -655,6 +670,36 @@ mk_root_dir(xfs_mount_t *mp) libxfs_irele(ip); } +/* Create a new metadata directory root. */ +static void +mk_metadir( + struct xfs_mount *mp) +{ + struct xfs_trans *tp; + int error; + + error = init_fs_root_dir(mp, mp->m_sb.sb_metadirino, 0, + &mp->m_metadirip); + if (error) + do_error( + _("Initialization of the metadata root directory failed, error %d\n"), + error); + + /* Mark the new metadata root dir as metadata. */ + error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); + if (error) + do_error( + _("Marking metadata root directory failed")); + + libxfs_trans_ijoin(tp, mp->m_metadirip, 0); + libxfs_metafile_set_iflag(tp, mp->m_metadirip, XFS_METAFILE_DIR); + + error = -libxfs_trans_commit(tp); + if (error) + do_error( + _("Marking metadata root directory failed, error %d\n"), error); +} + /* * orphanage name == lost+found */ @@ -1168,6 +1213,8 @@ longform_dir2_rebuild( if (ino == mp->m_sb.sb_rootino) need_root_dotdot = 0; + else if (ino == mp->m_sb.sb_metadirino) + need_metadir_dotdot = 0; /* go through the hash list and re-add the inodes */ @@ -2789,7 +2836,7 @@ process_dir_inode( need_dot = dirty = num_illegal = 0; - if (mp->m_sb.sb_rootino == ino) { + if (mp->m_sb.sb_rootino == ino || mp->m_sb.sb_metadirino == ino) { /* * mark root inode reached and bump up * link count for root inode to account @@ -2864,6 +2911,9 @@ _("error %d fixing shortform directory %llu\n"), dir_hash_done(hashtab); fix_dotdot(mp, ino, ip, mp->m_sb.sb_rootino, "root", &need_root_dotdot); + if (xfs_has_metadir(mp)) + fix_dotdot(mp, ino, ip, mp->m_sb.sb_metadirino, "metadata", + &need_metadir_dotdot); /* * if we need to create the '.' entry, do so only if @@ -3117,6 +3167,21 @@ phase6(xfs_mount_t *mp) } } + if (!no_modify && xfs_has_metadir(mp)) { + /* + * In write mode, we always rebuild the metadata directory + * tree, even if the old one was correct. However, we still + * want to log something if we couldn't find the old root. + */ + if (need_metadir_inode) + do_warn(_("reinitializing metadata root directory\n")); + mk_metadir(mp); + need_metadir_inode = false; + need_metadir_dotdot = 0; + } else if (need_metadir_inode) { + do_warn(_("would reinitialize metadata root directory\n")); + } + if (need_rbmino) { if (!no_modify) { do_warn(_("reinitializing realtime bitmap inode\n")); diff --git a/repair/pptr.c b/repair/pptr.c index ee29e47a87bd07..ac0a9c618bc87d 100644 --- a/repair/pptr.c +++ b/repair/pptr.c @@ -1334,3 +1334,97 @@ check_parent_ptrs( destroy_work_queue(&wq); } + +static int +erase_pptrs( + struct xfs_trans *tp, + struct xfs_inode *ip, + unsigned int attr_flags, + const unsigned char *name, + unsigned int namelen, + const void *value, + unsigned int valuelen, + void *priv) +{ + struct garbage_xattr garbage_xattr = { + .attr_filter = attr_flags, + .attrnamelen = namelen, + .attrvaluelen = valuelen, + }; + struct file_scan *fscan = priv; + int error; + + if (!(attr_flags & XFS_ATTR_PARENT)) + return 0; + + error = -xfblob_store(fscan->garbage_xattr_names, + &garbage_xattr.attrname_cookie, name, namelen); + if (error) + do_error(_("storing ino %llu garbage pptr failed: %s\n"), + (unsigned long long)ip->i_ino, + strerror(error)); + + error = -xfblob_store(fscan->garbage_xattr_names, + &garbage_xattr.attrvalue_cookie, value, valuelen); + if (error) + do_error(_("storing ino %llu garbage pptr failed: %s\n"), + (unsigned long long)ip->i_ino, + strerror(error)); + + error = -slab_add(fscan->garbage_xattr_recs, &garbage_xattr); + if (error) + do_error(_("storing ino %llu garbage pptr rec failed: %s\n"), + (unsigned long long)ip->i_ino, + strerror(error)); + + return 0; +} + +/* Delete all of this file's parent pointers if we can. */ +void +try_erase_parent_ptrs( + struct xfs_inode *ip) +{ + struct file_scan fscan = { + .have_garbage = true, + }; + struct xfs_mount *mp = ip->i_mount; + struct xfs_trans *tp = NULL; + char *descr; + int error; + + if (!xfs_has_parent(ip->i_mount)) + return; + + if (no_modify) { + do_warn( + _("would delete garbage parent pointers in metadata ino %llu\n"), + (unsigned long long)ip->i_ino); + return; + } + + error = -init_slab(&fscan.garbage_xattr_recs, + sizeof(struct garbage_xattr)); + if (error) + do_error(_("init garbage pptr recs failed: %s\n"), + strerror(error)); + + descr = kasprintf(GFP_KERNEL, "xfs_repair (%s): garbage pptr names", + mp->m_fsname); + error = -xfblob_create(descr, &fscan.garbage_xattr_names); + kfree(descr); + if (error) + do_error("init garbage pptr names failed: %s\n", + strerror(error)); + + libxfs_trans_alloc_empty(ip->i_mount, &tp); + error = xattr_walk(tp, ip, erase_pptrs, &fscan); + if (tp) + libxfs_trans_cancel(tp); + if (error) + do_warn(_("ino %llu garbage pptr collection failed: %s\n"), + (unsigned long long)ip->i_ino, + strerror(error)); + + remove_garbage_xattrs(ip, &fscan); +} diff --git a/repair/pptr.h b/repair/pptr.h index 65acff963a3fe9..38d5c4052ea86c 100644 --- a/repair/pptr.h +++ b/repair/pptr.h @@ -14,4 +14,6 @@ void add_parent_ptr(xfs_ino_t ino, const unsigned char *fname, void check_parent_ptrs(struct xfs_mount *mp); +void try_erase_parent_ptrs(struct xfs_inode *ip); + #endif /* __REPAIR_PPTR_H__ */ diff --git a/repair/sb.c b/repair/sb.c index 1320929caee590..7f27833d697ea9 100644 --- a/repair/sb.c +++ b/repair/sb.c @@ -28,6 +28,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest) xfs_ino_t uquotino; xfs_ino_t gquotino; xfs_ino_t pquotino; + xfs_ino_t metadirino; uint16_t versionnum; rootino = dest->sb_rootino; @@ -36,6 +37,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest) uquotino = dest->sb_uquotino; gquotino = dest->sb_gquotino; pquotino = dest->sb_pquotino; + metadirino = dest->sb_metadirino; versionnum = dest->sb_versionnum; @@ -47,6 +49,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest) dest->sb_uquotino = uquotino; dest->sb_gquotino = gquotino; dest->sb_pquotino = pquotino; + dest->sb_metadirino = metadirino; dest->sb_versionnum = versionnum; diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 3ade85bbcbb7fd..70cab1ad852a21 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -644,6 +644,46 @@ guess_correct_sunit( do_warn(_("Would reset sb_width to %u\n"), new_sunit); } +/* + * Check that the metadata directory inode comes immediately after the root + * directory inode and that it seems to look like a metadata directory. + */ +STATIC void +check_metadir_inode( + struct xfs_mount *mp, + xfs_ino_t rootino) +{ + int error; + + validate_sb_ino(&mp->m_sb.sb_metadirino, rootino + 1, + _("metadata root directory")); + + /* If we changed the metadir inode, try reloading it. */ + if (!mp->m_metadirip || + mp->m_metadirip->i_ino != mp->m_sb.sb_metadirino) { + if (mp->m_metadirip) + libxfs_irele(mp->m_metadirip); + + error = -libxfs_metafile_iget(mp, mp->m_sb.sb_metadirino, + XFS_METAFILE_DIR, &mp->m_metadirip); + if (error) { + need_metadir_inode = true; + goto done; + } + } + +done: + if (need_metadir_inode) { + if (!no_modify) + do_warn(_("will reset metadata root directory\n")); + else + do_warn(_("would reset metadata root directory\n")); + if (mp->m_metadirip) + libxfs_irele(mp->m_metadirip); + mp->m_metadirip = NULL; + } +} + /* * Make sure that the first 3 inodes in the filesystem are the root directory, * the realtime bitmap, and the realtime summary, in that order. @@ -673,6 +713,16 @@ _("sb root inode value %" PRIu64 " valid but in unaligned location (expected %"P validate_sb_ino(&mp->m_sb.sb_rootino, rootino, _("root")); + + if (xfs_has_metadir(mp)) { + /* + * The metadata root directory comes after the regular root + * directory. + */ + check_metadir_inode(mp, rootino); + rootino++; + } + validate_sb_ino(&mp->m_sb.sb_rbmino, rootino + 1, _("realtime bitmap")); validate_sb_ino(&mp->m_sb.sb_rsumino, rootino + 2, From patchwork Mon Dec 23 21:54:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919299 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E6DE71422AB for ; Mon, 23 Dec 2024 21:54:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990875; cv=none; b=sOA6XuCSpm9l8hTEnO0UDjoaaGgvLk7gRQ741Za0leFIx1ewA/jgDh9NKgyPGKLXzL4d3YBdpNXEwVNki89R0jIzJdY/6ZY+n8UjB6GBrw/PlL5rrcLy4e2Rf5+7ndGl5YAMRq1v4KZwAYXfNE/m8d14gU32VbCDs9ymtK8kph8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990875; c=relaxed/simple; bh=Q0HoA9NzWrmvTFqenbcYZxTrgYq6qwPbdDdSlb3cMu0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=brrIr1ulJpfHHDru2iuxr1pOVhJLJ6UJQ/jdHc6Z+JyU1bU+5C5/CNfZDeiXFvm7NLEe7AQSsbd38sgz/shAYX1JHTcmGsIQeF4XJY0xj5bmfaICBCEShgZOIPeScGFjHIXMdheXmDB7S6DqAsZ7XF6jJCIftIbVS9R4s3+m9T4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=byQYzlDP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="byQYzlDP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BBDE9C4CED3; Mon, 23 Dec 2024 21:54:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990874; bh=Q0HoA9NzWrmvTFqenbcYZxTrgYq6qwPbdDdSlb3cMu0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=byQYzlDPa8KUagPdJU8qIp8HbEku1tGM/KZ/0bH58QfdYlswX/I/bXeSvPTYME4E2 PKK+mJGcMKVyIfZONG9tjhfXLOvnhKrf9z43Jl5zLZS/EFTEd8/ntjJqsz6igvYQAK 7Vu67E6NGh7N8pIN2EwPPYCT6BqZBXkLL1ckxP3rpqVQNv5KxlY+bH0oDVunyoIGJg QbMlluW6svTxlXjxbJrQzgUhFyoFA3npPt5E8d0RFPCS5oOfGRmg89NBYRCpxeW0IM FjPsw3xRtrA39kmbQRXliSWlZZOYHfuFvv32HNf5408HpKJdZpu1ShhEJWHkZCfY0/ O2MQIWhTlOrcA== Date: Mon, 23 Dec 2024 13:54:34 -0800 Subject: [PATCH 31/41] xfs_repair: don't let metadata and regular files mix From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941444.2294268.11205149904208261584.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Track whether or not inodes thought they were metadata inodes. We cannot allow metadata inodes to appear in the regular directory tree, and we cannot allow regular inodes to appear in the metadata directory tree. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/dinode.c | 21 +++++++++++++++++ repair/incore.h | 19 +++++++++++++++ repair/incore_ino.c | 1 + repair/phase2.c | 7 +++++- repair/phase6.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+), 1 deletion(-) diff --git a/repair/dinode.c b/repair/dinode.c index 5dd7edfa36aed0..60a853d152ccec 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2392,6 +2392,7 @@ process_dinode_int( struct xfs_dinode *dino = *dinop; xfs_agino_t unlinked_ino; struct xfs_perag *pag; + bool is_meta = false; *dirty = *isa_dir = 0; *used = is_used; @@ -2971,6 +2972,18 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "), if (collect_rmaps) record_inode_reflink_flag(mp, dino, agno, ino, lino); + /* Does this inode think it was metadata? */ + if (dino->di_version >= 3 && + (dino->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA))) { + struct ino_tree_node *irec; + int off; + + irec = find_inode_rec(mp, agno, ino); + off = get_inode_offset(mp, lino, irec); + set_inode_is_meta(irec, off); + is_meta = true; + } + /* * check data fork -- if it's bad, clear the inode */ @@ -3057,6 +3070,14 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "), *used = is_free; *isa_dir = 0; blkmap_free(dblkmap); + if (is_meta) { + struct ino_tree_node *irec; + int off; + + irec = find_inode_rec(mp, agno, ino); + off = get_inode_offset(mp, lino, irec); + clear_inode_is_meta(irec, off); + } return 1; } diff --git a/repair/incore.h b/repair/incore.h index 4f32ad3377faed..568a8c7cb75b7c 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -271,6 +271,7 @@ typedef struct ino_tree_node { uint64_t ino_isa_dir; /* bit == 1 if a directory */ uint64_t ino_was_rl; /* bit == 1 if reflink flag set */ uint64_t ino_is_rl; /* bit == 1 if reflink flag should be set */ + uint64_t ino_is_meta; /* bit == 1 if metadata */ uint8_t nlink_size; union ino_nlink disk_nlinks; /* on-disk nlinks, set in P3 */ union { @@ -538,6 +539,24 @@ static inline int inode_is_rl(struct ino_tree_node *irec, int offset) return (irec->ino_is_rl & IREC_MASK(offset)) != 0; } +/* + * set/clear/test was inode marked as metadata + */ +static inline void set_inode_is_meta(struct ino_tree_node *irec, int offset) +{ + irec->ino_is_meta |= IREC_MASK(offset); +} + +static inline void clear_inode_is_meta(struct ino_tree_node *irec, int offset) +{ + irec->ino_is_meta &= ~IREC_MASK(offset); +} + +static inline int inode_is_meta(struct ino_tree_node *irec, int offset) +{ + return (irec->ino_is_meta & IREC_MASK(offset)) != 0; +} + /* * add_inode_reached() is set on inode I only if I has been reached * by an inode P claiming to be the parent and if I is a directory, diff --git a/repair/incore_ino.c b/repair/incore_ino.c index 158e9b4980d984..3189e019faa23d 100644 --- a/repair/incore_ino.c +++ b/repair/incore_ino.c @@ -257,6 +257,7 @@ alloc_ino_node( irec->ino_isa_dir = 0; irec->ino_was_rl = 0; irec->ino_is_rl = 0; + irec->ino_is_meta = 0; irec->ir_free = (xfs_inofree_t) - 1; irec->ir_sparse = 0; irec->ino_un.ex_data = NULL; diff --git a/repair/phase2.c b/repair/phase2.c index 17c16e94a600c2..476a1c74db8c8d 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -557,8 +557,10 @@ phase2( */ ino_rec = set_inode_used_alloc(mp, 0, XFS_INO_TO_AGINO(mp, sb->sb_rootino)); - for (j = 1; j < inuse; j++) + for (j = 1; j < inuse; j++) { set_inode_used(ino_rec, j); + set_inode_is_meta(ino_rec, j); + } for (j = inuse; j < XFS_INODES_PER_CHUNK; j++) set_inode_free(ino_rec, j); @@ -594,6 +596,7 @@ phase2( else do_warn(_("would correct\n")); } + set_inode_is_meta(ino_rec, j); j++; } @@ -605,6 +608,7 @@ phase2( else do_warn(_("would correct\n")); } + set_inode_is_meta(ino_rec, j); j++; if (is_inode_free(ino_rec, j)) { @@ -615,6 +619,7 @@ phase2( else do_warn(_("would correct\n")); } + set_inode_is_meta(ino_rec, j); j++; } diff --git a/repair/phase6.c b/repair/phase6.c index 7a8edbad2ebfc2..688eee20bb3e8e 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1610,6 +1610,38 @@ longform_dir2_entry_check_data( continue; } + /* + * Regular directories cannot point to metadata files. If + * we find such a thing, blow out the entry. + */ + if (!xfs_is_metadir_inode(ip) && + inode_is_meta(irec, ino_offset)) { + nbad++; + if (entry_junked( + _("entry \"%s\" in regular dir %" PRIu64" points to a metadata inode %" PRIu64 ", "), + fname, ip->i_ino, inum, NULLFSINO)) { + dep->name[0] = '/'; + libxfs_dir2_data_log_entry(&da, bp, dep); + } + continue; + } + + /* + * Metadata directories cannot point to regular files. If + * we find such a thing, blow out the entry. + */ + if (xfs_is_metadir_inode(ip) && + !inode_is_meta(irec, ino_offset)) { + nbad++; + if (entry_junked( + _("entry \"%s\" in metadata dir %" PRIu64" points to a regular inode %" PRIu64 ", "), + fname, ip->i_ino, inum, NULLFSINO)) { + dep->name[0] = '/'; + libxfs_dir2_data_log_entry(&da, bp, dep); + } + continue; + } + /* * check if this inode is lost+found dir in the root */ @@ -2521,6 +2553,37 @@ shortform_dir2_entry_check( ino_dirty); continue; } + + /* + * Regular directories cannot point to metadata files. If + * we find such a thing, blow out the entry. + */ + if (!xfs_is_metadir_inode(ip) && + inode_is_meta(irec, ino_offset)) { + do_warn( + _("entry \"%s\" in regular dir %" PRIu64" points to a metadata inode %" PRIu64 ", "), + fname, ip->i_ino, lino); + next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino, + &max_size, &i, &bytes_deleted, + ino_dirty); + continue; + } + + /* + * Metadata directories cannot point to regular files. If + * we find such a thing, blow out the entry. + */ + if (xfs_is_metadir_inode(ip) && + !inode_is_meta(irec, ino_offset)) { + do_warn( + _("entry \"%s\" in metadata dir %" PRIu64" points to a regular inode %" PRIu64 ", "), + fname, ip->i_ino, lino); + next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino, + &max_size, &i, &bytes_deleted, + ino_dirty); + continue; + } + /* * check if this inode is lost+found dir in the root */ From patchwork Mon Dec 23 21:54:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919300 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 85C4F1422AB for ; Mon, 23 Dec 2024 21:54:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990890; cv=none; b=cvWrwYWPMA6H1sLhg6SjBjzX5YMB+jjz+KCfBEYZ2F1dmaneODF7EefuLoYsrxoGLzpRfWYECR7S3pfMO7bwXG7v00z/5XJWf005NnKpIm1IegB8NoI4c9nO8G6bmSiHvuA/8B2uHOni0QqkeDIeTvocmX6Pvii38wWkp3aR3qk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990890; c=relaxed/simple; bh=MS5yVfNU50cycZuzgO4Kh26q4X/ajMaqnZtRKIS9T6Q=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kEVVrpl+57yeNJ8d9OZF2jrG/1peCbHrq58OF55K8NPrinlM4UEvk8jUfzQqg8onJ4g/OLaq7i/OUOaiV3AUt0FTyJnG5aSDasdpkHDo/sGKUaiyJi6rV0XQ40CWU9XzSWIJdS4A6LEpFwqLbyrcyKuJTx2c0qk2LDP0kJX78yA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SPfweeY3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SPfweeY3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E984C4CED3; Mon, 23 Dec 2024 21:54:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990890; bh=MS5yVfNU50cycZuzgO4Kh26q4X/ajMaqnZtRKIS9T6Q=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=SPfweeY3zuzuBUerpct1qpUVWX7iC3VISoNfcv3nBoza1mbNcTnvtd8k7lVF6kMoD h8LqyYbpJnTs0tdmltRXZDvnYo5E1qctUj3VtOabF7Fc2YdB0W37icTAaBAwsP9MOt Ozf8u6KX+7qV6MCjYzrLw54ZtKTmpvagl6Q4HsjPJdapxFFoIQ3pNpsr6ZC5L5y8CA EKeTLqmZu87zqDtyioLlrtW0THlBQabsMJGi+CMNHnOxKq+5Sti+qxvka6pzorkYsL SvgLy4omqMDbpEfVYwV6sndSatxci7Qos4x1j52WhNCmoE+Dk2R6sAaVbY94PK1PGx Ma8GU3Di4QFKg== Date: Mon, 23 Dec 2024 13:54:49 -0800 Subject: [PATCH 32/41] xfs_repair: update incore metadata state whenever we create new files From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941458.2294268.17770338571940137824.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Make sure that we update our incore metadata inode bookkeepping whenever we create new metadata files. There will be many more of these later. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase6.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/repair/phase6.c b/repair/phase6.c index 688eee20bb3e8e..8fa2c3c8bf0419 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -474,6 +474,22 @@ reset_sbroot_ino( libxfs_inode_init(tp, &args, ip); } +/* + * Mark a newly allocated inode as metadata in the incore bitmap. Callers + * must have already called mark_ino_inuse to ensure there is an incore record. + */ +static void +mark_ino_metadata( + struct xfs_mount *mp, + xfs_ino_t ino) +{ + struct ino_tree_node *irec = + find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ino), + XFS_INO_TO_AGINO(mp, ino)); + + set_inode_is_meta(irec, get_inode_offset(mp, ino, irec)); +} + /* Load a realtime freespace metadata inode from disk and reset it. */ static int ensure_rtino( @@ -693,6 +709,7 @@ mk_metadir( libxfs_trans_ijoin(tp, mp->m_metadirip, 0); libxfs_metafile_set_iflag(tp, mp->m_metadirip, XFS_METAFILE_DIR); + mark_ino_metadata(mp, mp->m_metadirip->i_ino); error = -libxfs_trans_commit(tp); if (error) From patchwork Mon Dec 23 21:55:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919301 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 1B50819259D for ; Mon, 23 Dec 2024 21:55:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990906; cv=none; b=eGWdHzrTldIydnL9R4YK3DVUnpQFvqYwol6/D1p5cTa9xy6k2VwLb+rYyu2aLkYe8PB1RWSPrP3YLm0yJmu+8yqHQaqPS72X68N7gxRbT1mhO1oJexATDbXLSq9XiV9risCWzs2i4hKyWzJSQuH6H5QZJigKCgEEwcmxoTWlgho= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990906; c=relaxed/simple; bh=5eeo+6EuWAOv8PfOHufJjvecuPAZ5gABUa4UQ4OOA78=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=L4QRcOGanBf7GEkvpHyQbVrDNNjKGimLnZrMhaTSMUZvBf3jFQL+5IkcSGHe2Z2xcyhWxqsLBu3UJCDj0peS8FCUdg5NXWgj/wvk6YrvyoHepP7HvCiZ1JRThXZppsgdju37PlEnaeMjOh9UoaTklrra2FEZWfaJql8TgeSBjs8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K67ceYCi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="K67ceYCi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E5F6DC4CED3; Mon, 23 Dec 2024 21:55:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990906; bh=5eeo+6EuWAOv8PfOHufJjvecuPAZ5gABUa4UQ4OOA78=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=K67ceYCiaDXzp9AP62h7I9QVsKbTXfiI/gvKW6NkQiVIRGU4fTnrNQHraCNfqjcKe 8rX95eF5lNALGxqAfjqIKOCh0J/ThlGmDLW2F4ECyPcJE93N4Q4TfcfNjxNCfYgBOy oapFXrvtn5FB32TwDpwCSbGpPfdhmpqSc1J0Zj0I73Ihqu2AajwpPHVHhPAe1horBj 8ZT2s/nOn1ccYUB+68pJBXhOqUXRW4PkBBuBRXr1H5XAHHtyh/CLizhsnDKD/4PGaT s8JUDa+Lz0wYsxT49IldiLsNCsLfSytTv94qsLFWdIZ2wi9rMTMCqQhhzf37HKgsOZ KGraqWBUfLLwQ== Date: Mon, 23 Dec 2024 13:55:05 -0800 Subject: [PATCH 33/41] xfs_repair: pass private data pointer to scan_lbtree From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941474.2294268.18233001467953743677.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Pass a private data pointer through scan_lbtree. We'll use this later when scanning the rtrmapbt to keep track of scan state. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/dinode.c | 2 +- repair/scan.c | 11 +++++++---- repair/scan.h | 7 +++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index 60a853d152ccec..4ca45ad4aab1fa 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -839,7 +839,7 @@ _("bad bmap btree ptr 0x%" PRIx64 " in ino %" PRIu64 "\n"), if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, type, whichfork, lino, tot, nex, blkmapp, - &cursor, 1, check_dups, magic, + &cursor, 1, check_dups, magic, NULL, &xfs_bmbt_buf_ops)) return(1); /* diff --git a/repair/scan.c b/repair/scan.c index b115dd4948b969..f6d46a2861b312 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -139,7 +139,8 @@ scan_lbtree( int isroot, int check_dups, int *dirty, - uint64_t magic), + uint64_t magic, + void *priv), int type, int whichfork, xfs_ino_t ino, @@ -150,6 +151,7 @@ scan_lbtree( int isroot, int check_dups, uint64_t magic, + void *priv, const struct xfs_buf_ops *ops) { struct xfs_buf *bp; @@ -181,7 +183,7 @@ scan_lbtree( err = (*func)(XFS_BUF_TO_BLOCK(bp), nlevels - 1, type, whichfork, root, ino, tot, nex, blkmapp, bm_cursor, isroot, check_dups, &dirty, - magic); + magic, priv); ASSERT(dirty == 0 || (dirty && !no_modify)); @@ -210,7 +212,8 @@ scan_bmapbt( int isroot, int check_dups, int *dirty, - uint64_t magic) + uint64_t magic, + void *priv) { int i; int err; @@ -486,7 +489,7 @@ _("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), err = scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, whichfork, ino, tot, nex, blkmapp, - bm_cursor, 0, check_dups, magic, + bm_cursor, 0, check_dups, magic, priv, &xfs_bmbt_buf_ops); if (err) return(1); diff --git a/repair/scan.h b/repair/scan.h index ee16362b6d3c69..4da788becbef66 100644 --- a/repair/scan.h +++ b/repair/scan.h @@ -26,7 +26,8 @@ int scan_lbtree( int isroot, int check_dups, int *dirty, - uint64_t magic), + uint64_t magic, + void *priv), int type, int whichfork, xfs_ino_t ino, @@ -37,6 +38,7 @@ int scan_lbtree( int isroot, int check_dups, uint64_t magic, + void *priv, const struct xfs_buf_ops *ops); int scan_bmapbt( @@ -53,7 +55,8 @@ int scan_bmapbt( int isroot, int check_dups, int *dirty, - uint64_t magic); + uint64_t magic, + void *priv); void scan_ags( From patchwork Mon Dec 23 21:55:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919302 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B9E6619259D for ; Mon, 23 Dec 2024 21:55:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990921; cv=none; b=DU+RocG/laTMBcJaYXqCczg8ZZJl729MdQe97b889+6+4RYreLSu5i6LwMf6ijLvF0pBLVVDXaEI04HspT5d/PACcKNdZKSnBE5xZCwDjvY+xqjkXqYpqxcLF4M66BuK4bRQ/0TB67K+v+cF0UKF+vt9BQhu/B1dQ1kNE1fcYko= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990921; c=relaxed/simple; bh=fIUmEQA4v/MOi9El7L4la8p/35aXPsLbTV4Zp1Km530=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Ko14KMkdB3CH6kaPb5syZ4fy8shIMMyf3z6b5NKuHdjflxNyRjHjVouYk6FthQ4oteg2k0WdIS3PziYjgNuRFf15IFvgAMHMWj5aYVU03FyHRysIm43J7WVid/ovLF1xFJ2t8zvZ5HN9Q7BEi4lq0w+/hmAvKdC5iMT9XmR4xAg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=S7XjYLOH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="S7XjYLOH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 935DBC4CED3; Mon, 23 Dec 2024 21:55:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990921; bh=fIUmEQA4v/MOi9El7L4la8p/35aXPsLbTV4Zp1Km530=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=S7XjYLOHNrI/zAERZ7kJwudveM8KHmm6XPdOg7heszbwa16TSi4w5bHWM0HrG9gRB kFmbsW0LA8RytsqJw3H59GtDF9lHc98dMGdGWmZt4fFaRfWZjrNfNEdyfvdHo3KYKF 4OqHBDGj7duUrl9wrLV5oI6MwOLMfqMKY94UREKf9LDSwdTWyLdLbmERX21bWUN2Do Ntxxept/ltVbPmQNye/1OV5qQEuEUPKKbhUDh8S5Smzd1+Qvy/VvRZWEvK7n8M4jmH bhdNpIbU4j7rlbaXbIBAUdwO1g+GyHQb/jR4C3nU+ukhju83nUPpYzUAvUSydUac8p lUtoeoqEZd4iA== Date: Mon, 23 Dec 2024 13:55:21 -0800 Subject: [PATCH 34/41] xfs_repair: mark space used by metadata files From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941489.2294268.3788483920934017496.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Track space used by metadata files as a separate incore extent type. This ensures that we can warn about cross-linked metadata files, even though we are going to rebuild the entire metadata directory tree in the end. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/dino_chunks.c | 31 +++++++++++++ repair/dinode.c | 122 ++++++++++++++++++++++++++++++++++++++------------ repair/dinode.h | 6 ++ repair/incore.h | 31 ++++++++----- repair/phase4.c | 2 + repair/scan.c | 30 +++++++++++- 6 files changed, 175 insertions(+), 47 deletions(-) diff --git a/repair/dino_chunks.c b/repair/dino_chunks.c index 0d9b3a01bc298d..0cbc498101ec72 100644 --- a/repair/dino_chunks.c +++ b/repair/dino_chunks.c @@ -141,6 +141,16 @@ verify_inode_chunk(xfs_mount_t *mp, _("uncertain inode block %d/%d already known\n"), agno, agbno); break; + case XR_E_METADATA: + /* + * Files in the metadata directory tree are always + * reconstructed, so it's ok to let go if this block + * is also a valid inode cluster. + */ + do_warn( + _("inode block %d/%d claimed by metadata file\n"), + agno, agbno); + fallthrough; case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: @@ -430,6 +440,7 @@ verify_inode_chunk(xfs_mount_t *mp, set_bmap_ext(agno, cur_agbno, blen, XR_E_MULT); pthread_mutex_unlock(&ag_locks[agno].lock); return 0; + case XR_E_METADATA: case XR_E_INO: do_error( _("uncertain inode block overlap, agbno = %d, ino = %" PRIu64 "\n"), @@ -474,6 +485,16 @@ verify_inode_chunk(xfs_mount_t *mp, _("uncertain inode block %" PRIu64 " already known\n"), XFS_AGB_TO_FSB(mp, agno, cur_agbno)); break; + case XR_E_METADATA: + /* + * Files in the metadata directory tree are always + * reconstructed, so it's ok to let go if this block + * is also a valid inode cluster. + */ + do_warn( + _("inode block %d/%d claimed by metadata file\n"), + agno, agbno); + fallthrough; case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: @@ -559,6 +580,16 @@ process_inode_agbno_state( switch (state) { case XR_E_INO: /* already marked */ break; + case XR_E_METADATA: + /* + * Files in the metadata directory tree are always + * reconstructed, so it's ok to let go if this block is also a + * valid inode cluster. + */ + do_warn( + _("inode block %d/%d claimed by metadata file\n"), + agno, agbno); + fallthrough; case XR_E_UNKNOWN: case XR_E_FREE: case XR_E_FREE1: diff --git a/repair/dinode.c b/repair/dinode.c index 4ca45ad4aab1fa..8148cdbc4f10ad 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -220,6 +220,7 @@ static int process_rt_rec_state( struct xfs_mount *mp, xfs_ino_t ino, + bool zap_metadata, struct xfs_bmbt_irec *irec) { xfs_fsblock_t b = irec->br_startblock; @@ -256,7 +257,13 @@ _("data fork in rt inode %" PRIu64 " found invalid rt extent %"PRIu64" state %d switch (state) { case XR_E_FREE: case XR_E_UNKNOWN: - set_rtbmap(ext, XR_E_INUSE); + set_rtbmap(ext, zap_metadata ? XR_E_METADATA : + XR_E_INUSE); + break; + case XR_E_METADATA: + do_error( +_("data fork in rt inode %" PRIu64 " found metadata file block %" PRIu64 " in rt bmap\n"), + ino, ext); break; case XR_E_BAD_STATE: do_error( @@ -293,7 +300,8 @@ process_rt_rec( struct xfs_bmbt_irec *irec, xfs_ino_t ino, xfs_rfsblock_t *tot, - int check_dups) + int check_dups, + bool zap_metadata) { xfs_fsblock_t lastb; int bad; @@ -333,7 +341,7 @@ _("inode %" PRIu64 " - bad rt extent overflows - start %" PRIu64 ", " if (check_dups) bad = process_rt_rec_dups(mp, ino, irec); else - bad = process_rt_rec_state(mp, ino, irec); + bad = process_rt_rec_state(mp, ino, zap_metadata, irec); if (bad) return bad; @@ -364,7 +372,8 @@ process_bmbt_reclist_int( xfs_fileoff_t *first_key, xfs_fileoff_t *last_key, int check_dups, - int whichfork) + int whichfork, + bool zap_metadata) { xfs_bmbt_irec_t irec; xfs_filblks_t cp = 0; /* prev count */ @@ -443,7 +452,8 @@ _("zero length extent (off = %" PRIu64 ", fsbno = %" PRIu64 ") in ino %" PRIu64 if (type == XR_INO_RTDATA && whichfork == XFS_DATA_FORK) { pthread_mutex_lock(&rt_lock.lock); - error2 = process_rt_rec(mp, &irec, ino, tot, check_dups); + error2 = process_rt_rec(mp, &irec, ino, tot, check_dups, + zap_metadata); pthread_mutex_unlock(&rt_lock.lock); if (error2) return error2; @@ -558,6 +568,11 @@ _("%s fork in ino %" PRIu64 " claims free block %" PRIu64 "\n"), case XR_E_INUSE_FS1: do_warn(_("rmap claims metadata use!\n")); fallthrough; + case XR_E_METADATA: + do_warn( +_("%s fork in inode %" PRIu64 " claims metadata file block %" PRIu64 "\n"), + forkname, ino, b); + break; case XR_E_FS_MAP: case XR_E_INO: case XR_E_INUSE_FS: @@ -614,15 +629,28 @@ _("illegal state %d in block map %" PRIu64 "\n"), for (; agbno < ebno; agbno += blen) { state = get_bmap_ext(agno, agbno, ebno, &blen); switch (state) { + case XR_E_METADATA: + /* + * The entire metadata directory tree is rebuilt + * every time, so we can let regular files take + * ownership of this block. + */ + if (zap_metadata) + break; + fallthrough; case XR_E_FREE: case XR_E_FREE1: case XR_E_INUSE1: case XR_E_UNKNOWN: - set_bmap_ext(agno, agbno, blen, XR_E_INUSE); + set_bmap_ext(agno, agbno, blen, zap_metadata ? + XR_E_METADATA : XR_E_INUSE); break; + case XR_E_INUSE: case XR_E_MULT: - set_bmap_ext(agno, agbno, blen, XR_E_MULT); + if (!zap_metadata) + set_bmap_ext(agno, agbno, blen, + XR_E_MULT); break; default: break; @@ -661,10 +689,12 @@ process_bmbt_reclist( blkmap_t **blkmapp, xfs_fileoff_t *first_key, xfs_fileoff_t *last_key, - int whichfork) + int whichfork, + bool zap_metadata) { return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot, - blkmapp, first_key, last_key, 0, whichfork); + blkmapp, first_key, last_key, 0, whichfork, + zap_metadata); } /* @@ -679,13 +709,15 @@ scan_bmbt_reclist( int type, xfs_ino_t ino, xfs_rfsblock_t *tot, - int whichfork) + int whichfork, + bool zap_metadata) { xfs_fileoff_t first_key = 0; xfs_fileoff_t last_key = 0; return process_bmbt_reclist_int(mp, rp, numrecs, type, ino, tot, - NULL, &first_key, &last_key, 1, whichfork); + NULL, &first_key, &last_key, 1, whichfork, + zap_metadata); } /* @@ -760,7 +792,8 @@ process_btinode( xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork, - int check_dups) + int check_dups, + bool zap_metadata) { xfs_bmdr_block_t *dib; xfs_fileoff_t last_key; @@ -839,8 +872,8 @@ _("bad bmap btree ptr 0x%" PRIx64 " in ino %" PRIu64 "\n"), if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, type, whichfork, lino, tot, nex, blkmapp, - &cursor, 1, check_dups, magic, NULL, - &xfs_bmbt_buf_ops)) + &cursor, 1, check_dups, magic, + (void *)zap_metadata, &xfs_bmbt_buf_ops)) return(1); /* * fix key (offset) mismatches between the keys in root @@ -935,7 +968,8 @@ process_exinode( xfs_extnum_t *nex, blkmap_t **blkmapp, int whichfork, - int check_dups) + int check_dups, + bool zap_metadata) { xfs_ino_t lino; xfs_bmbt_rec_t *rp; @@ -969,10 +1003,10 @@ process_exinode( if (check_dups == 0) ret = process_bmbt_reclist(mp, rp, &numrecs, type, lino, tot, blkmapp, &first_key, &last_key, - whichfork); + whichfork, zap_metadata); else ret = scan_bmbt_reclist(mp, rp, &numrecs, type, lino, tot, - whichfork); + whichfork, zap_metadata); *nex = numrecs; return ret; @@ -1901,7 +1935,8 @@ process_inode_data_fork( xfs_extnum_t *nextents, blkmap_t **dblkmap, int check_dups, - struct xfs_buf **ino_bpp) + struct xfs_buf **ino_bpp, + bool zap_metadata) { struct xfs_dinode *dino = *dinop; xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); @@ -1948,14 +1983,14 @@ process_inode_data_fork( try_rebuild = 1; err = process_exinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, XFS_DATA_FORK, - check_dups); + check_dups, zap_metadata); break; case XFS_DINODE_FMT_BTREE: if (!rmapbt_suspect && try_rebuild == -1) try_rebuild = 1; err = process_btinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, XFS_DATA_FORK, - check_dups); + check_dups, zap_metadata); break; case XFS_DINODE_FMT_DEV: err = 0; @@ -2008,12 +2043,12 @@ _("would have tried to rebuild inode %"PRIu64" data fork\n"), case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, - XFS_DATA_FORK, 0); + XFS_DATA_FORK, 0, zap_metadata); break; case XFS_DINODE_FMT_BTREE: err = process_btinode(mp, agno, ino, dino, type, dirty, totblocks, nextents, dblkmap, - XFS_DATA_FORK, 0); + XFS_DATA_FORK, 0, zap_metadata); break; case XFS_DINODE_FMT_DEV: err = 0; @@ -2048,7 +2083,8 @@ process_inode_attr_fork( int check_dups, int extra_attr_check, int *retval, - struct xfs_buf **ino_bpp) + struct xfs_buf **ino_bpp, + bool zap_metadata) { xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino); struct xfs_dinode *dino = *dinop; @@ -2096,7 +2132,7 @@ process_inode_attr_fork( *anextents = 0; err = process_exinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, &ablkmap, - XFS_ATTR_FORK, check_dups); + XFS_ATTR_FORK, check_dups, zap_metadata); break; case XFS_DINODE_FMT_BTREE: if (!rmapbt_suspect && try_rebuild == -1) @@ -2105,7 +2141,7 @@ process_inode_attr_fork( *anextents = 0; err = process_btinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, &ablkmap, - XFS_ATTR_FORK, check_dups); + XFS_ATTR_FORK, check_dups, zap_metadata); break; default: do_warn(_("illegal attribute format %d, ino %" PRIu64 "\n"), @@ -2169,12 +2205,12 @@ _("would have tried to rebuild inode %"PRIu64" attr fork or cleared it\n"), case XFS_DINODE_FMT_EXTENTS: err = process_exinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, - &ablkmap, XFS_ATTR_FORK, 0); + &ablkmap, XFS_ATTR_FORK, 0, zap_metadata); break; case XFS_DINODE_FMT_BTREE: err = process_btinode(mp, agno, ino, dino, type, dirty, atotblocks, anextents, - &ablkmap, XFS_ATTR_FORK, 0); + &ablkmap, XFS_ATTR_FORK, 0, zap_metadata); break; default: do_error(_("illegal attribute fmt %d, ino %" PRIu64 "\n"), @@ -2393,6 +2429,7 @@ process_dinode_int( xfs_agino_t unlinked_ino; struct xfs_perag *pag; bool is_meta = false; + bool zap_metadata = false; *dirty = *isa_dir = 0; *used = is_used; @@ -2982,6 +3019,33 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "), off = get_inode_offset(mp, lino, irec); set_inode_is_meta(irec, off); is_meta = true; + + /* + * We always rebuild the metadata directory tree during phase + * 6, so we use this flag to get all the directory blocks + * marked as free, and any other metadata files whose contents + * we don't want to save. + * + * Currently, there are no metadata files that use xattrs, so + * we always drop the xattr blocks of metadata files. Parent + * pointers will be rebuilt during phase 6. + */ + switch (type) { + case XR_INO_RTBITMAP: + case XR_INO_RTSUM: + case XR_INO_UQUOTA: + case XR_INO_GQUOTA: + case XR_INO_PQUOTA: + /* + * This inode was recognized as being filesystem + * metadata, so preserve the inode and its contents for + * later checking and repair. + */ + break; + default: + zap_metadata = true; + break; + } } /* @@ -2989,7 +3053,7 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "), */ if (process_inode_data_fork(mp, agno, ino, dinop, type, dirty, &totblocks, &nextents, &dblkmap, check_dups, - ino_bpp) != 0) + ino_bpp, zap_metadata) != 0) goto bad_out; dino = *dinop; @@ -2999,7 +3063,7 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "), */ if (process_inode_attr_fork(mp, agno, ino, dinop, type, dirty, &atotblocks, &anextents, check_dups, extra_attr_check, - &retval, ino_bpp)) + &retval, ino_bpp, is_meta)) goto bad_out; dino = *dinop; diff --git a/repair/dinode.h b/repair/dinode.h index 92df83da621053..ed2ec4ca2386ff 100644 --- a/repair/dinode.h +++ b/repair/dinode.h @@ -27,7 +27,8 @@ process_bmbt_reclist(xfs_mount_t *mp, struct blkmap **blkmapp, uint64_t *first_key, uint64_t *last_key, - int whichfork); + int whichfork, + bool zap_metadata); int scan_bmbt_reclist( @@ -37,7 +38,8 @@ scan_bmbt_reclist( int type, xfs_ino_t ino, xfs_rfsblock_t *tot, - int whichfork); + int whichfork, + bool zap_metadata); void update_rootino(xfs_mount_t *mp); diff --git a/repair/incore.h b/repair/incore.h index 568a8c7cb75b7c..07716fc4c01a05 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -85,18 +85,25 @@ typedef struct rt_extent_tree_node { #define XR_E_UNKNOWN 0 /* unknown state */ #define XR_E_FREE1 1 /* free block (marked by one fs space tree) */ #define XR_E_FREE 2 /* free block (marked by both fs space trees) */ -#define XR_E_INUSE 3 /* extent used by file/dir data or metadata */ -#define XR_E_INUSE_FS 4 /* extent used by fs ag header or log */ -#define XR_E_MULT 5 /* extent is multiply referenced */ -#define XR_E_INO 6 /* extent used by inodes (inode blocks) */ -#define XR_E_FS_MAP 7 /* extent used by fs space/inode maps */ -#define XR_E_INUSE1 8 /* used block (marked by rmap btree) */ -#define XR_E_INUSE_FS1 9 /* used by fs ag header or log (rmap btree) */ -#define XR_E_INO1 10 /* used by inodes (marked by rmap btree) */ -#define XR_E_FS_MAP1 11 /* used by fs space/inode maps (rmap btree) */ -#define XR_E_REFC 12 /* used by fs ag reference count btree */ -#define XR_E_COW 13 /* leftover cow extent */ -#define XR_E_BAD_STATE 14 +/* + * Space used by metadata files. The entire metadata directory tree will be + * rebuilt from scratch during phase 6, so this value must be less than + * XR_E_INUSE so that the space will go back to the free space btrees during + * phase 5. + */ +#define XR_E_METADATA 3 +#define XR_E_INUSE 4 /* extent used by file/dir data or metadata */ +#define XR_E_INUSE_FS 5 /* extent used by fs ag header or log */ +#define XR_E_MULT 6 /* extent is multiply referenced */ +#define XR_E_INO 7 /* extent used by inodes (inode blocks) */ +#define XR_E_FS_MAP 8 /* extent used by fs space/inode maps */ +#define XR_E_INUSE1 9 /* used block (marked by rmap btree) */ +#define XR_E_INUSE_FS1 10 /* used by fs ag header or log (rmap btree) */ +#define XR_E_INO1 11 /* used by inodes (marked by rmap btree) */ +#define XR_E_FS_MAP1 12 /* used by fs space/inode maps (rmap btree) */ +#define XR_E_REFC 13 /* used by fs ag reference count btree */ +#define XR_E_COW 14 /* leftover cow extent */ +#define XR_E_BAD_STATE 15 /* separate state bit, OR'ed into high (4th) bit of ex_state field */ diff --git a/repair/phase4.c b/repair/phase4.c index 7efef86245fbe7..40db36f1f93020 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -303,6 +303,7 @@ phase4(xfs_mount_t *mp) _("unknown block state, ag %d, blocks %u-%u\n"), i, j, j + blen - 1); fallthrough; + case XR_E_METADATA: case XR_E_UNKNOWN: case XR_E_FREE: case XR_E_INUSE: @@ -335,6 +336,7 @@ phase4(xfs_mount_t *mp) _("unknown rt extent state, extent %" PRIu64 "\n"), rtx); fallthrough; + case XR_E_METADATA: case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: diff --git a/repair/scan.c b/repair/scan.c index f6d46a2861b312..0fec7c222ff156 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -227,6 +227,7 @@ scan_bmapbt( xfs_agnumber_t agno; xfs_agblock_t agbno; int state; + bool zap_metadata = priv != NULL; /* * unlike the ag freeblock btrees, if anything looks wrong @@ -352,7 +353,20 @@ _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n" case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: - set_bmap(agno, agbno, XR_E_INUSE); + set_bmap(agno, agbno, zap_metadata ? XR_E_METADATA : + XR_E_INUSE); + break; + case XR_E_METADATA: + /* + * bmbt block already claimed by a metadata file. We + * always reconstruct the entire metadata tree, so if + * this is a regular file we mark it owned by the file. + */ + do_warn( +_("inode 0x%" PRIx64 "bmap block 0x%" PRIx64 " claimed by metadata file\n"), + ino, bno); + if (!zap_metadata) + set_bmap(agno, agbno, XR_E_INUSE); break; case XR_E_FS_MAP: case XR_E_INUSE: @@ -364,7 +378,8 @@ _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n" * we made it here, the block probably * contains btree data. */ - set_bmap(agno, agbno, XR_E_MULT); + if (!zap_metadata) + set_bmap(agno, agbno, XR_E_MULT); do_warn( _("inode 0x%" PRIx64 "bmap block 0x%" PRIx64 " claimed, state is %d\n"), ino, bno, state); @@ -429,7 +444,8 @@ _("inode %" PRIu64 " bad # of bmap records (%" PRIu64 ", min - %u, max - %u)\n") if (check_dups == 0) { err = process_bmbt_reclist(mp, rp, &numrecs, type, ino, tot, blkmapp, &first_key, - &last_key, whichfork); + &last_key, whichfork, + zap_metadata); if (err) return 1; @@ -459,7 +475,7 @@ _("out-of-order bmap key (file offset) in inode %" PRIu64 ", %s fork, fsbno %" P return 0; } else { return scan_bmbt_reclist(mp, rp, &numrecs, type, ino, - tot, whichfork); + tot, whichfork, zap_metadata); } } if (numrecs > mp->m_bmap_dmxr[1] || (isroot == 0 && numrecs < @@ -849,6 +865,12 @@ process_rmap_rec( break; } break; + case XR_E_METADATA: + do_warn( +_("Metadata file block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), + agno, b, b + blen - 1, + name, state, owner); + break; case XR_E_INUSE_FS: if (owner == XFS_RMAP_OWN_FS || owner == XFS_RMAP_OWN_LOG) From patchwork Mon Dec 23 21:55:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919303 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B0C5419048A for ; Mon, 23 Dec 2024 21:55:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990937; cv=none; b=ntdx9W9Q3UP3if+//cyaBP6CJ/dfmag6Ru74ywIwZTMwnPYW/AvimYuC29s/fjcsewNhVuEXMtKF2R++zRgDy9fsE5QTxTmyRL90FUjkDKvte/LqtlQI9QI0WgECjz3GpmoKvGNAaXUssLIfD/njWrX7MfrovawJoIqmsngDdLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990937; c=relaxed/simple; bh=wmRtCNxTuLtr2HPBl4IC/DlDiKiiT1XkGwz5l7l4Qhk=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eFJJuUJ9vUuacJVUcXGIVRGZW3SX/+TcYd03n5vhJzpZ5AT1qhM42Q33bg3x4MKbvFlh01luqhwme74UWuYOuHPpOs/Lwm8oVTgf6aPc50wRKEm1PPHHmYoAtHFdS917tNh5juAgAH2DdwzxNLuAApuuxf6Gaf5O06slp1VgbYQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qCgCAZ3O; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qCgCAZ3O" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34D27C4CED3; Mon, 23 Dec 2024 21:55:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990937; bh=wmRtCNxTuLtr2HPBl4IC/DlDiKiiT1XkGwz5l7l4Qhk=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=qCgCAZ3ODujG0H15hSHJKE8AtmFAmCU/11gvMoKH/96RHMNS6s/bbyiYsg+HhmkOd vlUDpbER67hgBpLh4XLkpE9cz4QxbZQHgMePGwiaMtUmUdgiz8JCs3xs8K+0vqn7Kt sgZNkmCf1chnZ/88uv9zMyPpAgkZjM2Lfw2zyUti41GkDjaYQ7cjPyUvIscun435Sw FdUenTLQpT1kwwArKApk0pxaQB1NLC2NU0CZfe3qsZrAyb9Vn1pyNK3dHPQ8FeuD+P /0uZJgdZ6JCMVaoa0y7oa/qQIxLzd6INlheJ/QjyNMj+a9cv2mibbdNZ8nMTJ4G34z is3AMfh8L5vLg== Date: Mon, 23 Dec 2024 13:55:36 -0800 Subject: [PATCH 35/41] xfs_repair: adjust keep_fsinos to handle metadata directories From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941504.2294268.4810880574555896160.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong In keep_fsinos, mark the root of the metadata directory tree as inuse. The realtime bitmap and summary files still come after the root directories, so this is a fairly simple change to the loop test. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase5.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/repair/phase5.c b/repair/phase5.c index 86b1f681a72bb8..a5e19998b97061 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -419,13 +419,18 @@ static void keep_fsinos(xfs_mount_t *mp) { ino_tree_node_t *irec; - int i; + unsigned int inuse = xfs_rootrec_inodes_inuse(mp), i; irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); - for (i = 0; i < 3; i++) + for (i = 0; i < inuse; i++) { set_inode_used(irec, i); + + /* Everything after the root dir is metadata */ + if (i) + set_inode_is_meta(irec, i); + } } static void From patchwork Mon Dec 23 21:55:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919304 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 03C2F1422AB for ; Mon, 23 Dec 2024 21:55:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990953; cv=none; b=GFi0NWcsVSOhd8F9OIsFw+0by6B24eYNxbPKIsYpimk2IMTlN/4wymR3WFG1f0zxyubIkFOMEcw21vwVGWNyvazOzvdFk3JEp2DqfbNZCHJ2nIpnLawVQG7h2OpYdI1AX7hCPrL5RIbM0KW2HaGXijMJrdx5NaMMrI1ZSvU/iZg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990953; c=relaxed/simple; bh=ccLIe5fRGu6J+3J+uLeO+yiC5qI/xj3fSQufACj8K0c=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IbIvolU2yRt5PANYo5UYJUeyATV41uTnbBVQz/VU+4v8P+BEgQJO/V2lv3wDpVdoiq38X8QJVK+oH89z2ioUTc2jxj4EFN+2w/GmPUdGkiB8sZpIdOtHIr0etbQAvBEGlhvPomGM9DwfCX8YHrHI5B925/MlTvAJoB1okKXyWEc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=k27kFii7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="k27kFii7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CD945C4CED3; Mon, 23 Dec 2024 21:55:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990952; bh=ccLIe5fRGu6J+3J+uLeO+yiC5qI/xj3fSQufACj8K0c=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=k27kFii7+56lLU55J5T3l4nvBhflAq9A3RfS7cK9b+FZjnhsQ1WvQQVMS2m+aNBcG 3n/PTp5J6uhQFBYL6pLZvAu1zuwLoosN7VuHFRARfXCrq6UJ2EI6TJCYoysHQmwAZt UtTzYRtZyTZyoyoUWinIYFHqrzamjDJvU19PjfWWZCFdteA+ZXQhuaAbeZ+MkjhMfK 5gefCpMp081TnMNhytkukA9dnljFrjOdx87OirrFEj2qOyoY0CydJz0UPX7NQN5zYE 8uTkLwOY5AC1r/uX/qGwE9R0wwq+z70EHYXkR9ussLfHG8bEdTq+dIucMbvPsDe3+P piHXLIPSZ8f1w== Date: Mon, 23 Dec 2024 13:55:52 -0800 Subject: [PATCH 36/41] xfs_repair: metadata dirs are never plausible root dirs From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941520.2294268.381012865092926549.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Metadata directories are never candidates to be the root of the user-accessible directory tree. Update has_plausible_rootdir to ignore them all, as well as detecting the case where the superblock incorrectly thinks both trees have the same root. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/xfs_repair.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 70cab1ad852a21..30b014898c3203 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -546,9 +546,15 @@ has_plausible_rootdir( int error; bool ret = false; + if (xfs_has_metadir(mp) && + mp->m_sb.sb_rootino == mp->m_sb.sb_metadirino) + goto out; + error = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &ip); if (error) goto out; + if (xfs_is_metadir_inode(ip)) + goto out_rele; if (!S_ISDIR(VFS_I(ip)->i_mode)) goto out_rele; From patchwork Mon Dec 23 21:56:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919305 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 9D6421422AB for ; Mon, 23 Dec 2024 21:56:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990968; cv=none; b=tvax5Nl+Drmu20+jEXKECZRO1z3QOK8v9bPSOuh81wRbkKaIZqZO4M9hQj8hqg+jAw8yLwgdNdGKWlIJ7G6pWYMBc58ass8bOYfys9HPDpM/8TeB7Y4NqUWNlwJjAWjtNq0SvsDJ7JWRTobnLBwAGA5c3Qt9joL2o3MF1zdW9yg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990968; c=relaxed/simple; bh=tt5/BQJPtCEDRDcdBCtrjDfKHB55GPnka1Fc6Tgydm0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gQLiBMv6JEgCnYL5etkjQqhbwEs+LJpjXQDOSD6ajnCSvBnLpu1gsYMQqgcb2ql58fFBWX0zPdLZwe1p0N8dh4MWlOObXid63Jd5OZDut6N9Gr9cKoMLg2VR4fQwiAYfLqXhyw6Mm4rPAxlPNoAYXgjnkNtMmTFzX3S0NZ+juQs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=osLY4jg6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="osLY4jg6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E753C4CED3; Mon, 23 Dec 2024 21:56:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990968; bh=tt5/BQJPtCEDRDcdBCtrjDfKHB55GPnka1Fc6Tgydm0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=osLY4jg62wAVyZ8x9shsXs3tpgvupE0g83iTEtrmdTvX86DKpa79oA/Mt5pPKFshD GW7hPKWomwu3TnnrsiGouSjzNkZJioTlA4wlWA/UKNasX2L0mLXbzE0IdXzOKaB8im DdOpasbB2SRWLq0QrUZACc6blOdDvvsHw5jgOz+bXjAfBeEu8UK1+BUm3kG+pEiVRi B8Wesg1rvaWvNCmlQFfFHqs0yzPfQ05IJRfmQzLKii1UTmJ10MOhUun/RvSbUsE05D eA8eKdODmXbi06ayv1ZiDxoYziCo3yhWBnr+gKGgtGYNkQItWuV/qsrxa8Fcnoyp4h NlVGClLw8vXmw== Date: Mon, 23 Dec 2024 13:56:08 -0800 Subject: [PATCH 37/41] xfs_repair: drop all the metadata directory files during pass 4 From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941535.2294268.3801251769353928342.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Drop the entire metadata directory tree during pass 4 so that we can reinitialize the entire tree in phase 6. The existing metadata files (rtbitmap, rtsummary, quotas) will be reattached to the newly rebuilt directory tree. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/dinode.c | 14 +++++++++++++- repair/scan.c | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index 8148cdbc4f10ad..2185214ac41bdf 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -656,7 +656,7 @@ _("illegal state %d in block map %" PRIu64 "\n"), break; } } - if (collect_rmaps) /* && !check_dups */ + if (collect_rmaps && !zap_metadata) /* && !check_dups */ rmap_add_rec(mp, ino, whichfork, &irec); *tot += irec.br_blockcount; } @@ -3123,6 +3123,18 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "), */ *dirty += process_check_inode_nlink_version(dino, lino); + /* + * The entire metadata directory tree will be rebuilt during phase 6. + * Therefore, if we're at the end of phase 4 and this is a metadata + * file, zero the ondisk inode and the incore state. + */ + if (check_dups && zap_metadata && !no_modify) { + clear_dinode(mp, dino, lino); + *dirty += 1; + *used = is_free; + *isa_dir = 0; + } + return retval; clear_bad_out: diff --git a/repair/scan.c b/repair/scan.c index 0fec7c222ff156..ed73de4b2477bf 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -418,7 +418,7 @@ _("bad state %d, inode %" PRIu64 " bmap block 0x%" PRIx64 "\n"), numrecs = be16_to_cpu(block->bb_numrecs); /* Record BMBT blocks in the reverse-mapping data. */ - if (check_dups && collect_rmaps) { + if (check_dups && collect_rmaps && !zap_metadata) { agno = XFS_FSB_TO_AGNO(mp, bno); pthread_mutex_lock(&ag_locks[agno].lock); rmap_add_bmbt_rec(mp, ino, whichfork, bno); From patchwork Mon Dec 23 21:56:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919306 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 49F7F1B395B for ; Mon, 23 Dec 2024 21:56:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990984; cv=none; b=YSn/YDF33G+4kZSFEakwjmQl3ZMAmfVZ5B1JZ3LLQcb94bGAp1SSlD6MlfZA7QtboZG24yx96B60BAHi7b58OQKzorIbd2AK8a2Cx60nZfEoHt2Dd8DYzwa4nTLAqJ9z/gRQQyBUxzHIm3VVwXNo3crfdiSGQvjiM6JkFO5TrDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734990984; c=relaxed/simple; bh=92UckHqm+r3FqG5u99FtFM3L6D0VmzLJZt/xcmLkSzA=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=haLVi+na8EvLgEFQ3pk5XBb5ZhAxJQO34fvsnj1O4jf0bm32ZULVzctQrktxlfuqA+2rdiZ+kdrKMbYyDZ/HAei7lfgdH27ZOBgc5ng5rEWmMUubh/lzuK9+7XBWjXnq3CbNize8YFeU2lAqHVCu0LSv2vQGhZm89TnmILM6jpE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eSsdHjWi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eSsdHjWi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 22B14C4CED3; Mon, 23 Dec 2024 21:56:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734990984; bh=92UckHqm+r3FqG5u99FtFM3L6D0VmzLJZt/xcmLkSzA=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=eSsdHjWic0nLVTFHamR6a/HN/5nxNTfMnKi2GRLU5OPI6ITD/ePZatqOVLyugg40o 2xU06B1ZobBLgiIUXinHtGjvQ4DzTefbDirKb+DSd1BzXi639zmuLzJ+IsnywpAgHt 6UhvbkOOySSBUaQGus70g7aM9uuMhjZLRUhV0/9bFgRcnk3mV1TUJaNMCFmrm3BnVm RNsLrXNvVKtnK+qcpBB6d/Mec4Hxgvo++SoyPKQ+GpzAxK9XOZ9OpUVwrb5seWp4AR u0eXBsNapJ0E/WyP//sjnbfepdmqdABLYkbz4RelOjDQGn9menqJTm8DsGu9Nqnrml lrCMA0IAFnchw== Date: Mon, 23 Dec 2024 13:56:23 -0800 Subject: [PATCH 38/41] xfs_repair: truncate and unmark orphaned metadata inodes From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941551.2294268.13361852125408207098.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong If an inode claims to be a metadata inode but wasn't linked in either directory tree, remove the attr fork and reset the data fork if the contents weren't regular extent mappings before moving the inode to the lost+found. We don't ifree the inode, because it's possible that the inode was not actually a metadata inode but simply got corrupted due to bitflips or something, and we'd rather let the sysadmin examine what's left of the file instead of photorec'ing it. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/phase6.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/repair/phase6.c b/repair/phase6.c index 8fa2c3c8bf0419..3dd67f7e0ec051 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -853,6 +853,53 @@ mk_orphanage( return(ino); } +/* Don't let metadata inode contents leak to lost+found. */ +static void +trunc_metadata_inode( + struct xfs_inode *ip) +{ + struct xfs_trans *tp; + struct xfs_mount *mp = ip->i_mount; + int err; + + err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); + if (err) + do_error( + _("space reservation failed (%d), filesystem may be out of space\n"), + err); + + libxfs_trans_ijoin(tp, ip, 0); + ip->i_diflags2 &= ~XFS_DIFLAG2_METADATA; + + switch (VFS_I(ip)->i_mode & S_IFMT) { + case S_IFIFO: + case S_IFCHR: + case S_IFBLK: + case S_IFSOCK: + ip->i_df.if_format = XFS_DINODE_FMT_DEV; + break; + case S_IFREG: + switch (ip->i_df.if_format) { + case XFS_DINODE_FMT_EXTENTS: + case XFS_DINODE_FMT_BTREE: + break; + default: + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; + ip->i_df.if_nextents = 0; + break; + } + break; + } + + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + + err = -libxfs_trans_commit(tp); + if (err) + do_error( + _("truncation of metadata inode 0x%llx failed, err=%d\n"), + (unsigned long long)ip->i_ino, err); +} + /* * Add a parent pointer back to the orphanage for any file we're moving into * the orphanage, being careful not to trip over any existing parent pointer. @@ -943,6 +990,9 @@ mv_orphanage( if (err) do_error(_("%d - couldn't iget disconnected inode\n"), err); + if (xfs_is_metadir_inode(ino_p)) + trunc_metadata_inode(ino_p); + xname.type = libxfs_mode_to_ftype(VFS_I(ino_p)->i_mode); if (isa_dir) { From patchwork Mon Dec 23 21:56:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919307 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8F4DD18BBAC for ; Mon, 23 Dec 2024 21:56:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734991000; cv=none; b=JBXd/O7tgaLGNjqKJam+T+xr3hPYR23giIlvrXnwAVI6/lKI3yaTXtyFM63bif+5oC3QB2EjeXefMoiitscRGX6eIpR/K1YAjCr0lubIciTZLAEoL80WttIK/mXZQiUDzxcB9qIZBe6c46JX0kc8RXGQUiolrlhVSIZHcFaDH58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734991000; c=relaxed/simple; bh=Jy9I/ao4X/OfY0hJjjYxxU206rw9sl82DqSf45tabXw=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kblby7fetN1OfUOaS1ltUSmFGXPqJUgp+bKXO2X9GPZr0xrcWu2u8+c1zl7oBVsKrDoGCpe7u6Wkpwb4j+7/ycmKQQlNmOFT9GBLttmwp8m0hfbxUMS+U8LISvZ8R1Ll8Agh9eb5NbFnwKxAwvnQJyw9Gvbrmy0+MuGjFCKMpHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P2VIppOs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="P2VIppOs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F2D70C4CED3; Mon, 23 Dec 2024 21:56:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734991000; bh=Jy9I/ao4X/OfY0hJjjYxxU206rw9sl82DqSf45tabXw=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=P2VIppOsJ5iY3j5tqsPOq2sCfj9CsdHF6M1fbN+R2W7e3GJIseYxeug9IGaeYoZLm NjC9/v4dFS/jnMHEDgqLSWsRYH/5XTtPgrCdxpFA65qe5RWwyMieBvSHczvZr1wwft RatvzGa/3Ex2Tg4BgSuVOP39SyBEP5SKtpDs8iIl4QnIm+kUjvypXbhT6jm6pzPMR8 yRbx8IG0qERtQscGjvf4Ai6C6Tc1ISkmOP+GIzdVqG13xQiTDgO9Fr37NssHm4inZG hr/w/oVeIBFn/SGjVqrQc/kG17oRG/pdtEU/fvwE7KnBvV6ojWXpELY2CfR22EhSnU Nd1qAxQJkOglg== Date: Mon, 23 Dec 2024 13:56:39 -0800 Subject: [PATCH 39/41] xfs_repair: do not count metadata directory files when doing quotacheck From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941566.2294268.6459977657374405160.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Previously, we stated that files in the metadata directory tree are not counted in the dquot information. Fix the offline quotacheck code in xfs_repair and xfs_check to reflect this. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/quotacheck.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/repair/quotacheck.c b/repair/quotacheck.c index d9e08059927f80..11e2d64eb34791 100644 --- a/repair/quotacheck.c +++ b/repair/quotacheck.c @@ -217,6 +217,10 @@ quotacheck_adjust( return; } + /* Metadata directory files aren't counted in quota. */ + if (xfs_is_metadir_inode(ip)) + goto out_rele; + /* Count the file's blocks. */ if (XFS_IS_REALTIME_INODE(ip)) rtblks = qc_count_rtblocks(ip); @@ -229,6 +233,7 @@ quotacheck_adjust( if (proj_dquots) qc_adjust(proj_dquots, ip->i_projid, blocks, rtblks); +out_rele: libxfs_irele(ip); } From patchwork Mon Dec 23 21:56:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919308 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 BF7BB1422AB for ; Mon, 23 Dec 2024 21:56:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734991015; cv=none; b=XuQlhtJHiDoencKosH6uJWXNtvutAB8pQhim8QMFJ2YKVWjdw8JnD/pxhs8K5I5BVkxSo3eeg1IGsLtXKUEnd30Mj6b2+4gM1ByluZNxumUY4ivBsxEmz+UbvfFyP/E2mSD7OYg33WvLzERrrFA22SMeRc1WXPpKpPiNxckjbTQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734991015; c=relaxed/simple; bh=oDv/LMlfq1OwKKxbi0xHhiAI8bRkuM2m4+EjLXNhm/c=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XD/TB8QpeNxkSDCO29jO0/1HI3j7DqP62RcgwVe1/egsGQxrqrRnWk/W1Yc2XUONGacD6x93j7TjnM47Q/ybfsIit3J9NjE6JaaE03z5nFr9sIMpuinOJ48DjFE3a8AYtj9QMOBYNGa9OEHkpoaimj7FohDT6oF+FqilHLu2Kl4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ga6biTF0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ga6biTF0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9C269C4CED3; Mon, 23 Dec 2024 21:56:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734991015; bh=oDv/LMlfq1OwKKxbi0xHhiAI8bRkuM2m4+EjLXNhm/c=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Ga6biTF0gdaPmEKgHTY+8oNVkKV561roEcSgrrTFxmxcoS2eU5CVT7vQ/hlN9l6fL gqIykZ73rDYr8afAysHznudAOy7fFt5gMN4VaBzSjY1Cb7GzS4uw5Q/0y3/ArX613a EBfHywDiag1dLamdrme9CDWfEu/7dr2gf64D6IJbonzDNmXrvaDDEvbQotJSaR8mu4 TSEiIjJssbQP9C7/mEGRYOVvZiORbqDp3HolR0Bdr/B+w7GJkx+BqvxnLGq6+PTZda e5WwhNwviD2OF0R/whksJjEOYBQucsfdcEoDK5IV5sghpM63033VRgWDh30yIEZXTH FYHx9K2jvAC1w== Date: Mon, 23 Dec 2024 13:56:55 -0800 Subject: [PATCH 40/41] xfs_repair: refactor generate_rtinfo From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941582.2294268.16026971866728598437.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christoph Hellwig Move the allocation of the computed values into generate_rtinfo, and thus make the variables holding them private in rt.c, and clean up a few formatting nits. Signed-off-by: Christoph Hellwig Reviewed-by: "Darrick J. Wong" [djwong: move functions to fix build errors] Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- repair/globals.c | 5 -- repair/globals.h | 5 -- repair/phase5.c | 3 - repair/phase6.c | 51 +---------------- repair/rt.c | 160 ++++++++++++++++++++++++++++++++---------------------- repair/rt.h | 12 +--- 6 files changed, 104 insertions(+), 132 deletions(-) diff --git a/repair/globals.c b/repair/globals.c index b63931be9fdb70..bd07a9656d193b 100644 --- a/repair/globals.c +++ b/repair/globals.c @@ -87,11 +87,6 @@ unsigned int glob_agcount; int chunks_pblock; /* # of 64-ino chunks per allocation */ int max_symlink_blocks; -/* realtime info */ - -union xfs_rtword_raw *btmcompute; -union xfs_suminfo_raw *sumcompute; - /* inode tree records have full or partial backptr fields ? */ int full_ino_ex_data; /* diff --git a/repair/globals.h b/repair/globals.h index 1dc85ce7f8114c..ebe8d5ee132b8d 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -128,11 +128,6 @@ extern unsigned int glob_agcount; extern int chunks_pblock; /* # of 64-ino chunks per allocation */ extern int max_symlink_blocks; -/* realtime info */ - -extern union xfs_rtword_raw *btmcompute; -extern union xfs_suminfo_raw *sumcompute; - /* inode tree records have full or partial backptr fields ? */ extern int full_ino_ex_data;/* diff --git a/repair/phase5.c b/repair/phase5.c index a5e19998b97061..91c4a8662a69f2 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -627,8 +627,7 @@ void check_rtmetadata( struct xfs_mount *mp) { - rtinit(mp); - generate_rtinfo(mp, btmcompute, sumcompute); + generate_rtinfo(mp); check_rtbitmap(mp); check_rtsummary(mp); } diff --git a/repair/phase6.c b/repair/phase6.c index 3dd67f7e0ec051..44677096873a54 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -19,6 +19,7 @@ #include "progress.h" #include "versions.h" #include "repair/pptr.h" +#include "repair/rt.h" static xfs_ino_t orphanage_ino; @@ -556,52 +557,6 @@ mk_rbmino( libxfs_irele(ip); } -static void -fill_rbmino( - struct xfs_mount *mp) -{ - struct xfs_inode *ip; - int error; - - error = -libxfs_metafile_iget(mp, mp->m_sb.sb_rbmino, - XFS_METAFILE_RTBITMAP, &ip); - if (error) - do_error( -_("couldn't iget realtime bitmap inode, error %d\n"), error); - - error = -libxfs_rtfile_initialize_blocks(ip, 0, mp->m_sb.sb_rbmblocks, - btmcompute); - if (error) - do_error( -_("couldn't re-initialize realtime bitmap inode, error %d\n"), error); - - libxfs_irele(ip); -} - -static void -fill_rsumino( - struct xfs_mount *mp) -{ - struct xfs_inode *ip; - int error; - - error = -libxfs_metafile_iget(mp, mp->m_sb.sb_rsumino, - XFS_METAFILE_RTSUMMARY, &ip); - if (error) - do_error( -_("couldn't iget realtime summary inode, error %d\n"), error); - - mp->m_rsumip = ip; - error = -libxfs_rtfile_initialize_blocks(ip, 0, mp->m_rsumblocks, - sumcompute); - mp->m_rsumip = NULL; - if (error) - do_error( -_("couldn't re-initialize realtime summary inode, error %d\n"), error); - - libxfs_irele(ip); -} - static void mk_rsumino( struct xfs_mount *mp) @@ -3335,8 +3290,8 @@ phase6(xfs_mount_t *mp) if (!no_modify) { do_log( _(" - resetting contents of realtime bitmap and summary inodes\n")); - fill_rbmino(mp); - fill_rsumino(mp); + fill_rtbitmap(mp); + fill_rtsummary(mp); } mark_standalone_inodes(mp); diff --git a/repair/rt.c b/repair/rt.c index 9ae421168e84b4..d0a171020c4b49 100644 --- a/repair/rt.c +++ b/repair/rt.c @@ -14,31 +14,9 @@ #include "err_protos.h" #include "rt.h" -void -rtinit(xfs_mount_t *mp) -{ - unsigned long long wordcnt; - - if (mp->m_sb.sb_rblocks == 0) - return; - - /* - * Allocate buffers for formatting the collected rt free space - * information. The rtbitmap buffer must be large enough to compare - * against any unused bytes in the last block of the file. - */ - wordcnt = XFS_FSB_TO_B(mp, mp->m_sb.sb_rbmblocks) >> XFS_WORDLOG; - btmcompute = calloc(wordcnt, sizeof(union xfs_rtword_raw)); - if (!btmcompute) - do_error( - _("couldn't allocate memory for incore realtime bitmap.\n")); - - wordcnt = XFS_FSB_TO_B(mp, mp->m_rsumblocks) >> XFS_WORDLOG; - sumcompute = calloc(wordcnt, sizeof(union xfs_suminfo_raw)); - if (!sumcompute) - do_error( - _("couldn't allocate memory for incore realtime summary info.\n")); -} +/* Computed rt bitmap/summary data */ +static union xfs_rtword_raw *btmcompute; +static union xfs_suminfo_raw *sumcompute; static inline void set_rtword( @@ -64,58 +42,66 @@ inc_sumcount( * generate the real-time bitmap and summary info based on the * incore realtime extent map. */ -int +void generate_rtinfo( - struct xfs_mount *mp, - union xfs_rtword_raw *words, - union xfs_suminfo_raw *sumcompute) + struct xfs_mount *mp) { - xfs_rtxnum_t extno; - xfs_rtxnum_t start_ext; - int bitsperblock; - int bmbno; - xfs_rtword_t freebit; - xfs_rtword_t bits; - int start_bmbno; - int i; - int offs; - int log; - int len; - int in_extent; + unsigned int bitsperblock = + mp->m_blockwsize << XFS_NBWORDLOG; + xfs_rtxnum_t extno = 0; + xfs_rtxnum_t start_ext = 0; + int bmbno = 0; + int start_bmbno = 0; + bool in_extent = false; + unsigned long long wordcnt; + union xfs_rtword_raw *words; + + wordcnt = XFS_FSB_TO_B(mp, mp->m_sb.sb_rbmblocks) >> XFS_WORDLOG; + btmcompute = calloc(wordcnt, sizeof(union xfs_rtword_raw)); + if (!btmcompute) + do_error( +_("couldn't allocate memory for incore realtime bitmap.\n")); + words = btmcompute; + + wordcnt = XFS_FSB_TO_B(mp, mp->m_rsumblocks) >> XFS_WORDLOG; + sumcompute = calloc(wordcnt, sizeof(union xfs_suminfo_raw)); + if (!sumcompute) + do_error( +_("couldn't allocate memory for incore realtime summary info.\n")); ASSERT(mp->m_rbmip == NULL); - bitsperblock = mp->m_blockwsize << XFS_NBWORDLOG; - extno = start_ext = 0; - bmbno = in_extent = start_bmbno = 0; - /* - * slower but simple, don't play around with trying to set - * things one word at a time, just set bit as required. - * Have to * track start and end (size) of each range of - * free extents to set the summary info properly. + * Slower but simple, don't play around with trying to set things one + * word at a time, just set bit as required. Have to track start and + * end (size) of each range of free extents to set the summary info + * properly. */ while (extno < mp->m_sb.sb_rextents) { - freebit = 1; + xfs_rtword_t freebit = 1; + xfs_rtword_t bits = 0; + int i; + set_rtword(mp, words, 0); - bits = 0; for (i = 0; i < sizeof(xfs_rtword_t) * NBBY && extno < mp->m_sb.sb_rextents; i++, extno++) { if (get_rtbmap(extno) == XR_E_FREE) { sb_frextents++; bits |= freebit; - if (in_extent == 0) { + if (!in_extent) { start_ext = extno; start_bmbno = bmbno; - in_extent = 1; + in_extent = true; } - } else if (in_extent == 1) { - len = (int) (extno - start_ext); - log = libxfs_highbit64(len); - offs = xfs_rtsumoffs(mp, log, start_bmbno); + } else if (in_extent) { + uint64_t len = extno - start_ext; + xfs_rtsumoff_t offs; + + offs = xfs_rtsumoffs(mp, libxfs_highbit64(len), + start_bmbno); inc_sumcount(mp, sumcompute, offs); - in_extent = 0; + in_extent = false; } freebit <<= 1; @@ -126,10 +112,12 @@ generate_rtinfo( if (extno % bitsperblock == 0) bmbno++; } - if (in_extent == 1) { - len = (int) (extno - start_ext); - log = libxfs_highbit64(len); - offs = xfs_rtsumoffs(mp, log, start_bmbno); + + if (in_extent) { + uint64_t len = extno - start_ext; + xfs_rtsumoff_t offs; + + offs = xfs_rtsumoffs(mp, libxfs_highbit64(len), start_bmbno); inc_sumcount(mp, sumcompute, offs); } @@ -137,8 +125,6 @@ generate_rtinfo( do_warn(_("sb_frextents %" PRIu64 ", counted %" PRIu64 "\n"), mp->m_sb.sb_frextents, sb_frextents); } - - return(0); } static void @@ -245,3 +231,49 @@ check_rtsummary( check_rtfile_contents(mp, XFS_METAFILE_RTSUMMARY, mp->m_rsumblocks); } + +void +fill_rtbitmap( + struct xfs_mount *mp) +{ + struct xfs_inode *ip; + int error; + + error = -libxfs_metafile_iget(mp, mp->m_sb.sb_rbmino, + XFS_METAFILE_RTBITMAP, &ip); + if (error) + do_error( +_("couldn't iget realtime bitmap inode, error %d\n"), error); + + error = -libxfs_rtfile_initialize_blocks(ip, 0, mp->m_sb.sb_rbmblocks, + btmcompute); + if (error) + do_error( +_("couldn't re-initialize realtime bitmap inode, error %d\n"), error); + + libxfs_irele(ip); +} + +void +fill_rtsummary( + struct xfs_mount *mp) +{ + struct xfs_inode *ip; + int error; + + error = -libxfs_metafile_iget(mp, mp->m_sb.sb_rsumino, + XFS_METAFILE_RTSUMMARY, &ip); + if (error) + do_error( +_("couldn't iget realtime summary inode, error %d\n"), error); + + mp->m_rsumip = ip; + error = -libxfs_rtfile_initialize_blocks(ip, 0, mp->m_rsumblocks, + sumcompute); + mp->m_rsumip = NULL; + if (error) + do_error( +_("couldn't re-initialize realtime summary inode, error %d\n"), error); + + libxfs_irele(ip); +} diff --git a/repair/rt.h b/repair/rt.h index 862695487bcd4c..f8caa5dc874ec2 100644 --- a/repair/rt.h +++ b/repair/rt.h @@ -6,15 +6,11 @@ #ifndef _XFS_REPAIR_RT_H_ #define _XFS_REPAIR_RT_H_ -struct blkmap; - -void -rtinit(xfs_mount_t *mp); - -int generate_rtinfo(struct xfs_mount *mp, union xfs_rtword_raw *words, - union xfs_suminfo_raw *sumcompute); - +void generate_rtinfo(struct xfs_mount *mp); void check_rtbitmap(struct xfs_mount *mp); void check_rtsummary(struct xfs_mount *mp); +void fill_rtbitmap(struct xfs_mount *mp); +void fill_rtsummary(struct xfs_mount *mp); + #endif /* _XFS_REPAIR_RT_H_ */ From patchwork Mon Dec 23 21:57:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13919309 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A9FED1422AB for ; Mon, 23 Dec 2024 21:57:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734991031; cv=none; b=lf8cumHL4Ndvp8b+QNmv9xeDgrWqHGO8TiT+Sb4mcNbwTTvIC0cHDtVXewEOTrhazpWicS3g4k1HYQJ5aLi24U6IlWu8+j5QERV8AoDsAefuyUHJdzP7TEbFUkHPR7XJbSSwv8HROFlRrh5mqEVDciCj2zqrJAEKlIS98ERBJBc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734991031; c=relaxed/simple; bh=P1hK+7zEA27qmyW0L/SVdBH1YcVaJat0QAt4SNKvzGI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VC5HrBF6d1DZwhJmm4yZ9ZyEGDBBaSXatIU7RC9zh3o7BW7Il/DiKSINrVKTctjJrrWaZ41A4RCe8BuZyStBcmHBESj2fkFYpvIprUDRwqY4xzLVcQEzrPflRv+sLfUb3/WY5vxm5jRGZ3tMEv5iSHlW06vMj7ci/VIopC83rdA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J81eodG3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J81eodG3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3C48BC4CED3; Mon, 23 Dec 2024 21:57:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1734991031; bh=P1hK+7zEA27qmyW0L/SVdBH1YcVaJat0QAt4SNKvzGI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=J81eodG37S6qJnBNuQGsHS2p3HGactHWy60fK4YdnROPsJH9jNjFgw/8G2JKU2H+w wQP1em6mkNt0d6PponNN+pP2o2ICy8keYdA3L8+lTmPWGxvl8tnY3Tb7HfDnZ3G3E7 F+IillCGWwSYBs9zCV3B4fRfo3xQBT1AgSPkAPISAbx7XzB2amLjRpxrNxwvdYvdPS lBtS3t9YjCZNcQwx7NhsHWtT7D/PZZq7UZ6ecMjZdTuib4v4XBuEH5XS8lKQbhVcTu 9UvKKojcpY9bBqLs42qtfOntLKNjlDe5+aUGecuEC6AP5st8/V/DOgoLA34p15ccdT Pf5+in1xMFSKw== Date: Mon, 23 Dec 2024 13:57:10 -0800 Subject: [PATCH 41/41] mkfs.xfs: enable metadata directories From: "Darrick J. Wong" To: djwong@kernel.org, aalbersh@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <173498941597.2294268.604845279727850514.stgit@frogsfrogsfrogs> In-Reply-To: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> References: <173498940899.2294268.17862292027916012046.stgit@frogsfrogsfrogs> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Enable formatting filesystems with metadata directories. Signed-off-by: "Darrick J. Wong" Reviewed-by: Christoph Hellwig --- libxfs/libxfs_api_defs.h | 2 + man/man8/mkfs.xfs.8.in | 11 +++++++ mkfs/lts_4.19.conf | 1 + mkfs/lts_5.10.conf | 1 + mkfs/lts_5.15.conf | 1 + mkfs/lts_5.4.conf | 1 + mkfs/lts_6.1.conf | 1 + mkfs/lts_6.12.conf | 1 + mkfs/lts_6.6.conf | 1 + mkfs/proto.c | 68 +++++++++++++++++++++++++++++++++++++++++++++- mkfs/xfs_mkfs.c | 33 +++++++++++++++++++++- 11 files changed, 118 insertions(+), 3 deletions(-) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index e79aa0e06e4f90..2f218296688477 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -215,6 +215,8 @@ #define xfs_metafile_iget libxfs_metafile_iget #define xfs_trans_metafile_iget libxfs_trans_metafile_iget #define xfs_metafile_set_iflag libxfs_metafile_set_iflag +#define xfs_metadir_cancel libxfs_metadir_cancel +#define xfs_metadir_commit libxfs_metadir_commit #define xfs_metadir_link libxfs_metadir_link #define xfs_metadir_lookup libxfs_metadir_lookup #define xfs_metadir_start_create libxfs_metadir_start_create diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in index e56c8f31a52c78..de5f6baf59df95 100644 --- a/man/man8/mkfs.xfs.8.in +++ b/man/man8/mkfs.xfs.8.in @@ -271,6 +271,17 @@ .SH OPTIONS When the option .B \-m finobt=0 is used, the inode btree counter feature is not supported and is disabled. +.TP +.BI metadir= value +This option creates an internal directory tree to store filesystem metadata. +.IP +By default, +.B mkfs.xfs +will not enable this feature. +If the option +.B \-m crc=0 +is used, the metadata directory feature is not supported and is disabled. + .TP .BI uuid= value Use the given value as the filesystem UUID for the newly created filesystem. diff --git a/mkfs/lts_4.19.conf b/mkfs/lts_4.19.conf index 4f190bacf9780c..4aa12f429ca2dd 100644 --- a/mkfs/lts_4.19.conf +++ b/mkfs/lts_4.19.conf @@ -6,6 +6,7 @@ crc=1 finobt=1 inobtcount=0 +metadir=0 reflink=0 rmapbt=0 autofsck=0 diff --git a/mkfs/lts_5.10.conf b/mkfs/lts_5.10.conf index a55fc68e4e3f2f..9625135c011f08 100644 --- a/mkfs/lts_5.10.conf +++ b/mkfs/lts_5.10.conf @@ -6,6 +6,7 @@ crc=1 finobt=1 inobtcount=0 +metadir=0 reflink=1 rmapbt=0 autofsck=0 diff --git a/mkfs/lts_5.15.conf b/mkfs/lts_5.15.conf index daea0b40671936..5306fad7e02f0f 100644 --- a/mkfs/lts_5.15.conf +++ b/mkfs/lts_5.15.conf @@ -6,6 +6,7 @@ crc=1 finobt=1 inobtcount=1 +metadir=0 reflink=1 rmapbt=0 autofsck=0 diff --git a/mkfs/lts_5.4.conf b/mkfs/lts_5.4.conf index 0f807fc35e34b4..9114388b0248a5 100644 --- a/mkfs/lts_5.4.conf +++ b/mkfs/lts_5.4.conf @@ -6,6 +6,7 @@ crc=1 finobt=1 inobtcount=0 +metadir=0 reflink=1 rmapbt=0 autofsck=0 diff --git a/mkfs/lts_6.1.conf b/mkfs/lts_6.1.conf index 0ff5bbad5a1c2d..1d5378042eed6c 100644 --- a/mkfs/lts_6.1.conf +++ b/mkfs/lts_6.1.conf @@ -6,6 +6,7 @@ crc=1 finobt=1 inobtcount=1 +metadir=0 reflink=1 rmapbt=0 autofsck=0 diff --git a/mkfs/lts_6.12.conf b/mkfs/lts_6.12.conf index 35b79082495d24..b204b78511f666 100644 --- a/mkfs/lts_6.12.conf +++ b/mkfs/lts_6.12.conf @@ -6,6 +6,7 @@ crc=1 finobt=1 inobtcount=1 +metadir=0 reflink=1 rmapbt=1 autofsck=0 diff --git a/mkfs/lts_6.6.conf b/mkfs/lts_6.6.conf index 2ef5957e0b3a3f..d2649c562fac12 100644 --- a/mkfs/lts_6.6.conf +++ b/mkfs/lts_6.6.conf @@ -6,6 +6,7 @@ crc=1 finobt=1 inobtcount=1 +metadir=0 reflink=1 rmapbt=1 autofsck=0 diff --git a/mkfs/proto.c b/mkfs/proto.c index d8eb6ca33672bd..05c2621f8a0b13 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -471,6 +471,65 @@ creatproto( return 0; } +/* Create a new metadata root directory. */ +static int +create_metadir( + struct xfs_mount *mp) +{ + struct xfs_inode *ip = NULL; + struct xfs_trans *tp; + int error; + struct xfs_icreate_args args = { + .mode = S_IFDIR, + .flags = XFS_ICREATE_UNLINKABLE, + }; + xfs_ino_t ino; + + if (!xfs_has_metadir(mp)) + return 0; + + error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_create, + libxfs_create_space_res(mp, MAXNAMELEN), 0, 0, &tp); + if (error) + return error; + + /* + * Create a new inode and set the sb pointer. The primary super is + * still marked inprogress, so we do not need to log the metadirino + * change ourselves. + */ + error = -libxfs_dialloc(&tp, &args, &ino); + if (error) + goto out_cancel; + error = -libxfs_icreate(tp, ino, &args, &ip); + if (error) + goto out_cancel; + mp->m_sb.sb_metadirino = ino; + + /* + * Initialize the root directory. There are no ILOCKs in userspace + * so we do not need to drop it here. + */ + libxfs_metafile_set_iflag(tp, ip, XFS_METAFILE_DIR); + error = -libxfs_dir_init(tp, ip, ip); + if (error) + goto out_cancel; + + error = -libxfs_trans_commit(tp); + if (error) + goto out_rele; + + mp->m_metadirip = ip; + return 0; + +out_cancel: + libxfs_trans_cancel(tp); +out_rele: + if (ip) + libxfs_irele(ip); + return error; +} + static void parseproto( xfs_mount_t *mp, @@ -709,8 +768,15 @@ parseproto( * RT initialization. Do this here to ensure that * the RT inodes get placed after the root inode. */ - if (isroot) + if (isroot) { + error = create_metadir(mp); + if (error) + fail( + _("Creation of the metadata directory inode failed"), + error); + rtinit(mp); + } tp = NULL; for (;;) { name = getdirentname(pp); diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index bbd0dbb6c80ab6..4e51caead9dac2 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -150,6 +150,7 @@ enum { M_INOBTCNT, M_BIGTIME, M_AUTOFSCK, + M_METADIR, M_MAX_OPTS, }; @@ -812,6 +813,7 @@ static struct opt_params mopts = { [M_INOBTCNT] = "inobtcount", [M_BIGTIME] = "bigtime", [M_AUTOFSCK] = "autofsck", + [M_METADIR] = "metadir", [M_MAX_OPTS] = NULL, }, .subopt_params = { @@ -861,6 +863,12 @@ static struct opt_params mopts = { .maxval = 1, .defaultval = 1, }, + { .index = M_METADIR, + .conflicts = { { NULL, LAST_CONFLICT } }, + .minval = 0, + .maxval = 1, + .defaultval = 1, + }, }, }; @@ -913,6 +921,7 @@ struct sb_feat_args { bool reflink; /* XFS_SB_FEAT_RO_COMPAT_REFLINK */ bool inobtcnt; /* XFS_SB_FEAT_RO_COMPAT_INOBTCNT */ bool bigtime; /* XFS_SB_FEAT_INCOMPAT_BIGTIME */ + bool metadir; /* XFS_SB_FEAT_INCOMPAT_METADIR */ bool nodalign; bool nortalign; bool nrext64; @@ -1048,7 +1057,8 @@ usage( void ) /* blocksize */ [-b size=num]\n\ /* config file */ [-c options=xxx]\n\ /* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\ - inobtcount=0|1,bigtime=0|1,autofsck=xxx]\n\ + inobtcount=0|1,bigtime=0|1,autofsck=xxx,\n\ + metadir=0|1]\n\ /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\ (sunit=value,swidth=value|su=num,sw=num|noalign),\n\ sectsize=num,concurrency=num]\n\ @@ -1883,6 +1893,9 @@ meta_opts_parser( illegal(value, "m autofsck"); } break; + case M_METADIR: + cli->sb_feat.metadir = getnum(value, opts, subopt); + break; default: return -EINVAL; } @@ -2465,6 +2478,14 @@ _("autofsck not supported without CRC support\n")); usage(); } cli->autofsck = FSPROP_AUTOFSCK_UNSET; + + if (cli->sb_feat.metadir && + cli_opt_set(&mopts, M_METADIR)) { + fprintf(stderr, +_("metadata directory not supported without CRC support\n")); + usage(); + } + cli->sb_feat.metadir = false; } if (!cli->sb_feat.finobt) { @@ -3568,7 +3589,8 @@ sb_set_features( * the sb_bad_features2 field. To avoid older kernels mounting * filesystems they shouldn't, set both field to the same value. */ - sbp->sb_bad_features2 = sbp->sb_features2; + if (!fp->metadir) + sbp->sb_bad_features2 = sbp->sb_features2; if (!fp->crcs_enabled) return; @@ -3618,6 +3640,8 @@ sb_set_features( */ sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT; } + if (fp->metadir) + sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_METADIR; } /* @@ -4053,6 +4077,7 @@ finish_superblock_setup( platform_uuid_copy(&sbp->sb_meta_uuid, &cfg->uuid); sbp->sb_logstart = cfg->logstart; sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO; + sbp->sb_metadirino = NULLFSINO; sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount; sbp->sb_rbmblocks = cfg->rtbmblocks; sbp->sb_logblocks = (xfs_extlen_t)cfg->logblocks; @@ -4279,6 +4304,8 @@ rewrite_secondary_superblocks( } dsb = buf->b_addr; dsb->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino); + if (xfs_has_metadir(mp)) + dsb->sb_metadirino = cpu_to_be64(mp->m_sb.sb_metadirino); libxfs_buf_mark_dirty(buf); libxfs_buf_relse(buf); @@ -4297,6 +4324,8 @@ rewrite_secondary_superblocks( } dsb = buf->b_addr; dsb->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino); + if (xfs_has_metadir(mp)) + dsb->sb_metadirino = cpu_to_be64(mp->m_sb.sb_metadirino); libxfs_buf_mark_dirty(buf); libxfs_buf_relse(buf); }