From patchwork Thu Feb 16 20:53:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143859 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AADBAC636CC for ; Thu, 16 Feb 2023 20:53:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229803AbjBPUxs (ORCPT ); Thu, 16 Feb 2023 15:53:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229793AbjBPUxs (ORCPT ); Thu, 16 Feb 2023 15:53:48 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E02384CCBA for ; Thu, 16 Feb 2023 12:53:47 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7C74360B71 for ; Thu, 16 Feb 2023 20:53:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DAC2CC433EF; Thu, 16 Feb 2023 20:53:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580826; bh=00HFnC++bGgVrFyVSGe8zk6pbRyRQWN+fVdBPOXQ2cs=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=u0Lv6n9xSEswGfwEaNymx1Uci5pMRro1j+CiawDul2t4vLQVRy+QxaTSn2zIzrvmr q+UjcKeXys/IS1FxTl7dMY4NOjAUHmwuzC8prvoYfJ2QzIDEDIa6zf5RQm4ejYw0o/ ugRi1f9IxyFn95hHBFfFbPeNvsxWm3WT9y+XJtT0p16ZBzoNJVdw4Qnl+OeE2fIo+v 8HvCZ73SCHrUcTfqFFKM7GiELCmdpnVCsAGe7FZwb6EFA5bwhWfyqnDazRBY79hmXp ky6kIDEcjiyon01gcN1WjEI6p4qaV4oAHV9LF724dN2VZFoLnazfdeo3CiBc2RT0vU uWY7dTJD+Y+oA== Date: Thu, 16 Feb 2023 12:53:46 -0800 Subject: [PATCH 01/25] xfsprogs: Fix default superblock attr bits From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657878908.3476112.7469636876565461550.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Recent parent pointer testing discovered that the default attr configuration has XFS_SB_VERSION2_ATTR2BIT enabled but XFS_SB_VERSION_ATTRBIT disabled. This is incorrect since XFS_SB_VERSION2_ATTR2BIT describes the format of the attr where as XFS_SB_VERSION_ATTRBIT enables or disables attrs. Fix this by enableing XFS_SB_VERSION_ATTRBIT for either attr version 1 or 2 Signed-off-by: Allison Henderson --- mkfs/xfs_mkfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index e219ec16..d95394a5 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -3205,7 +3205,7 @@ sb_set_features( sbp->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT; if (fp->log_version == 2) sbp->sb_versionnum |= XFS_SB_VERSION_LOGV2BIT; - if (fp->attr_version == 1) + if (fp->attr_version >= 1) sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT; if (fp->nci) sbp->sb_versionnum |= XFS_SB_VERSION_BORGBIT; From patchwork Thu Feb 16 20:54:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143862 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4467DC61DA4 for ; Thu, 16 Feb 2023 20:54:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229817AbjBPUyF (ORCPT ); Thu, 16 Feb 2023 15:54:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229793AbjBPUyE (ORCPT ); Thu, 16 Feb 2023 15:54:04 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 72D612942C for ; Thu, 16 Feb 2023 12:54:03 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 10D4C60A55 for ; Thu, 16 Feb 2023 20:54:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7375BC433EF; Thu, 16 Feb 2023 20:54:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580842; bh=mji0PllpvZlYfAIpul0+BmnVD81hSKypHV5C62iNgVQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=o5DGJHRC+82jdWrDeLPZsjWFxM0JCgkFn4QuvollVb0T0vfY6evXh9RADiZbUUYwx uuQRk6qfbOUBWgZ13P8UEDk0gtXuYQf02ZX2qsEzVj3KURpetphVE7ZGDOnKS+Dg5o 6Ld/k84aF6tdR666tbJkhUAgj0TMIuWElEmO5di+dQL4suiseKy61uvpwy97lKETAC KAFPTna61rvmOP5WhJ1eVgbopd717CGlppyU7+iZFluyMAE2JRCr92l22HQaXe6p5w z06Z3dnWD9nB6/8dULfTYxXWFMsV50w6e2Raw+Dfhx7pu4/yxFBjFr3LaCjkTugXTF slumikm32Ka+g== Date: Thu, 16 Feb 2023 12:54:02 -0800 Subject: [PATCH 02/25] xfsprogs: Add new name to attri/d From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657878922.3476112.9094775507103949014.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson This patch adds two new fields to the atti/d. They are nname and nnamelen. This will be used for parent pointer updates since a rename operation may cause the parent pointer to update both the name and value. So we need to carry both the new name as well as the target name in the attri/d. This patch also applies the necassary updates to print the new attri/d name fields. Source kernel commit: 7b3bde6f488372494236cb96da308b192bbe72c9 Signed-off-by: Allison Henderson --- libxfs/xfs_attr.c | 12 +++++++++++- libxfs/xfs_attr.h | 4 ++-- libxfs/xfs_da_btree.h | 2 ++ libxfs/xfs_log_format.h | 6 ++++-- logprint/log_redo.c | 27 ++++++++++++++++++++++----- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 2103a06b..2f619286 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -421,6 +421,12 @@ xfs_attr_complete_op( args->op_flags &= ~XFS_DA_OP_REPLACE; if (do_replace) { args->attr_filter &= ~XFS_ATTR_INCOMPLETE; + if (args->new_namelen > 0) { + args->name = args->new_name; + args->namelen = args->new_namelen; + args->hashval = xfs_da_hashname(args->name, + args->namelen); + } return replace_state; } return XFS_DAS_DONE; @@ -920,9 +926,13 @@ xfs_attr_defer_replace( struct xfs_da_args *args) { struct xfs_attr_intent *new; + int op_flag; int error = 0; - error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REPLACE, &new); + op_flag = args->new_namelen == 0 ? XFS_ATTRI_OP_FLAGS_REPLACE : + XFS_ATTRI_OP_FLAGS_NVREPLACE; + + error = xfs_attr_intent_init(args, op_flag, &new); if (error) return error; diff --git a/libxfs/xfs_attr.h b/libxfs/xfs_attr.h index 81be9b3e..3e81f3f4 100644 --- a/libxfs/xfs_attr.h +++ b/libxfs/xfs_attr.h @@ -510,8 +510,8 @@ struct xfs_attr_intent { struct xfs_da_args *xattri_da_args; /* - * Shared buffer containing the attr name and value so that the logging - * code can share large memory buffers between log items. + * Shared buffer containing the attr name, new name, and value so that + * the logging code can share large memory buffers between log items. */ struct xfs_attri_log_nameval *xattri_nameval; diff --git a/libxfs/xfs_da_btree.h b/libxfs/xfs_da_btree.h index ffa3df5b..a4b29827 100644 --- a/libxfs/xfs_da_btree.h +++ b/libxfs/xfs_da_btree.h @@ -55,7 +55,9 @@ enum xfs_dacmp { typedef struct xfs_da_args { struct xfs_da_geometry *geo; /* da block geometry */ const uint8_t *name; /* string (maybe not NULL terminated) */ + const uint8_t *new_name; /* new attr name */ int namelen; /* length of string (maybe no NULL) */ + int new_namelen; /* new attr name len */ uint8_t filetype; /* filetype of inode for directories */ void *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h index f13e0809..ae9c9976 100644 --- a/libxfs/xfs_log_format.h +++ b/libxfs/xfs_log_format.h @@ -117,7 +117,8 @@ struct xfs_unmount_log_format { #define XLOG_REG_TYPE_ATTRD_FORMAT 28 #define XLOG_REG_TYPE_ATTR_NAME 29 #define XLOG_REG_TYPE_ATTR_VALUE 30 -#define XLOG_REG_TYPE_MAX 30 +#define XLOG_REG_TYPE_ATTR_NNAME 31 +#define XLOG_REG_TYPE_MAX 31 /* @@ -957,6 +958,7 @@ struct xfs_icreate_log { #define XFS_ATTRI_OP_FLAGS_SET 1 /* Set the attribute */ #define XFS_ATTRI_OP_FLAGS_REMOVE 2 /* Remove the attribute */ #define XFS_ATTRI_OP_FLAGS_REPLACE 3 /* Replace the attribute */ +#define XFS_ATTRI_OP_FLAGS_NVREPLACE 4 /* Replace attr name and val */ #define XFS_ATTRI_OP_FLAGS_TYPE_MASK 0xFF /* Flags type mask */ /* @@ -974,7 +976,7 @@ struct xfs_icreate_log { struct xfs_attri_log_format { uint16_t alfi_type; /* attri log item type */ uint16_t alfi_size; /* size of this item */ - uint32_t __pad; /* pad to 64 bit aligned */ + uint32_t alfi_nname_len; /* attr new name length */ uint64_t alfi_id; /* attri identifier */ uint64_t alfi_ino; /* the inode for this attr operation */ uint32_t alfi_op_flags; /* marks the op as a set or remove */ diff --git a/logprint/log_redo.c b/logprint/log_redo.c index edf7e0fb..b596af02 100644 --- a/logprint/log_redo.c +++ b/logprint/log_redo.c @@ -705,9 +705,9 @@ xlog_print_trans_attri( memmove((char*)src_f, *ptr, src_len); *ptr += src_len; - printf(_("ATTRI: #regs: %d name_len: %d, value_len: %d id: 0x%llx\n"), - src_f->alfi_size, src_f->alfi_name_len, src_f->alfi_value_len, - (unsigned long long)src_f->alfi_id); + printf(_("ATTRI: #regs: %d name_len: %d, nname_len: %d value_len: %d id: 0x%llx\n"), + src_f->alfi_size, src_f->alfi_name_len, src_f->alfi_nname_len, + src_f->alfi_value_len, (unsigned long long)src_f->alfi_id); if (src_f->alfi_name_len > 0) { printf(_("\n")); @@ -719,6 +719,16 @@ xlog_print_trans_attri( goto error; } + if (src_f->alfi_nname_len > 0) { + printf(_("\n")); + (*i)++; + head = (xlog_op_header_t *)*ptr; + xlog_print_op_header(head, *i, ptr); + error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len)); + if (error) + goto error; + } + if (src_f->alfi_value_len > 0) { printf(_("\n")); (*i)++; @@ -788,8 +798,8 @@ xlog_recover_print_attri( if (xfs_attri_copy_log_format((char*)src_f, src_len, f)) goto out; - printf(_("ATTRI: #regs: %d name_len: %d, value_len: %d id: 0x%llx\n"), - f->alfi_size, f->alfi_name_len, f->alfi_value_len, (unsigned long long)f->alfi_id); + printf(_("ATTRI: #regs: %d name_len: %d, nname_len:%d, value_len: %d id: 0x%llx\n"), + f->alfi_size, f->alfi_name_len, f->alfi_nname_len, f->alfi_value_len, (unsigned long long)f->alfi_id); if (f->alfi_name_len > 0) { region++; @@ -798,6 +808,13 @@ xlog_recover_print_attri( f->alfi_name_len); } + if (f->alfi_nname_len > 0) { + region++; + printf(_("ATTRI: nname len:%u\n"), f->alfi_nname_len); + print_or_dump((char *)item->ri_buf[region].i_addr, + f->alfi_nname_len); + } + if (f->alfi_value_len > 0) { int len = f->alfi_value_len; From patchwork Thu Feb 16 20:54:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143863 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 191D4C6379F for ; Thu, 16 Feb 2023 20:54:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229845AbjBPUyU (ORCPT ); Thu, 16 Feb 2023 15:54:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60190 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229818AbjBPUyT (ORCPT ); Thu, 16 Feb 2023 15:54:19 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0EAA14CCBA for ; Thu, 16 Feb 2023 12:54:19 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 9F6CF60B61 for ; Thu, 16 Feb 2023 20:54:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0BD4FC433EF; Thu, 16 Feb 2023 20:54:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580858; bh=zx/F0ycCkjxhICjxY+eGkRwMXM9b1C1ESrceGGOyBUc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=LqbA6AaRlISQjNiZ2bATtU/NAyAT/vwxbrxO17xdGecMd25bhKXf3Urdr1Jk8bhr8 wpsiggKRGy2JSa1WA2N2eZaemhq49vxlYDdzjse53K2MiJdyuw8RexUWv472yPOVyj F5RDjnlCp6tjw9huQ4Iq1Z2U0GKgU3L28E2Me8lMchQJrEdsWSPPPr9hj+jCs4HAcl b2of33cCCXi6GRILXwBQtlwwdsGgiNC/cvhVR7pD8L8wToQlTApPUcx13ozKZGif5f L3RC1mmjLqRUdh2IbEf1agB4ikTiJR34r0zVtmfsuEVm/b2PG6YINyUq4Y8CQIQJBB wZXud717C6qRQ== Date: Thu, 16 Feb 2023 12:54:17 -0800 Subject: [PATCH 03/25] xfsprogs: Increase XFS_DEFER_OPS_NR_INODES to 5 From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , Catherine Hoang , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657878936.3476112.4696036081030015916.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: e9dc6a1e293b7e3843cd3868603801a1af2704c3 Renames that generate parent pointer updates can join up to 5 inodes locked in sorted order. So we need to increase the number of defer ops inodes and relock them in the same way. Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong Reviewed-by: Catherine Hoang --- libxfs/libxfs_priv.h | 1 + libxfs/xfs_defer.c | 28 ++++++++++++++++++++++++++-- libxfs/xfs_defer.h | 8 +++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 456c82d7..567bd237 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -477,6 +477,7 @@ void __xfs_buf_mark_corrupt(struct xfs_buf *bp, xfs_failaddr_t fa); __mode = __mode; /* no set-but-unused warning */ \ }) #define xfs_lock_two_inodes(ip0,mode0,ip1,mode1) ((void) 0) +#define xfs_lock_inodes(ips,num_ips,mode) ((void) 0) /* space allocation */ #define XFS_EXTENT_BUSY_DISCARDED 0x01 /* undergoing a discard op. */ diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c index c4f0269d..415fcaf5 100644 --- a/libxfs/xfs_defer.c +++ b/libxfs/xfs_defer.c @@ -815,13 +815,37 @@ xfs_defer_ops_continue( struct xfs_trans *tp, struct xfs_defer_resources *dres) { - unsigned int i; + unsigned int i, j; + struct xfs_inode *sips[XFS_DEFER_OPS_NR_INODES]; + struct xfs_inode *temp; ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); ASSERT(!(tp->t_flags & XFS_TRANS_DIRTY)); /* Lock the captured resources to the new transaction. */ - if (dfc->dfc_held.dr_inos == 2) + if (dfc->dfc_held.dr_inos > 2) { + /* + * Renames with parent pointer updates can lock up to 5 inodes, + * sorted by their inode number. So we need to make sure they + * are relocked in the same way. + */ + memset(sips, 0, sizeof(sips)); + for (i = 0; i < dfc->dfc_held.dr_inos; i++) + sips[i] = dfc->dfc_held.dr_ip[i]; + + /* Bubble sort of at most 5 inodes */ + for (i = 0; i < dfc->dfc_held.dr_inos; i++) { + for (j = 1; j < dfc->dfc_held.dr_inos; j++) { + if (sips[j]->i_ino < sips[j-1]->i_ino) { + temp = sips[j]; + sips[j] = sips[j-1]; + sips[j-1] = temp; + } + } + } + + xfs_lock_inodes(sips, dfc->dfc_held.dr_inos, XFS_ILOCK_EXCL); + } else if (dfc->dfc_held.dr_inos == 2) xfs_lock_two_inodes(dfc->dfc_held.dr_ip[0], XFS_ILOCK_EXCL, dfc->dfc_held.dr_ip[1], XFS_ILOCK_EXCL); else if (dfc->dfc_held.dr_inos == 1) diff --git a/libxfs/xfs_defer.h b/libxfs/xfs_defer.h index 114a3a49..fdf6941f 100644 --- a/libxfs/xfs_defer.h +++ b/libxfs/xfs_defer.h @@ -70,7 +70,13 @@ extern const struct xfs_defer_op_type xfs_attr_defer_type; /* * Deferred operation item relogging limits. */ -#define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ + +/* + * Rename w/ parent pointers can require up to 5 inodes with deferred ops to + * be joined to the transaction: src_dp, target_dp, src_ip, target_ip, and wip. + * These inodes are locked in sorted order by their inode numbers + */ +#define XFS_DEFER_OPS_NR_INODES 5 #define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ /* Resources that must be held across a transaction roll. */ From patchwork Thu Feb 16 20:54:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143864 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19459C636CC for ; Thu, 16 Feb 2023 20:54:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229793AbjBPUyv (ORCPT ); Thu, 16 Feb 2023 15:54:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60834 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229982AbjBPUyp (ORCPT ); Thu, 16 Feb 2023 15:54:45 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 93C3352CF3 for ; Thu, 16 Feb 2023 12:54:36 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 0AB7DB829BC for ; Thu, 16 Feb 2023 20:54:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 94D8AC43444; Thu, 16 Feb 2023 20:54:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580873; bh=zs6Lb14BGUmoz2qTVA7UlZhI6IuDHzwoAzm7FvpO9eE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=N00HdKnzrPtWwpXNM/iRJp39qT+YvG5mEhXBAWdAmxPqPHtiuQkFId58be/RvxVTI 97DqL4/2roVOB1cU+ZJAb8+/Y1L9mDtwRVxf6IV6NSKpNkTtB6pg4eq0UjYtTIcNnA ZAKvuU/KDLU+ClEkMHTw/hN3eVcyHauv81Q14dXIaKBCHXErGuVJSqu56tXA72V1gP DUMkL1l3YoPGJPaw4aXTVGbDXnrMozqnTgIlkT8pInRywdi6c4n3oE/pn4RvBl6Cpq 1JbUObqba2NqeBxbwxmnj2BEmPGV7zGPuwIAOtMvwOjTBu2oWI6l16aEBWoF0jEqNM ARktdtpzRlq/Q== Date: Thu, 16 Feb 2023 12:54:33 -0800 Subject: [PATCH 04/25] xfsprogs: get directory offset when adding directory name From: "Darrick J. Wong" To: djwong@kernel.org Cc: Dave Chinner , Allison Henderson , Catherine Hoang , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657878951.3476112.6748533618671731957.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Collins Return the directory offset information when adding an entry to the directory. This offset will be used as the parent pointer offset in xfs_create, xfs_symlink, xfs_link and xfs_rename. Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong Reviewed-by: Catherine Hoang --- libxfs/xfs_da_btree.h | 1 + libxfs/xfs_dir2.c | 9 +++++++-- libxfs/xfs_dir2.h | 2 +- libxfs/xfs_dir2_block.c | 1 + libxfs/xfs_dir2_leaf.c | 2 ++ libxfs/xfs_dir2_node.c | 2 ++ libxfs/xfs_dir2_sf.c | 2 ++ mkfs/proto.c | 2 +- repair/phase6.c | 16 ++++++++-------- 9 files changed, 25 insertions(+), 12 deletions(-) diff --git a/libxfs/xfs_da_btree.h b/libxfs/xfs_da_btree.h index a4b29827..90b86d00 100644 --- a/libxfs/xfs_da_btree.h +++ b/libxfs/xfs_da_btree.h @@ -81,6 +81,7 @@ typedef struct xfs_da_args { int rmtvaluelen2; /* remote attr value length in bytes */ uint32_t op_flags; /* operation flags */ enum xfs_dacmp cmpresult; /* name compare result for lookups */ + xfs_dir2_dataptr_t offset; /* OUT: offset in directory */ } xfs_da_args_t; /* diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index d6a19296..409d74a1 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -256,7 +256,8 @@ xfs_dir_createname( struct xfs_inode *dp, const struct xfs_name *name, xfs_ino_t inum, /* new entry inode number */ - xfs_extlen_t total) /* bmap's total block count */ + xfs_extlen_t total, /* bmap's total block count */ + xfs_dir2_dataptr_t *offset) /* OUT entry's dir offset */ { struct xfs_da_args *args; int rval; @@ -311,6 +312,10 @@ xfs_dir_createname( rval = xfs_dir2_node_addname(args); out_free: + /* return the location that this entry was place in the parent inode */ + if (offset) + *offset = args->offset; + kmem_free(args); return rval; } @@ -549,7 +554,7 @@ xfs_dir_canenter( xfs_inode_t *dp, struct xfs_name *name) /* name of entry to add */ { - return xfs_dir_createname(tp, dp, name, 0, 0); + return xfs_dir_createname(tp, dp, name, 0, 0, NULL); } /* diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index dd39f17d..d9695447 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -40,7 +40,7 @@ extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_inode *pdp); extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, const struct xfs_name *name, xfs_ino_t inum, - xfs_extlen_t tot); + xfs_extlen_t tot, xfs_dir2_dataptr_t *offset); extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, const struct xfs_name *name, xfs_ino_t *inum, struct xfs_name *ci_name); diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index bb9301b7..fb5b4179 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -570,6 +570,7 @@ xfs_dir2_block_addname( xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); + args->offset = xfs_dir2_byte_to_dataptr((char *)dep - (char *)hdr); /* * Clean up the bestfree array and log the header, tail, and entry. */ diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 5da66006..2dac830c 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -868,6 +868,8 @@ xfs_dir2_leaf_addname( xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); + args->offset = xfs_dir2_db_off_to_dataptr(args->geo, use_block, + (char *)dep - (char *)hdr); /* * Need to scan fix up the bestfree table. */ diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index c0eb335c..45fb218f 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -1971,6 +1971,8 @@ xfs_dir2_node_addname_int( xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); + args->offset = xfs_dir2_db_off_to_dataptr(args->geo, dbno, + (char *)dep - (char *)hdr); xfs_dir2_data_log_entry(args, dbp, dep); /* Rescan the freespace and log the data block if needed. */ diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index 08b36c95..a3f1e657 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/libxfs/xfs_dir2_sf.c @@ -485,6 +485,7 @@ xfs_dir2_sf_addname_easy( memcpy(sfep->name, args->name, sfep->namelen); xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); + args->offset = xfs_dir2_byte_to_dataptr(offset); /* * Update the header and inode. @@ -575,6 +576,7 @@ xfs_dir2_sf_addname_hard( memcpy(sfep->name, args->name, sfep->namelen); xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); + args->offset = xfs_dir2_byte_to_dataptr(offset); sfp->count++; if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) sfp->i8count++; diff --git a/mkfs/proto.c b/mkfs/proto.c index 68ecdbf3..6b6a070f 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -328,7 +328,7 @@ newdirent( rsv = XFS_DIRENTER_SPACE_RES(mp, name->len); - error = -libxfs_dir_createname(tp, pip, name, inum, rsv); + error = -libxfs_dir_createname(tp, pip, name, inum, rsv, NULL); if (error) fail(_("directory createname error"), error); } diff --git a/repair/phase6.c b/repair/phase6.c index 0be2c9c9..d1e9c0d9 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -973,7 +973,7 @@ mk_orphanage(xfs_mount_t *mp) /* * create the actual entry */ - error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, nres); + error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, nres, NULL); if (error) do_error( _("can't make %s, createname error %d\n"), @@ -1070,7 +1070,7 @@ mv_orphanage( libxfs_trans_ijoin(tp, ino_p, 0); err = -libxfs_dir_createname(tp, orphanage_ip, &xname, - ino, nres); + ino, nres, NULL); if (err) do_error( _("name create failed in %s (%d)\n"), ORPHANAGE, err); @@ -1082,7 +1082,7 @@ mv_orphanage( libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE); err = -libxfs_dir_createname(tp, ino_p, &xfs_name_dotdot, - orphanage_ino, nres); + orphanage_ino, nres, NULL); if (err) do_error( _("creation of .. entry failed (%d)\n"), err); @@ -1104,7 +1104,7 @@ mv_orphanage( err = -libxfs_dir_createname(tp, orphanage_ip, &xname, - ino, nres); + ino, nres, NULL); if (err) do_error( _("name create failed in %s (%d)\n"), ORPHANAGE, err); @@ -1151,7 +1151,7 @@ mv_orphanage( libxfs_trans_ijoin(tp, ino_p, 0); err = -libxfs_dir_createname(tp, orphanage_ip, &xname, ino, - nres); + nres, NULL); if (err) do_error( _("name create failed in %s (%d)\n"), ORPHANAGE, err); @@ -1334,7 +1334,7 @@ longform_dir2_rebuild( libxfs_trans_ijoin(tp, ip, 0); error = -libxfs_dir_createname(tp, ip, &p->name, p->inum, - nres); + nres, NULL); if (error) { do_warn( _("name create failed in ino %" PRIu64 " (%d)\n"), ino, error); @@ -2943,7 +2943,7 @@ _("error %d fixing shortform directory %llu\n"), libxfs_trans_ijoin(tp, ip, 0); error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot, - ip->i_ino, nres); + ip->i_ino, nres, NULL); if (error) do_error( _("can't make \"..\" entry in root inode %" PRIu64 ", createname error %d\n"), ino, error); @@ -2998,7 +2998,7 @@ _("error %d fixing shortform directory %llu\n"), libxfs_trans_ijoin(tp, ip, 0); error = -libxfs_dir_createname(tp, ip, &xfs_name_dot, - ip->i_ino, nres); + ip->i_ino, nres, NULL); if (error) do_error( _("can't make \".\" entry in dir ino %" PRIu64 ", createname error %d\n"), From patchwork Thu Feb 16 20:54:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143865 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F879C636CC for ; Thu, 16 Feb 2023 20:55:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229888AbjBPUzO (ORCPT ); Thu, 16 Feb 2023 15:55:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229874AbjBPUzK (ORCPT ); Thu, 16 Feb 2023 15:55:10 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C0D9A52CFF for ; Thu, 16 Feb 2023 12:54:51 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 78C08B826BA for ; Thu, 16 Feb 2023 20:54:50 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3B680C433D2; Thu, 16 Feb 2023 20:54:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580889; bh=G46Y/6kKaRTVspGZvduQb4NdaQGE1laDLTrm0iGoP00=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=OREgxrgyq4r5GuM/ihUhaslRQy++CxIC5yDgeRBCiTiJSy9mEsAwH6YN9KgK8axTD ZanEWcnyodajNFQKzWWpKbFHrsMzKWVzuJg6cO0+ImVpGKPey/1ZH0JxqLaqTtbrDR hFpNbPTF6Ff8x86xMZB72yP7a/mWRUrk2gsHhsv4GsS4caOHNAFG9quVz4BSfZI6TJ rl/s3N6iGerDVD3ZT2Y+VGl167MhAtsjKcD78DUj92pR0Ne+A4zHrLQu1fXMsuU7+8 lV2RBJS64JMgFxO3giZvNxrJCE3G2xGMjOJMa9UcpblrI3d4Fjl9DNPvCDfArD1uEI QbWZIo7RSCcyA== Date: Thu, 16 Feb 2023 12:54:48 -0800 Subject: [PATCH 05/25] xfsprogs: get directory offset when removing directory name From: "Darrick J. Wong" To: djwong@kernel.org Cc: Mark Tinguely , Dave Chinner , Allison Henderson , Catherine Hoang , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657878965.3476112.6345717511317408242.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Return the directory offset information when removing an entry to the directory. This offset will be used as the parent pointer offset in xfs_remove. Signed-off-by: Mark Tinguely Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong Reviewed-by: Catherine Hoang --- libxfs/xfs_dir2.c | 6 +++++- libxfs/xfs_dir2.h | 3 ++- libxfs/xfs_dir2_block.c | 4 ++-- libxfs/xfs_dir2_leaf.c | 5 +++-- libxfs/xfs_dir2_node.c | 5 +++-- libxfs/xfs_dir2_sf.c | 2 ++ 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 409d74a1..6aa1db0e 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -435,7 +435,8 @@ xfs_dir_removename( struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t ino, - xfs_extlen_t total) /* bmap's total block count */ + xfs_extlen_t total, /* bmap's total block count */ + xfs_dir2_dataptr_t *offset) /* OUT: offset in directory */ { struct xfs_da_args *args; int rval; @@ -480,6 +481,9 @@ xfs_dir_removename( else rval = xfs_dir2_node_removename(args); out_free: + if (offset) + *offset = args->offset; + kmem_free(args); return rval; } diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index d9695447..0c2d7c0a 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -46,7 +46,8 @@ extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *ci_name); extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name, xfs_ino_t ino, - xfs_extlen_t tot); + xfs_extlen_t tot, + xfs_dir2_dataptr_t *offset); extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, const struct xfs_name *name, xfs_ino_t inum, xfs_extlen_t tot); diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index fb5b4179..43b9c18f 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -807,9 +807,9 @@ xfs_dir2_block_removename( /* * Point to the data entry using the leaf entry. */ + args->offset = be32_to_cpu(blp[ent].address); dep = (xfs_dir2_data_entry_t *)((char *)hdr + - xfs_dir2_dataptr_to_off(args->geo, - be32_to_cpu(blp[ent].address))); + xfs_dir2_dataptr_to_off(args->geo, args->offset)); /* * Mark the data entry's space free. */ diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 2dac830c..ee9cfbe9 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -1384,9 +1384,10 @@ xfs_dir2_leaf_removename( * Point to the leaf entry, use that to point to the data entry. */ lep = &leafhdr.ents[index]; - db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address)); + args->offset = be32_to_cpu(lep->address); + db = xfs_dir2_dataptr_to_db(args->geo, args->offset); dep = (xfs_dir2_data_entry_t *)((char *)hdr + - xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address))); + xfs_dir2_dataptr_to_off(args->geo, args->offset)); needscan = needlog = 0; oldbest = be16_to_cpu(bf[0].length); ltp = xfs_dir2_leaf_tail_p(geo, leaf); diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index 45fb218f..ac6a7089 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -1293,9 +1293,10 @@ xfs_dir2_leafn_remove( /* * Extract the data block and offset from the entry. */ - db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address)); + args->offset = be32_to_cpu(lep->address); + db = xfs_dir2_dataptr_to_db(args->geo, args->offset); ASSERT(dblk->blkno == db); - off = xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address)); + off = xfs_dir2_dataptr_to_off(args->geo, args->offset); ASSERT(dblk->index == off); /* diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index a3f1e657..4dc74734 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/libxfs/xfs_dir2_sf.c @@ -969,6 +969,8 @@ xfs_dir2_sf_removename( XFS_CMP_EXACT) { ASSERT(xfs_dir2_sf_get_ino(mp, sfp, sfep) == args->inumber); + args->offset = xfs_dir2_byte_to_dataptr( + xfs_dir2_sf_get_offset(sfep)); break; } } From patchwork Thu Feb 16 20:55:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143866 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E26AC61DA4 for ; Thu, 16 Feb 2023 20:55:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229834AbjBPUzT (ORCPT ); Thu, 16 Feb 2023 15:55:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229490AbjBPUzS (ORCPT ); Thu, 16 Feb 2023 15:55:18 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AACF0505E5 for ; Thu, 16 Feb 2023 12:55:07 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 3173CB82958 for ; Thu, 16 Feb 2023 20:55:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2D88C433D2; Thu, 16 Feb 2023 20:55:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580904; bh=Z3Lw5ZvmezaF8bLXrPt3M56f9esv7E5Ds1nxUwDNbHw=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Q02I7aw9EX7thmV2YPqg9B36vINv/8OcqUQoO3upRHnQTpsJ5GwIEPYDBx8//peIQ aQLTHODDUyy7kNfk4Sub51V/bw1OGgRcr0Yn4WXRPi8wH6EAdK07RZLQriN8MklU4H pPyjk0veycLfMsgjpRAP0e9UVlcKCBBZRdPyzyJl7dD2rnHHAPvwJMOqswXJqEPkzn tzPwM9XDJkkpmI/+oC607qC8HLCziCtFeu45t+8KKcoQ9eC1RhtQHrYgPS6uKvqVQW Z+BglZT/UVvIz6P5ng+DK/CuGqvpWBo10FRcgvgHcLcRi7HsxZ5RdZ4QYYqJq0X7Rs Aq5dawGuGdgWA== Date: Thu, 16 Feb 2023 12:55:04 -0800 Subject: [PATCH 06/25] xfsprogs: get directory offset when replacing a directory name From: "Darrick J. Wong" To: djwong@kernel.org Cc: Mark Tinguely , Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657878979.3476112.559762145986643324.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Collins Return the directory offset information when replacing an entry to the directory. This offset will be used as the parent pointer offset in xfs_rename. Signed-off-by: Mark Tinguely Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- libxfs/xfs_dir2.c | 8 ++++++-- libxfs/xfs_dir2.h | 2 +- libxfs/xfs_dir2_block.c | 4 ++-- libxfs/xfs_dir2_leaf.c | 1 + libxfs/xfs_dir2_node.c | 1 + libxfs/xfs_dir2_sf.c | 2 ++ repair/phase6.c | 2 +- 7 files changed, 14 insertions(+), 6 deletions(-) diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 6aa1db0e..43b4e46b 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -481,7 +481,7 @@ xfs_dir_removename( else rval = xfs_dir2_node_removename(args); out_free: - if (offset) + if (!rval && offset) *offset = args->offset; kmem_free(args); @@ -497,7 +497,8 @@ xfs_dir_replace( struct xfs_inode *dp, const struct xfs_name *name, /* name of entry to replace */ xfs_ino_t inum, /* new inode number */ - xfs_extlen_t total) /* bmap's total block count */ + xfs_extlen_t total, /* bmap's total block count */ + xfs_dir2_dataptr_t *offset) /* OUT: offset in directory */ { struct xfs_da_args *args; int rval; @@ -545,6 +546,9 @@ xfs_dir_replace( else rval = xfs_dir2_node_replace(args); out_free: + if (offset) + *offset = args->offset; + kmem_free(args); return rval; } diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index 0c2d7c0a..ff59f009 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -50,7 +50,7 @@ extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, xfs_dir2_dataptr_t *offset); extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, const struct xfs_name *name, xfs_ino_t inum, - xfs_extlen_t tot); + xfs_extlen_t tot, xfs_dir2_dataptr_t *offset); extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name); diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index 43b9c18f..c743fa67 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -882,9 +882,9 @@ xfs_dir2_block_replace( /* * Point to the data entry we need to change. */ + args->offset = be32_to_cpu(blp[ent].address); dep = (xfs_dir2_data_entry_t *)((char *)hdr + - xfs_dir2_dataptr_to_off(args->geo, - be32_to_cpu(blp[ent].address))); + xfs_dir2_dataptr_to_off(args->geo, args->offset)); ASSERT(be64_to_cpu(dep->inumber) != args->inumber); /* * Change the inode number to the new value. diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index ee9cfbe9..1be7773e 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -1521,6 +1521,7 @@ xfs_dir2_leaf_replace( /* * Point to the data entry. */ + args->offset = be32_to_cpu(lep->address); dep = (xfs_dir2_data_entry_t *) ((char *)dbp->b_addr + xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index ac6a7089..621e8bf5 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -2239,6 +2239,7 @@ xfs_dir2_node_replace( hdr = state->extrablk.bp->b_addr; ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); + args->offset = be32_to_cpu(leafhdr.ents[blk->index].address); dep = (xfs_dir2_data_entry_t *) ((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index 4dc74734..6a128748 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/libxfs/xfs_dir2_sf.c @@ -1107,6 +1107,8 @@ xfs_dir2_sf_replace( xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); + args->offset = xfs_dir2_byte_to_dataptr( + xfs_dir2_sf_get_offset(sfep)); break; } } diff --git a/repair/phase6.c b/repair/phase6.c index d1e9c0d9..a347c390 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1122,7 +1122,7 @@ mv_orphanage( if (entry_ino_num != orphanage_ino) { err = -libxfs_dir_replace(tp, ino_p, &xfs_name_dotdot, orphanage_ino, - nres); + nres, NULL); if (err) do_error( _("name replace op failed (%d)\n"), err); From patchwork Thu Feb 16 20:55:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143867 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1679C61DA4 for ; Thu, 16 Feb 2023 20:55:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229956AbjBPUz3 (ORCPT ); Thu, 16 Feb 2023 15:55:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229935AbjBPUzW (ORCPT ); Thu, 16 Feb 2023 15:55:22 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79AF84ECFE for ; Thu, 16 Feb 2023 12:55:21 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0AB5D60B71 for ; Thu, 16 Feb 2023 20:55:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71F63C433D2; Thu, 16 Feb 2023 20:55:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580920; bh=NtpwOtgPQImtERZU2O5byAL1v2Ag0M+xgXbgVXtd0S4=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Y5MLpDiuyTJfLX7B57e1p85eUwdnBmCc/ZcDHIbur68hAjS/s/wX5npOOz/viQuwP QpvlKObU0w+Ca2JConL95zvoTiC2v28XAYs5tQTK0lAIJjX/09Bki4ndKtdhVFl3/h fN3YrbR4naLmRUYPkuzi68pTL1x9rxeBEtTfSrW032TBTBk+jx83mW9JuvYGEd3Ol4 IqhEYhBr4/+7KA4P6idq/8dO1jX7DuLUyu63Zga3NCPHHc4sntlv5ATu/559wmZJk5 aX6Oc97RUQJIqzn9h1tDhsNjXc6Lxok5hdB+u08YTFQtZJbJGnx4w4XtqA/9vjwhNo 08Ltz8HSNSjoQ== Date: Thu, 16 Feb 2023 12:55:20 -0800 Subject: [PATCH 07/25] xfsprogs: add parent pointer support to attribute code From: "Darrick J. Wong" To: djwong@kernel.org Cc: Mark Tinguely , Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657878994.3476112.2059265226064745533.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Add the new parent attribute type. XFS_ATTR_PARENT is used only for parent pointer entries; it uses reserved blocks like XFS_ATTR_ROOT. Signed-off-by: Mark Tinguely Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson [djwong: fix whitespace errors] Reviewed-by: Darrick J. Wong --- libxfs/xfs_attr.c | 4 +++- libxfs/xfs_da_format.h | 5 ++++- libxfs/xfs_log_format.h | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 2f619286..04f8e349 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -974,11 +974,13 @@ xfs_attr_set( struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; struct xfs_trans_res tres; - bool rsvd = (args->attr_filter & XFS_ATTR_ROOT); + bool rsvd; int error, local; int rmt_blks = 0; unsigned int total; + rsvd = (args->attr_filter & (XFS_ATTR_ROOT | XFS_ATTR_PARENT)) != 0; + if (xfs_is_shutdown(dp->i_mount)) return -EIO; diff --git a/libxfs/xfs_da_format.h b/libxfs/xfs_da_format.h index 25e28410..3dc03968 100644 --- a/libxfs/xfs_da_format.h +++ b/libxfs/xfs_da_format.h @@ -688,12 +688,15 @@ struct xfs_attr3_leafblock { #define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */ #define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */ #define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */ +#define XFS_ATTR_PARENT_BIT 3 /* parent pointer attrs */ #define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */ #define XFS_ATTR_LOCAL (1u << XFS_ATTR_LOCAL_BIT) #define XFS_ATTR_ROOT (1u << XFS_ATTR_ROOT_BIT) #define XFS_ATTR_SECURE (1u << XFS_ATTR_SECURE_BIT) +#define XFS_ATTR_PARENT (1u << XFS_ATTR_PARENT_BIT) #define XFS_ATTR_INCOMPLETE (1u << XFS_ATTR_INCOMPLETE_BIT) -#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) +#define XFS_ATTR_NSP_ONDISK_MASK \ + (XFS_ATTR_ROOT | XFS_ATTR_SECURE | XFS_ATTR_PARENT) /* * Alignment for namelist and valuelist entries (since they are mixed diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h index ae9c9976..727b5a85 100644 --- a/libxfs/xfs_log_format.h +++ b/libxfs/xfs_log_format.h @@ -967,6 +967,7 @@ struct xfs_icreate_log { */ #define XFS_ATTRI_FILTER_MASK (XFS_ATTR_ROOT | \ XFS_ATTR_SECURE | \ + XFS_ATTR_PARENT | \ XFS_ATTR_INCOMPLETE) /* From patchwork Thu Feb 16 20:55:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143868 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 51BA0C636CC for ; Thu, 16 Feb 2023 20:55:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229490AbjBPUzy (ORCPT ); Thu, 16 Feb 2023 15:55:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229906AbjBPUzx (ORCPT ); Thu, 16 Feb 2023 15:55:53 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1390452CCA for ; Thu, 16 Feb 2023 12:55:39 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id AC48BB82962 for ; Thu, 16 Feb 2023 20:55:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4AFB0C433EF; Thu, 16 Feb 2023 20:55:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580936; bh=uj9EeYr/6ka8DVlebjCW61OQGVkKk4LU5t9szUs8l7o=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=qJscDW998ivbphcQGOwKa0zqIYv5aF3PBeHHb//IaHFR6buett1B6pFVjDDczEzck yNPnQhFq1FXkbpPLlX4J0QrZd6LKcQWhKWi9EgvVNsMcUowi7w7oICQ1jHNbxaMuSU pH9h9DjGALSUEQDPWNOOHeAQUDTEpmiwhlnkJHodLZ8UUOhBeaylkD/QZo19tMUQ1b eZAj/YtTOIUwNFRDxtk/tae9CLykXDeQoqMHCyzSe3x+eKplMGhowuTLp4k+J74KLL vyilaqCwp8095roGPVjnCB8BNlRfbxaoTPP/cCJiuTX4G/n+7Ghr5+h1zwaar5pKgG GWF2F34USGgAw== Date: Thu, 16 Feb 2023 12:55:35 -0800 Subject: [PATCH 08/25] xfsprogs: define parent pointer xattr format From: "Darrick J. Wong" To: djwong@kernel.org Cc: Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879008.3476112.5817042695666164354.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: 059f7b9c5aedf18990aaaee05ff9938b8d87a5ef We need to define the parent pointer attribute format before we start adding support for it into all the code that needs to use it. The EA format we will use encodes the following information: name={parent inode #, parent inode generation, dirent offset} value={dirent filename} The inode/gen gives all the information we need to reliably identify the parent without requiring child->parent lock ordering, and allows userspace to do pathname component level reconstruction without the kernel ever needing to verify the parent itself as part of ioctl calls. By using the dirent offset in the EA name, we have a method of knowing the exact parent pointer EA we need to modify/remove in rename/unlink without an unbound EA name search. By keeping the dirent name in the value, we have enough information to be able to validate and reconstruct damaged directory trees. While the diroffset of a filename alone is not unique enough to identify the child, the {diroffset,filename,child_inode} tuple is sufficient. That is, if the diroffset gets reused and points to a different filename, we can detect that from the contents of EA. If a link of the same name is created, then we can check whether it points at the same inode as the parent EA we current have. Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- libxfs/xfs_da_format.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/libxfs/xfs_da_format.h b/libxfs/xfs_da_format.h index 3dc03968..b02b67f1 100644 --- a/libxfs/xfs_da_format.h +++ b/libxfs/xfs_da_format.h @@ -805,4 +805,29 @@ static inline unsigned int xfs_dir2_dirblock_bytes(struct xfs_sb *sbp) xfs_failaddr_t xfs_da3_blkinfo_verify(struct xfs_buf *bp, struct xfs_da3_blkinfo *hdr3); +/* + * Parent pointer attribute format definition + * + * EA name encodes the parent inode number, generation and the offset of + * the dirent that points to the child inode. The EA value contains the + * same name as the dirent in the parent directory. + */ +struct xfs_parent_name_rec { + __be64 p_ino; + __be32 p_gen; + __be32 p_diroffset; +}; + +/* + * incore version of the above, also contains name pointers so callers + * can pass/obtain all the parent pointer information in a single structure + */ +struct xfs_parent_name_irec { + xfs_ino_t p_ino; + uint32_t p_gen; + xfs_dir2_dataptr_t p_diroffset; + const char *p_name; + uint8_t p_namelen; +}; + #endif /* __XFS_DA_FORMAT_H__ */ From patchwork Thu Feb 16 20:55:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD31BC636CC for ; Thu, 16 Feb 2023 20:56:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229902AbjBPU4E (ORCPT ); Thu, 16 Feb 2023 15:56:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229906AbjBPU4D (ORCPT ); Thu, 16 Feb 2023 15:56:03 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA4EE521F1 for ; Thu, 16 Feb 2023 12:55:52 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7CF3360C1A for ; Thu, 16 Feb 2023 20:55:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2870C433EF; Thu, 16 Feb 2023 20:55:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580951; bh=MHoo9KgKzn31KNpYVr+bq857Q28DUN5fwtbFMizX3kE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=oY31dgHtimx1EsSm8looAzIz6Ad7VRq5pjbs121EdFGBRRi9KJpGW9asKeL74z71F vQVED5s6FSD905nN/DAEyiIIV2ceXyW8ciBkMgh92KFPfWdzgSV+S9KBO1X/dpxXL2 SiPutCX+DdYtnjGWD/Tneca0H5bS/dqO9tVP9UIkRKP7NxBtejMrLuig63kH6G5oYd fA4eCWWZHKulsqmsyoFzjP3lS8Iu33A3wmE1s+7orTp2U1/OdVBs2OwVPit0hGJXaM lqtkK4GYm5VN5Lk3b8/yD/4UgwN/+uTiUCVedvfRZfE73mrep9t+vGSiULqS13/t1A CtDNlV61pmzgg== Date: Thu, 16 Feb 2023 12:55:51 -0800 Subject: [PATCH 09/25] xfsprogs: Add xfs_verify_pptr From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879022.3476112.514649224408561663.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: b328f630fcee8dc96e0e3942355fd211f8e15a5d Attribute names of parent pointers are not strings. So we need to modify attr_namecheck to verify parent pointer records when the XFS_ATTR_PARENT flag is set. Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- libxfs/xfs_attr.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- libxfs/xfs_attr.h | 3 ++- libxfs/xfs_da_format.h | 8 ++++++++ repair/attr_repair.c | 19 ++++++++++++------- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 04f8e349..d5f1f488 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -1575,9 +1575,33 @@ xfs_attr_node_get( return error; } -/* Returns true if the attribute entry name is valid. */ -bool -xfs_attr_namecheck( +/* + * Verify parent pointer attribute is valid. + * Return true on success or false on failure + */ +STATIC bool +xfs_verify_pptr( + struct xfs_mount *mp, + const struct xfs_parent_name_rec *rec) +{ + xfs_ino_t p_ino; + xfs_dir2_dataptr_t p_diroffset; + + p_ino = be64_to_cpu(rec->p_ino); + p_diroffset = be32_to_cpu(rec->p_diroffset); + + if (!xfs_verify_ino(mp, p_ino)) + return false; + + if (p_diroffset > XFS_DIR2_MAX_DATAPTR) + return false; + + return true; +} + +/* Returns true if the string attribute entry name is valid. */ +static bool +xfs_str_attr_namecheck( const void *name, size_t length) { @@ -1592,6 +1616,23 @@ xfs_attr_namecheck( return !memchr(name, 0, length); } +/* Returns true if the attribute entry name is valid. */ +bool +xfs_attr_namecheck( + struct xfs_mount *mp, + const void *name, + size_t length, + int flags) +{ + if (flags & XFS_ATTR_PARENT) { + if (length != sizeof(struct xfs_parent_name_rec)) + return false; + return xfs_verify_pptr(mp, (struct xfs_parent_name_rec *)name); + } + + return xfs_str_attr_namecheck(name, length); +} + int __init xfs_attr_intent_init_cache(void) { diff --git a/libxfs/xfs_attr.h b/libxfs/xfs_attr.h index 3e81f3f4..b79dae78 100644 --- a/libxfs/xfs_attr.h +++ b/libxfs/xfs_attr.h @@ -547,7 +547,8 @@ int xfs_attr_get(struct xfs_da_args *args); int xfs_attr_set(struct xfs_da_args *args); int xfs_attr_set_iter(struct xfs_attr_intent *attr); int xfs_attr_remove_iter(struct xfs_attr_intent *attr); -bool xfs_attr_namecheck(const void *name, size_t length); +bool xfs_attr_namecheck(struct xfs_mount *mp, const void *name, size_t length, + int flags); int xfs_attr_calc_size(struct xfs_da_args *args, int *local); void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres, unsigned int *total); diff --git a/libxfs/xfs_da_format.h b/libxfs/xfs_da_format.h index b02b67f1..75b13807 100644 --- a/libxfs/xfs_da_format.h +++ b/libxfs/xfs_da_format.h @@ -731,6 +731,14 @@ xfs_attr3_leaf_name(xfs_attr_leafblock_t *leafp, int idx) return &((char *)leafp)[be16_to_cpu(entries[idx].nameidx)]; } +static inline int +xfs_attr3_leaf_flags(xfs_attr_leafblock_t *leafp, int idx) +{ + struct xfs_attr_leaf_entry *entries = xfs_attr3_leaf_entryp(leafp); + + return entries[idx].flags; +} + static inline xfs_attr_leaf_name_remote_t * xfs_attr3_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) { diff --git a/repair/attr_repair.c b/repair/attr_repair.c index c3a6d502..afe8073c 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -293,8 +293,9 @@ process_shortform_attr( } /* namecheck checks for null chars in attr names. */ - if (!libxfs_attr_namecheck(currententry->nameval, - currententry->namelen)) { + if (!libxfs_attr_namecheck(mp, currententry->nameval, + currententry->namelen, + currententry->flags)) { do_warn( _("entry contains illegal character in shortform attribute name\n")); junkit = 1; @@ -454,12 +455,14 @@ process_leaf_attr_local( xfs_dablk_t da_bno, xfs_ino_t ino) { - xfs_attr_leaf_name_local_t *local; + xfs_attr_leaf_name_local_t *local; + int flags; local = xfs_attr3_leaf_name_local(leaf, i); + flags = xfs_attr3_leaf_flags(leaf, i); if (local->namelen == 0 || - !libxfs_attr_namecheck(local->nameval, - local->namelen)) { + !libxfs_attr_namecheck(mp, local->nameval, + local->namelen, flags)) { do_warn( _("attribute entry %d in attr block %u, inode %" PRIu64 " has bad name (namelen = %d)\n"), i, da_bno, ino, local->namelen); @@ -510,12 +513,14 @@ process_leaf_attr_remote( { xfs_attr_leaf_name_remote_t *remotep; char* value; + int flags; remotep = xfs_attr3_leaf_name_remote(leaf, i); + flags = xfs_attr3_leaf_flags(leaf, i); if (remotep->namelen == 0 || - !libxfs_attr_namecheck(remotep->name, - remotep->namelen) || + !libxfs_attr_namecheck(mp, remotep->name, + remotep->namelen, flags) || be32_to_cpu(entry->hashval) != libxfs_da_hashname((unsigned char *)&remotep->name[0], remotep->namelen) || From patchwork Thu Feb 16 20:56:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143870 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AB52C61DA4 for ; Thu, 16 Feb 2023 20:56:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229927AbjBPU4N (ORCPT ); Thu, 16 Feb 2023 15:56:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229906AbjBPU4M (ORCPT ); Thu, 16 Feb 2023 15:56:12 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 410A34E5C5 for ; Thu, 16 Feb 2023 12:56:10 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id BCAB4B82958 for ; Thu, 16 Feb 2023 20:56:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 79C13C433EF; Thu, 16 Feb 2023 20:56:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580967; bh=Oe0vtEnajby24/YMbaStKIJblIJwTqMapF7EqRcEV0E=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=PJ5AQWzSCjjRTTI5XoM/b3o/VdRUALibcsZsZ9lzD3BWT9Hbk92yvz4zbC2lFIcJQ A3b7RHy/CDgxc9TPFGcVexfXZYrWaC5sWMTVQjlRh9sfhX8+34rWE3lNl+l5ycMlzW Cdus2iQzv182ObyeXwRiX7/VNRxZXXdGoFu7vdsVf6loTRLyq8aiK0ejm6DNE+AEeI o+4iD+i4tEiSNYjgTy65BB3cKUr7sjhYrZzqgaiB/IF7gmwc9ba9dPGMTfzziFTMMR CjYyU9L6OHWNTuUyVb3ixMxbNTVNTm5vpqDN48Y9Wx5Xq7k4UwoZIl4+sRogWlJW/O LVLorRCaJ2sEw== Date: Thu, 16 Feb 2023 12:56:07 -0800 Subject: [PATCH 10/25] xfsprogs: extend transaction reservations for parent attributes From: "Darrick J. Wong" To: djwong@kernel.org Cc: Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879036.3476112.16087980108025238104.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: 99c10e460207a624b3e243e4a3665737d436d08c We need to add, remove or modify parent pointer attributes during create/link/unlink/rename operations atomically with the dirents in the parent directories being modified. This means they need to be modified in the same transaction as the parent directories, and so we need to add the required space for the attribute modifications to the transaction reservations. Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson [djwong: fix indentation errors] Signed-off-by: Darrick J. Wong --- libxfs/libxfs_priv.h | 1 libxfs/xfs_trans_resv.c | 322 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 271 insertions(+), 52 deletions(-) diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 567bd237..9dec26f9 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -521,6 +521,7 @@ static inline int retzero(void) { return 0; } #define xfs_icreate_log(tp, agno, agbno, cnt, isize, len, gen) ((void) 0) #define xfs_sb_validate_fsb_count(sbp, nblks) (0) +#define xlog_calc_iovec_len(len) roundup(len, sizeof(uint32_t)) /* * Prototypes for kernel static functions that are aren't in their diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c index 04c44480..50315738 100644 --- a/libxfs/xfs_trans_resv.c +++ b/libxfs/xfs_trans_resv.c @@ -18,6 +18,7 @@ #include "xfs_trans.h" #include "xfs_trans_space.h" #include "xfs_quota_defs.h" +#include "xfs_da_format.h" #define _ALLOC true #define _FREE false @@ -419,29 +420,108 @@ xfs_calc_itruncate_reservation_minlogsize( return xfs_calc_itruncate_reservation(mp, true); } +static inline unsigned int xfs_calc_pptr_link_overhead(void) +{ + return sizeof(struct xfs_attri_log_format) + + xlog_calc_iovec_len(XATTR_NAME_MAX) + + xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec)); +} +static inline unsigned int xfs_calc_pptr_unlink_overhead(void) +{ + return sizeof(struct xfs_attri_log_format) + + xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec)); +} +static inline unsigned int xfs_calc_pptr_replace_overhead(void) +{ + return sizeof(struct xfs_attri_log_format) + + xlog_calc_iovec_len(XATTR_NAME_MAX) + + xlog_calc_iovec_len(XATTR_NAME_MAX) + + xlog_calc_iovec_len(sizeof(struct xfs_parent_name_rec)); +} + /* * In renaming a files we can modify: * the five inodes involved: 5 * inode size * the two directory btrees: 2 * (max depth + v2) * dir block size * the two directory bmap btrees: 2 * max depth * block size * And the bmap_finish transaction can free dir and bmap blocks (two sets - * of bmap blocks) giving: + * of bmap blocks) giving (t2): * the agf for the ags in which the blocks live: 3 * sector size * the agfl for the ags in which the blocks live: 3 * sector size * the superblock for the free block count: sector size * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size + * If parent pointers are enabled (t3), then each transaction in the chain + * must be capable of setting or removing the extended attribute + * containing the parent information. It must also be able to handle + * the three xattr intent items that track the progress of the parent + * pointer update. */ STATIC uint xfs_calc_rename_reservation( struct xfs_mount *mp) { - return XFS_DQUOT_LOGRES(mp) + - max((xfs_calc_inode_res(mp, 5) + - xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), - XFS_FSB_TO_B(mp, 1))), - (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_block_count(mp, 3), - XFS_FSB_TO_B(mp, 1)))); + unsigned int overhead = XFS_DQUOT_LOGRES(mp); + struct xfs_trans_resv *resp = M_RES(mp); + unsigned int t1, t2, t3 = 0; + + t1 = xfs_calc_inode_res(mp, 5) + + xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), + XFS_FSB_TO_B(mp, 1)); + + t2 = xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(xfs_allocfree_block_count(mp, 3), + XFS_FSB_TO_B(mp, 1)); + + if (xfs_has_parent(mp)) { + unsigned int rename_overhead, exchange_overhead; + + t3 = max(resp->tr_attrsetm.tr_logres, + resp->tr_attrrm.tr_logres); + + /* + * For a standard rename, the three xattr intent log items + * are (1) replacing the pptr for the source file; (2) + * removing the pptr on the dest file; and (3) adding a + * pptr for the whiteout file in the src dir. + * + * For an RENAME_EXCHANGE, there are two xattr intent + * items to replace the pptr for both src and dest + * files. Link counts don't change and there is no + * whiteout. + * + * In the worst case we can end up relogging all log + * intent items to allow the log tail to move ahead, so + * they become overhead added to each transaction in a + * processing chain. + */ + rename_overhead = xfs_calc_pptr_replace_overhead() + + xfs_calc_pptr_unlink_overhead() + + xfs_calc_pptr_link_overhead(); + exchange_overhead = 2 * xfs_calc_pptr_replace_overhead(); + + overhead += max(rename_overhead, exchange_overhead); + } + + return overhead + max3(t1, t2, t3); +} + +static inline unsigned int +xfs_rename_log_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + /* One for the rename, one more for freeing blocks */ + unsigned int ret = XFS_RENAME_LOG_COUNT; + + /* + * Pre-reserve enough log reservation to handle the transaction + * rolling needed to remove or add one parent pointer. + */ + if (xfs_has_parent(mp)) + ret += max(resp->tr_attrsetm.tr_logcount, + resp->tr_attrrm.tr_logcount); + + return ret; } /* @@ -458,6 +538,23 @@ xfs_calc_iunlink_remove_reservation( 2 * M_IGEO(mp)->inode_cluster_size; } +static inline unsigned int +xfs_link_log_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + unsigned int ret = XFS_LINK_LOG_COUNT; + + /* + * Pre-reserve enough log reservation to handle the transaction + * rolling needed to add one parent pointer. + */ + if (xfs_has_parent(mp)) + ret += resp->tr_attrsetm.tr_logcount; + + return ret; +} + /* * For creating a link to an inode: * the parent directory inode: inode size @@ -474,14 +571,23 @@ STATIC uint xfs_calc_link_reservation( struct xfs_mount *mp) { - return XFS_DQUOT_LOGRES(mp) + - xfs_calc_iunlink_remove_reservation(mp) + - max((xfs_calc_inode_res(mp, 2) + - xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), - XFS_FSB_TO_B(mp, 1))), - (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1), - XFS_FSB_TO_B(mp, 1)))); + unsigned int overhead = XFS_DQUOT_LOGRES(mp); + struct xfs_trans_resv *resp = M_RES(mp); + unsigned int t1, t2, t3 = 0; + + overhead += xfs_calc_iunlink_remove_reservation(mp); + t1 = xfs_calc_inode_res(mp, 2) + + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)); + t2 = xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(xfs_allocfree_block_count(mp, 1), + XFS_FSB_TO_B(mp, 1)); + + if (xfs_has_parent(mp)) { + t3 = resp->tr_attrsetm.tr_logres; + overhead += xfs_calc_pptr_link_overhead(); + } + + return overhead + max3(t1, t2, t3); } /* @@ -496,6 +602,23 @@ xfs_calc_iunlink_add_reservation(xfs_mount_t *mp) M_IGEO(mp)->inode_cluster_size; } +static inline unsigned int +xfs_remove_log_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + unsigned int ret = XFS_REMOVE_LOG_COUNT; + + /* + * Pre-reserve enough log reservation to handle the transaction + * rolling needed to add one parent pointer. + */ + if (xfs_has_parent(mp)) + ret += resp->tr_attrrm.tr_logcount; + + return ret; +} + /* * For removing a directory entry we can modify: * the parent directory inode: inode size @@ -512,14 +635,24 @@ STATIC uint xfs_calc_remove_reservation( struct xfs_mount *mp) { - return XFS_DQUOT_LOGRES(mp) + - xfs_calc_iunlink_add_reservation(mp) + - max((xfs_calc_inode_res(mp, 2) + - xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), - XFS_FSB_TO_B(mp, 1))), - (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_block_count(mp, 2), - XFS_FSB_TO_B(mp, 1)))); + unsigned int overhead = XFS_DQUOT_LOGRES(mp); + struct xfs_trans_resv *resp = M_RES(mp); + unsigned int t1, t2, t3 = 0; + + overhead += xfs_calc_iunlink_add_reservation(mp); + + t1 = xfs_calc_inode_res(mp, 2) + + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)); + t2 = xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(xfs_allocfree_block_count(mp, 2), + XFS_FSB_TO_B(mp, 1)); + + if (xfs_has_parent(mp)) { + t3 = resp->tr_attrrm.tr_logres; + overhead += xfs_calc_pptr_unlink_overhead(); + } + + return overhead + max3(t1, t2, t3); } /* @@ -568,12 +701,40 @@ xfs_calc_icreate_resv_alloc( xfs_calc_finobt_res(mp); } +static inline unsigned int +xfs_icreate_log_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + unsigned int ret = XFS_CREATE_LOG_COUNT; + + /* + * Pre-reserve enough log reservation to handle the transaction + * rolling needed to add one parent pointer. + */ + if (xfs_has_parent(mp)) + ret += resp->tr_attrsetm.tr_logcount; + + return ret; +} + STATIC uint -xfs_calc_icreate_reservation(xfs_mount_t *mp) +xfs_calc_icreate_reservation( + struct xfs_mount *mp) { - return XFS_DQUOT_LOGRES(mp) + - max(xfs_calc_icreate_resv_alloc(mp), - xfs_calc_create_resv_modify(mp)); + struct xfs_trans_resv *resp = M_RES(mp); + unsigned int overhead = XFS_DQUOT_LOGRES(mp); + unsigned int t1, t2, t3 = 0; + + t1 = xfs_calc_icreate_resv_alloc(mp); + t2 = xfs_calc_create_resv_modify(mp); + + if (xfs_has_parent(mp)) { + t3 = resp->tr_attrsetm.tr_logres; + overhead += xfs_calc_pptr_link_overhead(); + } + + return overhead + max3(t1, t2, t3); } STATIC uint @@ -586,6 +747,23 @@ xfs_calc_create_tmpfile_reservation( return res + xfs_calc_iunlink_add_reservation(mp); } +static inline unsigned int +xfs_mkdir_log_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + unsigned int ret = XFS_MKDIR_LOG_COUNT; + + /* + * Pre-reserve enough log reservation to handle the transaction + * rolling needed to add one parent pointer. + */ + if (xfs_has_parent(mp)) + ret += resp->tr_attrsetm.tr_logcount; + + return ret; +} + /* * Making a new directory is the same as creating a new file. */ @@ -596,6 +774,22 @@ xfs_calc_mkdir_reservation( return xfs_calc_icreate_reservation(mp); } +static inline unsigned int +xfs_symlink_log_count( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + unsigned int ret = XFS_SYMLINK_LOG_COUNT; + + /* + * Pre-reserve enough log reservation to handle the transaction + * rolling needed to add one parent pointer. + */ + if (xfs_has_parent(mp)) + ret += resp->tr_attrsetm.tr_logcount; + + return ret; +} /* * Making a new symplink is the same as creating a new file, but @@ -908,6 +1102,52 @@ xfs_calc_sb_reservation( return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); } +/* + * Namespace reservations. + * + * These get tricky when parent pointers are enabled as we have attribute + * modifications occurring from within these transactions. Rather than confuse + * each of these reservation calculations with the conditional attribute + * reservations, add them here in a clear and concise manner. This requires that + * the attribute reservations have already been calculated. + * + * Note that we only include the static attribute reservation here; the runtime + * reservation will have to be modified by the size of the attributes being + * added/removed/modified. See the comments on the attribute reservation + * calculations for more details. + */ +STATIC void +xfs_calc_namespace_reservations( + struct xfs_mount *mp, + struct xfs_trans_resv *resp) +{ + ASSERT(resp->tr_attrsetm.tr_logres > 0); + + resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp); + resp->tr_rename.tr_logcount = xfs_rename_log_count(mp, resp); + resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_link.tr_logres = xfs_calc_link_reservation(mp); + resp->tr_link.tr_logcount = xfs_link_log_count(mp, resp); + resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp); + resp->tr_remove.tr_logcount = xfs_remove_log_count(mp, resp); + resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp); + resp->tr_symlink.tr_logcount = xfs_symlink_log_count(mp, resp); + resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp); + resp->tr_create.tr_logcount = xfs_icreate_log_count(mp, resp); + resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + + resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp); + resp->tr_mkdir.tr_logcount = xfs_mkdir_log_count(mp, resp); + resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES; +} + void xfs_trans_resv_calc( struct xfs_mount *mp, @@ -927,35 +1167,11 @@ xfs_trans_resv_calc( resp->tr_itruncate.tr_logcount = XFS_ITRUNCATE_LOG_COUNT; resp->tr_itruncate.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - resp->tr_rename.tr_logres = xfs_calc_rename_reservation(mp); - resp->tr_rename.tr_logcount = XFS_RENAME_LOG_COUNT; - resp->tr_rename.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - - resp->tr_link.tr_logres = xfs_calc_link_reservation(mp); - resp->tr_link.tr_logcount = XFS_LINK_LOG_COUNT; - resp->tr_link.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - - resp->tr_remove.tr_logres = xfs_calc_remove_reservation(mp); - resp->tr_remove.tr_logcount = XFS_REMOVE_LOG_COUNT; - resp->tr_remove.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - - resp->tr_symlink.tr_logres = xfs_calc_symlink_reservation(mp); - resp->tr_symlink.tr_logcount = XFS_SYMLINK_LOG_COUNT; - resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - - resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp); - resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT; - resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - resp->tr_create_tmpfile.tr_logres = xfs_calc_create_tmpfile_reservation(mp); resp->tr_create_tmpfile.tr_logcount = XFS_CREATE_TMPFILE_LOG_COUNT; resp->tr_create_tmpfile.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp); - resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT; - resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES; - resp->tr_ifree.tr_logres = xfs_calc_ifree_reservation(mp); resp->tr_ifree.tr_logcount = XFS_INACTIVE_LOG_COUNT; resp->tr_ifree.tr_logflags |= XFS_TRANS_PERM_LOG_RES; @@ -985,6 +1201,8 @@ xfs_trans_resv_calc( resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT; resp->tr_qm_dqalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + xfs_calc_namespace_reservations(mp, resp); + /* * The following transactions are logged in logical format with * a default log count. From patchwork Thu Feb 16 20:56:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143871 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54B85C636CC for ; Thu, 16 Feb 2023 20:56:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229923AbjBPU40 (ORCPT ); Thu, 16 Feb 2023 15:56:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229906AbjBPU4Z (ORCPT ); Thu, 16 Feb 2023 15:56:25 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 238644E5C5 for ; Thu, 16 Feb 2023 12:56:24 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id B214C60A55 for ; Thu, 16 Feb 2023 20:56:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 19C11C433EF; Thu, 16 Feb 2023 20:56:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580983; bh=EnGRM37QchEM3xwB6ODimyMEf6Fvn1UIMqDjLRQ1I3g=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ZhuO2rb2icT2Nc7ZCxAJ8pcR7Je+pS+c93AGtIUD9bLjlufDONfO5Qqb/9fTg5QdO +UjWdGXmV//LIa4YMqjPJBfE2Lyx2zh4cv1YLTPXPYgdjVPJ6yUzveG1bD/cDpqaZ6 v3k373CISXxuh/yF0W5fYo2VEwDezMI3w9bF4jyZszL+iyTwWlJFUwLXTdp0O+Cqmn 34Q/MZgP6ur6aXDY6qjG+HSCuhrWUl61X8Lq6R1NOFSCdZ6xOoSpn7c/FXANbPsoDZ hxn8mFuuYOaByZ3W5o6/JOFayMF6EpkXCv2he3oYcHT2RcWuZ/1UIQ1WM7k2n6nsoB Rx0X15Kep6xrA== Date: Thu, 16 Feb 2023 12:56:22 -0800 Subject: [PATCH 11/25] xfsprogs: parent pointer attribute creation From: "Darrick J. Wong" To: djwong@kernel.org Cc: Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879051.3476112.8270420254403475829.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: bb5cfa7e0c8eff07c62b1a28e0a4ea1d2561e0bb Add parent pointer attribute during xfs_create, and subroutines to initialize attributes Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson [djwong: sync with kernel code] Signed-off-by: Darrick J. Wong --- libxfs/Makefile | 2 + libxfs/libxfs_priv.h | 3 + libxfs/xfs_attr.c | 4 + libxfs/xfs_attr.h | 4 + libxfs/xfs_da_format.h | 12 ---- libxfs/xfs_parent.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_parent.h | 57 ++++++++++++++++++++ 7 files changed, 206 insertions(+), 16 deletions(-) create mode 100644 libxfs/xfs_parent.c create mode 100644 libxfs/xfs_parent.h diff --git a/libxfs/Makefile b/libxfs/Makefile index 010ee68e..89d29dc9 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -45,6 +45,7 @@ HFILES = \ xfs_ialloc_btree.h \ xfs_inode_buf.h \ xfs_inode_fork.h \ + xfs_parent.h \ xfs_quota_defs.h \ xfs_refcount.h \ xfs_refcount_btree.h \ @@ -92,6 +93,7 @@ CFILES = cache.c \ xfs_inode_fork.c \ xfs_ialloc_btree.c \ xfs_log_rlimit.c \ + xfs_parent.c \ xfs_refcount.c \ xfs_refcount_btree.c \ xfs_rmap.c \ diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 9dec26f9..ad21a25d 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -614,7 +614,8 @@ int libxfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, /* xfs_log.c */ bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t); void xfs_log_item_init(struct xfs_mount *, struct xfs_log_item *, int); -#define xfs_attr_use_log_assist(mp) (0) +#define xfs_attr_grab_log_assist(mp) (0) +#define xfs_attr_rele_log_assist(mp) ((void) 0) #define xlog_drop_incompat_feat(log) do { } while (0) #define xfs_log_in_recovery(mp) (false) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index d5f1f488..edf7e1ee 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -884,7 +884,7 @@ xfs_attr_lookup( return error; } -static int +int xfs_attr_intent_init( struct xfs_da_args *args, unsigned int op_flags, /* op flag (set or remove) */ @@ -902,7 +902,7 @@ xfs_attr_intent_init( } /* Sets an attribute for an inode as a deferred operation */ -static int +int xfs_attr_defer_add( struct xfs_da_args *args) { diff --git a/libxfs/xfs_attr.h b/libxfs/xfs_attr.h index b79dae78..0cf23f51 100644 --- a/libxfs/xfs_attr.h +++ b/libxfs/xfs_attr.h @@ -544,6 +544,7 @@ int xfs_inode_hasattr(struct xfs_inode *ip); bool xfs_attr_is_leaf(struct xfs_inode *ip); int xfs_attr_get_ilocked(struct xfs_da_args *args); int xfs_attr_get(struct xfs_da_args *args); +int xfs_attr_defer_add(struct xfs_da_args *args); int xfs_attr_set(struct xfs_da_args *args); int xfs_attr_set_iter(struct xfs_attr_intent *attr); int xfs_attr_remove_iter(struct xfs_attr_intent *attr); @@ -552,7 +553,8 @@ bool xfs_attr_namecheck(struct xfs_mount *mp, const void *name, size_t length, int xfs_attr_calc_size(struct xfs_da_args *args, int *local); void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres, unsigned int *total); - +int xfs_attr_intent_init(struct xfs_da_args *args, unsigned int op_flags, + struct xfs_attr_intent **attr); /* * Check to see if the attr should be upgraded from non-existent or shortform to * single-leaf-block attribute list. diff --git a/libxfs/xfs_da_format.h b/libxfs/xfs_da_format.h index 75b13807..2db1cf97 100644 --- a/libxfs/xfs_da_format.h +++ b/libxfs/xfs_da_format.h @@ -826,16 +826,4 @@ struct xfs_parent_name_rec { __be32 p_diroffset; }; -/* - * incore version of the above, also contains name pointers so callers - * can pass/obtain all the parent pointer information in a single structure - */ -struct xfs_parent_name_irec { - xfs_ino_t p_ino; - uint32_t p_gen; - xfs_dir2_dataptr_t p_diroffset; - const char *p_name; - uint8_t p_namelen; -}; - #endif /* __XFS_DA_FORMAT_H__ */ diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c new file mode 100644 index 00000000..e0a59998 --- /dev/null +++ b/libxfs/xfs_parent.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Oracle, Inc. + * All rights reserved. + */ +#include "libxfs_priv.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_mount.h" +#include "xfs_inode.h" +#include "xfs_trans_resv.h" +#include "xfs_mount.h" +#include "xfs_trace.h" +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_da_format.h" +#include "xfs_bmap_btree.h" +#include "xfs_trans.h" +#include "xfs_da_btree.h" +#include "xfs_attr.h" +#include "xfs_da_btree.h" +#include "xfs_attr_sf.h" +#include "xfs_bmap.h" +#include "xfs_parent.h" +#include "xfs_da_format.h" +#include "xfs_format.h" +#include "xfs_trans_space.h" + +struct kmem_cache *xfs_parent_intent_cache; + +/* + * Parent pointer attribute handling. + * + * Because the attribute value is a filename component, it will never be longer + * than 255 bytes. This means the attribute will always be a local format + * attribute as it is xfs_attr_leaf_entsize_local_max() for v5 filesystems will + * always be larger than this (max is 75% of block size). + * + * Creating a new parent attribute will always create a new attribute - there + * should never, ever be an existing attribute in the tree for a new inode. + * ENOSPC behavior is problematic - creating the inode without the parent + * pointer is effectively a corruption, so we allow parent attribute creation + * to dip into the reserve block pool to avoid unexpected ENOSPC errors from + * occurring. + */ + + +/* Initializes a xfs_parent_name_rec to be stored as an attribute name */ +void +xfs_init_parent_name_rec( + struct xfs_parent_name_rec *rec, + struct xfs_inode *ip, + uint32_t p_diroffset) +{ + xfs_ino_t p_ino = ip->i_ino; + uint32_t p_gen = VFS_I(ip)->i_generation; + + rec->p_ino = cpu_to_be64(p_ino); + rec->p_gen = cpu_to_be32(p_gen); + rec->p_diroffset = cpu_to_be32(p_diroffset); +} + +int +__xfs_parent_init( + struct xfs_mount *mp, + struct xfs_parent_defer **parentp) +{ + struct xfs_parent_defer *parent; + int error; + + error = xfs_attr_grab_log_assist(mp); + if (error) + return error; + + parent = kmem_cache_zalloc(xfs_parent_intent_cache, GFP_KERNEL); + if (!parent) { + xfs_attr_rele_log_assist(mp); + return -ENOMEM; + } + + /* init parent da_args */ + parent->args.geo = mp->m_attr_geo; + parent->args.whichfork = XFS_ATTR_FORK; + parent->args.attr_filter = XFS_ATTR_PARENT; + parent->args.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_LOGGED; + parent->args.name = (const uint8_t *)&parent->rec; + parent->args.namelen = sizeof(struct xfs_parent_name_rec); + + *parentp = parent; + return 0; +} + +int +xfs_parent_defer_add( + struct xfs_trans *tp, + struct xfs_parent_defer *parent, + struct xfs_inode *dp, + struct xfs_name *parent_name, + xfs_dir2_dataptr_t diroffset, + struct xfs_inode *child) +{ + struct xfs_da_args *args = &parent->args; + + xfs_init_parent_name_rec(&parent->rec, dp, diroffset); + args->hashval = xfs_da_hashname(args->name, args->namelen); + + args->trans = tp; + args->dp = child; + if (parent_name) { + parent->args.value = (void *)parent_name->name; + parent->args.valuelen = parent_name->len; + } + + return xfs_attr_defer_add(args); +} + +void +__xfs_parent_cancel( + xfs_mount_t *mp, + struct xfs_parent_defer *parent) +{ + xlog_drop_incompat_feat(mp->m_log); + kmem_cache_free(xfs_parent_intent_cache, parent); +} + +unsigned int +xfs_pptr_calc_space_res( + struct xfs_mount *mp, + unsigned int namelen) +{ + /* + * Pptrs are always the first attr in an attr tree, and never larger + * than a block + */ + return XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK) + + XFS_NEXTENTADD_SPACE_RES(mp, namelen, XFS_ATTR_FORK); +} + diff --git a/libxfs/xfs_parent.h b/libxfs/xfs_parent.h new file mode 100644 index 00000000..d5a8c8e5 --- /dev/null +++ b/libxfs/xfs_parent.h @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Oracle, Inc. + * All Rights Reserved. + */ +#ifndef __XFS_PARENT_H__ +#define __XFS_PARENT_H__ + +extern struct kmem_cache *xfs_parent_intent_cache; + +/* + * Dynamically allocd structure used to wrap the needed data to pass around + * the defer ops machinery + */ +struct xfs_parent_defer { + struct xfs_parent_name_rec rec; + struct xfs_da_args args; +}; + +/* + * Parent pointer attribute prototypes + */ +void xfs_init_parent_name_rec(struct xfs_parent_name_rec *rec, + struct xfs_inode *ip, + uint32_t p_diroffset); +int __xfs_parent_init(struct xfs_mount *mp, struct xfs_parent_defer **parentp); + +static inline int +xfs_parent_start( + struct xfs_mount *mp, + struct xfs_parent_defer **pp) +{ + *pp = NULL; + + if (xfs_has_parent(mp)) + return __xfs_parent_init(mp, pp); + return 0; +} + +int xfs_parent_defer_add(struct xfs_trans *tp, struct xfs_parent_defer *parent, + struct xfs_inode *dp, struct xfs_name *parent_name, + xfs_dir2_dataptr_t diroffset, struct xfs_inode *child); +void __xfs_parent_cancel(struct xfs_mount *mp, struct xfs_parent_defer *parent); + +static inline void +xfs_parent_finish( + struct xfs_mount *mp, + struct xfs_parent_defer *p) +{ + if (p) + __xfs_parent_cancel(mp, p); +} + +unsigned int xfs_pptr_calc_space_res(struct xfs_mount *mp, + unsigned int namelen); + +#endif /* __XFS_PARENT_H__ */ From patchwork Thu Feb 16 20:56:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143872 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E382C636CC for ; Thu, 16 Feb 2023 20:56:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229906AbjBPU4l (ORCPT ); Thu, 16 Feb 2023 15:56:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34198 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229935AbjBPU4k (ORCPT ); Thu, 16 Feb 2023 15:56:40 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCF804D606 for ; Thu, 16 Feb 2023 12:56:39 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 584F160C20 for ; Thu, 16 Feb 2023 20:56:39 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B20B5C433D2; Thu, 16 Feb 2023 20:56:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676580998; bh=qfyM6y5bq45+QteprUZIwQskwprkqtd8M0Tj7SFLDds=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=QyH7+P5RBDwNiHQqNjmL8EXPT+eW7s0ybmemi8n88VYV0JzgquCh6bUy1ocXyMDom Wh+tn9gjvAlPLre4hf5SUSyKCWuQmpU9PYdDvgC7XCpjT+f4zkaAAUlL25IkCjlb9l zztec5kyFu63OPE2oVyxDxre1mpdJWjWaeLLoRJ01rwa89bXnh7VthFInNNUy5olRw 12ealfD4yXbUmexaVfx2cyoUR6ouJLH7VgJ+u4+DXEzKat0ZlPPlgHPfEKQ7Qa0s5D w7fpeDgAzc/xHT9QPDEGN4ObytkoOUhoyoZHc9EBMMEg/OKutvbJZz/0dkBvhuSsHl 6aRbksIcTDgiA== Date: Thu, 16 Feb 2023 12:56:38 -0800 Subject: [PATCH 12/25] xfsprogs: add parent attributes to link From: "Darrick J. Wong" To: djwong@kernel.org Cc: Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879065.3476112.7980816751548942388.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson This patch modifies xfs_link to add a parent pointer to the inode. Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- libxfs/xfs_trans_space.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h index 87b31c69..f7220792 100644 --- a/libxfs/xfs_trans_space.h +++ b/libxfs/xfs_trans_space.h @@ -84,8 +84,6 @@ (2 * (mp)->m_alloc_maxlevels) #define XFS_GROWFSRT_SPACE_RES(mp,b) \ ((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK)) -#define XFS_LINK_SPACE_RES(mp,nl) \ - XFS_DIRENTER_SPACE_RES(mp,nl) #define XFS_MKDIR_SPACE_RES(mp,nl) \ (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_QM_DQALLOC_SPACE_RES(mp) \ From patchwork Thu Feb 16 20:56:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143873 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FC09C636CC for ; Thu, 16 Feb 2023 20:57:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229955AbjBPU5E (ORCPT ); Thu, 16 Feb 2023 15:57:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34596 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229960AbjBPU5D (ORCPT ); Thu, 16 Feb 2023 15:57:03 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AA965034B for ; Thu, 16 Feb 2023 12:56:55 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 06AB160B42 for ; Thu, 16 Feb 2023 20:56:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 67E0DC433EF; Thu, 16 Feb 2023 20:56:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581014; bh=VtdOvAar+LlFzjfI4PucUHHS/smwnawW8hlc3QUw86Q=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=oXYHuVgVR5qruCBoH0x02UJuGaWvaYy441BvzDIJdpXCkEiT9INODhby2h1Q3als/ KJBidTxc2kSH7iLYHvy8GDH04ju1MDHEEHnyIM6uETRH4rLxZ39gFSlPIYDBUjnJMI IEycqk+k2a3WHqpD9w/TlAXOtnOX/AU5cUTXUfYueTAG4tpTvaQYS9C5LDDjCxKvBU 2QzS/HH++qnHTmvobmft6gbO4CvsEtDC2021xJkhd8f2YfEaR8dLlUdtwUNPcwnhvI uLCbzwkODE/61I5wnSPlNeNIwL3wnyLmyyfZv0VYm+n4kYaYC74OmTbMyIaDdFbWb8 pYaUheWZ4xUCw== Date: Thu, 16 Feb 2023 12:56:53 -0800 Subject: [PATCH 13/25] xfsprogs: add parent attributes to symlink From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879079.3476112.4128801881562451403.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson This patch modifies xfs_symlink to add a parent pointer to the inode. Signed-off-by: Allison Henderson --- libxfs/xfs_trans_space.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h index f7220792..25a55650 100644 --- a/libxfs/xfs_trans_space.h +++ b/libxfs/xfs_trans_space.h @@ -95,8 +95,6 @@ XFS_DIRREMOVE_SPACE_RES(mp) #define XFS_RENAME_SPACE_RES(mp,nl) \ (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) -#define XFS_SYMLINK_SPACE_RES(mp,nl,b) \ - (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b)) #define XFS_IFREE_SPACE_RES(mp) \ (xfs_has_finobt(mp) ? M_IGEO(mp)->inobt_maxlevels : 0) From patchwork Thu Feb 16 20:57:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143874 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1CEC3C61DA4 for ; Thu, 16 Feb 2023 20:57:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229960AbjBPU5S (ORCPT ); Thu, 16 Feb 2023 15:57:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34754 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229884AbjBPU5R (ORCPT ); Thu, 16 Feb 2023 15:57:17 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 175B2521FD for ; Thu, 16 Feb 2023 12:57:11 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A3BDB60A55 for ; Thu, 16 Feb 2023 20:57:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0CB3AC433D2; Thu, 16 Feb 2023 20:57:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581030; bh=TDYCZVurn5Mzd4DlgIE9Nf4jwyCApIFlsyh17exO6zU=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=o83zc6r2ewWZ95MAHXnq5eb44HyXN0HQ/WX57mVdievC3MD4nzVjGHxgUKY3KRBB1 iV0gw7Qe49as7VK7bf3rCiqIUxcW0yx9QYbG2CoY0+G10CGtmsUC5vME3Uqw+TjN9a Y+uCutq6t7MBxxebrArctbcci8wwxoZqTkziSrA9IBo6UE2XH2RrB/3EqXOEnUNSeT pBNbjdTYouIwekviybDmkIie+qN1XPzeNT2fQn+Ax4Nj97e4y5oUeP54cilmR+2pLH 2idsf4Aq8GC7fmNTZ1ixYcW5CW6VdIv/A3fqHWqJgWteZvJrEWn2TmQL6kBzVKVtgW A8GgS0HQ9uKVQ== Date: Thu, 16 Feb 2023 12:57:09 -0800 Subject: [PATCH 14/25] xfsprogs: remove parent pointers in unlink From: "Darrick J. Wong" To: djwong@kernel.org Cc: Dave Chinner , Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879093.3476112.7527681927685399317.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: b9ffc3d05531820aea30b2caf3368c312d8b2508 This patch removes the parent pointer attribute during unlink Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- libxfs/xfs_attr.c | 2 +- libxfs/xfs_attr.h | 1 + libxfs/xfs_parent.c | 17 +++++++++++++++++ libxfs/xfs_parent.h | 5 +++++ libxfs/xfs_trans_space.h | 2 -- repair/phase6.c | 6 +++--- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index edf7e1ee..04cafc5f 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -944,7 +944,7 @@ xfs_attr_defer_replace( } /* Removes an attribute for an inode as a deferred operation */ -static int +int xfs_attr_defer_remove( struct xfs_da_args *args) { diff --git a/libxfs/xfs_attr.h b/libxfs/xfs_attr.h index 0cf23f51..03300554 100644 --- a/libxfs/xfs_attr.h +++ b/libxfs/xfs_attr.h @@ -545,6 +545,7 @@ bool xfs_attr_is_leaf(struct xfs_inode *ip); int xfs_attr_get_ilocked(struct xfs_da_args *args); int xfs_attr_get(struct xfs_da_args *args); int xfs_attr_defer_add(struct xfs_da_args *args); +int xfs_attr_defer_remove(struct xfs_da_args *args); int xfs_attr_set(struct xfs_da_args *args); int xfs_attr_set_iter(struct xfs_attr_intent *attr); int xfs_attr_remove_iter(struct xfs_attr_intent *attr); diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c index e0a59998..b137cfda 100644 --- a/libxfs/xfs_parent.c +++ b/libxfs/xfs_parent.c @@ -116,6 +116,23 @@ xfs_parent_defer_add( return xfs_attr_defer_add(args); } +int +xfs_parent_defer_remove( + struct xfs_trans *tp, + struct xfs_inode *dp, + struct xfs_parent_defer *parent, + xfs_dir2_dataptr_t diroffset, + struct xfs_inode *child) +{ + struct xfs_da_args *args = &parent->args; + + xfs_init_parent_name_rec(&parent->rec, dp, diroffset); + args->trans = tp; + args->dp = child; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return xfs_attr_defer_remove(args); +} + void __xfs_parent_cancel( xfs_mount_t *mp, diff --git a/libxfs/xfs_parent.h b/libxfs/xfs_parent.h index d5a8c8e5..0f39d033 100644 --- a/libxfs/xfs_parent.h +++ b/libxfs/xfs_parent.h @@ -40,6 +40,11 @@ xfs_parent_start( int xfs_parent_defer_add(struct xfs_trans *tp, struct xfs_parent_defer *parent, struct xfs_inode *dp, struct xfs_name *parent_name, xfs_dir2_dataptr_t diroffset, struct xfs_inode *child); +int xfs_parent_defer_remove(struct xfs_trans *tp, struct xfs_inode *dp, + struct xfs_parent_defer *parent, + xfs_dir2_dataptr_t diroffset, + struct xfs_inode *child); + void __xfs_parent_cancel(struct xfs_mount *mp, struct xfs_parent_defer *parent); static inline void diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h index 25a55650..b5ab6701 100644 --- a/libxfs/xfs_trans_space.h +++ b/libxfs/xfs_trans_space.h @@ -91,8 +91,6 @@ XFS_DQUOT_CLUSTER_SIZE_FSB) #define XFS_QM_QINOCREATE_SPACE_RES(mp) \ XFS_IALLOC_SPACE_RES(mp) -#define XFS_REMOVE_SPACE_RES(mp) \ - XFS_DIRREMOVE_SPACE_RES(mp) #define XFS_RENAME_SPACE_RES(mp,nl) \ (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_IFREE_SPACE_RES(mp) \ diff --git a/repair/phase6.c b/repair/phase6.c index a347c390..e202398e 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1266,7 +1266,7 @@ longform_dir2_rebuild( libxfs_dir_ino_validate(mp, pip.i_ino)) pip.i_ino = mp->m_sb.sb_rootino; - nres = XFS_REMOVE_SPACE_RES(mp); + nres = XFS_DIRREMOVE_SPACE_RES(mp); error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp); if (error) res_failed(error); @@ -1371,7 +1371,7 @@ dir2_kill_block( int nres; xfs_trans_t *tp; - nres = XFS_REMOVE_SPACE_RES(mp); + nres = XFS_DIRREMOVE_SPACE_RES(mp); error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp); if (error) res_failed(error); @@ -2887,7 +2887,7 @@ process_dir_inode( * inode but it's easier than wedging a * new define in ourselves. */ - nres = no_modify ? 0 : XFS_REMOVE_SPACE_RES(mp); + nres = no_modify ? 0 : XFS_DIRREMOVE_SPACE_RES(mp); error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove, nres, 0, 0, &tp); if (error) From patchwork Thu Feb 16 20:57:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143875 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D21C4C636D7 for ; Thu, 16 Feb 2023 20:57:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229658AbjBPU5a (ORCPT ); Thu, 16 Feb 2023 15:57:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229715AbjBPU53 (ORCPT ); Thu, 16 Feb 2023 15:57:29 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3FDF850348 for ; Thu, 16 Feb 2023 12:57:28 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id E633CB82958 for ; Thu, 16 Feb 2023 20:57:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A827EC433EF; Thu, 16 Feb 2023 20:57:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581045; bh=+m0D2ZL7wlIhJ6e7oP7v1yDjOx/fw4Tavc8rO8O//Y0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=tKyy5/0tjZNcGOY7nw29xhjy/AWj4s+ErwMPu2KjNymufd9JsMdyT7ZnZ7678cHB+ MiKAo9ov86PGCQUG1uJEGIh2ApfRWBchi/me+m1r0fsFyli2oPbtqZ1AkQPQimml9j EowxrnyMAXD2dNNTa5BDegMMonKtwLsQzmblVdbCPFzaF2/FUAynSqOUbmrXm5bIIf s6iNlZjQrOH9/ZBQtQ7OdRlxQWzZL94acYmbdrIuYZef5RZm5wj+c1nyTklJgIOilH u6e5wzUmlfKbIVEkL8nKT0Fq6nweASsimiZaeZDYO9kIPOixxm0D7B+EKwh8R7L44f 0ang4LWSh72iQ== Date: Thu, 16 Feb 2023 12:57:25 -0800 Subject: [PATCH 15/25] xfsprogs: Add parent pointers to rename From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879108.3476112.8331830884740886775.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson This patch removes the old parent pointer attribute during the rename operation, and re-adds the updated parent pointer. In the case of xfs_cross_rename, we modify the routine not to roll the transaction just yet. We will do this after the parent pointer is added in the calling xfs_rename function. Source kernel commit: d00721b30fd1923f6e9e9c1ca6f2a74cfc4ed5d3 Signed-off-by: Allison Henderson [djwong: fix indent with kernel] Signed-off-by: Darrick J. Wong --- libxfs/xfs_attr.c | 2 +- libxfs/xfs_attr.h | 1 + libxfs/xfs_parent.c | 47 +++++++++++++++++++++++++++++++++++++++++----- libxfs/xfs_parent.h | 24 ++++++++++++++++++++++- libxfs/xfs_trans_space.h | 2 -- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 04cafc5f..0cb76f8f 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -921,7 +921,7 @@ xfs_attr_defer_add( } /* Sets an attribute for an inode as a deferred operation */ -static int +int xfs_attr_defer_replace( struct xfs_da_args *args) { diff --git a/libxfs/xfs_attr.h b/libxfs/xfs_attr.h index 03300554..98576126 100644 --- a/libxfs/xfs_attr.h +++ b/libxfs/xfs_attr.h @@ -546,6 +546,7 @@ int xfs_attr_get_ilocked(struct xfs_da_args *args); int xfs_attr_get(struct xfs_da_args *args); int xfs_attr_defer_add(struct xfs_da_args *args); int xfs_attr_defer_remove(struct xfs_da_args *args); +int xfs_attr_defer_replace(struct xfs_da_args *args); int xfs_attr_set(struct xfs_da_args *args); int xfs_attr_set_iter(struct xfs_attr_intent *attr); int xfs_attr_remove_iter(struct xfs_attr_intent *attr); diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c index b137cfda..3f02271f 100644 --- a/libxfs/xfs_parent.c +++ b/libxfs/xfs_parent.c @@ -65,22 +65,27 @@ xfs_init_parent_name_rec( int __xfs_parent_init( struct xfs_mount *mp, + bool grab_log, struct xfs_parent_defer **parentp) { struct xfs_parent_defer *parent; int error; - error = xfs_attr_grab_log_assist(mp); - if (error) - return error; + if (grab_log) { + error = xfs_attr_grab_log_assist(mp); + if (error) + return error; + } parent = kmem_cache_zalloc(xfs_parent_intent_cache, GFP_KERNEL); if (!parent) { - xfs_attr_rele_log_assist(mp); + if (grab_log) + xfs_attr_rele_log_assist(mp); return -ENOMEM; } /* init parent da_args */ + parent->have_log = grab_log; parent->args.geo = mp->m_attr_geo; parent->args.whichfork = XFS_ATTR_FORK; parent->args.attr_filter = XFS_ATTR_PARENT; @@ -133,12 +138,44 @@ xfs_parent_defer_remove( return xfs_attr_defer_remove(args); } + +int +xfs_parent_defer_replace( + struct xfs_trans *tp, + struct xfs_parent_defer *new_parent, + struct xfs_inode *old_dp, + xfs_dir2_dataptr_t old_diroffset, + struct xfs_name *parent_name, + struct xfs_inode *new_dp, + xfs_dir2_dataptr_t new_diroffset, + struct xfs_inode *child) +{ + struct xfs_da_args *args = &new_parent->args; + + xfs_init_parent_name_rec(&new_parent->old_rec, old_dp, old_diroffset); + xfs_init_parent_name_rec(&new_parent->rec, new_dp, new_diroffset); + new_parent->args.name = (const uint8_t *)&new_parent->old_rec; + new_parent->args.namelen = sizeof(struct xfs_parent_name_rec); + new_parent->args.new_name = (const uint8_t *)&new_parent->rec; + new_parent->args.new_namelen = sizeof(struct xfs_parent_name_rec); + args->trans = tp; + args->dp = child; + + ASSERT(parent_name != NULL); + new_parent->args.value = (void *)parent_name->name; + new_parent->args.valuelen = parent_name->len; + + args->hashval = xfs_da_hashname(args->name, args->namelen); + return xfs_attr_defer_replace(args); +} + void __xfs_parent_cancel( xfs_mount_t *mp, struct xfs_parent_defer *parent) { - xlog_drop_incompat_feat(mp->m_log); + if (parent->have_log) + xlog_drop_incompat_feat(mp->m_log); kmem_cache_free(xfs_parent_intent_cache, parent); } diff --git a/libxfs/xfs_parent.h b/libxfs/xfs_parent.h index 0f39d033..03900588 100644 --- a/libxfs/xfs_parent.h +++ b/libxfs/xfs_parent.h @@ -14,7 +14,9 @@ extern struct kmem_cache *xfs_parent_intent_cache; */ struct xfs_parent_defer { struct xfs_parent_name_rec rec; + struct xfs_parent_name_rec old_rec; struct xfs_da_args args; + bool have_log; }; /* @@ -23,7 +25,8 @@ struct xfs_parent_defer { void xfs_init_parent_name_rec(struct xfs_parent_name_rec *rec, struct xfs_inode *ip, uint32_t p_diroffset); -int __xfs_parent_init(struct xfs_mount *mp, struct xfs_parent_defer **parentp); +int __xfs_parent_init(struct xfs_mount *mp, bool grab_log, + struct xfs_parent_defer **parentp); static inline int xfs_parent_start( @@ -33,13 +36,30 @@ xfs_parent_start( *pp = NULL; if (xfs_has_parent(mp)) - return __xfs_parent_init(mp, pp); + return __xfs_parent_init(mp, true, pp); + return 0; +} + +static inline int +xfs_parent_start_locked( + struct xfs_mount *mp, + struct xfs_parent_defer **pp) +{ + *pp = NULL; + + if (xfs_has_parent(mp)) + return __xfs_parent_init(mp, false, pp); return 0; } int xfs_parent_defer_add(struct xfs_trans *tp, struct xfs_parent_defer *parent, struct xfs_inode *dp, struct xfs_name *parent_name, xfs_dir2_dataptr_t diroffset, struct xfs_inode *child); +int xfs_parent_defer_replace(struct xfs_trans *tp, + struct xfs_parent_defer *new_parent, struct xfs_inode *old_dp, + xfs_dir2_dataptr_t old_diroffset, struct xfs_name *parent_name, + struct xfs_inode *new_ip, xfs_dir2_dataptr_t new_diroffset, + struct xfs_inode *child); int xfs_parent_defer_remove(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_parent_defer *parent, xfs_dir2_dataptr_t diroffset, diff --git a/libxfs/xfs_trans_space.h b/libxfs/xfs_trans_space.h index b5ab6701..810610a1 100644 --- a/libxfs/xfs_trans_space.h +++ b/libxfs/xfs_trans_space.h @@ -91,8 +91,6 @@ XFS_DQUOT_CLUSTER_SIZE_FSB) #define XFS_QM_QINOCREATE_SPACE_RES(mp) \ XFS_IALLOC_SPACE_RES(mp) -#define XFS_RENAME_SPACE_RES(mp,nl) \ - (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) #define XFS_IFREE_SPACE_RES(mp) \ (xfs_has_finobt(mp) ? M_IGEO(mp)->inobt_maxlevels : 0) From patchwork Thu Feb 16 20:57:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143876 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 627D6C61DA4 for ; Thu, 16 Feb 2023 20:57:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229760AbjBPU5p (ORCPT ); Thu, 16 Feb 2023 15:57:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229715AbjBPU5p (ORCPT ); Thu, 16 Feb 2023 15:57:45 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E84674D606 for ; Thu, 16 Feb 2023 12:57:43 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 91192B82962 for ; Thu, 16 Feb 2023 20:57:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3BB0EC433D2; Thu, 16 Feb 2023 20:57:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581061; bh=xCdmQNGFfqXPHZIMNZgz937VJMuXEEHSkOx7Xk8VZCc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=GWDpaOjqp/fqY1AjwQ3RrZme9bHQv/dxLWaqJUhy6DJrNjxMntY+ArVrczHp7Lv/A iEEOUMsh6ZthAIhHelWkfzxQ7YAnvXBtgFhUGJS3Lr0QDoat5ejXCMqhFNUDM7X/q4 qoY2OhcrDd8Kit6iq6LGsyo4ErAby1byfrOkpev6ylvcJqCBQx+TJM0xJEwDdKKVb6 SyULXSXSnioEbLRsCqpscHTXk6ovataRFHQ3WmGgD576rKh3i9yX+qWIgdD+G3Y8wb 0tu7cuhhRvsSeyeuGyZlxWCNbOXAfuZxGzbzFkVciRE6nuGbYKB5ia/Sspdgk2bPQ5 Xz8aILCPfwb9g== Date: Thu, 16 Feb 2023 12:57:40 -0800 Subject: [PATCH 16/25] xfsprogs: Add the parent pointer support to the superblock version 5. From: "Darrick J. Wong" To: djwong@kernel.org Cc: Mark Tinguely , Dave Chinner , Allison Henderson , "Darrick J. Wong" , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879123.3476112.18429672769647602745.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: 724321b7f1c737ce880ea0e6fa4422ad13c4d440 Signed-off-by: Mark Tinguely Signed-off-by: Dave Chinner Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- libfrog/fsgeom.c | 4 ++++ libxfs/xfs_format.h | 4 +++- libxfs/xfs_fs.h | 1 + libxfs/xfs_sb.c | 4 ++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c index 3e7f0797..3bb753ac 100644 --- a/libfrog/fsgeom.c +++ b/libfrog/fsgeom.c @@ -31,6 +31,7 @@ xfs_report_geom( int bigtime_enabled; int inobtcount; int nrext64; + int parent; isint = geo->logstart > 0; lazycount = geo->flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0; @@ -49,12 +50,14 @@ xfs_report_geom( bigtime_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_BIGTIME ? 1 : 0; inobtcount = geo->flags & XFS_FSOP_GEOM_FLAGS_INOBTCNT ? 1 : 0; nrext64 = geo->flags & XFS_FSOP_GEOM_FLAGS_NREXT64 ? 1 : 0; + parent = geo->flags & XFS_FSOP_GEOM_FLAGS_PARENT ? 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 parent=%d\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\n" @@ -65,6 +68,7 @@ xfs_report_geom( "", geo->sectsize, attrversion, projid32bit, "", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled, "", reflink_enabled, bigtime_enabled, inobtcount, nrext64, + "", parent, "", geo->blocksize, (unsigned long long)geo->datablocks, geo->imaxpct, "", geo->sunit, geo->swidth, diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index 371dc072..f413819b 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -373,13 +373,15 @@ xfs_sb_has_ro_compat_feature( #define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */ #define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */ #define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */ +#define XFS_SB_FEAT_INCOMPAT_PARENT (1 << 6) /* parent pointers */ #define XFS_SB_FEAT_INCOMPAT_ALL \ (XFS_SB_FEAT_INCOMPAT_FTYPE| \ XFS_SB_FEAT_INCOMPAT_SPINODES| \ XFS_SB_FEAT_INCOMPAT_META_UUID| \ XFS_SB_FEAT_INCOMPAT_BIGTIME| \ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR| \ - XFS_SB_FEAT_INCOMPAT_NREXT64) + XFS_SB_FEAT_INCOMPAT_NREXT64| \ + XFS_SB_FEAT_INCOMPAT_PARENT) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 1cfd5bc6..b0b4d7a3 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -237,6 +237,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_BIGTIME (1 << 21) /* 64-bit nsec timestamps */ #define XFS_FSOP_GEOM_FLAGS_INOBTCNT (1 << 22) /* inobt btree counter */ #define XFS_FSOP_GEOM_FLAGS_NREXT64 (1 << 23) /* large extent counters */ +#define XFS_FSOP_GEOM_FLAGS_PARENT (1 << 24) /* parent pointers */ /* * Minimum and maximum sizes need for growth checks. diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index d05f0e6e..2ce2ba75 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -171,6 +171,8 @@ xfs_sb_version_to_features( features |= XFS_FEAT_NEEDSREPAIR; if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_NREXT64) features |= XFS_FEAT_NREXT64; + if (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_PARENT) + features |= XFS_FEAT_PARENT; return features; } @@ -1187,6 +1189,8 @@ xfs_fs_geometry( geo->flags |= XFS_FSOP_GEOM_FLAGS_BIGTIME; if (xfs_has_inobtcounts(mp)) geo->flags |= XFS_FSOP_GEOM_FLAGS_INOBTCNT; + if (xfs_has_parent(mp)) + geo->flags |= XFS_FSOP_GEOM_FLAGS_PARENT; if (xfs_has_sector(mp)) { geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR; geo->logsectsize = sbp->sb_logsectsize; From patchwork Thu Feb 16 20:57:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143877 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D51C8C636CC for ; Thu, 16 Feb 2023 20:58:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229965AbjBPU6C (ORCPT ); Thu, 16 Feb 2023 15:58:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35650 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229715AbjBPU6B (ORCPT ); Thu, 16 Feb 2023 15:58:01 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61E5631E31 for ; Thu, 16 Feb 2023 12:57:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 16C69B82958 for ; Thu, 16 Feb 2023 20:57:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2F60C433D2; Thu, 16 Feb 2023 20:57:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581076; bh=ILMdEUeBruRY9kokNbKbmhhPLObrAUPJKa1EWWbVpEQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=pIKLDUhZltNKNe9ny0YuofIKBgZKEHo3J9q5CKXoYbdVc7pIcla+RH2NX2WE6TcrA jxtjavq0q4lrJX8VgOAMkmT/+CaIC6Ebv40UEfniQ5l4DJmoki+bQlMfbJxPUohdxN bDxS3SO4qifgEQ4StrfRgaHxUt5VQwu+v817+H6fJZeOncAJmOUZhi6+Sy5gI5hFNn 68RBPEzZrsowQ/y/RV1pJipEl8a/S8PCY3/gF62ZO9W9q8wGMBC69+E+8+9NfBjhce Zj2dW/McGMopu0ddrUPVo6kUKTQmLB8v4kIsioTJHLnr3t/V3kXqUeZkVXGA5a6CdA Iuj671DN5W21g== Date: Thu, 16 Feb 2023 12:57:56 -0800 Subject: [PATCH 17/25] xfsprogs: Add parent pointer ioctl From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879137.3476112.1273779539233633833.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: 5e5cdd593342c5ff8aeef9daaa93293f63079b4b This patch adds a new file ioctl to retrieve the parent pointer of a given inode Signed-off-by: Allison Henderson --- libxfs/xfs_fs.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_parent.c | 10 +++++++ libxfs/xfs_parent.h | 2 + man/man3/xfsctl.3 | 55 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index b0b4d7a3..9e59a1fd 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -752,6 +752,79 @@ struct xfs_scrub_metadata { XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED) #define XFS_SCRUB_FLAGS_ALL (XFS_SCRUB_FLAGS_IN | XFS_SCRUB_FLAGS_OUT) +#define XFS_PPTR_MAXNAMELEN 256 + +/* return parents of the handle, not the open fd */ +#define XFS_PPTR_IFLAG_HANDLE (1U << 0) + +/* target was the root directory */ +#define XFS_PPTR_OFLAG_ROOT (1U << 1) + +/* Cursor is done iterating pptrs */ +#define XFS_PPTR_OFLAG_DONE (1U << 2) + + #define XFS_PPTR_FLAG_ALL (XFS_PPTR_IFLAG_HANDLE | XFS_PPTR_OFLAG_ROOT | \ + XFS_PPTR_OFLAG_DONE) + +/* Get an inode parent pointer through ioctl */ +struct xfs_parent_ptr { + __u64 xpp_ino; /* Inode */ + __u32 xpp_gen; /* Inode generation */ + __u32 xpp_diroffset; /* Directory offset */ + __u64 xpp_rsvd; /* Reserved */ + __u8 xpp_name[XFS_PPTR_MAXNAMELEN]; /* File name */ +}; + +/* Iterate through an inodes parent pointers */ +struct xfs_pptr_info { + /* File handle, if XFS_PPTR_IFLAG_HANDLE is set */ + struct xfs_handle pi_handle; + + /* + * Structure to track progress in iterating the parent pointers. + * Must be initialized to zeroes before the first ioctl call, and + * not touched by callers after that. + */ + struct xfs_attrlist_cursor pi_cursor; + + /* Operational flags: XFS_PPTR_*FLAG* */ + __u32 pi_flags; + + /* Must be set to zero */ + __u32 pi_reserved; + + /* # of entries in array */ + __u32 pi_ptrs_size; + + /* # of entries filled in (output) */ + __u32 pi_ptrs_used; + + /* Must be set to zero */ + __u64 pi_reserved2[6]; + + /* + * An array of struct xfs_parent_ptr follows the header + * information. Use xfs_ppinfo_to_pp() to access the + * parent pointer array entries. + */ + struct xfs_parent_ptr pi_parents[]; +}; + +static inline size_t +xfs_pptr_info_sizeof(int nr_ptrs) +{ + return sizeof(struct xfs_pptr_info) + + (nr_ptrs * sizeof(struct xfs_parent_ptr)); +} + +static inline struct xfs_parent_ptr* +xfs_ppinfo_to_pp( + struct xfs_pptr_info *info, + int idx) +{ + return &info->pi_parents[idx]; +} + /* * ioctl limits */ @@ -797,6 +870,7 @@ struct xfs_scrub_metadata { /* XFS_IOC_GETFSMAP ------ hoisted 59 */ #define XFS_IOC_SCRUB_METADATA _IOWR('X', 60, struct xfs_scrub_metadata) #define XFS_IOC_AG_GEOMETRY _IOWR('X', 61, struct xfs_ag_geometry) +#define XFS_IOC_GETPARENTS _IOWR('X', 62, struct xfs_parent_ptr) /* * ioctl commands that replace IRIX syssgi()'s diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c index 3f02271f..47ea6b89 100644 --- a/libxfs/xfs_parent.c +++ b/libxfs/xfs_parent.c @@ -30,6 +30,16 @@ struct kmem_cache *xfs_parent_intent_cache; +/* Initializes a xfs_parent_ptr from an xfs_parent_name_rec */ +void +xfs_init_parent_ptr(struct xfs_parent_ptr *xpp, + const struct xfs_parent_name_rec *rec) +{ + xpp->xpp_ino = be64_to_cpu(rec->p_ino); + xpp->xpp_gen = be32_to_cpu(rec->p_gen); + xpp->xpp_diroffset = be32_to_cpu(rec->p_diroffset); +} + /* * Parent pointer attribute handling. * diff --git a/libxfs/xfs_parent.h b/libxfs/xfs_parent.h index 03900588..13040b9d 100644 --- a/libxfs/xfs_parent.h +++ b/libxfs/xfs_parent.h @@ -25,6 +25,8 @@ struct xfs_parent_defer { void xfs_init_parent_name_rec(struct xfs_parent_name_rec *rec, struct xfs_inode *ip, uint32_t p_diroffset); +void xfs_init_parent_ptr(struct xfs_parent_ptr *xpp, + const struct xfs_parent_name_rec *rec); int __xfs_parent_init(struct xfs_mount *mp, bool grab_log, struct xfs_parent_defer **parentp); diff --git a/man/man3/xfsctl.3 b/man/man3/xfsctl.3 index 4a0d4d08..7cc97499 100644 --- a/man/man3/xfsctl.3 +++ b/man/man3/xfsctl.3 @@ -321,6 +321,61 @@ They are all subject to change and should not be called directly by applications. XFS_IOC_FSSETDM_BY_HANDLE is not supported as of Linux 5.5. +.PP +.TP +.B XFS_IOC_GETPARENTS +This command is used to get a files parent pointers. Parent pointers are +file attributes used to store meta data information about an inodes parent. +This command takes a xfs_pptr_info structure with trailing array of +struct xfs_parent_ptr as an input to store an inodes parents. The +xfs_pptr_info_sizeof() and xfs_ppinfo_to_pp() routines are provided to +create and iterate through these structures. The number of pointers stored +in the array is indicated by the xfs_pptr_info.used field, and the +XFS_PPTR_OFLAG_DONE flag will be set in xfs_pptr_info.flags when there are +no more parent pointers to be read. The below code is an example +of XFS_IOC_GETPARENTS usage: + +.nf +#include +#include +#include +#include +#include +#include +#include + +int main() { + struct xfs_pptr_info *pi; + struct xfs_parent_ptr *p; + int i, error, fd, nr_ptrs = 4; + + unsigned char buffer[xfs_pptr_info_sizeof(nr_ptrs)]; + memset(buffer, 0, sizeof(buffer)); + pi = (struct xfs_pptr_info *)&buffer; + pi->pi_ptrs_size = nr_ptrs; + + fd = open("/mnt/test/foo.txt", O_RDONLY | O_CREAT); + if (fd == -1) + return errno; + + do { + error = ioctl(fd, XFS_IOC_GETPARENTS, pi); + if (error) + return error; + + for (i = 0; i < pi->pi_ptrs_used; i++) { + p = xfs_ppinfo_to_pp(pi, i); + printf("inode = %llu\\n", (unsigned long long)p->xpp_ino); + printf("generation = %u\\n", (unsigned int)p->xpp_gen); + printf("diroffset = %u\\n", (unsigned int)p->xpp_diroffset); + printf("name = \\"%s\\"\\n\\n", (char *)p->xpp_name); + } + } while (!pi->pi_flags & XFS_PPTR_OFLAG_DONE); + + return 0; +} +.fi + .SS Filesystem Operations In order to effect one of the following operations, the pathname and descriptor arguments passed to From patchwork Thu Feb 16 20:58:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143878 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F366C636CC for ; Thu, 16 Feb 2023 20:58:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229715AbjBPU6O (ORCPT ); Thu, 16 Feb 2023 15:58:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229879AbjBPU6O (ORCPT ); Thu, 16 Feb 2023 15:58:14 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65E3731E31 for ; Thu, 16 Feb 2023 12:58:13 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0310A60A55 for ; Thu, 16 Feb 2023 20:58:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 63D31C433EF; Thu, 16 Feb 2023 20:58:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581092; bh=syZ3adEdQ9Ecpdm0c7DVLlMxe7J+Yodf2LVTmLSdqnw=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=J9/FvLW8HyhfMtnX/thIwcB2d2p54oa8TT873m57US34qVA06GYR1EBxihAvUhTyk IArDPnQ1Z2FOFZri0AjgqzGp4W/1Yrkyp8LaLmCnkUYEXmBTOOa4ALO+SuDc+yRHAM zrYerf3QE8I8axwSgGQ7EOW2TM97fSeAEx5QKCIa3Xp7V4s8qF0yJiypJCB1Mr2Lwu L2k+EXY4hUm1uQi/GQqTjZVY9FTQLiuhxLEbaQSo6h3Nhbenr6Xmpg/njqcigz13YL YVQhL8ICkeJsRgvLlfThloziPNTLO0u4OBHJZqjZZKqumKDlX0w76msm8uC/7Z3eA7 lZVsj5xNL2whw== Date: Thu, 16 Feb 2023 12:58:12 -0800 Subject: [PATCH 18/25] xfsprogs: fix unit conversion error in xfs_log_calc_max_attrsetm_res From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879149.3476112.7688659824978464579.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: 46f34ae75a2ef5ca24104377a10a57f9d4151e1d Dave and I were discussing some recent test regressions as a result of me turning on nrext64=1 on realtime filesystems, when we noticed that the minimum log size of a 32M filesystem jumped from 954 blocks to 4287 blocks. Digging through xfs_log_calc_max_attrsetm_res, Dave noticed that @size contains the maximum estimated amount of space needed for a local format xattr, in bytes, but we feed this quantity to XFS_NEXTENTADD_SPACE_RES, which requires units of blocks. This has resulted in an overestimation of the minimum log size over the years. We should nominally correct this, but there's a backwards compatibility problem -- if we enable it now, the minimum log size will decrease. If a corrected mkfs formats a filesystem with this new smaller log size, a user will encounter mount failures on an uncorrected kernel due to the larger minimum log size computations there. However, the large extent counters feature is still EXPERIMENTAL, so we can gate the correction on that feature (or any features that get added after that) being enabled. Any filesystem with nrext64 or any of the as-yet-undefined feature bits turned on will be rejected by old uncorrected kernels, so this should be safe even in the upgrade case. Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson --- libxfs/xfs_log_rlimit.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/libxfs/xfs_log_rlimit.c b/libxfs/xfs_log_rlimit.c index cba24493..6ecb9ad5 100644 --- a/libxfs/xfs_log_rlimit.c +++ b/libxfs/xfs_log_rlimit.c @@ -16,6 +16,39 @@ #include "xfs_bmap_btree.h" #include "xfs_trace.h" +/* + * Decide if the filesystem has the parent pointer feature or any feature + * added after that. + */ +static inline bool +xfs_has_parent_or_newer_feature( + struct xfs_mount *mp) +{ + if (!xfs_sb_is_v5(&mp->m_sb)) + return false; + + if (xfs_sb_has_compat_feature(&mp->m_sb, ~0)) + return true; + + if (xfs_sb_has_ro_compat_feature(&mp->m_sb, + ~(XFS_SB_FEAT_RO_COMPAT_FINOBT | + XFS_SB_FEAT_RO_COMPAT_RMAPBT | + XFS_SB_FEAT_RO_COMPAT_REFLINK | + XFS_SB_FEAT_RO_COMPAT_INOBTCNT))) + return true; + + if (xfs_sb_has_incompat_feature(&mp->m_sb, + ~(XFS_SB_FEAT_INCOMPAT_FTYPE | + XFS_SB_FEAT_INCOMPAT_SPINODES | + XFS_SB_FEAT_INCOMPAT_META_UUID | + XFS_SB_FEAT_INCOMPAT_BIGTIME | + XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | + XFS_SB_FEAT_INCOMPAT_NREXT64))) + return true; + + return false; +} + /* * Calculate the maximum length in bytes that would be required for a local * attribute value as large attributes out of line are not logged. @@ -31,6 +64,16 @@ xfs_log_calc_max_attrsetm_res( MAXNAMELEN - 1; nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); nblks += XFS_B_TO_FSB(mp, size); + + /* + * Starting with the parent pointer feature, every new fs feature + * corrects a unit conversion error in the xattr transaction + * reservation code that resulted in oversized minimum log size + * computations. + */ + if (xfs_has_parent_or_newer_feature(mp)) + size = XFS_B_TO_FSB(mp, size); + nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK); return M_RES(mp)->tr_attrsetm.tr_logres + From patchwork Thu Feb 16 20:58:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143879 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B646BC636CC for ; Thu, 16 Feb 2023 20:58:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229986AbjBPU6f (ORCPT ); Thu, 16 Feb 2023 15:58:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36120 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229991AbjBPU6f (ORCPT ); Thu, 16 Feb 2023 15:58:35 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8A38452894 for ; Thu, 16 Feb 2023 12:58:30 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 33791B82962 for ; Thu, 16 Feb 2023 20:58:29 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EBD56C433D2; Thu, 16 Feb 2023 20:58:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581108; bh=QjCPbFO9hWHc2w+9tZvZDkdWlFLPtNvu2yd7XprUtYA=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ntZyC7jwYAfPFWCw0Q+FUeCqUJndTHDZa9MWXPjQI5HgpqzTqZXJuWVEDaJoNUsAW rS2wvuJYcosxH5GoxLafuLceI7xyQ/OX8inlRH83O/7gnkl+iTMHf5qsIcR+ZGcxUf ocszAdesVIqV1ESP1fbH6pqePbBGktMYg1KtJnGv35KnltF2Q2uDYfVOR/PpBbuQuE wxl4ENH8ahT+wYfTKcYPZ5a2cBsltv8jp5Y/+gjvVeIcHd9yt6LGCBEL0YH/GvtC1n mGujmDzgbvIg/vzjaAPJ6VsA3XF4ju28g32wDkp9QQSpm1dTN8BU271mbAgp3GJpz7 47+5HdXq4Y/eg== Date: Thu, 16 Feb 2023 12:58:27 -0800 Subject: [PATCH 19/25] xfsprogs: drop compatibility minimum log size computations for reflink From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879161.3476112.12858146976098748353.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Source kernel commit: c14b8c08a1dff8019bc4cd1674c5d5bd4248a1e5 Having established that we can reduce the minimum log size computation for filesystems with parent pointers or any newer feature, we should also drop the compat minlogsize code that we added when we reduced the transaction reservation size for rmap and reflink. Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson --- libxfs/xfs_log_rlimit.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libxfs/xfs_log_rlimit.c b/libxfs/xfs_log_rlimit.c index 6ecb9ad5..59605f0d 100644 --- a/libxfs/xfs_log_rlimit.c +++ b/libxfs/xfs_log_rlimit.c @@ -91,6 +91,16 @@ xfs_log_calc_trans_resv_for_minlogblocks( { unsigned int rmap_maxlevels = mp->m_rmap_maxlevels; + /* + * Starting with the parent pointer feature, every new fs feature + * drops the oversized minimum log size computation introduced by the + * original reflink code. + */ + if (xfs_has_parent_or_newer_feature(mp)) { + xfs_trans_resv_calc(mp, resv); + return; + } + /* * In the early days of rmap+reflink, we always set the rmap maxlevels * to 9 even if the AG was small enough that it would never grow to From patchwork Thu Feb 16 20:58:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143880 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3ED4DC61DA4 for ; Thu, 16 Feb 2023 20:58:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229991AbjBPU6z (ORCPT ); Thu, 16 Feb 2023 15:58:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229934AbjBPU6y (ORCPT ); Thu, 16 Feb 2023 15:58:54 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E86DC50AC3 for ; Thu, 16 Feb 2023 12:58:46 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id 43619CE2D89 for ; Thu, 16 Feb 2023 20:58:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8831BC433EF; Thu, 16 Feb 2023 20:58:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581123; bh=mv8q5PFfnZZbISyBF+xSWQceC8/biyNP2lI1hdbjZac=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=EJCgzlW8gzrAGyv/qt3x4URmOstN45+8MBGdinbTkQVVlm4ErWCbctlzoKeNtMmEC QVmYU3NuOoS5TbvR68wuQ6W10tGIBNuqbpnBp70/JZwFVf2KUfdcipfylkoUwgV+fU hDg95ZLTMbF5rwUVcyokZKX0Oh2OenOA4kgWmL1OnP8mmCvYnFGByyRitXCqb/otzG OfRzINSJj3E5kKHsHiw+ch1srUeQmk4R5RWNPW/R5FHui5GBw6HhZ1cEukmCME6qBS 7c0c0yPZHbbAh4uVTHxzKBKM1qmEFzQOJdaBVYx5TTPPcC8jVPBg0IB3W3wNs+L97q vsbkXxXeyS+/A== Date: Thu, 16 Feb 2023 12:58:43 -0800 Subject: [PATCH 20/25] xfsprogs: Add parent pointer flag to cmd From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879174.3476112.13283595059308677022.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson mkfs: enable formatting with parent pointers. Enable parent pointer support in mkfs via the '-n parent' parameter. Signed-off-by: Allison Henderson --- mkfs/xfs_mkfs.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index d95394a5..dffee9e2 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -110,6 +110,7 @@ enum { N_SIZE = 0, N_VERSION, N_FTYPE, + N_PARENT, N_MAX_OPTS, }; @@ -615,6 +616,7 @@ static struct opt_params nopts = { [N_SIZE] = "size", [N_VERSION] = "version", [N_FTYPE] = "ftype", + [N_PARENT] = "parent", [N_MAX_OPTS] = NULL, }, .subopt_params = { @@ -638,6 +640,14 @@ static struct opt_params nopts = { .maxval = 1, .defaultval = 1, }, + { .index = N_PARENT, + .conflicts = { { NULL, LAST_CONFLICT } }, + .minval = 0, + .maxval = 1, + .defaultval = 1, + }, + + }, }; @@ -970,7 +980,7 @@ usage( void ) /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\ sunit=value|su=num,sectsize=num,lazy-count=0|1]\n\ /* label */ [-L label (maximum 12 characters)]\n\ -/* naming */ [-n size=num,version=2|ci,ftype=0|1]\n\ +/* naming */ [-n size=num,version=2|ci,ftype=0|1,parent=0|1]]\n\ /* no-op info only */ [-N]\n\ /* prototype file */ [-p fname]\n\ /* quiet */ [-q]\n\ @@ -1744,6 +1754,9 @@ naming_opts_parser( case N_FTYPE: cli->sb_feat.dirftype = getnum(value, opts, subopt); break; + case N_PARENT: + cli->sb_feat.parent_pointers = getnum(value, &nopts, N_PARENT); + break; default: return -EINVAL; } @@ -2225,6 +2238,14 @@ _("inode btree counters not supported without finobt support\n")); cli->sb_feat.inobtcnt = false; } + if ((cli->sb_feat.parent_pointers) && + cli->sb_feat.dir_version == 4) { + fprintf(stderr, +_("parent pointers not supported on v4 filesystems\n")); + usage(); + cli->sb_feat.parent_pointers = false; + } + if (cli->xi->rtname) { if (cli->sb_feat.reflink && cli_opt_set(&mopts, M_REFLINK)) { fprintf(stderr, @@ -3224,8 +3245,6 @@ sb_set_features( sbp->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT; if (fp->projid32bit) sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT; - if (fp->parent_pointers) - sbp->sb_features2 |= XFS_SB_VERSION2_PARENTBIT; if (fp->crcs_enabled) sbp->sb_features2 |= XFS_SB_VERSION2_CRCBIT; if (fp->attr_version == 2) @@ -3266,6 +3285,10 @@ sb_set_features( sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT; if (fp->bigtime) sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME; + if (fp->parent_pointers) { + sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_PARENT; + sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT; + } /* * Sparse inode chunk support has two main inode alignment requirements. From patchwork Thu Feb 16 20:58:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143883 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DFAFFC636CC for ; Thu, 16 Feb 2023 20:59:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229879AbjBPU7I (ORCPT ); Thu, 16 Feb 2023 15:59:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230004AbjBPU7D (ORCPT ); Thu, 16 Feb 2023 15:59:03 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94AC1505E5 for ; Thu, 16 Feb 2023 12:59:01 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 4D3A2B82958 for ; Thu, 16 Feb 2023 20:59:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14D83C433EF; Thu, 16 Feb 2023 20:58:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581139; bh=Wxf+sVc/7ZeuE5fyC27ctdwNyLHmTgk/OggyzIZzhX0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=FMRpCeLb64N1+0yzILGHZz8deCKFcQQzAiPzGqiK4dP27xu7R+n6dXbhqp/YY/b1f 4FLU8yldJkhDhJuKsejIayVEErYxn5U8yzedlZe5wUZt2zd/ylTH4HqUSmvBk8NOTw GODQowfAtGDOJBrQkl7ZJ4VmPhKOenqHAaG34nZFnsKQKbXQ/tsNNEkNvS7ft3GMSn myAgO/v55bqougZgsL8NCjxYh/oHNoev5xoN+UN+C3dJ7FjBAWHxKQn6/9DMnMFM3Q LJOzZsjD0JagpfeQ7O0JwUgYaLMXrvkUq1MKoJxHqP5MZtc8WFiYGu7wruxtn3SsJ4 U4t9HSfF0imfg== Date: Thu, 16 Feb 2023 12:58:58 -0800 Subject: [PATCH 21/25] xfsprogs: Print pptrs in ATTRI items From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879188.3476112.14960178578853220838.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson This patch modifies the ATTRI print routines to look for the parent pointer flag, and print the log entry name as a parent pointer name record. Values are printed as strings since they contain the file name. Signed-off-by: Allison Henderson --- logprint/log_redo.c | 193 +++++++++++++++++++++++++++++++++++++++++++++------ logprint/logprint.h | 5 + 2 files changed, 172 insertions(+), 26 deletions(-) diff --git a/logprint/log_redo.c b/logprint/log_redo.c index b596af02..f7e9c9ad 100644 --- a/logprint/log_redo.c +++ b/logprint/log_redo.c @@ -674,6 +674,31 @@ xfs_attri_copy_log_format( return 1; } +/* iovec length must be 32-bit aligned */ +static inline size_t ATTR_NVEC_SIZE(size_t size) +{ + return round_up(size, sizeof(int32_t)); +} + +static int +xfs_attri_copy_name_format( + char *buf, + uint len, + struct xfs_parent_name_rec *dst_attri_fmt) +{ + uint dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec)); + + if (len == dst_len) { + memcpy((char *)dst_attri_fmt, buf, len); + return 0; + } + + fprintf(stderr, _("%s: bad size of attri name format: %u; expected %u\n"), + progname, len, dst_len); + + return 1; +} + int xlog_print_trans_attri( char **ptr, @@ -714,7 +739,8 @@ xlog_print_trans_attri( (*i)++; head = (xlog_op_header_t *)*ptr; xlog_print_op_header(head, *i, ptr); - error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len)); + error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len), + src_f->alfi_attr_filter); if (error) goto error; } @@ -724,7 +750,8 @@ xlog_print_trans_attri( (*i)++; head = (xlog_op_header_t *)*ptr; xlog_print_op_header(head, *i, ptr); - error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len)); + error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len), + src_f->alfi_attr_filter); if (error) goto error; } @@ -735,7 +762,7 @@ xlog_print_trans_attri( head = (xlog_op_header_t *)*ptr; xlog_print_op_header(head, *i, ptr); error = xlog_print_trans_attri_value(ptr, be32_to_cpu(head->oh_len), - src_f->alfi_value_len); + src_f->alfi_value_len, src_f->alfi_attr_filter); } error: free(src_f); @@ -746,13 +773,45 @@ xlog_print_trans_attri( int xlog_print_trans_attri_name( char **ptr, - uint src_len) + uint src_len, + uint attr_flags) { - printf(_("ATTRI: name len:%u\n"), src_len); - print_or_dump(*ptr, src_len); + struct xfs_parent_name_rec *src_f = NULL; + uint dst_len; + /* + * If this is not a parent pointer, just do a bin dump + */ + if (!(attr_flags & XFS_ATTR_PARENT)) { + printf(_("ATTRI: name len:%u\n"), src_len); + print_or_dump(*ptr, src_len); + goto out; + } + + dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec)); + if (dst_len != src_len) { + fprintf(stderr, _("%s: bad size of attri name format: %u; expected %u\n"), + progname, src_len, dst_len); + return 1; + } + + /* + * memmove to ensure 8-byte alignment for the long longs in + * xfs_parent_name_rec structure + */ + if ((src_f = (struct xfs_parent_name_rec *)malloc(src_len)) == NULL) { + fprintf(stderr, _("%s: xlog_print_trans_attri_name: malloc failed\n"), progname); + exit(1); + } + memmove((char*)src_f, *ptr, src_len); + + printf(_("ATTRI: #p_ino: %llu p_gen: %u, p_diroffset: %u\n"), + be64_to_cpu(src_f->p_ino), be32_to_cpu(src_f->p_gen), + be32_to_cpu(src_f->p_diroffset)); + + free(src_f); +out: *ptr += src_len; - return 0; } /* xlog_print_trans_attri */ @@ -760,15 +819,32 @@ int xlog_print_trans_attri_value( char **ptr, uint src_len, - int value_len) + int value_len, + uint attr_flags) { int len = min(value_len, src_len); + char *f = NULL; - printf(_("ATTRI: value len:%u\n"), value_len); - print_or_dump(*ptr, len); + /* + * If this is not a parent pointer, just do a bin dump + */ + if (!(attr_flags & XFS_ATTR_PARENT)) { + printf(_("ATTRI: value len:%u\n"), value_len); + print_or_dump(*ptr, min(len, MAX_ATTR_VAL_PRINT)); + goto out; + } + if ((f = (char *)malloc(src_len)) == NULL) { + fprintf(stderr, _("%s: xlog_print_trans_attri: malloc failed\n"), progname); + exit(1); + } + + memcpy(f, *ptr, value_len); + printf(_("ATTRI: value: %.*s\n"), value_len, f); + + free(f); +out: *ptr += src_len; - return 0; } /* xlog_print_trans_attri_value */ @@ -779,6 +855,9 @@ xlog_recover_print_attri( struct xfs_attri_log_format *f, *src_f = NULL; uint src_len, dst_len; + struct xfs_parent_name_rec *rec, *src_rec = NULL; + char *value, *src_value = NULL; + int region = 0; src_f = (struct xfs_attri_log_format *)item->ri_buf[0].i_addr; @@ -803,27 +882,93 @@ xlog_recover_print_attri( if (f->alfi_name_len > 0) { region++; - printf(_("ATTRI: name len:%u\n"), f->alfi_name_len); - print_or_dump((char *)item->ri_buf[region].i_addr, - f->alfi_name_len); + + if (f->alfi_attr_filter & XFS_ATTR_PARENT) { + src_rec = (struct xfs_parent_name_rec *)item->ri_buf[region].i_addr; + src_len = item->ri_buf[region].i_len; + + dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec)); + + if ((rec = ((struct xfs_parent_name_rec *)malloc(dst_len))) == NULL) { + fprintf(stderr, _("%s: xlog_recover_print_attri: malloc failed\n"), + progname); + exit(1); + } + if (xfs_attri_copy_name_format((char *)src_rec, src_len, rec)) { + goto out; + } + + printf(_("ATTRI: #inode: %llu gen: %u, offset: %u\n"), + be64_to_cpu(rec->p_ino), be32_to_cpu(rec->p_gen), + be32_to_cpu(rec->p_diroffset)); + + free(rec); + } + else { + printf(_("ATTRI: name len:%u\n"), f->alfi_name_len); + print_or_dump((char *)item->ri_buf[region].i_addr, + f->alfi_name_len); + } } if (f->alfi_nname_len > 0) { region++; - printf(_("ATTRI: nname len:%u\n"), f->alfi_nname_len); - print_or_dump((char *)item->ri_buf[region].i_addr, - f->alfi_nname_len); + + if (f->alfi_attr_filter & XFS_ATTR_PARENT) { + src_rec = (struct xfs_parent_name_rec *)item->ri_buf[region].i_addr; + src_len = item->ri_buf[region].i_len; + + dst_len = ATTR_NVEC_SIZE(sizeof(struct xfs_parent_name_rec)); + + if ((rec = ((struct xfs_parent_name_rec *)malloc(dst_len))) == NULL) { + fprintf(stderr, _("%s: xlog_recover_print_attri: malloc failed\n"), + progname); + exit(1); + } + if (xfs_attri_copy_name_format((char *)src_rec, src_len, rec)) { + goto out; + } + + printf(_("ATTRI: new #inode: %llu gen: %u, offset: %u\n"), + be64_to_cpu(rec->p_ino), be32_to_cpu(rec->p_gen), + be32_to_cpu(rec->p_diroffset)); + + free(rec); + } + else { + printf(_("ATTRI: nname len:%u\n"), f->alfi_nname_len); + print_or_dump((char *)item->ri_buf[region].i_addr, + f->alfi_nname_len); + } } if (f->alfi_value_len > 0) { - int len = f->alfi_value_len; - - if (len > MAX_ATTR_VAL_PRINT) - len = MAX_ATTR_VAL_PRINT; - region++; - printf(_("ATTRI: value len:%u\n"), f->alfi_value_len); - print_or_dump((char *)item->ri_buf[region].i_addr, len); + + if (f->alfi_attr_filter & XFS_ATTR_PARENT) { + src_value = (char *)item->ri_buf[region].i_addr; + + if ((value = ((char *)malloc(f->alfi_value_len))) == NULL) { + fprintf(stderr, _("%s: xlog_recover_print_attri: malloc failed\n"), + progname); + exit(1); + } + + memcpy((char *)value, (char *)src_value, f->alfi_value_len); + printf("ATTRI: value: %.*s\n", f->alfi_value_len, value); + + free(value); + } + else { + int len = f->alfi_value_len; + + if (len > MAX_ATTR_VAL_PRINT) + len = MAX_ATTR_VAL_PRINT; + + printf(_("ATTRI: value len:%u\n"), f->alfi_value_len); + print_or_dump((char *)item->ri_buf[region].i_addr, + len); + } } out: diff --git a/logprint/logprint.h b/logprint/logprint.h index b4479c24..b8e1c932 100644 --- a/logprint/logprint.h +++ b/logprint/logprint.h @@ -59,8 +59,9 @@ extern void xlog_recover_print_bud(struct xlog_recover_item *item); #define MAX_ATTR_VAL_PRINT 128 extern int xlog_print_trans_attri(char **ptr, uint src_len, int *i); -extern int xlog_print_trans_attri_name(char **ptr, uint src_len); -extern int xlog_print_trans_attri_value(char **ptr, uint src_len, int value_len); +extern int xlog_print_trans_attri_name(char **ptr, uint src_len, uint attr_flags); +extern int xlog_print_trans_attri_value(char **ptr, uint src_len, int value_len, + uint attr_flags); extern void xlog_recover_print_attri(struct xlog_recover_item *item); extern int xlog_print_trans_attrd(char **ptr, uint len); extern void xlog_recover_print_attrd(struct xlog_recover_item *item); From patchwork Thu Feb 16 20:59:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143884 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72F85C61DA4 for ; Thu, 16 Feb 2023 20:59:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230010AbjBPU71 (ORCPT ); Thu, 16 Feb 2023 15:59:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230007AbjBPU7W (ORCPT ); Thu, 16 Feb 2023 15:59:22 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 284C0528BE for ; Thu, 16 Feb 2023 12:59:17 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id D897CB82962 for ; Thu, 16 Feb 2023 20:59:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 953EAC433EF; Thu, 16 Feb 2023 20:59:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581154; bh=rMIqy3yUnFVYfjKK++U6n17GtUlAI8hq1rHQ5EgIeyA=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=RpdqYqztlatEgSUn18TKTXoBJnSkhczx4pOY/lExGUEVBKR5eFS94yfy/Fb8L1ebE 3DQnPPDV8m6j7V1oqJ5/YPpPEtgFI5zlT14UzrdZZ3kvktA0yJHpWT53Ao7CNhmaR1 6xEvYqcJpAXANdbuNXFeDm5ZGHppxreiIf7f85OvV40XjKXhD3lEGv5pFdr/jnfagD LtQ58jm07zs+gI6/OnrX+CL9PhLb/QTNuLQ8J7xdtJWmFDv1no99ASX2nWj1Klr4L5 tXGHR0ZvOn5JOjTbSBEI3Sf7UsFR7pYX1ixfEtizadtLFs76DwezHBiK9yKlGY5FzD RGHFKBwIG2zmQ== Date: Thu, 16 Feb 2023 12:59:14 -0800 Subject: [PATCH 22/25] xfs_db: report parent bit on xattrs From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879201.3476112.8276460435509436134.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Display the parent bit on xattr keys Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson --- db/attr.c | 3 +++ db/attrshort.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/db/attr.c b/db/attr.c index ba722e14..f29e4a54 100644 --- a/db/attr.c +++ b/db/attr.c @@ -82,6 +82,9 @@ const field_t attr_leaf_entry_flds[] = { { "local", FLDT_UINT1, OI(LEOFF(flags) + bitsz(uint8_t) - XFS_ATTR_LOCAL_BIT - 1), C1, 0, TYP_NONE }, + { "parent", FLDT_UINT1, + OI(LEOFF(flags) + bitsz(uint8_t) - XFS_ATTR_PARENT_BIT - 1), C1, 0, + TYP_NONE }, { "pad2", FLDT_UINT8X, OI(LEOFF(pad2)), C1, FLD_SKIPALL, TYP_NONE }, { NULL } }; diff --git a/db/attrshort.c b/db/attrshort.c index e234fbd8..872d771d 100644 --- a/db/attrshort.c +++ b/db/attrshort.c @@ -44,6 +44,9 @@ const field_t attr_sf_entry_flds[] = { { "secure", FLDT_UINT1, OI(EOFF(flags) + bitsz(uint8_t) - XFS_ATTR_SECURE_BIT - 1), C1, 0, TYP_NONE }, + { "parent", FLDT_UINT1, + OI(EOFF(flags) + bitsz(uint8_t) - XFS_ATTR_PARENT_BIT - 1), C1, 0, + TYP_NONE }, { "name", FLDT_CHARNS, OI(EOFF(nameval)), attr_sf_entry_name_count, FLD_COUNT, TYP_NONE }, { "value", FLDT_CHARNS, attr_sf_entry_value_offset, From patchwork Thu Feb 16 20:59:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143885 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 248F2C636CC for ; Thu, 16 Feb 2023 20:59:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230012AbjBPU7g (ORCPT ); Thu, 16 Feb 2023 15:59:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230004AbjBPU7g (ORCPT ); Thu, 16 Feb 2023 15:59:36 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB632505D9 for ; Thu, 16 Feb 2023 12:59:32 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7F0B8B82962 for ; Thu, 16 Feb 2023 20:59:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 28F79C433EF; Thu, 16 Feb 2023 20:59:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581170; bh=aYxcg7I8+S/CgFUYdqXMBLWo6bt/Hbq+mGM8dgH/UXI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=pWphOzTaNjgtrs96Vs+t5uaEXnVM0T2SyA6Tx1izorugQLsMl1KecSHB39biUKlNm e3t6yb6HpeSmqj+jBBQWLD/iCU4/7Uu4WwPVxPbg8xW+on/JMrOiCPF3XK7U7ZBCTW k5WkkjFzbD6eMUWmANeahDksiH30hK3zIMXb5TtvCKYsOr47XG2Q+1PHJHhZrZG0J+ Mw3pXmIE3fzhivA/OsOXy5xXejrRMpHKb4tGL2G5T3Fxpuzg3Y0WIIs0qfkVNvB1ND Ll5bNzAnGzcDKGufRrmgg3fg0Ag8Pm8peOVMFHULmYSN1oE7G1vz3dyKk+wfhpuQYK U0XZg6h88V7WQ== Date: Thu, 16 Feb 2023 12:59:29 -0800 Subject: [PATCH 23/25] xfsprogs: implement the upper half of parent pointers From: "Darrick J. Wong" To: djwong@kernel.org Cc: "Darrick J. Wong" , Allison Collins , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879213.3476112.16199141689205878747.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Collins Add ioctl definitions to libxfs, build the necessary helpers into libfrog and libhandle to iterate parents (and parent paths), then wire up xfs_scrub to be able to query parent pointers from userspace. The goal of this patch is to exercise userspace, and is nowhere near a complete solution. A basic xfs_io parent command implementation replaces ... whatever that is that's there now. Signed-off-by: Darrick J. Wong Signed-off-by: Allison Collins --- include/handle.h | 2 include/parent.h | 18 ++ io/parent.c | 473 +++++++++++++--------------------------------------- libfrog/paths.c | 136 +++++++++++++++ libfrog/paths.h | 21 ++ libhandle/Makefile | 2 libhandle/handle.c | 7 - libhandle/parent.c | 328 ++++++++++++++++++++++++++++++++++++ scrub/inodes.c | 26 +++ scrub/inodes.h | 2 10 files changed, 658 insertions(+), 357 deletions(-) create mode 100644 libhandle/parent.c diff --git a/include/handle.h b/include/handle.h index 34246f38..1f02c964 100644 --- a/include/handle.h +++ b/include/handle.h @@ -40,6 +40,8 @@ extern int fssetdm_by_handle (void *__hanp, size_t __hlen, void fshandle_destroy(void); +int handle_to_fsfd(void *hanp, char **path); + #ifdef __cplusplus } #endif diff --git a/include/parent.h b/include/parent.h index 4d3ad51b..fb900041 100644 --- a/include/parent.h +++ b/include/parent.h @@ -17,4 +17,22 @@ typedef struct parent_cursor { __u32 opaque[4]; /* an opaque cookie */ } parent_cursor_t; +struct path_list; + +typedef int (*walk_pptr_fn)(struct xfs_pptr_info *pi, struct xfs_parent_ptr *pptr, + void *arg); +typedef int (*walk_ppath_fn)(const char *mntpt, struct path_list *path, + void *arg); + +#define WALK_PPTRS_ABORT 1 +int fd_walk_pptrs(int fd, walk_pptr_fn fn, void *arg); +int handle_walk_pptrs(void *hanp, size_t hanlen, walk_pptr_fn fn, void *arg); + +#define WALK_PPATHS_ABORT 1 +int fd_walk_ppaths(int fd, walk_ppath_fn fn, void *arg); +int handle_walk_ppaths(void *hanp, size_t hanlen, walk_ppath_fn fn, void *arg); + +int fd_to_path(int fd, char *path, size_t pathlen); +int handle_to_path(void *hanp, size_t hlen, char *path, size_t pathlen); + #endif diff --git a/io/parent.c b/io/parent.c index 8f63607f..e0ca29eb 100644 --- a/io/parent.c +++ b/io/parent.c @@ -9,363 +9,106 @@ #include "libfrog/paths.h" #include "parent.h" #include "handle.h" -#include "jdm.h" #include "init.h" #include "io.h" -#define PARENTBUF_SZ 16384 -#define BSTATBUF_SZ 16384 - static cmdinfo_t parent_cmd; -static int verbose_flag; -static int err_status; -static __u64 inodes_checked; static char *mntpt; -/* - * check out a parent entry to see if the values seem valid - */ -static void -check_parent_entry(struct xfs_bstat *bstatp, parent_t *parent) -{ - int sts; - char fullpath[PATH_MAX]; - struct stat statbuf; - char *str; - - sprintf(fullpath, _("%s%s"), mntpt, parent->p_name); - - sts = lstat(fullpath, &statbuf); - if (sts != 0) { - fprintf(stderr, - _("inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n"), - (unsigned long long) bstatp->bs_ino, fullpath); - if (verbose_flag) { - fprintf(stderr, - _("path \"%s\" does not stat for inode: %llu; err = %s\n"), - fullpath, - (unsigned long long) bstatp->bs_ino, - strerror(errno)); - } - err_status++; - return; - } else { - if (verbose_flag > 1) { - printf(_("path \"%s\" found\n"), fullpath); - } - } - - if (statbuf.st_ino != bstatp->bs_ino) { - fprintf(stderr, - _("inode-path for inode: %llu is incorrect - wrong inode#\n"), - (unsigned long long) bstatp->bs_ino); - if (verbose_flag) { - fprintf(stderr, - _("ino mismatch for path \"%s\" %llu vs %llu\n"), - fullpath, - (unsigned long long)statbuf.st_ino, - (unsigned long long)bstatp->bs_ino); - } - err_status++; - return; - } else if (verbose_flag > 1) { - printf(_("inode number match: %llu\n"), - (unsigned long long)statbuf.st_ino); - } - - /* get parent path */ - str = strrchr(fullpath, '/'); - *str = '\0'; - sts = stat(fullpath, &statbuf); - if (sts != 0) { - fprintf(stderr, - _("parent path \"%s\" does not stat: %s\n"), - fullpath, - strerror(errno)); - err_status++; - return; - } else { - if (parent->p_ino != statbuf.st_ino) { - fprintf(stderr, - _("inode-path for inode: %llu is incorrect - wrong parent inode#\n"), - (unsigned long long) bstatp->bs_ino); - if (verbose_flag) { - fprintf(stderr, - _("ino mismatch for path \"%s\" %llu vs %llu\n"), - fullpath, - (unsigned long long)parent->p_ino, - (unsigned long long)statbuf.st_ino); - } - err_status++; - return; - } else { - if (verbose_flag > 1) { - printf(_("parent ino match for %llu\n"), - (unsigned long long) parent->p_ino); - } - } - } -} - -static void -check_parents(parent_t *parentbuf, size_t *parentbuf_size, - jdm_fshandle_t *fshandlep, struct xfs_bstat *statp) -{ - int error, i; - __u32 count; - parent_t *entryp; - - do { - error = jdm_parentpaths(fshandlep, statp, parentbuf, *parentbuf_size, &count); - - if (error == ERANGE) { - *parentbuf_size *= 2; - parentbuf = (parent_t *)realloc(parentbuf, *parentbuf_size); - } else if (error) { - fprintf(stderr, _("parentpaths failed for ino %llu: %s\n"), - (unsigned long long) statp->bs_ino, - strerror(errno)); - err_status++; - break; - } - } while (error == ERANGE); - - - if (count == 0) { - /* no links for inode - something wrong here */ - fprintf(stderr, _("inode-path for inode: %llu is missing\n"), - (unsigned long long) statp->bs_ino); - err_status++; - } - - entryp = parentbuf; - for (i = 0; i < count; i++) { - check_parent_entry(statp, entryp); - entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen); - } -} - static int -do_bulkstat(parent_t *parentbuf, size_t *parentbuf_size, - struct xfs_bstat *bstatbuf, int fsfd, jdm_fshandle_t *fshandlep) +pptr_print( + struct xfs_pptr_info *pi, + struct xfs_parent_ptr *pptr, + void *arg) { - __s32 buflenout; - __u64 lastino = 0; - struct xfs_bstat *p; - struct xfs_bstat *endp; - struct xfs_fsop_bulkreq bulkreq; - struct stat mntstat; + char buf[XFS_PPTR_MAXNAMELEN + 1]; + unsigned int namelen = strlen((char *)pptr->xpp_name); - if (stat(mntpt, &mntstat)) { - fprintf(stderr, _("can't stat mount point \"%s\": %s\n"), - mntpt, strerror(errno)); - return 1; + if (pi->pi_flags & XFS_PPTR_OFLAG_ROOT) { + printf(_("Root directory.\n")); + return 0; } - bulkreq.lastip = &lastino; - bulkreq.icount = BSTATBUF_SZ; - bulkreq.ubuffer = (void *)bstatbuf; - bulkreq.ocount = &buflenout; - - while (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT, &bulkreq) == 0) { - if (*(bulkreq.ocount) == 0) { - return 0; - } - for (p = bstatbuf, endp = bstatbuf + *bulkreq.ocount; p < endp; p++) { - - /* inode being modified, get synced data with iget */ - if ( (!p->bs_nlink || !p->bs_mode) && p->bs_ino != 0 ) { - - if (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq) < 0) { - fprintf(stderr, - _("failed to get bulkstat information for inode %llu\n"), - (unsigned long long) p->bs_ino); - continue; - } - if (!p->bs_nlink || !p->bs_mode || !p->bs_ino) { - fprintf(stderr, - _("failed to get valid bulkstat information for inode %llu\n"), - (unsigned long long) p->bs_ino); - continue; - } - } - - /* skip root */ - if (p->bs_ino == mntstat.st_ino) { - continue; - } - - if (verbose_flag > 1) { - printf(_("checking inode %llu\n"), - (unsigned long long) p->bs_ino); - } - - /* print dotted progress */ - if ((inodes_checked % 100) == 0 && verbose_flag == 1) { - printf("."); fflush(stdout); - } - inodes_checked++; - - check_parents(parentbuf, parentbuf_size, fshandlep, p); - } - - }/*while*/ - - fprintf(stderr, _("syssgi bulkstat failed: %s\n"), strerror(errno)); - return 1; + memcpy(buf, pptr->xpp_name, namelen); + buf[namelen] = 0; + printf(_("p_ino = %llu\n"), (unsigned long long)pptr->xpp_ino); + printf(_("p_gen = %u\n"), (unsigned int)pptr->xpp_gen); + printf(_("p_reclen = %u\n"), namelen); + printf(_("p_name = \"%s\"\n\n"), buf); + return 0; } -static int -parent_check(void) +int +print_parents( + struct xfs_handle *handle) { - int fsfd; - jdm_fshandle_t *fshandlep; - parent_t *parentbuf; - size_t parentbuf_size = PARENTBUF_SZ; - struct xfs_bstat *bstatbuf; - - err_status = 0; - inodes_checked = 0; - - sync(); - - fsfd = file->fd; - - fshandlep = jdm_getfshandle(mntpt); - if (fshandlep == NULL) { - fprintf(stderr, _("unable to open \"%s\" for jdm: %s\n"), - mntpt, - strerror(errno)); - return 1; - } - - /* allocate buffers */ - bstatbuf = (struct xfs_bstat *)calloc(BSTATBUF_SZ, sizeof(struct xfs_bstat)); - parentbuf = (parent_t *)malloc(parentbuf_size); - if (!bstatbuf || !parentbuf) { - fprintf(stderr, _("unable to allocate buffers: %s\n"), - strerror(errno)); - err_status = 1; - goto out; - } - - if (do_bulkstat(parentbuf, &parentbuf_size, bstatbuf, fsfd, fshandlep) != 0) - err_status++; + int ret; - if (err_status > 0) - fprintf(stderr, _("num errors: %d\n"), err_status); + if (handle) + ret = handle_walk_pptrs(handle, sizeof(*handle), pptr_print, + NULL); else - printf(_("succeeded checking %llu inodes\n"), - (unsigned long long) inodes_checked); + ret = fd_walk_pptrs(file->fd, pptr_print, NULL); + if (ret) + perror(file->name); -out: - free(bstatbuf); - free(parentbuf); - free(fshandlep); - return err_status; -} - -static void -print_parent_entry(parent_t *parent, int fullpath) -{ - printf(_("p_ino = %llu\n"), (unsigned long long) parent->p_ino); - printf(_("p_gen = %u\n"), parent->p_gen); - printf(_("p_reclen = %u\n"), parent->p_reclen); - if (fullpath) - printf(_("p_name = \"%s%s\"\n"), mntpt, parent->p_name); - else - printf(_("p_name = \"%s\"\n"), parent->p_name); + return 0; } static int -parent_list(int fullpath) -{ - void *handlep = NULL; - size_t handlen; - int error, i; - int retval = 1; - __u32 count; - parent_t *entryp; - parent_t *parentbuf = NULL; - char *path = file->name; - int pb_size = PARENTBUF_SZ; - - /* XXXX for linux libhandle version - to set libhandle fsfd cache */ - { - void *fshandle; - size_t fshlen; - - if (path_to_fshandle(mntpt, &fshandle, &fshlen) != 0) { - fprintf(stderr, _("%s: failed path_to_fshandle \"%s\": %s\n"), - progname, path, strerror(errno)); - goto error; - } - free_handle(fshandle, fshlen); +path_print( + const char *mntpt, + struct path_list *path, + void *arg) { + + char buf[PATH_MAX]; + size_t len = PATH_MAX; + int ret; + + ret = snprintf(buf, len, "%s", mntpt); + if (ret != strlen(mntpt)) { + errno = ENOMEM; + return -1; } - if (path_to_handle(path, &handlep, &handlen) != 0) { - fprintf(stderr, _("%s: path_to_handle failed for \"%s\"\n"), progname, path); - goto error; - } - - do { - parentbuf = (parent_t *)realloc(parentbuf, pb_size); - if (!parentbuf) { - fprintf(stderr, _("%s: unable to allocate parent buffer: %s\n"), - progname, strerror(errno)); - goto error; - } - - if (fullpath) { - error = parentpaths_by_handle(handlep, - handlen, - parentbuf, - pb_size, - &count); - } else { - error = parents_by_handle(handlep, - handlen, - parentbuf, - pb_size, - &count); - } - if (error == ERANGE) { - pb_size *= 2; - } else if (error) { - fprintf(stderr, _("%s: %s call failed for \"%s\": %s\n"), - progname, fullpath ? "parentpaths" : "parents", - path, strerror(errno)); - goto error; - } - } while (error == ERANGE); - - if (count == 0) { - /* no links for inode - something wrong here */ - fprintf(stderr, _("%s: inode-path is missing\n"), progname); - goto error; - } - - entryp = parentbuf; - for (i = 0; i < count; i++) { - print_parent_entry(entryp, fullpath); - entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen); - } + ret = path_list_to_string(path, buf + ret, len - ret); + if (ret < 0) + return ret; + return 0; +} - retval = 0; -error: - free(handlep); - free(parentbuf); - return retval; +int +print_paths( + struct xfs_handle *handle) +{ + int ret; + + if (handle) + ret = handle_walk_ppaths(handle, sizeof(*handle), path_print, + NULL); + else + ret = fd_walk_ppaths(file->fd, path_print, NULL); + if (ret) + perror(file->name); + return 0; } static int -parent_f(int argc, char **argv) +parent_f( + int argc, + char **argv) { - int c; - int listpath_flag = 0; - int check_flag = 0; - fs_path_t *fs; - static int tab_init; + struct xfs_handle handle; + void *hanp = NULL; + size_t hlen; + struct fs_path *fs; + char *p; + uint64_t ino = 0; + uint32_t gen = 0; + int c; + int listpath_flag = 0; + int ret; + static int tab_init; if (!tab_init) { tab_init = 1; @@ -380,46 +123,72 @@ parent_f(int argc, char **argv) } mntpt = fs->fs_dir; - verbose_flag = 0; - - while ((c = getopt(argc, argv, "cpv")) != EOF) { + while ((c = getopt(argc, argv, "p")) != EOF) { switch (c) { - case 'c': - check_flag = 1; - break; case 'p': listpath_flag = 1; break; - case 'v': - verbose_flag++; - break; default: return command_usage(&parent_cmd); } } - if (!check_flag && !listpath_flag) /* default case */ - exitcode = parent_list(listpath_flag); - else { - if (listpath_flag) - exitcode = parent_list(listpath_flag); - if (check_flag) - exitcode = parent_check(); + /* + * Always initialize the fshandle table because we need it for + * the ppaths functions to work. + */ + ret = path_to_fshandle((char *)mntpt, &hanp, &hlen); + if (ret) { + perror(mntpt); + return 0; + } + + if (optind + 2 == argc) { + ino = strtoull(argv[optind], &p, 0); + if (*p != '\0' || ino == 0) { + fprintf(stderr, + _("Bad inode number '%s'.\n"), + argv[optind]); + return 0; + } + gen = strtoul(argv[optind + 1], &p, 0); + if (*p != '\0') { + fprintf(stderr, + _("Bad generation number '%s'.\n"), + argv[optind + 1]); + return 0; + } + + memcpy(&handle, hanp, sizeof(handle)); + handle.ha_fid.fid_len = sizeof(xfs_fid_t) - + sizeof(handle.ha_fid.fid_len); + handle.ha_fid.fid_pad = 0; + handle.ha_fid.fid_ino = ino; + handle.ha_fid.fid_gen = gen; + } + if (listpath_flag) + exitcode = print_paths(ino ? &handle : NULL); + else + exitcode = print_parents(ino ? &handle : NULL); + + if (hanp) + free_handle(hanp, hlen); + return 0; } static void parent_help(void) { - printf(_( +printf(_( "\n" " list the current file's parents and their filenames\n" "\n" -" -c -- check the current file's file system for parent consistency\n" -" -p -- list the current file's parents and their full paths\n" -" -v -- verbose mode\n" +" -p -- list the current file's paths up to the root\n" +"\n" +"If ino and gen are supplied, use them instead.\n" "\n")); } @@ -430,9 +199,9 @@ parent_init(void) parent_cmd.cfunc = parent_f; parent_cmd.argmin = 0; parent_cmd.argmax = -1; - parent_cmd.args = _("[-cpv]"); + parent_cmd.args = _("[-p] [ino gen]"); parent_cmd.flags = CMD_NOMAP_OK; - parent_cmd.oneline = _("print or check parent inodes"); + parent_cmd.oneline = _("print parent inodes"); parent_cmd.help = parent_help; if (expert) diff --git a/libfrog/paths.c b/libfrog/paths.c index abb29a23..a86ae07c 100644 --- a/libfrog/paths.c +++ b/libfrog/paths.c @@ -15,6 +15,7 @@ #include "paths.h" #include "input.h" #include "projects.h" +#include "list.h" #include extern char *progname; @@ -563,3 +564,138 @@ fs_table_insert_project_path( return error; } + + +/* Structured path components. */ + +struct path_list { + struct list_head p_head; +}; + +struct path_component { + struct list_head pc_list; + char *pc_fname; +}; + +/* Initialize a path component with a given name. */ +struct path_component * +path_component_init( + const char *name) +{ + struct path_component *pc; + + pc = malloc(sizeof(struct path_component)); + if (!pc) + return NULL; + INIT_LIST_HEAD(&pc->pc_list); + pc->pc_fname = strdup(name); + if (!pc->pc_fname) { + free(pc); + return NULL; + } + return pc; +} + +/* Free a path component. */ +void +path_component_free( + struct path_component *pc) +{ + free(pc->pc_fname); + free(pc); +} + +/* Change a path component's filename. */ +int +path_component_change( + struct path_component *pc, + void *name, + size_t namelen) +{ + void *p; + + p = realloc(pc->pc_fname, namelen + 1); + if (!p) + return -1; + pc->pc_fname = p; + memcpy(pc->pc_fname, name, namelen); + pc->pc_fname[namelen] = 0; + return 0; +} + +/* Initialize a pathname. */ +struct path_list * +path_list_init(void) +{ + struct path_list *path; + + path = malloc(sizeof(struct path_list)); + if (!path) + return NULL; + INIT_LIST_HEAD(&path->p_head); + return path; +} + +/* Empty out a pathname. */ +void +path_list_free( + struct path_list *path) +{ + struct path_component *pos; + struct path_component *n; + + list_for_each_entry_safe(pos, n, &path->p_head, pc_list) { + path_list_del_component(path, pos); + path_component_free(pos); + } + free(path); +} + +/* Add a parent component to a pathname. */ +void +path_list_add_parent_component( + struct path_list *path, + struct path_component *pc) +{ + list_add(&pc->pc_list, &path->p_head); +} + +/* Add a component to a pathname. */ +void +path_list_add_component( + struct path_list *path, + struct path_component *pc) +{ + list_add_tail(&pc->pc_list, &path->p_head); +} + +/* Remove a component from a pathname. */ +void +path_list_del_component( + struct path_list *path, + struct path_component *pc) +{ + list_del_init(&pc->pc_list); +} + +/* Convert a pathname into a string. */ +ssize_t +path_list_to_string( + struct path_list *path, + char *buf, + size_t buflen) +{ + struct path_component *pos; + ssize_t bytes = 0; + int ret; + + list_for_each_entry(pos, &path->p_head, pc_list) { + ret = snprintf(buf, buflen, "/%s", pos->pc_fname); + if (ret != 1 + strlen(pos->pc_fname)) + return -1; + bytes += ret; + buf += ret; + buflen -= ret; + } + return bytes; +} diff --git a/libfrog/paths.h b/libfrog/paths.h index f20a2c3e..52538fb5 100644 --- a/libfrog/paths.h +++ b/libfrog/paths.h @@ -58,4 +58,23 @@ typedef struct fs_cursor { extern void fs_cursor_initialise(char *__dir, uint __flags, fs_cursor_t *__cp); extern fs_path_t *fs_cursor_next_entry(fs_cursor_t *__cp); -#endif /* __LIBFROG_PATH_H__ */ +/* Path information. */ + +struct path_list; +struct path_component; + +struct path_component *path_component_init(const char *name); +void path_component_free(struct path_component *pc); +int path_component_change(struct path_component *pc, void *name, + size_t namelen); + +struct path_list *path_list_init(void); +void path_list_free(struct path_list *path); +void path_list_add_parent_component(struct path_list *path, + struct path_component *pc); +void path_list_add_component(struct path_list *path, struct path_component *pc); +void path_list_del_component(struct path_list *path, struct path_component *pc); + +ssize_t path_list_to_string(struct path_list *path, char *buf, size_t buflen); + +#endif /* __PATH_H__ */ diff --git a/libhandle/Makefile b/libhandle/Makefile index f297a59e..cf7df67c 100644 --- a/libhandle/Makefile +++ b/libhandle/Makefile @@ -12,7 +12,7 @@ LT_AGE = 0 LTLDFLAGS += -Wl,--version-script,libhandle.sym -CFILES = handle.c jdm.c +CFILES = handle.c jdm.c parent.c LSRCFILES = libhandle.sym default: ltdepend $(LTLIBRARY) diff --git a/libhandle/handle.c b/libhandle/handle.c index 333c2190..1e8fe9ac 100644 --- a/libhandle/handle.c +++ b/libhandle/handle.c @@ -29,7 +29,6 @@ typedef union { } comarg_t; static int obj_to_handle(char *, int, unsigned int, comarg_t, void**, size_t*); -static int handle_to_fsfd(void *, char **); static char *path_to_fspath(char *path); @@ -203,8 +202,10 @@ handle_to_fshandle( return 0; } -static int -handle_to_fsfd(void *hanp, char **path) +int +handle_to_fsfd( + void *hanp, + char **path) { struct fdhash *fdhp; diff --git a/libhandle/parent.c b/libhandle/parent.c new file mode 100644 index 00000000..ebd0abd5 --- /dev/null +++ b/libhandle/parent.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2017 Oracle. All Rights Reserved. + * + * Author: Darrick J. Wong + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "platform_defs.h" +#include "xfs.h" +#include "xfs_arch.h" +#include "list.h" +#include "libfrog/paths.h" +#include "handle.h" +#include "parent.h" + +/* Allocate a buffer large enough for some parent pointer records. */ +static inline struct xfs_pptr_info * +xfs_pptr_alloc( + size_t nr_ptrs) +{ + struct xfs_pptr_info *pi; + + pi = malloc(xfs_pptr_info_sizeof(nr_ptrs)); + if (!pi) + return NULL; + memset(pi, 0, sizeof(struct xfs_pptr_info)); + pi->pi_ptrs_size = nr_ptrs; + return pi; +} + +/* Walk all parents of the given file handle. */ +static int +handle_walk_parents( + int fd, + struct xfs_handle *handle, + walk_pptr_fn fn, + void *arg) +{ + struct xfs_pptr_info *pi; + struct xfs_parent_ptr *p; + unsigned int i; + ssize_t ret = -1; + + pi = xfs_pptr_alloc(4); + if (!pi) + return -1; + + if (handle) { + memcpy(&pi->pi_handle, handle, sizeof(struct xfs_handle)); + pi->pi_flags = XFS_PPTR_IFLAG_HANDLE; + } + + ret = ioctl(fd, XFS_IOC_GETPARENTS, pi); + while (!ret) { + if (pi->pi_flags & XFS_PPTR_OFLAG_ROOT) { + ret = fn(pi, NULL, arg); + break; + } + + for (i = 0; i < pi->pi_ptrs_used; i++) { + p = xfs_ppinfo_to_pp(pi, i); + ret = fn(pi, p, arg); + if (ret) + goto out_pi; + } + + if (pi->pi_flags & XFS_PPTR_OFLAG_DONE) + break; + + ret = ioctl(fd, XFS_IOC_GETPARENTS, pi); + } + +out_pi: + free(pi); + return ret; +} + +/* Walk all parent pointers of this handle. */ +int +handle_walk_pptrs( + void *hanp, + size_t hlen, + walk_pptr_fn fn, + void *arg) +{ + char *mntpt; + int fd; + + if (hlen != sizeof(struct xfs_handle)) { + errno = EINVAL; + return -1; + } + + fd = handle_to_fsfd(hanp, &mntpt); + if (fd < 0) + return -1; + + return handle_walk_parents(fd, hanp, fn, arg); +} + +/* Walk all parent pointers of this fd. */ +int +fd_walk_pptrs( + int fd, + walk_pptr_fn fn, + void *arg) +{ + return handle_walk_parents(fd, NULL, fn, arg); +} + +struct walk_ppaths_info { + walk_ppath_fn fn; + void *arg; + char *mntpt; + struct path_list *path; + int fd; +}; + +struct walk_ppath_level_info { + struct xfs_handle newhandle; + struct path_component *pc; + struct walk_ppaths_info *wpi; +}; + +static int handle_walk_parent_paths(struct walk_ppaths_info *wpi, + struct xfs_handle *handle); + +static int +handle_walk_parent_path_ptr( + struct xfs_pptr_info *pi, + struct xfs_parent_ptr *p, + void *arg) +{ + struct walk_ppath_level_info *wpli = arg; + struct walk_ppaths_info *wpi = wpli->wpi; + unsigned int i; + int ret = 0; + + if (pi->pi_flags & XFS_PPTR_OFLAG_ROOT) + return wpi->fn(wpi->mntpt, wpi->path, wpi->arg); + + for (i = 0; i < pi->pi_ptrs_used; i++) { + p = xfs_ppinfo_to_pp(pi, i); + ret = path_component_change(wpli->pc, p->xpp_name, + strlen((char *)p->xpp_name)); + if (ret) + break; + wpli->newhandle.ha_fid.fid_ino = p->xpp_ino; + wpli->newhandle.ha_fid.fid_gen = p->xpp_gen; + path_list_add_parent_component(wpi->path, wpli->pc); + ret = handle_walk_parent_paths(wpi, &wpli->newhandle); + path_list_del_component(wpi->path, wpli->pc); + if (ret) + break; + } + + return ret; +} + +/* + * Recursively walk all parents of the given file handle; if we hit the + * fs root then we call the associated function with the constructed path. + */ +static int +handle_walk_parent_paths( + struct walk_ppaths_info *wpi, + struct xfs_handle *handle) +{ + struct walk_ppath_level_info *wpli; + int ret; + + wpli = malloc(sizeof(struct walk_ppath_level_info)); + if (!wpli) + return -1; + wpli->pc = path_component_init(""); + if (!wpli->pc) { + free(wpli); + return -1; + } + wpli->wpi = wpi; + memcpy(&wpli->newhandle, handle, sizeof(struct xfs_handle)); + + ret = handle_walk_parents(wpi->fd, handle, handle_walk_parent_path_ptr, + wpli); + + path_component_free(wpli->pc); + free(wpli); + return ret; +} + +/* + * Call the given function on all known paths from the vfs root to the inode + * described in the handle. + */ +int +handle_walk_ppaths( + void *hanp, + size_t hlen, + walk_ppath_fn fn, + void *arg) +{ + struct walk_ppaths_info wpi; + ssize_t ret; + + if (hlen != sizeof(struct xfs_handle)) { + errno = EINVAL; + return -1; + } + + wpi.fd = handle_to_fsfd(hanp, &wpi.mntpt); + if (wpi.fd < 0) + return -1; + wpi.path = path_list_init(); + if (!wpi.path) + return -1; + wpi.fn = fn; + wpi.arg = arg; + + ret = handle_walk_parent_paths(&wpi, hanp); + path_list_free(wpi.path); + + return ret; +} + +/* + * Call the given function on all known paths from the vfs root to the inode + * referred to by the file description. + */ +int +fd_walk_ppaths( + int fd, + walk_ppath_fn fn, + void *arg) +{ + struct walk_ppaths_info wpi; + void *hanp; + size_t hlen; + int fsfd; + int ret; + + ret = fd_to_handle(fd, &hanp, &hlen); + if (ret) + return ret; + + fsfd = handle_to_fsfd(hanp, &wpi.mntpt); + if (fsfd < 0) + return -1; + wpi.fd = fd; + wpi.path = path_list_init(); + if (!wpi.path) + return -1; + wpi.fn = fn; + wpi.arg = arg; + + ret = handle_walk_parent_paths(&wpi, hanp); + path_list_free(wpi.path); + + return ret; +} + +struct path_walk_info { + char *buf; + size_t len; +}; + +/* Helper that stringifies the first full path that we find. */ +static int +handle_to_path_walk( + const char *mntpt, + struct path_list *path, + void *arg) +{ + struct path_walk_info *pwi = arg; + int ret; + + ret = snprintf(pwi->buf, pwi->len, "%s", mntpt); + if (ret != strlen(mntpt)) { + errno = ENOMEM; + return -1; + } + + ret = path_list_to_string(path, pwi->buf + ret, pwi->len - ret); + if (ret < 0) + return ret; + + return WALK_PPATHS_ABORT; +} + +/* Return any eligible path to this file handle. */ +int +handle_to_path( + void *hanp, + size_t hlen, + char *path, + size_t pathlen) +{ + struct path_walk_info pwi; + + pwi.buf = path; + pwi.len = pathlen; + return handle_walk_ppaths(hanp, hlen, handle_to_path_walk, &pwi); +} + +/* Return any eligible path to this file description. */ +int +fd_to_path( + int fd, + char *path, + size_t pathlen) +{ + struct path_walk_info pwi; + + pwi.buf = path; + pwi.len = pathlen; + return fd_walk_ppaths(fd, handle_to_path_walk, &pwi); +} diff --git a/scrub/inodes.c b/scrub/inodes.c index 78f0914b..245dd713 100644 --- a/scrub/inodes.c +++ b/scrub/inodes.c @@ -19,6 +19,7 @@ #include "descr.h" #include "libfrog/fsgeom.h" #include "libfrog/bulkstat.h" +#include "parent.h" /* * Iterate a range of inodes. @@ -449,3 +450,28 @@ scrub_open_handle( return open_by_fshandle(handle, sizeof(*handle), O_RDONLY | O_NOATIME | O_NOFOLLOW | O_NOCTTY); } + +/* Construct a description for an inode. */ +void +xfs_scrub_ino_descr( + struct scrub_ctx *ctx, + struct xfs_handle *handle, + char *buf, + size_t buflen) +{ + uint64_t ino; + xfs_agnumber_t agno; + xfs_agino_t agino; + int ret; + + ret = handle_to_path(handle, sizeof(struct xfs_handle), buf, buflen); + if (ret >= 0) + return; + + ino = handle->ha_fid.fid_ino; + agno = ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog)); + agino = ino % (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog)); + snprintf(buf, buflen, _("inode %"PRIu64" (%u/%u)"), ino, agno, + agino); +} + diff --git a/scrub/inodes.h b/scrub/inodes.h index f0318045..189fa282 100644 --- a/scrub/inodes.h +++ b/scrub/inodes.h @@ -21,5 +21,7 @@ int scrub_scan_all_inodes(struct scrub_ctx *ctx, scrub_inode_iter_fn fn, void *arg); int scrub_open_handle(struct xfs_handle *handle); +void xfs_scrub_ino_descr(struct scrub_ctx *ctx, struct xfs_handle *handle, + char *buf, size_t buflen); #endif /* XFS_SCRUB_INODES_H_ */ From patchwork Thu Feb 16 20:59:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143886 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E7E4C636D7 for ; Thu, 16 Feb 2023 20:59:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230031AbjBPU7y (ORCPT ); Thu, 16 Feb 2023 15:59:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230036AbjBPU7x (ORCPT ); Thu, 16 Feb 2023 15:59:53 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B8F3528B7 for ; Thu, 16 Feb 2023 12:59:48 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 16CDEB829AB for ; Thu, 16 Feb 2023 20:59:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B99C2C433EF; Thu, 16 Feb 2023 20:59:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581185; bh=2yOOOisYta9Q0oC4saoAKOx043xe1MlKQi0lmZKdib0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=i3+VcpNFQb55yfOpBw/23FIXmCXI1bbze8u2LRPoEHuBC4i9jNDWjRG6ETF/rscyq Rh461+pp1faWP2oVG3Q2Rxm1VlBsrjMfAGEXFapTbbRksNJIqwdnuD05mHBDIjVgtn Un6/NjEBa9tlPHp0jGA1EHdpsgV8a6yVU2lzVqEeLJd/K20AzCkh1DrZFXkvGG5Ygr ilZMD0xLDrEqwtkIC8VqHvlN30oAwHUNaX0Q1xZe+ZdyGVNMzq1LLkdxXbDIwHXEaV 95DVSDBENF62j3ex9+CzAeHoh2GpeIEdUQrKQ0PKIYXUd4ScFCiTakfohHnHJe4Ccm RWMeY9S7VJRLA== Date: Thu, 16 Feb 2023 12:59:45 -0800 Subject: [PATCH 24/25] xfsprogs: Add parent pointers during protofile creation From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879228.3476112.6635814832340093972.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson Inodes created from protofile parsing will also need to add the appropriate parent pointers Signed-off-by: Allison Henderson --- mkfs/proto.c | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/mkfs/proto.c b/mkfs/proto.c index 6b6a070f..36d8cde2 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -8,6 +8,7 @@ #include #include "libfrog/convert.h" #include "proto.h" +#include "xfs_parent.h" /* * Prototypes for internal functions. @@ -317,18 +318,19 @@ newregfile( static void newdirent( - xfs_mount_t *mp, - xfs_trans_t *tp, - xfs_inode_t *pip, - struct xfs_name *name, - xfs_ino_t inum) + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_inode *pip, + struct xfs_name *name, + xfs_ino_t inum, + xfs_dir2_dataptr_t *offset) { - int error; - int rsv; + int error; + int rsv; rsv = XFS_DIRENTER_SPACE_RES(mp, name->len); - error = -libxfs_dir_createname(tp, pip, name, inum, rsv, NULL); + error = -libxfs_dir_createname(tp, pip, name, inum, rsv, offset); if (error) fail(_("directory createname error"), error); } @@ -381,6 +383,7 @@ parseproto( struct cred creds; char *value; struct xfs_name xname; + xfs_dir2_dataptr_t offset; memset(&creds, 0, sizeof(creds)); mstr = getstr(pp); @@ -464,7 +467,7 @@ parseproto( free(buf); libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_REG_FILE; - newdirent(mp, tp, pip, &xname, ip->i_ino); + newdirent(mp, tp, pip, &xname, ip->i_ino, &offset); break; case IF_RESERVED: /* pre-allocated space only */ @@ -487,7 +490,7 @@ parseproto( libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_REG_FILE; - newdirent(mp, tp, pip, &xname, ip->i_ino); + newdirent(mp, tp, pip, &xname, ip->i_ino, &offset); libxfs_trans_log_inode(tp, ip, flags); error = -libxfs_trans_commit(tp); if (error) @@ -507,7 +510,7 @@ parseproto( } libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_BLKDEV; - newdirent(mp, tp, pip, &xname, ip->i_ino); + newdirent(mp, tp, pip, &xname, ip->i_ino, &offset); flags |= XFS_ILOG_DEV; break; @@ -521,7 +524,7 @@ parseproto( fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_CHRDEV; - newdirent(mp, tp, pip, &xname, ip->i_ino); + newdirent(mp, tp, pip, &xname, ip->i_ino, &offset); flags |= XFS_ILOG_DEV; break; @@ -533,7 +536,7 @@ parseproto( fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_FIFO; - newdirent(mp, tp, pip, &xname, ip->i_ino); + newdirent(mp, tp, pip, &xname, ip->i_ino, &offset); break; case IF_SYMLINK: buf = getstr(pp); @@ -546,7 +549,7 @@ parseproto( flags |= newfile(tp, ip, 1, 1, buf, len); libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_SYMLINK; - newdirent(mp, tp, pip, &xname, ip->i_ino); + newdirent(mp, tp, pip, &xname, ip->i_ino, &offset); break; case IF_DIRECTORY: tp = getres(mp, 0); @@ -563,7 +566,7 @@ parseproto( } else { libxfs_trans_ijoin(tp, pip, 0); xname.type = XFS_DIR3_FT_DIR; - newdirent(mp, tp, pip, &xname, ip->i_ino); + newdirent(mp, tp, pip, &xname, ip->i_ino, &offset); inc_nlink(VFS_I(pip)); libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); } @@ -599,6 +602,23 @@ parseproto( fail(_("Error encountered creating file from prototype file"), error); } + + if (xfs_has_parent(mp)) { + struct xfs_parent_name_rec rec; + struct xfs_da_args args = { + .dp = ip, + .name = (const unsigned char *)&rec, + .namelen = sizeof(rec), + .attr_filter = XFS_ATTR_PARENT, + .value = (void *)xname.name, + .valuelen = xname.len, + }; + xfs_init_parent_name_rec(&rec, pip, offset); + error = xfs_attr_set(&args); + if (error) + fail(_("Error creating parent pointer"), error); + } + libxfs_irele(ip); } From patchwork Thu Feb 16 21:00:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13143887 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E86AC61DA4 for ; Thu, 16 Feb 2023 21:00:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230034AbjBPVAJ (ORCPT ); Thu, 16 Feb 2023 16:00:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230033AbjBPVAI (ORCPT ); Thu, 16 Feb 2023 16:00:08 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16946521F1 for ; Thu, 16 Feb 2023 13:00:04 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id C8E3BB826BA for ; Thu, 16 Feb 2023 21:00:02 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 80597C433EF; Thu, 16 Feb 2023 21:00:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676581201; bh=1VlrpqX9uVr9veoNR+/lTiM8Gcxu2+TFeq5KUs/hWLw=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=oTJ0WS/XKXBPBvyakOo4JlbvkSoYEQeivipO/1t+OvYfdBxPMzrhKK8hfPBSmfwFO vQlMjoDxWGARd/3AjxDnU5+MgcECtqXu9D7mSoNOBNjRizQCm6zq7FYwS77Rs2g1ol 6BzpakzPTKJnoOMPdzLJm8KdXe5WHV5voWVkrZTxIWddhwjkkmLhEVBwIpnHSWanKe meQVQZay0YSChqr1Pbps1ZQVgMPjomjaVEiaVnA5OYkrh2ZQDwqQW5WTAWbLbkQpNO p631ZgoS5ErS1txpoj4cML7bFfZIXVK0ADAUzQYBjMSAAms5OVEINsMR0nbbRPJtfc W7GBuhDqX4W4Q== Date: Thu, 16 Feb 2023 13:00:00 -0800 Subject: [PATCH 25/25] xfsprogs: Add i, n and f flags to parent command From: "Darrick J. Wong" To: djwong@kernel.org Cc: Allison Henderson , allison.henderson@oracle.com, linux-xfs@vger.kernel.org Message-ID: <167657879242.3476112.116732180377794388.stgit@magnolia> In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia> References: <167657878885.3476112.11949206434283274332.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Allison Henderson This patch adds the flags i, n, and f to the parent command. These flags add filtering options that are used by the new parent pointer tests in xfstests, and help to improve the test run time. The flags are: -i: Only show parent pointer records containing the given inode -n: Only show parent pointer records containing the given filename -f: Print records in short format: ino/gen/namelen/name Signed-off-by: Allison Henderson --- include/parent.h | 17 ++++++++--- io/parent.c | 82 ++++++++++++++++++++++++++++++++++++++++------------ libhandle/parent.c | 73 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 128 insertions(+), 44 deletions(-) diff --git a/include/parent.h b/include/parent.h index fb900041..2e136724 100644 --- a/include/parent.h +++ b/include/parent.h @@ -17,20 +17,27 @@ typedef struct parent_cursor { __u32 opaque[4]; /* an opaque cookie */ } parent_cursor_t; +/* Print parent pointer option flags */ +#define XFS_PPPTR_OFLAG_SHORT (1<<0) /* Print in short format */ + struct path_list; typedef int (*walk_pptr_fn)(struct xfs_pptr_info *pi, struct xfs_parent_ptr *pptr, - void *arg); + void *arg, int flags); typedef int (*walk_ppath_fn)(const char *mntpt, struct path_list *path, void *arg); #define WALK_PPTRS_ABORT 1 -int fd_walk_pptrs(int fd, walk_pptr_fn fn, void *arg); -int handle_walk_pptrs(void *hanp, size_t hanlen, walk_pptr_fn fn, void *arg); +int fd_walk_pptrs(int fd, uint64_t pino, char *pname, walk_pptr_fn fn, + void *arg, int flags); +int handle_walk_pptrs(void *hanp, size_t hanlen, uint64_t pino, char *pname, + walk_pptr_fn fn, void *arg, int flags); #define WALK_PPATHS_ABORT 1 -int fd_walk_ppaths(int fd, walk_ppath_fn fn, void *arg); -int handle_walk_ppaths(void *hanp, size_t hanlen, walk_ppath_fn fn, void *arg); +int fd_walk_ppaths(int fd, uint64_t pino, char *pname, walk_ppath_fn fn, + void *arg, int flags); +int handle_walk_ppaths(void *hanp, size_t hanlen, uint64_t pino, char *pname, + walk_ppath_fn fn, void *arg, int flags); int fd_to_path(int fd, char *path, size_t pathlen); int handle_to_path(void *hanp, size_t hlen, char *path, size_t pathlen); diff --git a/io/parent.c b/io/parent.c index e0ca29eb..a6f3fa0c 100644 --- a/io/parent.c +++ b/io/parent.c @@ -19,7 +19,8 @@ static int pptr_print( struct xfs_pptr_info *pi, struct xfs_parent_ptr *pptr, - void *arg) + void *arg, + int flags) { char buf[XFS_PPTR_MAXNAMELEN + 1]; unsigned int namelen = strlen((char *)pptr->xpp_name); @@ -31,24 +32,36 @@ pptr_print( memcpy(buf, pptr->xpp_name, namelen); buf[namelen] = 0; - printf(_("p_ino = %llu\n"), (unsigned long long)pptr->xpp_ino); - printf(_("p_gen = %u\n"), (unsigned int)pptr->xpp_gen); - printf(_("p_reclen = %u\n"), namelen); - printf(_("p_name = \"%s\"\n\n"), buf); + + if (flags & XFS_PPPTR_OFLAG_SHORT) { + printf("%llu/%u/%u/%s\n", + (unsigned long long)pptr->xpp_ino, + (unsigned int)pptr->xpp_gen, namelen, buf); + } + else { + printf(_("p_ino = %llu\n"), (unsigned long long)pptr->xpp_ino); + printf(_("p_gen = %u\n"), (unsigned int)pptr->xpp_gen); + printf(_("p_reclen = %u\n"), namelen); + printf(_("p_name = \"%s\"\n\n"), buf); + } return 0; } -int +static int print_parents( - struct xfs_handle *handle) + struct xfs_handle *handle, + uint64_t pino, + char *pname, + int flags) { int ret; if (handle) - ret = handle_walk_pptrs(handle, sizeof(*handle), pptr_print, - NULL); + ret = handle_walk_pptrs(handle, sizeof(*handle), pino, + pname, pptr_print, NULL, flags); else - ret = fd_walk_pptrs(file->fd, pptr_print, NULL); + ret = fd_walk_pptrs(file->fd, pino, pname, pptr_print, + NULL, flags); if (ret) perror(file->name); @@ -77,17 +90,21 @@ path_print( return 0; } -int +static int print_paths( - struct xfs_handle *handle) + struct xfs_handle *handle, + uint64_t pino, + char *pname, + int flags) { int ret; if (handle) - ret = handle_walk_ppaths(handle, sizeof(*handle), path_print, - NULL); + ret = handle_walk_ppaths(handle, sizeof(*handle), pino, + pname, path_print, NULL, flags); else - ret = fd_walk_ppaths(file->fd, path_print, NULL); + ret = fd_walk_ppaths(file->fd, pino, pname, path_print, + NULL, flags); if (ret) perror(file->name); return 0; @@ -109,6 +126,9 @@ parent_f( int listpath_flag = 0; int ret; static int tab_init; + uint64_t pino = 0; + char *pname = NULL; + int ppptr_flags = 0; if (!tab_init) { tab_init = 1; @@ -123,11 +143,27 @@ parent_f( } mntpt = fs->fs_dir; - while ((c = getopt(argc, argv, "p")) != EOF) { + while ((c = getopt(argc, argv, "pfi:n:")) != EOF) { switch (c) { case 'p': listpath_flag = 1; break; + case 'i': + pino = strtoull(optarg, &p, 0); + if (*p != '\0' || pino == 0) { + fprintf(stderr, + _("Bad inode number '%s'.\n"), + optarg); + return 0; + } + + break; + case 'n': + pname = optarg; + break; + case 'f': + ppptr_flags |= XFS_PPPTR_OFLAG_SHORT; + break; default: return command_usage(&parent_cmd); } @@ -169,9 +205,11 @@ parent_f( } if (listpath_flag) - exitcode = print_paths(ino ? &handle : NULL); + exitcode = print_paths(ino ? &handle : NULL, + pino, pname, ppptr_flags); else - exitcode = print_parents(ino ? &handle : NULL); + exitcode = print_parents(ino ? &handle : NULL, + pino, pname, ppptr_flags); if (hanp) free_handle(hanp, hlen); @@ -189,6 +227,12 @@ printf(_( " -p -- list the current file's paths up to the root\n" "\n" "If ino and gen are supplied, use them instead.\n" +"\n" +" -i -- Only show parent pointer records containing the given inode\n" +"\n" +" -n -- Only show parent pointer records containing the given filename\n" +"\n" +" -f -- Print records in short format: ino/gen/namelen/filename\n" "\n")); } @@ -199,7 +243,7 @@ parent_init(void) parent_cmd.cfunc = parent_f; parent_cmd.argmin = 0; parent_cmd.argmax = -1; - parent_cmd.args = _("[-p] [ino gen]"); + parent_cmd.args = _("[-p] [ino gen] [-i] [ino] [-n] [name] [-f]"); parent_cmd.flags = CMD_NOMAP_OK; parent_cmd.oneline = _("print parent inodes"); parent_cmd.help = parent_help; diff --git a/libhandle/parent.c b/libhandle/parent.c index ebd0abd5..3de8742c 100644 --- a/libhandle/parent.c +++ b/libhandle/parent.c @@ -40,13 +40,21 @@ xfs_pptr_alloc( return pi; } -/* Walk all parents of the given file handle. */ +/* + * Walk all parents of the given file handle. + * If pino is set, print only the parent pointer + * of that inode. If pname is set, print only the + * parent pointer of that filename + */ static int handle_walk_parents( int fd, struct xfs_handle *handle, + uint64_t pino, + char *pname, walk_pptr_fn fn, - void *arg) + void *arg, + int flags) { struct xfs_pptr_info *pi; struct xfs_parent_ptr *p; @@ -65,13 +73,20 @@ handle_walk_parents( ret = ioctl(fd, XFS_IOC_GETPARENTS, pi); while (!ret) { if (pi->pi_flags & XFS_PPTR_OFLAG_ROOT) { - ret = fn(pi, NULL, arg); + ret = fn(pi, NULL, arg, flags); break; } for (i = 0; i < pi->pi_ptrs_used; i++) { p = xfs_ppinfo_to_pp(pi, i); - ret = fn(pi, p, arg); + if ((pino != 0) && (pino != p->xpp_ino)) + continue; + + if ((pname != NULL) && (strcmp(pname, + (char *)p->xpp_name) != 0)) + continue; + + ret = fn(pi, p, arg, flags); if (ret) goto out_pi; } @@ -92,8 +107,11 @@ int handle_walk_pptrs( void *hanp, size_t hlen, + uint64_t pino, + char *pname, walk_pptr_fn fn, - void *arg) + void *arg, + int flags) { char *mntpt; int fd; @@ -107,17 +125,20 @@ handle_walk_pptrs( if (fd < 0) return -1; - return handle_walk_parents(fd, hanp, fn, arg); + return handle_walk_parents(fd, hanp, pino, pname, fn, arg, flags); } /* Walk all parent pointers of this fd. */ int fd_walk_pptrs( int fd, + uint64_t pino, + char *pname, walk_pptr_fn fn, - void *arg) + void *arg, + int flags) { - return handle_walk_parents(fd, NULL, fn, arg); + return handle_walk_parents(fd, NULL, pino, pname, fn, arg, flags); } struct walk_ppaths_info { @@ -135,13 +156,15 @@ struct walk_ppath_level_info { }; static int handle_walk_parent_paths(struct walk_ppaths_info *wpi, - struct xfs_handle *handle); + struct xfs_handle *handle, uint64_t pino, char *pname, + int flags); static int handle_walk_parent_path_ptr( struct xfs_pptr_info *pi, struct xfs_parent_ptr *p, - void *arg) + void *arg, + int flags) { struct walk_ppath_level_info *wpli = arg; struct walk_ppaths_info *wpi = wpli->wpi; @@ -160,7 +183,7 @@ handle_walk_parent_path_ptr( wpli->newhandle.ha_fid.fid_ino = p->xpp_ino; wpli->newhandle.ha_fid.fid_gen = p->xpp_gen; path_list_add_parent_component(wpi->path, wpli->pc); - ret = handle_walk_parent_paths(wpi, &wpli->newhandle); + ret = handle_walk_parent_paths(wpi, &wpli->newhandle, 0, NULL, 0); path_list_del_component(wpi->path, wpli->pc); if (ret) break; @@ -176,7 +199,10 @@ handle_walk_parent_path_ptr( static int handle_walk_parent_paths( struct walk_ppaths_info *wpi, - struct xfs_handle *handle) + struct xfs_handle *handle, + uint64_t pino, + char *pname, + int flags) { struct walk_ppath_level_info *wpli; int ret; @@ -192,8 +218,8 @@ handle_walk_parent_paths( wpli->wpi = wpi; memcpy(&wpli->newhandle, handle, sizeof(struct xfs_handle)); - ret = handle_walk_parents(wpi->fd, handle, handle_walk_parent_path_ptr, - wpli); + ret = handle_walk_parents(wpi->fd, handle, pino, pname, + handle_walk_parent_path_ptr, wpli, flags); path_component_free(wpli->pc); free(wpli); @@ -208,8 +234,11 @@ int handle_walk_ppaths( void *hanp, size_t hlen, + uint64_t pino, + char *pname, walk_ppath_fn fn, - void *arg) + void *arg, + int flags) { struct walk_ppaths_info wpi; ssize_t ret; @@ -228,7 +257,7 @@ handle_walk_ppaths( wpi.fn = fn; wpi.arg = arg; - ret = handle_walk_parent_paths(&wpi, hanp); + ret = handle_walk_parent_paths(&wpi, hanp, pino, pname, flags); path_list_free(wpi.path); return ret; @@ -241,8 +270,11 @@ handle_walk_ppaths( int fd_walk_ppaths( int fd, + uint64_t pino, + char *pname, walk_ppath_fn fn, - void *arg) + void *arg, + int flags) { struct walk_ppaths_info wpi; void *hanp; @@ -264,7 +296,7 @@ fd_walk_ppaths( wpi.fn = fn; wpi.arg = arg; - ret = handle_walk_parent_paths(&wpi, hanp); + ret = handle_walk_parent_paths(&wpi, hanp, pino, pname, flags); path_list_free(wpi.path); return ret; @@ -310,7 +342,8 @@ handle_to_path( pwi.buf = path; pwi.len = pathlen; - return handle_walk_ppaths(hanp, hlen, handle_to_path_walk, &pwi); + return handle_walk_ppaths(hanp, hlen, 0, NULL, handle_to_path_walk, + &pwi, 0); } /* Return any eligible path to this file description. */ @@ -324,5 +357,5 @@ fd_to_path( pwi.buf = path; pwi.len = pathlen; - return fd_walk_ppaths(fd, handle_to_path_walk, &pwi); + return fd_walk_ppaths(fd, 0, NULL, handle_to_path_walk, &pwi, 0); }