From patchwork Fri Dec 30 22:19:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085567 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 3C67BC4332F for ; Sat, 31 Dec 2022 02:03:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236120AbiLaCDc (ORCPT ); Fri, 30 Dec 2022 21:03:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236143AbiLaCDV (ORCPT ); Fri, 30 Dec 2022 21:03:21 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A2082AF8 for ; Fri, 30 Dec 2022 18:03: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 BB09261C19 for ; Sat, 31 Dec 2022 02:03:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 28436C433EF; Sat, 31 Dec 2022 02:03:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452200; bh=c8807y3+Q+eEQuHSZ/lACy9JdnM+skcHahQLpjbPyHw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=sIVjwoEJ6ibdZYCdIw3ftE50hAfzNRZHLo1qbIFxhOxrc223x3atzbNv3SgG4I5dP Cfg8A5TAH36n1ga4z574Ooh/heARYnJYpr8NbEMOteB12aJqilClLR+Ag5o57CEosE uDF0heLdIfjzx2fg5YqcVNaWhJqaJQ1hFnhLY13zkuKT51VgfNPoKpFLblDDKycWLt TxSQCLTWI6RfRCuxx+zb16WpROMz6rsbZX3aM4m4j7MlLk4uWGtCM5i5mUMWBmhOBr OYzdqV2giUqke25kZl9GUwBEspM+FmKvB9XsWLiCOSfIREA9gh/ta6utPpFujY50ZL TfBd1lgbhFiBg== Subject: [PATCH 01/26] xfs: hoist extent size helpers to libxfs From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:13 -0800 Message-ID: <167243875339.723621.2360895558110300051.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move the extent size helpers to xfs_bmap.c in libxfs since they're used there already. Signed-off-by: Darrick J. Wong --- include/xfs_inode.h | 7 +++++++ libxfs/libxfs_priv.h | 2 -- libxfs/xfs_bmap.c | 41 +++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_bmap.h | 3 +++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 489fd7d107d..3bc5aa2c7cb 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -237,6 +237,11 @@ static inline bool xfs_inode_has_bigrtextents(struct xfs_inode *ip) return XFS_IS_REALTIME_INODE(ip) && ip->i_mount->m_sb.sb_rextsize > 1; } +static inline bool xfs_is_always_cow_inode(struct xfs_inode *ip) +{ + return false; +} + /* Always set the child's GID to this value, even if the parent is setgid. */ #define CRED_FORCE_GID (1U << 0) struct cred { @@ -262,4 +267,6 @@ extern int libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, uint, struct xfs_inode **); extern void libxfs_irele(struct xfs_inode *ip); +#define XFS_DEFAULT_COWEXTSZ_HINT 32 + #endif /* __XFS_INODE_H__ */ diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 63bc6ea7c2b..716e711cde4 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -508,8 +508,6 @@ void __xfs_buf_mark_corrupt(struct xfs_buf *bp, xfs_failaddr_t fa); #define xfs_rotorstep 1 #define xfs_bmap_rtalloc(a) (-ENOSYS) -#define xfs_get_extsz_hint(ip) (0) -#define xfs_get_cowextsz_hint(ip) (0) #define xfs_inode_is_filestream(ip) (0) #define xfs_filestream_lookup_ag(ip) (0) #define xfs_filestream_new_ag(ip,ag) (0) diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index f2af8a012a9..c4a81537ccf 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -6406,3 +6406,44 @@ xfs_bmap_query_all( return xfs_btree_query_all(cur, xfs_bmap_query_range_helper, &query); } + +/* Helper function to extract extent size hint from inode */ +xfs_extlen_t +xfs_get_extsz_hint( + struct xfs_inode *ip) +{ + /* + * No point in aligning allocations if we need to COW to actually + * write to them. + */ + if (xfs_is_always_cow_inode(ip)) + return 0; + if ((ip->i_diflags & XFS_DIFLAG_EXTSIZE) && ip->i_extsize) + return ip->i_extsize; + if (XFS_IS_REALTIME_INODE(ip)) + return ip->i_mount->m_sb.sb_rextsize; + return 0; +} + +/* + * Helper function to extract CoW extent size hint from inode. + * Between the extent size hint and the CoW extent size hint, we + * return the greater of the two. If the value is zero (automatic), + * use the default size. + */ +xfs_extlen_t +xfs_get_cowextsz_hint( + struct xfs_inode *ip) +{ + xfs_extlen_t a, b; + + a = 0; + if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) + a = ip->i_cowextsize; + b = xfs_get_extsz_hint(ip); + + a = max(a, b); + if (a == 0) + return XFS_DEFAULT_COWEXTSZ_HINT; + return a; +} diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h index 9559f7174bb..d870c6a62e4 100644 --- a/libxfs/xfs_bmap.h +++ b/libxfs/xfs_bmap.h @@ -292,4 +292,7 @@ typedef int (*xfs_bmap_query_range_fn)( int xfs_bmap_query_all(struct xfs_btree_cur *cur, xfs_bmap_query_range_fn fn, void *priv); +xfs_extlen_t xfs_get_extsz_hint(struct xfs_inode *ip); +xfs_extlen_t xfs_get_cowextsz_hint(struct xfs_inode *ip); + #endif /* __XFS_BMAP_H__ */ From patchwork Fri Dec 30 22:19:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085568 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 B88A7C4332F for ; Sat, 31 Dec 2022 02:03:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236145AbiLaCDi (ORCPT ); Fri, 30 Dec 2022 21:03:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236143AbiLaCDh (ORCPT ); Fri, 30 Dec 2022 21:03:37 -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 ADA0C10B64 for ; Fri, 30 Dec 2022 18:03: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 dfw.source.kernel.org (Postfix) with ESMTPS id 4915161C5B for ; Sat, 31 Dec 2022 02:03:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A005AC433EF; Sat, 31 Dec 2022 02:03:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452215; bh=n5KvCVS41tqf7u7/7Ro0SZ/U5evfri9SF9hnka4f6fM=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=WaORTVUoO3uhuPk01ww8C/eUOWCOqp342+Dbx9We8Pu0MzP+TIXeLYsaDbJhGqOyj gbzORHVOUiaUTXr4xL+i9MOvLmwnijD+5UMonnEMfMj6njx9rv8VdzqPTtUyQKyyJ/ 2wV+/kOnC9XZ+mUaIjbSTZso13CLVtNk+vMS4jw03CNpE+rzCHvRWhb9Eof2NOtcc+ TN8wNWZGEg63NrN0iagUJnfnRtdkEU2yy7leJEoqim8I46nNtqsY6AqxvD/8MTDTav e9RA6tNXRZE++mVYkf9p0THR3vQ1uDDVEbTjIg8HayxfVvhjDJB/ma7v5VkDFFamzL H06Z+aVhh3zqA== Subject: [PATCH 02/26] xfs: hoist inode flag conversion functions to libxfs From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:13 -0800 Message-ID: <167243875351.723621.2754453083089475155.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Hoist the inode flag conversion functions into libxfs so that we can keep them in sync. Do this by creating a new xfs_inode_util.c file in libxfs. Signed-off-by: Darrick J. Wong --- include/libxfs.h | 1 include/xfs_inode.h | 1 libxfs/Makefile | 2 + libxfs/util.c | 60 ----------------------- libxfs/xfs_bmap.c | 1 libxfs/xfs_inode_util.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_inode_util.h | 14 +++++ 7 files changed, 143 insertions(+), 60 deletions(-) create mode 100644 libxfs/xfs_inode_util.c create mode 100644 libxfs/xfs_inode_util.h diff --git a/include/libxfs.h b/include/libxfs.h index 14f6d629c9f..a4f6e1c2b28 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -68,6 +68,7 @@ struct iomap; #include "xfs_attr_sf.h" #include "xfs_inode_fork.h" #include "xfs_inode_buf.h" +#include "xfs_inode_util.h" #include "xfs_alloc.h" #include "xfs_btree.h" #include "xfs_bmap.h" diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 3bc5aa2c7cb..ef62ac50912 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -10,6 +10,7 @@ /* These match kernel side includes */ #include "xfs_inode_buf.h" #include "xfs_inode_fork.h" +#include "xfs_inode_util.h" struct xfs_trans; struct xfs_mount; diff --git a/libxfs/Makefile b/libxfs/Makefile index 0e43941948d..0d9c4adf82b 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -48,6 +48,7 @@ HFILES = \ xfs_ialloc_btree.h \ xfs_inode_buf.h \ xfs_inode_fork.h \ + xfs_inode_util.h \ xfs_quota_defs.h \ xfs_refcount.h \ xfs_refcount_btree.h \ @@ -96,6 +97,7 @@ CFILES = cache.c \ xfs_iext_tree.c \ xfs_inode_buf.c \ xfs_inode_fork.c \ + xfs_inode_util.c \ xfs_ialloc_btree.c \ xfs_log_rlimit.c \ xfs_refcount.c \ diff --git a/libxfs/util.c b/libxfs/util.c index 3d5ef68d8e7..6b888e9f996 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -150,66 +150,6 @@ current_time(struct inode *inode) return tv; } -STATIC uint16_t -xfs_flags2diflags( - struct xfs_inode *ip, - unsigned int xflags) -{ - /* can't set PREALLOC this way, just preserve it */ - uint16_t di_flags = - (ip->i_diflags & XFS_DIFLAG_PREALLOC); - - if (xflags & FS_XFLAG_IMMUTABLE) - di_flags |= XFS_DIFLAG_IMMUTABLE; - if (xflags & FS_XFLAG_APPEND) - di_flags |= XFS_DIFLAG_APPEND; - if (xflags & FS_XFLAG_SYNC) - di_flags |= XFS_DIFLAG_SYNC; - if (xflags & FS_XFLAG_NOATIME) - di_flags |= XFS_DIFLAG_NOATIME; - if (xflags & FS_XFLAG_NODUMP) - di_flags |= XFS_DIFLAG_NODUMP; - if (xflags & FS_XFLAG_NODEFRAG) - di_flags |= XFS_DIFLAG_NODEFRAG; - if (xflags & FS_XFLAG_FILESTREAM) - di_flags |= XFS_DIFLAG_FILESTREAM; - if (S_ISDIR(VFS_I(ip)->i_mode)) { - if (xflags & FS_XFLAG_RTINHERIT) - di_flags |= XFS_DIFLAG_RTINHERIT; - if (xflags & FS_XFLAG_NOSYMLINKS) - di_flags |= XFS_DIFLAG_NOSYMLINKS; - if (xflags & FS_XFLAG_EXTSZINHERIT) - di_flags |= XFS_DIFLAG_EXTSZINHERIT; - if (xflags & FS_XFLAG_PROJINHERIT) - di_flags |= XFS_DIFLAG_PROJINHERIT; - } else if (S_ISREG(VFS_I(ip)->i_mode)) { - if (xflags & FS_XFLAG_REALTIME) - di_flags |= XFS_DIFLAG_REALTIME; - if (xflags & FS_XFLAG_EXTSIZE) - di_flags |= XFS_DIFLAG_EXTSIZE; - } - - return di_flags; -} - -STATIC uint64_t -xfs_flags2diflags2( - struct xfs_inode *ip, - unsigned int xflags) -{ - uint64_t di_flags2 = - (ip->i_diflags2 & (XFS_DIFLAG2_REFLINK | - XFS_DIFLAG2_BIGTIME | - XFS_DIFLAG2_NREXT64)); - - if (xflags & FS_XFLAG_DAX) - di_flags2 |= XFS_DIFLAG2_DAX; - if (xflags & FS_XFLAG_COWEXTSIZE) - di_flags2 |= XFS_DIFLAG2_COWEXTSIZE; - - return di_flags2; -} - /* Propagate di_flags from a parent inode to a child inode. */ static void xfs_inode_propagate_flags( diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index c4a81537ccf..afa432727db 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -31,6 +31,7 @@ #include "xfs_refcount.h" #include "xfs_health.h" #include "xfs_symlink_remote.h" +#include "xfs_inode_util.h" struct kmem_cache *xfs_bmap_intent_cache; diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c new file mode 100644 index 00000000000..868a77cafa6 --- /dev/null +++ b/libxfs/xfs_inode_util.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2000-2006 Silicon Graphics, Inc. + * All Rights Reserved. + */ +#include "libxfs_priv.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_inode.h" +#include "xfs_inode_util.h" + +uint16_t +xfs_flags2diflags( + struct xfs_inode *ip, + unsigned int xflags) +{ + /* can't set PREALLOC this way, just preserve it */ + uint16_t di_flags = + (ip->i_diflags & XFS_DIFLAG_PREALLOC); + + if (xflags & FS_XFLAG_IMMUTABLE) + di_flags |= XFS_DIFLAG_IMMUTABLE; + if (xflags & FS_XFLAG_APPEND) + di_flags |= XFS_DIFLAG_APPEND; + if (xflags & FS_XFLAG_SYNC) + di_flags |= XFS_DIFLAG_SYNC; + if (xflags & FS_XFLAG_NOATIME) + di_flags |= XFS_DIFLAG_NOATIME; + if (xflags & FS_XFLAG_NODUMP) + di_flags |= XFS_DIFLAG_NODUMP; + if (xflags & FS_XFLAG_NODEFRAG) + di_flags |= XFS_DIFLAG_NODEFRAG; + if (xflags & FS_XFLAG_FILESTREAM) + di_flags |= XFS_DIFLAG_FILESTREAM; + if (S_ISDIR(VFS_I(ip)->i_mode)) { + if (xflags & FS_XFLAG_RTINHERIT) + di_flags |= XFS_DIFLAG_RTINHERIT; + if (xflags & FS_XFLAG_NOSYMLINKS) + di_flags |= XFS_DIFLAG_NOSYMLINKS; + if (xflags & FS_XFLAG_EXTSZINHERIT) + di_flags |= XFS_DIFLAG_EXTSZINHERIT; + if (xflags & FS_XFLAG_PROJINHERIT) + di_flags |= XFS_DIFLAG_PROJINHERIT; + } else if (S_ISREG(VFS_I(ip)->i_mode)) { + if (xflags & FS_XFLAG_REALTIME) + di_flags |= XFS_DIFLAG_REALTIME; + if (xflags & FS_XFLAG_EXTSIZE) + di_flags |= XFS_DIFLAG_EXTSIZE; + } + + return di_flags; +} + +uint64_t +xfs_flags2diflags2( + struct xfs_inode *ip, + unsigned int xflags) +{ + uint64_t di_flags2 = + (ip->i_diflags2 & (XFS_DIFLAG2_REFLINK | + XFS_DIFLAG2_BIGTIME | + XFS_DIFLAG2_NREXT64)); + + if (xflags & FS_XFLAG_DAX) + di_flags2 |= XFS_DIFLAG2_DAX; + if (xflags & FS_XFLAG_COWEXTSIZE) + di_flags2 |= XFS_DIFLAG2_COWEXTSIZE; + + return di_flags2; +} + +uint32_t +xfs_ip2xflags( + struct xfs_inode *ip) +{ + uint32_t flags = 0; + + if (ip->i_diflags & XFS_DIFLAG_ANY) { + if (ip->i_diflags & XFS_DIFLAG_REALTIME) + flags |= FS_XFLAG_REALTIME; + if (ip->i_diflags & XFS_DIFLAG_PREALLOC) + flags |= FS_XFLAG_PREALLOC; + if (ip->i_diflags & XFS_DIFLAG_IMMUTABLE) + flags |= FS_XFLAG_IMMUTABLE; + if (ip->i_diflags & XFS_DIFLAG_APPEND) + flags |= FS_XFLAG_APPEND; + if (ip->i_diflags & XFS_DIFLAG_SYNC) + flags |= FS_XFLAG_SYNC; + if (ip->i_diflags & XFS_DIFLAG_NOATIME) + flags |= FS_XFLAG_NOATIME; + if (ip->i_diflags & XFS_DIFLAG_NODUMP) + flags |= FS_XFLAG_NODUMP; + if (ip->i_diflags & XFS_DIFLAG_RTINHERIT) + flags |= FS_XFLAG_RTINHERIT; + if (ip->i_diflags & XFS_DIFLAG_PROJINHERIT) + flags |= FS_XFLAG_PROJINHERIT; + if (ip->i_diflags & XFS_DIFLAG_NOSYMLINKS) + flags |= FS_XFLAG_NOSYMLINKS; + if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) + flags |= FS_XFLAG_EXTSIZE; + if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) + flags |= FS_XFLAG_EXTSZINHERIT; + if (ip->i_diflags & XFS_DIFLAG_NODEFRAG) + flags |= FS_XFLAG_NODEFRAG; + if (ip->i_diflags & XFS_DIFLAG_FILESTREAM) + flags |= FS_XFLAG_FILESTREAM; + } + + if (ip->i_diflags2 & XFS_DIFLAG2_ANY) { + if (ip->i_diflags2 & XFS_DIFLAG2_DAX) + flags |= FS_XFLAG_DAX; + if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) + flags |= FS_XFLAG_COWEXTSIZE; + } + + if (xfs_inode_has_attr_fork(ip)) + flags |= FS_XFLAG_HASATTR; + return flags; +} diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h new file mode 100644 index 00000000000..6ad1898a0f7 --- /dev/null +++ b/libxfs/xfs_inode_util.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. + * All Rights Reserved. + */ +#ifndef __XFS_INODE_UTIL_H__ +#define __XFS_INODE_UTIL_H__ + +uint16_t xfs_flags2diflags(struct xfs_inode *ip, unsigned int xflags); +uint64_t xfs_flags2diflags2(struct xfs_inode *ip, unsigned int xflags); +uint32_t xfs_dic2xflags(struct xfs_inode *ip); +uint32_t xfs_ip2xflags(struct xfs_inode *ip); + +#endif /* __XFS_INODE_UTIL_H__ */ From patchwork Fri Dec 30 22:19:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085569 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 A29C5C4332F for ; Sat, 31 Dec 2022 02:03:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236146AbiLaCD4 (ORCPT ); Fri, 30 Dec 2022 21:03:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236143AbiLaCDy (ORCPT ); Fri, 30 Dec 2022 21:03:54 -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 B217F2AF8 for ; Fri, 30 Dec 2022 18:03:53 -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 7022DB81C23 for ; Sat, 31 Dec 2022 02:03:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2F1BAC433EF; Sat, 31 Dec 2022 02:03:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452231; bh=9hgBuR3PxBP47oOnbGAHCQkoj0gVExbDqco8knX96hY=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=XZ1fi0jOYO4BLPmkAuTEJii/if71EgCbriujn6c3pxm93qAHnM6ZE5wKloLQGl8RO x8PvLpvrR2gq4BKH6nnZ/9cPpPa/Uc68mZKwCet7w0UlaIfFZhBDsNFuIjTwkoGyQ1 mShob4Plx22L+dBzoG6TabE2NyFu3YHIqYgZuJYxPKibW4pjiD+F3+/Ih/2jO3xTF1 UwhH0xRhLmVIj09S3zkmATg9dL2apESkL2A4DIEaqim1CNU1xGKLRtBrT/FwIYBvr9 +gLMlXzFv1LtAQoW4KQhtJJeSmqhW8NItjqsg3NJfHOGhyY1RIFv0o9aY9KkK81Ggm 7WZuHDtE2YRQg== Subject: [PATCH 03/26] xfs: hoist project id get/set functions to libxfs From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:13 -0800 Message-ID: <167243875362.723621.17855762543390893319.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move the project id get and set functions into libxfs. Signed-off-by: Darrick J. Wong --- libxfs/libxfs_api_defs.h | 2 ++ libxfs/xfs_inode_util.c | 11 +++++++++++ libxfs/xfs_inode_util.h | 2 ++ 3 files changed, 15 insertions(+) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index d871963966c..01ad6e54624 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -135,6 +135,7 @@ #define xfs_free_extent libxfs_free_extent #define xfs_free_perag libxfs_free_perag #define xfs_fs_geometry libxfs_fs_geometry +#define xfs_get_projid libxfs_get_projid #define xfs_highbit32 libxfs_highbit32 #define xfs_highbit64 libxfs_highbit64 #define xfs_ialloc_calc_rootino libxfs_ialloc_calc_rootino @@ -207,6 +208,7 @@ #define xfs_sb_read_secondary libxfs_sb_read_secondary #define xfs_sb_to_disk libxfs_sb_to_disk #define xfs_sb_version_to_features libxfs_sb_version_to_features +#define xfs_set_projid libxfs_set_projid #define xfs_symlink_blocks libxfs_symlink_blocks #define xfs_symlink_hdr_ok libxfs_symlink_hdr_ok #define xfs_symlink_write_target libxfs_symlink_write_target diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c index 868a77cafa6..89fb58807a1 100644 --- a/libxfs/xfs_inode_util.c +++ b/libxfs/xfs_inode_util.c @@ -122,3 +122,14 @@ xfs_ip2xflags( flags |= FS_XFLAG_HASATTR; return flags; } + +#define XFS_PROJID_DEFAULT 0 + +prid_t +xfs_get_initial_prid(struct xfs_inode *dp) +{ + if (dp->i_diflags & XFS_DIFLAG_PROJINHERIT) + return dp->i_projid; + + return XFS_PROJID_DEFAULT; +} diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h index 6ad1898a0f7..f7e4d5a8235 100644 --- a/libxfs/xfs_inode_util.h +++ b/libxfs/xfs_inode_util.h @@ -11,4 +11,6 @@ uint64_t xfs_flags2diflags2(struct xfs_inode *ip, unsigned int xflags); uint32_t xfs_dic2xflags(struct xfs_inode *ip); uint32_t xfs_ip2xflags(struct xfs_inode *ip); +prid_t xfs_get_initial_prid(struct xfs_inode *dp); + #endif /* __XFS_INODE_UTIL_H__ */ From patchwork Fri Dec 30 22:19:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085570 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 0FBF3C4332F for ; Sat, 31 Dec 2022 02:04:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236147AbiLaCEK (ORCPT ); Fri, 30 Dec 2022 21:04:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51844 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236143AbiLaCEJ (ORCPT ); Fri, 30 Dec 2022 21:04:09 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA28110B64 for ; Fri, 30 Dec 2022 18:04: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 dfw.source.kernel.org (Postfix) with ESMTPS id 5856A61C99 for ; Sat, 31 Dec 2022 02:04:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B4CEFC433D2; Sat, 31 Dec 2022 02:04:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452246; bh=0Nz1lS+yQBsStEkRAOZWFj9+npWb2MA6CONBzSr0OgA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=fxXYoaS1DBDcj2PeB5zlEg/mEyrGmIdVr3Z9hYmp1uaQ5feW5q5KwJs7M/+Ch6ian 7w3A0sbpi9qcVHaSqPHeYNTe8JF7io5Wffo/6pvHtzkxFRNH4AHXh5mE4x36aqYt0h 9kCgV3Nfln4lFuo1fUr0o6SSYO60qErLMVrAzau+njUvBOFjrXNl3wiXUWH6qmE2/x AllFlG6yjWBz8lxLw5WvpyrGhk5uFSSx0E2IwavebR/G+Iuos9ZSr5+pvQmw3z3nw8 Yyg+ABHELguW7zBQuBZayk+WEMH1+xQvjJSoDsVEVaxNXUjjVw5iR42P1oVg+oAz6i 5Q4F+KIBKro5w== Subject: [PATCH 04/26] libxfs: put all the inode functions in a single file From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:13 -0800 Message-ID: <167243875374.723621.1245982412844488917.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move all the inode functions into a single source code file. Signed-off-by: Darrick J. Wong --- libxfs/Makefile | 1 libxfs/inode.c | 340 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/rdwr.c | 87 -------------- libxfs/util.c | 222 ------------------------------------ 4 files changed, 341 insertions(+), 309 deletions(-) create mode 100644 libxfs/inode.c diff --git a/libxfs/Makefile b/libxfs/Makefile index 0d9c4adf82b..f9bc82cc9e8 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -64,6 +64,7 @@ HFILES = \ CFILES = cache.c \ defer_item.c \ init.c \ + inode.c \ kmem.c \ logitem.c \ rdwr.c \ diff --git a/libxfs/inode.c b/libxfs/inode.c new file mode 100644 index 00000000000..c7843aea753 --- /dev/null +++ b/libxfs/inode.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. + */ + +#include "libxfs_priv.h" +#include "libxfs.h" +#include "libxfs_io.h" +#include "init.h" +#include "xfs_fs.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_defer.h" +#include "xfs_inode_buf.h" +#include "xfs_inode_fork.h" +#include "xfs_inode.h" +#include "xfs_trans.h" +#include "xfs_bmap.h" +#include "xfs_bmap_btree.h" +#include "xfs_trans_space.h" +#include "xfs_ialloc.h" +#include "xfs_alloc.h" +#include "xfs_bit.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_dir2_priv.h" + +/* Propagate di_flags from a parent inode to a child inode. */ +static void +xfs_inode_propagate_flags( + struct xfs_inode *ip, + const struct xfs_inode *pip) +{ + unsigned int di_flags = 0; + umode_t mode = VFS_I(ip)->i_mode; + + if ((mode & S_IFMT) == S_IFDIR) { + if (pip->i_diflags & XFS_DIFLAG_RTINHERIT) + di_flags |= XFS_DIFLAG_RTINHERIT; + if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { + di_flags |= XFS_DIFLAG_EXTSZINHERIT; + ip->i_extsize = pip->i_extsize; + } + } else { + if ((pip->i_diflags & XFS_DIFLAG_RTINHERIT) && + xfs_has_realtime(ip->i_mount)) + di_flags |= XFS_DIFLAG_REALTIME; + if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { + di_flags |= XFS_DIFLAG_EXTSIZE; + ip->i_extsize = pip->i_extsize; + } + } + if (pip->i_diflags & XFS_DIFLAG_PROJINHERIT) + di_flags |= XFS_DIFLAG_PROJINHERIT; + ip->i_diflags |= di_flags; +} + +/* + * Initialise a newly allocated inode and return the in-core inode to the + * caller locked exclusively. + */ +static int +libxfs_init_new_inode( + struct xfs_trans *tp, + struct xfs_inode *pip, + xfs_ino_t ino, + umode_t mode, + xfs_nlink_t nlink, + dev_t rdev, + struct cred *cr, + struct fsxattr *fsx, + struct xfs_inode **ipp) +{ + struct xfs_inode *ip; + unsigned int flags; + int error; + + error = libxfs_iget(tp->t_mountp, tp, ino, 0, &ip); + if (error != 0) + return error; + ASSERT(ip != NULL); + + VFS_I(ip)->i_mode = mode; + set_nlink(VFS_I(ip), nlink); + i_uid_write(VFS_I(ip), cr->cr_uid); + i_gid_write(VFS_I(ip), cr->cr_gid); + ip->i_projid = pip ? 0 : fsx->fsx_projid; + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD); + + if (pip && (VFS_I(pip)->i_mode & S_ISGID)) { + if (!(cr->cr_flags & CRED_FORCE_GID)) + VFS_I(ip)->i_gid = VFS_I(pip)->i_gid; + if ((VFS_I(pip)->i_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) + VFS_I(ip)->i_mode |= S_ISGID; + } + + ip->i_disk_size = 0; + ip->i_df.if_nextents = 0; + ASSERT(ip->i_nblocks == 0); + ip->i_extsize = pip ? 0 : fsx->fsx_extsize; + ip->i_diflags = pip ? 0 : xfs_flags2diflags(ip, fsx->fsx_xflags); + + if (xfs_has_v3inodes(ip->i_mount)) { + VFS_I(ip)->i_version = 1; + ip->i_diflags2 = ip->i_mount->m_ino_geo.new_diflags2; + if (!pip) + ip->i_diflags2 = xfs_flags2diflags2(ip, + fsx->fsx_xflags); + ip->i_crtime = VFS_I(ip)->i_mtime; /* struct copy */ + ip->i_cowextsize = pip ? 0 : fsx->fsx_cowextsize; + } + + flags = XFS_ILOG_CORE; + switch (mode & S_IFMT) { + case S_IFIFO: + case S_IFSOCK: + /* doesn't make sense to set an rdev for these */ + rdev = 0; + /* FALLTHROUGH */ + case S_IFCHR: + case S_IFBLK: + ip->i_df.if_format = XFS_DINODE_FMT_DEV; + flags |= XFS_ILOG_DEV; + VFS_I(ip)->i_rdev = rdev; + break; + case S_IFREG: + case S_IFDIR: + if (pip && (pip->i_diflags & XFS_DIFLAG_ANY)) + xfs_inode_propagate_flags(ip, pip); + /* FALLTHROUGH */ + case S_IFLNK: + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; + ip->i_df.if_bytes = 0; + ip->i_df.if_u1.if_root = NULL; + break; + default: + ASSERT(0); + } + + /* + * Log the new values stuffed into the inode. + */ + xfs_trans_ijoin(tp, ip, 0); + xfs_trans_log_inode(tp, ip, flags); + *ipp = ip; + return 0; +} + +/* + * Writes a modified inode's changes out to the inode's on disk home. + * Originally based on xfs_iflush_int() from xfs_inode.c in the kernel. + */ +int +libxfs_iflush_int( + struct xfs_inode *ip, + struct xfs_buf *bp) +{ + struct xfs_inode_log_item *iip; + struct xfs_dinode *dip; + struct xfs_mount *mp; + + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || + ip->i_df.if_nextents > ip->i_df.if_ext_max); + + iip = ip->i_itemp; + mp = ip->i_mount; + + /* set *dip = inode's place in the buffer */ + dip = xfs_buf_offset(bp, ip->i_imap.im_boffset); + + if (XFS_ISREG(ip)) { + ASSERT( (ip->i_df.if_format == XFS_DINODE_FMT_EXTENTS) || + (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) ); + } else if (XFS_ISDIR(ip)) { + ASSERT( (ip->i_df.if_format == XFS_DINODE_FMT_EXTENTS) || + (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) || + (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) ); + } + ASSERT(ip->i_df.if_nextents+ip.i_af->if_nextents <= ip->i_nblocks); + ASSERT(ip->i_forkoff <= mp->m_sb.sb_inodesize); + + /* bump the change count on v3 inodes */ + if (xfs_has_v3inodes(mp)) + VFS_I(ip)->i_version++; + + /* + * If there are inline format data / attr forks attached to this inode, + * make sure they are not corrupt. + */ + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL && + xfs_ifork_verify_local_data(ip)) + return -EFSCORRUPTED; + if (xfs_inode_has_attr_fork(ip) && + ip->i_af.if_format == XFS_DINODE_FMT_LOCAL && + xfs_ifork_verify_local_attr(ip)) + return -EFSCORRUPTED; + + /* + * Copy the dirty parts of the inode into the on-disk + * inode. We always copy out the core of the inode, + * because if the inode is dirty at all the core must + * be. + */ + xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn); + + xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); + if (xfs_inode_has_attr_fork(ip)) + xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); + + /* generate the checksum. */ + xfs_dinode_calc_crc(mp, dip); + + return 0; +} + +/* + * Wrapper around call to libxfs_ialloc. Takes care of committing and + * allocating a new transaction as needed. + * + * Originally there were two copies of this code - one in mkfs, the + * other in repair - now there is just the one. + */ +int +libxfs_dir_ialloc( + struct xfs_trans **tpp, + struct xfs_inode *dp, + mode_t mode, + nlink_t nlink, + xfs_dev_t rdev, + struct cred *cr, + struct fsxattr *fsx, + struct xfs_inode **ipp) +{ + xfs_ino_t parent_ino = dp ? dp->i_ino : 0; + xfs_ino_t ino; + int error; + + /* + * Call the space management code to pick the on-disk inode to be + * allocated. + */ + error = xfs_dialloc(tpp, parent_ino, mode, &ino); + if (error) + return error; + + return libxfs_init_new_inode(*tpp, dp, ino, mode, nlink, rdev, cr, + fsx, ipp); +} + +/* + * Inode cache stubs. + */ + +struct kmem_cache *xfs_inode_cache; +extern struct kmem_cache *xfs_ili_cache; + +int +libxfs_iget( + struct xfs_mount *mp, + struct xfs_trans *tp, + xfs_ino_t ino, + uint lock_flags, + struct xfs_inode **ipp) +{ + struct xfs_inode *ip; + struct xfs_buf *bp; + int error = 0; + + ip = kmem_cache_zalloc(xfs_inode_cache, 0); + if (!ip) + return -ENOMEM; + + VFS_I(ip)->i_count = 1; + ip->i_ino = ino; + ip->i_mount = mp; + ip->i_af.if_format = XFS_DINODE_FMT_EXTENTS; + spin_lock_init(&VFS_I(ip)->i_lock); + + error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, 0); + if (error) + goto out_destroy; + + error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp); + if (error) + goto out_destroy; + + error = xfs_inode_from_disk(ip, + xfs_buf_offset(bp, ip->i_imap.im_boffset)); + if (!error) + xfs_buf_set_ref(bp, XFS_INO_REF); + xfs_trans_brelse(tp, bp); + + if (error) + goto out_destroy; + + *ipp = ip; + return 0; + +out_destroy: + kmem_cache_free(xfs_inode_cache, ip); + *ipp = NULL; + return error; +} + +static void +libxfs_idestroy( + struct xfs_inode *ip) +{ + switch (VFS_I(ip)->i_mode & S_IFMT) { + case S_IFREG: + case S_IFDIR: + case S_IFLNK: + libxfs_idestroy_fork(&ip->i_df); + break; + } + + libxfs_ifork_zap_attr(ip); + + if (ip->i_cowfp) { + libxfs_idestroy_fork(ip->i_cowfp); + kmem_cache_free(xfs_ifork_cache, ip->i_cowfp); + } +} + +void +libxfs_irele( + struct xfs_inode *ip) +{ + VFS_I(ip)->i_count--; + + if (VFS_I(ip)->i_count == 0) { + ASSERT(ip->i_itemp == NULL); + libxfs_idestroy(ip); + kmem_cache_free(xfs_inode_cache, ip); + } +} diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index c2dbc51f3f2..2c66b84ff83 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -1121,93 +1121,6 @@ xfs_verify_magic16( return dmagic == bp->b_ops->magic16[idx]; } -/* - * Inode cache stubs. - */ - -struct kmem_cache *xfs_inode_cache; -extern struct kmem_cache *xfs_ili_cache; - -int -libxfs_iget( - struct xfs_mount *mp, - struct xfs_trans *tp, - xfs_ino_t ino, - uint lock_flags, - struct xfs_inode **ipp) -{ - struct xfs_inode *ip; - struct xfs_buf *bp; - int error = 0; - - ip = kmem_cache_zalloc(xfs_inode_cache, 0); - if (!ip) - return -ENOMEM; - - VFS_I(ip)->i_count = 1; - ip->i_ino = ino; - ip->i_mount = mp; - ip->i_af.if_format = XFS_DINODE_FMT_EXTENTS; - spin_lock_init(&VFS_I(ip)->i_lock); - - error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, 0); - if (error) - goto out_destroy; - - error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp); - if (error) - goto out_destroy; - - error = xfs_inode_from_disk(ip, - xfs_buf_offset(bp, ip->i_imap.im_boffset)); - if (!error) - xfs_buf_set_ref(bp, XFS_INO_REF); - xfs_trans_brelse(tp, bp); - - if (error) - goto out_destroy; - - *ipp = ip; - return 0; - -out_destroy: - kmem_cache_free(xfs_inode_cache, ip); - *ipp = NULL; - return error; -} - -static void -libxfs_idestroy(xfs_inode_t *ip) -{ - switch (VFS_I(ip)->i_mode & S_IFMT) { - case S_IFREG: - case S_IFDIR: - case S_IFLNK: - libxfs_idestroy_fork(&ip->i_df); - break; - } - - libxfs_ifork_zap_attr(ip); - - if (ip->i_cowfp) { - libxfs_idestroy_fork(ip->i_cowfp); - kmem_cache_free(xfs_ifork_cache, ip->i_cowfp); - } -} - -void -libxfs_irele( - struct xfs_inode *ip) -{ - VFS_I(ip)->i_count--; - - if (VFS_I(ip)->i_count == 0) { - ASSERT(ip->i_itemp == NULL); - libxfs_idestroy(ip); - kmem_cache_free(xfs_inode_cache, ip); - } -} - /* * Flush everything dirty in the kernel and disk write caches to stable media. * Returns 0 for success or a negative error code. diff --git a/libxfs/util.c b/libxfs/util.c index 6b888e9f996..51a0f513e7a 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -150,194 +150,6 @@ current_time(struct inode *inode) return tv; } -/* Propagate di_flags from a parent inode to a child inode. */ -static void -xfs_inode_propagate_flags( - struct xfs_inode *ip, - const struct xfs_inode *pip) -{ - unsigned int di_flags = 0; - umode_t mode = VFS_I(ip)->i_mode; - - if ((mode & S_IFMT) == S_IFDIR) { - if (pip->i_diflags & XFS_DIFLAG_RTINHERIT) - di_flags |= XFS_DIFLAG_RTINHERIT; - if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { - di_flags |= XFS_DIFLAG_EXTSZINHERIT; - ip->i_extsize = pip->i_extsize; - } - } else { - if ((pip->i_diflags & XFS_DIFLAG_RTINHERIT) && - xfs_has_realtime(ip->i_mount)) - di_flags |= XFS_DIFLAG_REALTIME; - if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { - di_flags |= XFS_DIFLAG_EXTSIZE; - ip->i_extsize = pip->i_extsize; - } - } - if (pip->i_diflags & XFS_DIFLAG_PROJINHERIT) - di_flags |= XFS_DIFLAG_PROJINHERIT; - ip->i_diflags |= di_flags; -} - -/* - * Initialise a newly allocated inode and return the in-core inode to the - * caller locked exclusively. - */ -static int -libxfs_init_new_inode( - struct xfs_trans *tp, - struct xfs_inode *pip, - xfs_ino_t ino, - umode_t mode, - xfs_nlink_t nlink, - dev_t rdev, - struct cred *cr, - struct fsxattr *fsx, - struct xfs_inode **ipp) -{ - struct xfs_inode *ip; - unsigned int flags; - int error; - - error = libxfs_iget(tp->t_mountp, tp, ino, 0, &ip); - if (error != 0) - return error; - ASSERT(ip != NULL); - - VFS_I(ip)->i_mode = mode; - set_nlink(VFS_I(ip), nlink); - i_uid_write(VFS_I(ip), cr->cr_uid); - i_gid_write(VFS_I(ip), cr->cr_gid); - ip->i_projid = pip ? 0 : fsx->fsx_projid; - xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD); - - if (pip && (VFS_I(pip)->i_mode & S_ISGID)) { - if (!(cr->cr_flags & CRED_FORCE_GID)) - VFS_I(ip)->i_gid = VFS_I(pip)->i_gid; - if ((VFS_I(pip)->i_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) - VFS_I(ip)->i_mode |= S_ISGID; - } - - ip->i_disk_size = 0; - ip->i_df.if_nextents = 0; - ASSERT(ip->i_nblocks == 0); - ip->i_extsize = pip ? 0 : fsx->fsx_extsize; - ip->i_diflags = pip ? 0 : xfs_flags2diflags(ip, fsx->fsx_xflags); - - if (xfs_has_v3inodes(ip->i_mount)) { - VFS_I(ip)->i_version = 1; - ip->i_diflags2 = ip->i_mount->m_ino_geo.new_diflags2; - if (!pip) - ip->i_diflags2 = xfs_flags2diflags2(ip, - fsx->fsx_xflags); - ip->i_crtime = VFS_I(ip)->i_mtime; /* struct copy */ - ip->i_cowextsize = pip ? 0 : fsx->fsx_cowextsize; - } - - flags = XFS_ILOG_CORE; - switch (mode & S_IFMT) { - case S_IFIFO: - case S_IFSOCK: - /* doesn't make sense to set an rdev for these */ - rdev = 0; - /* FALLTHROUGH */ - case S_IFCHR: - case S_IFBLK: - ip->i_df.if_format = XFS_DINODE_FMT_DEV; - flags |= XFS_ILOG_DEV; - VFS_I(ip)->i_rdev = rdev; - break; - case S_IFREG: - case S_IFDIR: - if (pip && (pip->i_diflags & XFS_DIFLAG_ANY)) - xfs_inode_propagate_flags(ip, pip); - /* FALLTHROUGH */ - case S_IFLNK: - ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; - ip->i_df.if_bytes = 0; - ip->i_df.if_u1.if_root = NULL; - break; - default: - ASSERT(0); - } - - /* - * Log the new values stuffed into the inode. - */ - xfs_trans_ijoin(tp, ip, 0); - xfs_trans_log_inode(tp, ip, flags); - *ipp = ip; - return 0; -} - -/* - * Writes a modified inode's changes out to the inode's on disk home. - * Originally based on xfs_iflush_int() from xfs_inode.c in the kernel. - */ -int -libxfs_iflush_int( - xfs_inode_t *ip, - struct xfs_buf *bp) -{ - struct xfs_inode_log_item *iip; - struct xfs_dinode *dip; - xfs_mount_t *mp; - - ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || - ip->i_df.if_nextents > ip->i_df.if_ext_max); - - iip = ip->i_itemp; - mp = ip->i_mount; - - /* set *dip = inode's place in the buffer */ - dip = xfs_buf_offset(bp, ip->i_imap.im_boffset); - - if (XFS_ISREG(ip)) { - ASSERT( (ip->i_df.if_format == XFS_DINODE_FMT_EXTENTS) || - (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) ); - } else if (XFS_ISDIR(ip)) { - ASSERT( (ip->i_df.if_format == XFS_DINODE_FMT_EXTENTS) || - (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) || - (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) ); - } - ASSERT(ip->i_df.if_nextents+ip.i_af->if_nextents <= ip->i_nblocks); - ASSERT(ip->i_forkoff <= mp->m_sb.sb_inodesize); - - /* bump the change count on v3 inodes */ - if (xfs_has_v3inodes(mp)) - VFS_I(ip)->i_version++; - - /* - * If there are inline format data / attr forks attached to this inode, - * make sure they are not corrupt. - */ - if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL && - xfs_ifork_verify_local_data(ip)) - return -EFSCORRUPTED; - if (xfs_inode_has_attr_fork(ip) && - ip->i_af.if_format == XFS_DINODE_FMT_LOCAL && - xfs_ifork_verify_local_attr(ip)) - return -EFSCORRUPTED; - - /* - * Copy the dirty parts of the inode into the on-disk - * inode. We always copy out the core of the inode, - * because if the inode is dirty at all the core must - * be. - */ - xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn); - - xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); - if (xfs_inode_has_attr_fork(ip)) - xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); - - /* generate the checksum. */ - xfs_dinode_calc_crc(mp, dip); - - return 0; -} - int libxfs_mod_incore_sb( struct xfs_mount *mp, @@ -442,40 +254,6 @@ libxfs_alloc_file_space( return error; } -/* - * Wrapper around call to libxfs_ialloc. Takes care of committing and - * allocating a new transaction as needed. - * - * Originally there were two copies of this code - one in mkfs, the - * other in repair - now there is just the one. - */ -int -libxfs_dir_ialloc( - struct xfs_trans **tpp, - struct xfs_inode *dp, - mode_t mode, - nlink_t nlink, - xfs_dev_t rdev, - struct cred *cr, - struct fsxattr *fsx, - struct xfs_inode **ipp) -{ - xfs_ino_t parent_ino = dp ? dp->i_ino : 0; - xfs_ino_t ino; - int error; - - /* - * Call the space management code to pick the on-disk inode to be - * allocated. - */ - error = xfs_dialloc(tpp, parent_ino, mode, &ino); - if (error) - return error; - - return libxfs_init_new_inode(*tpp, dp, ino, mode, nlink, rdev, cr, - fsx, ipp); -} - void cmn_err(int level, char *fmt, ...) { From patchwork Fri Dec 30 22:19:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085571 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 44977C3DA7C for ; Sat, 31 Dec 2022 02:04:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236143AbiLaCE0 (ORCPT ); Fri, 30 Dec 2022 21:04:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236148AbiLaCEZ (ORCPT ); Fri, 30 Dec 2022 21:04:25 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 07BB8178A5 for ; Fri, 30 Dec 2022 18:04:25 -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 AB04CB81D63 for ; Sat, 31 Dec 2022 02:04:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 545B3C433EF; Sat, 31 Dec 2022 02:04:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452262; bh=1I8vjx1anjdjEC4TmUNaTtzTF/xQg3nLvg2APpdwBGs=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=PkyG5FNpIYgOaCRuDYqo8O6+0gzWsf/u3oUGtOvAMjHPtQDNHZB2XXb2PxBWSnjJP Vn0nBdeNmKWb283o8UcSmsKP5SezQKw3ts2gYMB4fyBQ2zGvrOPk8fF5IYz4Dtr1/F h5wC9crbvJiHGHlSIc3LDYUfYs6TIHo0a/oxJrkOqySzhcNpLtuKoLPNcnTXNCIXPb BkVV2kaxwVzy7rIxk4wXWMAZ8e57t1NMi1VwgbEb5nNF1s3t7rvUXPIluSKnbWJwfT cjlHuO35hOyb1gWpFEo2x7DOpqHWnrr7o9YauJSZ1RCgQBOaK02gH5SA9D9IiXZMRX PlQIRYhPPQ76A== Subject: [PATCH 05/26] libxfs: pass IGET flags through to xfs_iread From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:13 -0800 Message-ID: <167243875385.723621.4220111121208397182.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Change the lock_flags parameter to iget_flags so that we can supply XFS_IGET_ flags in future patches. All callers of libxfs_iget and libxfs_trans_iget pass zero for this parameter and there are no inode locks in xfsprogs, so there's no behavior change here. Port the kernel's version of the xfs_inode_from_disk callsite. Signed-off-by: Darrick J. Wong --- libxfs/inode.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/libxfs/inode.c b/libxfs/inode.c index c7843aea753..588aff33ef4 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -263,11 +263,10 @@ libxfs_iget( struct xfs_mount *mp, struct xfs_trans *tp, xfs_ino_t ino, - uint lock_flags, + uint flags, struct xfs_inode **ipp) { struct xfs_inode *ip; - struct xfs_buf *bp; int error = 0; ip = kmem_cache_zalloc(xfs_inode_cache, 0); @@ -284,18 +283,35 @@ libxfs_iget( if (error) goto out_destroy; - error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp); - if (error) - goto out_destroy; + /* + * For version 5 superblocks, if we are initialising a new inode and we + * are not utilising the XFS_MOUNT_IKEEP inode cluster mode, we can + * simply build the new inode core with a random generation number. + * + * For version 4 (and older) superblocks, log recovery is dependent on + * the di_flushiter field being initialised from the current on-disk + * value and hence we must also read the inode off disk even when + * initializing new inodes. + */ + if (xfs_has_v3inodes(mp) && + (flags & XFS_IGET_CREATE) && !xfs_has_ikeep(mp)) { + VFS_I(ip)->i_generation = get_random_u32(); + } else { + struct xfs_buf *bp; - error = xfs_inode_from_disk(ip, - xfs_buf_offset(bp, ip->i_imap.im_boffset)); - if (!error) - xfs_buf_set_ref(bp, XFS_INO_REF); - xfs_trans_brelse(tp, bp); + error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp); + if (error) + goto out_destroy; - if (error) - goto out_destroy; + error = xfs_inode_from_disk(ip, + xfs_buf_offset(bp, ip->i_imap.im_boffset)); + if (!error) + xfs_buf_set_ref(bp, XFS_INO_REF); + xfs_trans_brelse(tp, bp); + + if (error) + goto out_destroy; + } *ipp = ip; return 0; From patchwork Fri Dec 30 22:19:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085572 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 500D3C4332F for ; Sat, 31 Dec 2022 02:04:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236149AbiLaCEl (ORCPT ); Fri, 30 Dec 2022 21:04:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCEj (ORCPT ); Fri, 30 Dec 2022 21:04:39 -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 DB1E9140DE for ; Fri, 30 Dec 2022 18:04:38 -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 6C34561CAA for ; Sat, 31 Dec 2022 02:04:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7193C433D2; Sat, 31 Dec 2022 02:04:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452277; bh=VdSItYacWaQFCe8dud2wFaM30HEoSzH9jW3/e5UxbAg=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=IkzNZYe7ocw96jVw+iQOqIJNPPLuOhqmcd4wz2EslYD1ddVVXD0MD12d7inQdGM1d DkNXp6/6Q2zAkaayiPxHAlQDUfIoEdci5CjwwoW8XrugemynBylXHEsCOxyGngz86+ xV6OFGYByRh+951ppMMAf53joUkHNbYVyO0Qx2pjNY+31I6zCekDFA6TfofdDKQ2OV 9bTFRA0kbVm+HTrhxMkemDkLeEplS6ChRj4NJtEc20oLKJ5OECAlYEnI8DM6UCNfh/ Di3lQOwMcehMUTK7u8llDMBR98VXPjgstFQkiAM+9CXTgx2RqPzcki3waqbCvVuJSj a462ctxnY47QQ== Subject: [PATCH 06/26] libxfs: pack icreate initialization parameters into a separate structure From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:13 -0800 Message-ID: <167243875397.723621.6141500117189027371.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Callers that want to create an inode currently pass all possible file attribute values for the new inode into xfs_init_new_inode as ten separate parameters. This causes two code maintenance issues: first, we have large multi-line call sites which programmers must read carefully to make sure they did not accidentally invert a value. Second, all three file id parameters must be passed separately to the quota functions; any discrepancy results in quota count errors. Clean this up by creating a new icreate_args structure to hold all this information, some helpers to initialize them properly, and make the callers pass this structure through to the creation function, whose name we shorten to xfs_icreate. This eliminates the issues, enables us to keep the inode init code in sync with userspace via libxfs, and is needed for future metadata directory tree management. (A subsequent cleanup will also fix the quota alloc calls and remove libxfs_dir_ialloc entirely.) Signed-off-by: Darrick J. Wong --- include/xfs_inode.h | 37 +++++++++++++++++++---- libxfs/inode.c | 75 ++++++++++++++++++++++++++++------------------- libxfs/xfs_inode_util.h | 31 +++++++++++++++++++ 3 files changed, 107 insertions(+), 36 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index ef62ac50912..bf8322ee2ec 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -7,6 +7,31 @@ #ifndef __XFS_INODE_H__ #define __XFS_INODE_H__ +/* + * Borrow the kernel's uid/gid types. These are used by xfs_inode_util.h, so + * they must come first in the header file. + */ + +typedef struct { + uid_t val; +} kuid_t; + +typedef struct { + gid_t val; +} kgid_t; + +static inline kuid_t make_kuid(uid_t uid) +{ + kuid_t v = { .val = uid }; + return v; +} + +static inline kgid_t make_kgid(gid_t gid) +{ + kgid_t v = { .val = gid }; + return v; +} + /* These match kernel side includes */ #include "xfs_inode_buf.h" #include "xfs_inode_fork.h" @@ -33,8 +58,8 @@ struct xfs_inode_log_item; */ struct inode { mode_t i_mode; - uint32_t i_uid; - uint32_t i_gid; + kuid_t i_uid; + kgid_t i_gid; uint32_t i_nlink; xfs_dev_t i_rdev; /* This actually holds xfs_dev_t */ unsigned int i_count; @@ -49,19 +74,19 @@ struct inode { static inline uint32_t i_uid_read(struct inode *inode) { - return inode->i_uid; + return inode->i_uid.val; } static inline uint32_t i_gid_read(struct inode *inode) { - return inode->i_gid; + return inode->i_gid.val; } static inline void i_uid_write(struct inode *inode, uint32_t uid) { - inode->i_uid = uid; + inode->i_uid.val = uid; } static inline void i_gid_write(struct inode *inode, uint32_t gid) { - inode->i_gid = gid; + inode->i_gid.val = gid; } static inline void ihold(struct inode *inode) diff --git a/libxfs/inode.c b/libxfs/inode.c index 588aff33ef4..63150422b01 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -64,17 +64,13 @@ xfs_inode_propagate_flags( * caller locked exclusively. */ static int -libxfs_init_new_inode( +libxfs_icreate( struct xfs_trans *tp, - struct xfs_inode *pip, xfs_ino_t ino, - umode_t mode, - xfs_nlink_t nlink, - dev_t rdev, - struct cred *cr, - struct fsxattr *fsx, + const struct xfs_icreate_args *args, struct xfs_inode **ipp) { + struct xfs_inode *pip = args->pip; struct xfs_inode *ip; unsigned int flags; int error; @@ -84,48 +80,41 @@ libxfs_init_new_inode( return error; ASSERT(ip != NULL); - VFS_I(ip)->i_mode = mode; - set_nlink(VFS_I(ip), nlink); - i_uid_write(VFS_I(ip), cr->cr_uid); - i_gid_write(VFS_I(ip), cr->cr_gid); - ip->i_projid = pip ? 0 : fsx->fsx_projid; + VFS_I(ip)->i_mode = args->mode; + set_nlink(VFS_I(ip), args->nlink); + VFS_I(ip)->i_uid = args->uid; + ip->i_projid = args->prid; xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD); if (pip && (VFS_I(pip)->i_mode & S_ISGID)) { - if (!(cr->cr_flags & CRED_FORCE_GID)) + if (!(args->flags & XFS_ICREATE_ARGS_FORCE_GID)) VFS_I(ip)->i_gid = VFS_I(pip)->i_gid; - if ((VFS_I(pip)->i_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) + if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(args->mode)) VFS_I(ip)->i_mode |= S_ISGID; - } + } else + VFS_I(ip)->i_gid = args->gid; ip->i_disk_size = 0; ip->i_df.if_nextents = 0; ASSERT(ip->i_nblocks == 0); - ip->i_extsize = pip ? 0 : fsx->fsx_extsize; - ip->i_diflags = pip ? 0 : xfs_flags2diflags(ip, fsx->fsx_xflags); - + ip->i_extsize = 0; + ip->i_diflags = 0; if (xfs_has_v3inodes(ip->i_mount)) { VFS_I(ip)->i_version = 1; ip->i_diflags2 = ip->i_mount->m_ino_geo.new_diflags2; - if (!pip) - ip->i_diflags2 = xfs_flags2diflags2(ip, - fsx->fsx_xflags); - ip->i_crtime = VFS_I(ip)->i_mtime; /* struct copy */ - ip->i_cowextsize = pip ? 0 : fsx->fsx_cowextsize; + ip->i_crtime = VFS_I(ip)->i_mtime; + ip->i_cowextsize = 0; } flags = XFS_ILOG_CORE; - switch (mode & S_IFMT) { + switch (args->mode & S_IFMT) { case S_IFIFO: case S_IFSOCK: - /* doesn't make sense to set an rdev for these */ - rdev = 0; - /* FALLTHROUGH */ case S_IFCHR: case S_IFBLK: ip->i_df.if_format = XFS_DINODE_FMT_DEV; flags |= XFS_ILOG_DEV; - VFS_I(ip)->i_rdev = rdev; + VFS_I(ip)->i_rdev = args->rdev; break; case S_IFREG: case S_IFDIR: @@ -235,10 +224,22 @@ libxfs_dir_ialloc( struct fsxattr *fsx, struct xfs_inode **ipp) { + struct xfs_icreate_args args = { + .pip = dp, + .uid = make_kuid(cr->cr_uid), + .gid = make_kgid(cr->cr_gid), + .nlink = nlink, + .rdev = rdev, + .mode = mode, + }; + struct xfs_inode *ip; xfs_ino_t parent_ino = dp ? dp->i_ino : 0; xfs_ino_t ino; int error; + if (cr->cr_flags & CRED_FORCE_GID) + args.flags |= XFS_ICREATE_ARGS_FORCE_GID; + /* * Call the space management code to pick the on-disk inode to be * allocated. @@ -247,8 +248,22 @@ libxfs_dir_ialloc( if (error) return error; - return libxfs_init_new_inode(*tpp, dp, ino, mode, nlink, rdev, cr, - fsx, ipp); + error = libxfs_icreate(*tpp, ino, &args, ipp); + if (error || dp) + return error; + + /* If there is no parent dir, initialize the file from fsxattr data. */ + ip = *ipp; + ip->i_projid = fsx->fsx_projid; + ip->i_extsize = fsx->fsx_extsize; + ip->i_diflags = xfs_flags2diflags(ip, fsx->fsx_xflags); + + if (xfs_has_v3inodes(ip->i_mount)) { + ip->i_diflags2 = xfs_flags2diflags2(ip, fsx->fsx_xflags); + ip->i_cowextsize = fsx->fsx_cowextsize; + } + xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); + return 0; } /* diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h index f7e4d5a8235..466f0767ab5 100644 --- a/libxfs/xfs_inode_util.h +++ b/libxfs/xfs_inode_util.h @@ -13,4 +13,35 @@ uint32_t xfs_ip2xflags(struct xfs_inode *ip); prid_t xfs_get_initial_prid(struct xfs_inode *dp); +/* + * Initial ids, link count, device number, and mode of a new inode. + * + * Due to our only partial reliance on the VFS to propagate uid and gid values + * according to accepted Unix behaviors, callers must initialize mnt_userns to + * the appropriate namespace, uid to fsuid_into_mnt(), and gid to + * fsgid_into_mnt() to get the correct inheritance behaviors when + * XFS_MOUNT_GRPID is set. Use the xfs_ialloc_inherit_args() helper. + * + * To override the default ids, use the FORCE flags defined below. + */ +struct xfs_icreate_args { + struct user_namespace *mnt_userns; + struct xfs_inode *pip; /* parent inode or null */ + + kuid_t uid; + kgid_t gid; + prid_t prid; + + xfs_nlink_t nlink; + dev_t rdev; + + umode_t mode; + +#define XFS_ICREATE_ARGS_FORCE_UID (1 << 0) +#define XFS_ICREATE_ARGS_FORCE_GID (1 << 1) +#define XFS_ICREATE_ARGS_FORCE_MODE (1 << 2) +#define XFS_ICREATE_ARGS_INIT_XATTRS (1 << 3) + uint16_t flags; +}; + #endif /* __XFS_INODE_UTIL_H__ */ From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085573 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 62ACEC4332F for ; Sat, 31 Dec 2022 02:04:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236148AbiLaCE4 (ORCPT ); Fri, 30 Dec 2022 21:04:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCEz (ORCPT ); Fri, 30 Dec 2022 21:04:55 -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 6690810B64 for ; Fri, 30 Dec 2022 18:04:54 -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 0466661C19 for ; Sat, 31 Dec 2022 02:04:54 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68029C433D2; Sat, 31 Dec 2022 02:04:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452293; bh=dJ+x5WB/TPMO/qyO3qHsGTAoMXBKAMjyN4dQmcFYlE0=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=aU8VaZEKHGPhNYCzIn+LjeR/BTQysE2XWcEuRErgYLq/AfWa9cxYKlZBIdi331Gdb midhf7SoV+0SOEP4rcD2EXjrxSx1XKnwxQIf4FuVrUTthIbTep5yF9WTNwcjYiMri1 eXE+PITG5yMezdVPtDxd5N4A2hzjPyR27EMbylqGl2Bj1HmjINDqfBbWjfQ2GSeIix rMepPjChSoIkkv6rd+e4kwvHOQbDB84QpS7AHXecSJ11VpzYcX5X/ObAt8XRzA2CVX 0vUfTLrtplP4sK5IhZsRdh3doUr8ViD8rnBswvO+dhjb6zBBv5jv2G7/E5dp/gfccD R2ZMsgZK3B+EQ== Subject: [PATCH 07/26] libxfs: implement access timestamp updates in ichgtime From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875408.723621.3329159476206704247.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Implement access time updates in ichgtime so that we can use the common ichgtime function when setting up inodes. Signed-off-by: Darrick J. Wong --- libxfs/xfs_shared.h | 1 + libxfs/xfs_trans_inode.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h index 5127fa88531..acf527eb0e1 100644 --- a/libxfs/xfs_shared.h +++ b/libxfs/xfs_shared.h @@ -137,6 +137,7 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp, #define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ #define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ #define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */ +#define XFS_ICHGTIME_ACCESS 0x8 /* last access timestamp */ /* Computed inode geometry for the filesystem. */ struct xfs_ino_geometry { diff --git a/libxfs/xfs_trans_inode.c b/libxfs/xfs_trans_inode.c index 276d57cf737..6fc7a65d517 100644 --- a/libxfs/xfs_trans_inode.c +++ b/libxfs/xfs_trans_inode.c @@ -66,6 +66,8 @@ xfs_trans_ichgtime( inode->i_mtime = tv; if (flags & XFS_ICHGTIME_CHG) inode->i_ctime = tv; + if (flags & XFS_ICHGTIME_ACCESS) + inode->i_atime = tv; if (flags & XFS_ICHGTIME_CREATE) ip->i_crtime = tv; } From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085574 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 3688BC4332F for ; Sat, 31 Dec 2022 02:05:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236152AbiLaCFL (ORCPT ); Fri, 30 Dec 2022 21:05:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCFK (ORCPT ); Fri, 30 Dec 2022 21:05:10 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E64E92AF8 for ; Fri, 30 Dec 2022 18:05:09 -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 8319461CAA for ; Sat, 31 Dec 2022 02:05:09 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DE997C433D2; Sat, 31 Dec 2022 02:05:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452308; bh=mFfOvtEVcrc5Vkc68RqXpVGDcJWrgAQ3DMvn8TI1aaQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=hOwBohAuIKs2OjxNY1FrY40d750/U63p9Yid3mW8QJ9honQ9nlKkcFVumyl+s6iuY meuul0Qr5asshU+0CG4uj5as/lYBgVhDKjoube5Z+LQfIn4Ao9ZxIvmx0kPmbD9tgp IT54gBKIts0a4Al9BJeT4bFmH0yfNBKHki7JCYsXetkj6LyLP5feVInbd37L2ACfuV hge+bwBFNzcFZCiUnFH8huBTPJCb0//sgJnVQgLLTqNSXzfbxfgHCmATLyDgDqrb82 t/0W6srWj2cUIBuKbjzpotU+NIwM/HaBCxNRLMO3kHpDOD4BQT+CFWTM1RS4t+GYXL ccLyY2kOqkOvA== Subject: [PATCH 08/26] libxfs: rearrange libxfs_trans_ichgtime call when creating inodes From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875420.723621.13673052362667514239.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Rearrange the libxfs_trans_ichgtime call in libxfs_ialloc so that we call it once with the flags we want. Signed-off-by: Darrick J. Wong --- libxfs/inode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libxfs/inode.c b/libxfs/inode.c index 63150422b01..c14a4c5a27f 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -73,6 +73,7 @@ libxfs_icreate( struct xfs_inode *pip = args->pip; struct xfs_inode *ip; unsigned int flags; + int times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; int error; error = libxfs_iget(tp->t_mountp, tp, ino, 0, &ip); @@ -84,7 +85,6 @@ libxfs_icreate( set_nlink(VFS_I(ip), args->nlink); VFS_I(ip)->i_uid = args->uid; ip->i_projid = args->prid; - xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD); if (pip && (VFS_I(pip)->i_mode & S_ISGID)) { if (!(args->flags & XFS_ICREATE_ARGS_FORCE_GID)) @@ -102,10 +102,12 @@ libxfs_icreate( if (xfs_has_v3inodes(ip->i_mount)) { VFS_I(ip)->i_version = 1; ip->i_diflags2 = ip->i_mount->m_ino_geo.new_diflags2; - ip->i_crtime = VFS_I(ip)->i_mtime; ip->i_cowextsize = 0; + times |= XFS_ICHGTIME_CREATE; } + xfs_trans_ichgtime(tp, ip, times); + flags = XFS_ILOG_CORE; switch (args->mode & S_IFMT) { case S_IFIFO: From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085575 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 8D90EC4332F for ; Sat, 31 Dec 2022 02:05:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236153AbiLaCF2 (ORCPT ); Fri, 30 Dec 2022 21:05:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCF1 (ORCPT ); Fri, 30 Dec 2022 21:05:27 -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 14A952AF8 for ; Fri, 30 Dec 2022 18:05:27 -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 C131BB81C23 for ; Sat, 31 Dec 2022 02:05:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73286C433D2; Sat, 31 Dec 2022 02:05:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452324; bh=HvJQNooKpEqCgg1vfdBOGkA1mLQKJ7kFlKYpE5JOVZw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=b6J3+j24VDdF2d9g5rejrPtci52HJZINLFIxL/5nJuNIuOmKzzEja8h4PDlc/BO0L v+RYuGrq4XiMWZmPcHB9ZzO0U+RCPNHeC423vXeN3KZmQd7np+wD4wSlYJqdN/dC3n DRQ2jQz9oPkhmp5/L8Jpco7HTFYX0hSiBMSXmUfQZlgKKqOItn5yCpcpDyQgECOJfE sUUS7ySVGXKTEiobnP9KoAGHXxlqXUoUyLKdi0B60nYV3N+4t8lY4kln4RAtp9uORb IhpA0jy3eMJA9sdLnmRFXklKr18Bfh6L+X7LDUNF9MyrzfsHR5WXFkWp/RZ1pg34tv z2PesH4LaXRdQ== Subject: [PATCH 09/26] libxfs: set access time when creating files From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875431.723621.17001516036883152447.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Set the access time on files that we're creating, to match the behavior of the kernel. Signed-off-by: Darrick J. Wong --- libxfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libxfs/inode.c b/libxfs/inode.c index c14a4c5a27f..7f8f1164e08 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -73,7 +73,8 @@ libxfs_icreate( struct xfs_inode *pip = args->pip; struct xfs_inode *ip; unsigned int flags; - int times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; + int times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG | + XFS_ICHGTIME_ACCESS; int error; error = libxfs_iget(tp->t_mountp, tp, ino, 0, &ip); From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085576 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 5A4EEC4332F for ; Sat, 31 Dec 2022 02:05:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236154AbiLaCFo (ORCPT ); Fri, 30 Dec 2022 21:05:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCFn (ORCPT ); Fri, 30 Dec 2022 21:05:43 -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 6EFC22AF8 for ; Fri, 30 Dec 2022 18:05:42 -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 34117B81DD1 for ; Sat, 31 Dec 2022 02:05:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00168C433EF; Sat, 31 Dec 2022 02:05:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452340; bh=8ainxc/DtULUp4Aovq2lDxJIEgJHpkVe6xt4WLPseX8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=KyTOS8uSrkkQiTRpDFu0pcTaF365f/TyQpIy+jc88z6gtYplDwKWHMMEYOol/dmGy VbFG9rjtqAVzvcv2p7PThb6VOr4SVU+mQRnoAOILPXQ4ax1vT7yRA2eusAJRDaxQqz 459R/L845Wl6EiGNgAjb4dxj/dRYQ0BN8cL/fB/T4X20atjaALLxbWyo20a8ycldYH Wgb95zT2zh/XtLKH5yvNzSsgMrQcLPdb0LNlcT5Nwvfsk7tBfwL3NVK1b5WJFLkp7L tBrMUGv9C0I78rIXGb3c+KI8Wdmv91BX63Mk6mmCEBSeRt+2CqaacgqsxU4ds3ymL/ bTyFBBC0xTznQ== Subject: [PATCH 10/26] libxfs: when creating a file in a directory, set the project id based on the parent From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875442.723621.1176728186923814951.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong When we're creating a file as a child of an existing directory, use xfs_get_initial_prid to have the child inherit the project id of the directory if the directory has PROJINHERIT set, just like the kernel does. This fixes mkfs project id propagation with -d projinherit=X when protofiles are in use. Signed-off-by: Darrick J. Wong --- libxfs/inode.c | 1 + libxfs/libxfs_api_defs.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libxfs/inode.c b/libxfs/inode.c index 7f8f1164e08..c63cc0543d6 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -231,6 +231,7 @@ libxfs_dir_ialloc( .pip = dp, .uid = make_kuid(cr->cr_uid), .gid = make_kgid(cr->cr_gid), + .prid = dp ? libxfs_get_initial_prid(dp) : 0, .nlink = nlink, .rdev = rdev, .mode = mode, diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 01ad6e54624..5752733a833 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -136,6 +136,7 @@ #define xfs_free_perag libxfs_free_perag #define xfs_fs_geometry libxfs_fs_geometry #define xfs_get_projid libxfs_get_projid +#define xfs_get_initial_prid libxfs_get_initial_prid #define xfs_highbit32 libxfs_highbit32 #define xfs_highbit64 libxfs_highbit64 #define xfs_ialloc_calc_rootino libxfs_ialloc_calc_rootino From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085577 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 C4AD6C4332F for ; Sat, 31 Dec 2022 02:05:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236155AbiLaCF6 (ORCPT ); Fri, 30 Dec 2022 21:05:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCF5 (ORCPT ); Fri, 30 Dec 2022 21:05:57 -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 836071021 for ; Fri, 30 Dec 2022 18:05:56 -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 22A3F61CB1 for ; Sat, 31 Dec 2022 02:05:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85CD7C433EF; Sat, 31 Dec 2022 02:05:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452355; bh=mLpfzIp/FIGuKvfEQ4BTBFAUkduH6cnlmvtaIV9TJGc=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=hwCQ9SwCQEucT1PaJvVj2Dr6vuSwzES6OeAtotdAajaTCo7vWrycn6w5D1bVD2rLM M320lrpP7JdtkKjrLlIIzqTEzbY+zC5mak9U9l9c0VH8dz8oEZ3o/7R7cOkpiQ64a3 Xd1X5guRZyfGMb+s/Lj02SnkpD/d+Ftsiou58TlSl+t5KbAUKkVHEldEsX8FPOVl/y 3VmvN/hfxFpfy2lTUuH0Unuo6gD1RbIcrjM4/g36WAGvISS7f7CUW9jpEpR4YbGU+N 5F4CJwiy/5eriWR0QWqafEguSJWyZoI4vzmfUPA/QjZo96uVssNZ0S1WafrMYNiTH0 d6CuVvxHsLvTw== Subject: [PATCH 11/26] libxfs: pass flags2 from parent to child when creating files From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875454.723621.6299952463214494674.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong When mkfs creates a new file as a child of an existing directory, we should propagate the flags2 field from parent to child like the kernel does. This ensures that mkfs propagates cowextsize hints properly when protofiles are in use. Signed-off-by: Darrick J. Wong --- libxfs/inode.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libxfs/inode.c b/libxfs/inode.c index c63cc0543d6..9835c708021 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -59,6 +59,20 @@ xfs_inode_propagate_flags( ip->i_diflags |= di_flags; } +/* Propagate di_flags2 from a parent inode to a child inode. */ +static void +xfs_inode_inherit_flags2( + struct xfs_inode *ip, + const struct xfs_inode *pip) +{ + if (pip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) { + ip->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE; + ip->i_cowextsize = pip->i_cowextsize; + } + if (pip->i_diflags2 & XFS_DIFLAG2_DAX) + ip->i_diflags2 |= XFS_DIFLAG2_DAX; +} + /* * Initialise a newly allocated inode and return the in-core inode to the * caller locked exclusively. @@ -123,6 +137,8 @@ libxfs_icreate( case S_IFDIR: if (pip && (pip->i_diflags & XFS_DIFLAG_ANY)) xfs_inode_propagate_flags(ip, pip); + if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY)) + xfs_inode_inherit_flags2(ip, pip); /* FALLTHROUGH */ case S_IFLNK: ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085578 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 CEA75C4332F for ; Sat, 31 Dec 2022 02:06:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236156AbiLaCGN (ORCPT ); Fri, 30 Dec 2022 21:06:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52466 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCGM (ORCPT ); Fri, 30 Dec 2022 21:06:12 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1EF221021 for ; Fri, 30 Dec 2022 18:06:12 -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 AB3EC61CBD for ; Sat, 31 Dec 2022 02:06:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14490C433D2; Sat, 31 Dec 2022 02:06:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452371; bh=rzb0C5EHCoixlCb6jsycAt74JB1hVyE+63zOV7j2VI0=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=heEG3KKqkYViEfDPVNm3VFMBFGUqD18K1Rnx347hObLyL6id+RvRBc/NUG0Kbko/D 9pglgzwgwd/gf8iqhFQG7X+vu5NqsGYNfU/lDEW93FwBcfANbSzvvOD11/GbeVoVn5 FG1u7qMOVlh/ClnxWJw0Hh9+tMPsculbQyx/n05FDfEB29z8HA7Zh4obGPJMK6Bbx9 09l8ZPKMQMX/tbQgCdA5EAmPLlOZB9rrOTrrgW4y2eMisFQqyw36qKzL2r9PZe8n4Q h7RiRzIq1VMWMgjpZ3b4y6S2neE6jsjU0Fa9pSFZ//04PjbtHKLrez4Q1E7sqEY0uv rwbrOb83hDdKg== Subject: [PATCH 12/26] libxfs: split new inode creation into two pieces From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875465.723621.8558270654292621940.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong There are two parts to initializing a newly allocated inode: setting up the incore structures, and initializing the new inode core based on the parent inode and the current user's environment. The initialization code is not specific to the kernel, so we would like to share that with userspace by hoisting it to libxfs. Therefore, split xfs_icreate into separate functions to prepare for the next few patches. Signed-off-by: Darrick J. Wong --- libxfs/inode.c | 42 ++++++++++++++++++++++++++---------------- libxfs/xfs_ialloc.c | 20 ++++++++++++++++++-- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/libxfs/inode.c b/libxfs/inode.c index 9835c708021..44d889f3f0f 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -73,28 +73,17 @@ xfs_inode_inherit_flags2( ip->i_diflags2 |= XFS_DIFLAG2_DAX; } -/* - * Initialise a newly allocated inode and return the in-core inode to the - * caller locked exclusively. - */ -static int -libxfs_icreate( +/* Initialise an inode's attributes. */ +static void +xfs_inode_init( struct xfs_trans *tp, - xfs_ino_t ino, const struct xfs_icreate_args *args, - struct xfs_inode **ipp) + struct xfs_inode *ip) { struct xfs_inode *pip = args->pip; - struct xfs_inode *ip; unsigned int flags; int times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG | XFS_ICHGTIME_ACCESS; - int error; - - error = libxfs_iget(tp->t_mountp, tp, ino, 0, &ip); - if (error != 0) - return error; - ASSERT(ip != NULL); VFS_I(ip)->i_mode = args->mode; set_nlink(VFS_I(ip), args->nlink); @@ -154,7 +143,28 @@ libxfs_icreate( */ xfs_trans_ijoin(tp, ip, 0); xfs_trans_log_inode(tp, ip, flags); - *ipp = ip; +} + +/* + * Initialise a newly allocated inode and return the in-core inode to the + * caller locked exclusively. + */ +static int +libxfs_icreate( + struct xfs_trans *tp, + xfs_ino_t ino, + const struct xfs_icreate_args *args, + struct xfs_inode **ipp) +{ + struct xfs_mount *mp = tp->t_mountp; + int error; + + error = libxfs_iget(mp, tp, ino, 0, ipp); + if (error) + return error; + + ASSERT(*ipp != NULL); + xfs_inode_init(tp, args, *ipp); return 0; } diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 3d55f5d1f46..9ce36b2cd8d 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -1865,9 +1865,25 @@ xfs_dialloc( } xfs_perag_put(pag); } + if (error) + goto out; - if (!error) - *new_ino = ino; + /* + * Protect against obviously corrupt allocation btree records. Later + * xfs_iget checks will catch re-allocation of other active in-memory + * and on-disk inodes. If we don't catch reallocating the parent inode + * here we will deadlock in xfs_iget() so we have to do these checks + * first. + */ + if (ino == parent || !xfs_verify_dir_ino(mp, ino)) { + xfs_alert(mp, "Allocated a known in-use inode 0x%llx!", ino); + xfs_ag_mark_sick(pag, XFS_SICK_AG_INOBT); + error = -EFSCORRUPTED; + goto out; + } + + *new_ino = ino; +out: xfs_perag_put(pag); return error; } From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085579 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 386DBC4332F for ; Sat, 31 Dec 2022 02:06:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236157AbiLaCGb (ORCPT ); Fri, 30 Dec 2022 21:06:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236150AbiLaCGa (ORCPT ); Fri, 30 Dec 2022 21:06:30 -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 2AE612AC0 for ; Fri, 30 Dec 2022 18:06:29 -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 DA75CB81DE0 for ; Sat, 31 Dec 2022 02:06:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9AB5CC433D2; Sat, 31 Dec 2022 02:06:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452386; bh=4pM69lftUvBAQTv6GNVBzfXheV5ieRG3+QHtoFgDZAo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=ACbkirLD33sGZNkJkgMuAkal6hZGWc3Vgwoof4Q99wwZe0aE8UOL0RaUNBVh7SMSd 3NDeBOHja6Uzqm+PFrVzB4ABf2ndeu5GlQW8OQ6RGpQnKrTg6STq4GKtqMc+DifUfI 0I/Rbpuy9B3rE9cggOKYrA+gh9Bl6N1vkNMMjGuhL6HFuU0Tp2TU3ncJVF4d/hopql OY3yLMGnCGr92hfCtbR+q3m4XF6AhFIGc9Kjiz+vzdDDUeux43PC8826zbou2biNOu YajZdsfoPq8RCCBsT+fY5Zhi/4g4N/KKNLkmIFej4q3MWsCCB0kfslasU6Mmhmh6Z7 8C+3jipoxdhbg== Subject: [PATCH 13/26] libxfs: backport inode init code from the kernel From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875477.723621.59106054740264047.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Reorganize the userspace inode initialization code to more closely resemble its kernel counterpart. This is preparation to hoist the initialization routines to libxfs. Signed-off-by: Darrick J. Wong --- include/xfs_inode.h | 2 + include/xfs_mount.h | 1 + libxfs/inode.c | 92 +++++++++++++++++++++++++++++++++++++++++--------- libxfs/libxfs_priv.h | 6 +++ 4 files changed, 84 insertions(+), 17 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index bf8322ee2ec..4e8a3dc6fd8 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -295,4 +295,6 @@ extern void libxfs_irele(struct xfs_inode *ip); #define XFS_DEFAULT_COWEXTSZ_HINT 32 +#define XFS_INHERIT_GID(pip) (VFS_I(pip)->i_mode & S_ISGID) + #endif /* __XFS_INODE_H__ */ diff --git a/include/xfs_mount.h b/include/xfs_mount.h index c67d0237686..1690660ed5b 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -218,6 +218,7 @@ __XFS_UNSUPP_FEAT(ikeep) __XFS_UNSUPP_FEAT(swalloc) __XFS_UNSUPP_FEAT(small_inums) __XFS_UNSUPP_FEAT(readonly) +__XFS_UNSUPP_FEAT(grpid) /* Operational mount state flags */ #define XFS_OPSTATE_INODE32 0 /* inode32 allocator active */ diff --git a/libxfs/inode.c b/libxfs/inode.c index 44d889f3f0f..d311abafd79 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -31,7 +31,7 @@ /* Propagate di_flags from a parent inode to a child inode. */ static void -xfs_inode_propagate_flags( +xfs_inode_inherit_flags( struct xfs_inode *ip, const struct xfs_inode *pip) { @@ -81,31 +81,47 @@ xfs_inode_init( struct xfs_inode *ip) { struct xfs_inode *pip = args->pip; + struct inode *dir = pip ? VFS_I(pip) : NULL; + struct xfs_mount *mp = tp->t_mountp; + struct inode *inode = VFS_I(ip); unsigned int flags; int times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG | XFS_ICHGTIME_ACCESS; - VFS_I(ip)->i_mode = args->mode; - set_nlink(VFS_I(ip), args->nlink); - VFS_I(ip)->i_uid = args->uid; + set_nlink(inode, args->nlink); + inode->i_rdev = args->rdev; ip->i_projid = args->prid; - if (pip && (VFS_I(pip)->i_mode & S_ISGID)) { - if (!(args->flags & XFS_ICREATE_ARGS_FORCE_GID)) - VFS_I(ip)->i_gid = VFS_I(pip)->i_gid; - if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(args->mode)) - VFS_I(ip)->i_mode |= S_ISGID; - } else - VFS_I(ip)->i_gid = args->gid; + if (dir && !(dir->i_mode & S_ISGID) && + xfs_has_grpid(mp)) { + inode->i_uid = args->uid; + inode->i_gid = dir->i_gid; + inode->i_mode = args->mode; + } else { + inode_init_owner(args->mnt_userns, inode, dir, args->mode); + } + + /* struct copies */ + if (args->flags & XFS_ICREATE_ARGS_FORCE_UID) + inode->i_uid = args->uid; + else + ASSERT(uid_eq(inode->i_uid, args->uid)); + if (args->flags & XFS_ICREATE_ARGS_FORCE_GID) + inode->i_gid = args->gid; + else if (!pip || !XFS_INHERIT_GID(pip)) + ASSERT(gid_eq(inode->i_gid, args->gid)); + if (args->flags & XFS_ICREATE_ARGS_FORCE_MODE) + inode->i_mode = args->mode; ip->i_disk_size = 0; ip->i_df.if_nextents = 0; ASSERT(ip->i_nblocks == 0); + ip->i_extsize = 0; ip->i_diflags = 0; + if (xfs_has_v3inodes(ip->i_mount)) { VFS_I(ip)->i_version = 1; - ip->i_diflags2 = ip->i_mount->m_ino_geo.new_diflags2; ip->i_cowextsize = 0; times |= XFS_ICHGTIME_CREATE; } @@ -120,12 +136,11 @@ xfs_inode_init( case S_IFBLK: ip->i_df.if_format = XFS_DINODE_FMT_DEV; flags |= XFS_ILOG_DEV; - VFS_I(ip)->i_rdev = args->rdev; break; case S_IFREG: case S_IFDIR: if (pip && (pip->i_diflags & XFS_DIFLAG_ANY)) - xfs_inode_propagate_flags(ip, pip); + xfs_inode_inherit_flags(ip, pip); if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY)) xfs_inode_inherit_flags2(ip, pip); /* FALLTHROUGH */ @@ -138,6 +153,21 @@ xfs_inode_init( ASSERT(0); } + /* + * If we need to create attributes immediately after allocating the + * inode, initialise an empty attribute fork right now. We use the + * default fork offset for attributes here as we don't know exactly what + * size or how many attributes we might be adding. We can do this + * safely here because we know the data fork is completely empty and + * this saves us from needing to run a separate transaction to set the + * fork offset in the immediate future. + */ + if ((args->flags & XFS_ICREATE_ARGS_INIT_XATTRS) && + xfs_has_attr(mp)) { + ip->i_forkoff = xfs_default_attroffset(ip) >> 3; + xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0); + } + /* * Log the new values stuffed into the inode. */ @@ -261,15 +291,15 @@ libxfs_dir_ialloc( .nlink = nlink, .rdev = rdev, .mode = mode, + .flags = XFS_ICREATE_ARGS_FORCE_UID | + XFS_ICREATE_ARGS_FORCE_GID | + XFS_ICREATE_ARGS_FORCE_MODE, }; struct xfs_inode *ip; xfs_ino_t parent_ino = dp ? dp->i_ino : 0; xfs_ino_t ino; int error; - if (cr->cr_flags & CRED_FORCE_GID) - args.flags |= XFS_ICREATE_ARGS_FORCE_GID; - /* * Call the space management code to pick the on-disk inode to be * allocated. @@ -321,6 +351,7 @@ libxfs_iget( VFS_I(ip)->i_count = 1; ip->i_ino = ino; ip->i_mount = mp; + ip->i_diflags2 = mp->m_ino_geo.new_diflags2; ip->i_af.if_format = XFS_DINODE_FMT_EXTENTS; spin_lock_init(&VFS_I(ip)->i_lock); @@ -399,3 +430,30 @@ libxfs_irele( kmem_cache_free(xfs_inode_cache, ip); } } + +static inline void inode_fsuid_set(struct inode *inode, + struct user_namespace *mnt_userns) +{ + inode->i_uid = make_kuid(0); +} + +static inline void inode_fsgid_set(struct inode *inode, + struct user_namespace *mnt_userns) +{ + inode->i_gid = make_kgid(0); +} + +void inode_init_owner(struct user_namespace *mnt_userns, struct inode *inode, + const struct inode *dir, umode_t mode) +{ + inode_fsuid_set(inode, mnt_userns); + if (dir && dir->i_mode & S_ISGID) { + inode->i_gid = dir->i_gid; + + /* Directories are special, and always inherit S_ISGID */ + if (S_ISDIR(mode)) + mode |= S_ISGID; + } else + inode_fsgid_set(inode, mnt_userns); + inode->i_mode = mode; +} diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 716e711cde4..acad5ccd228 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -219,6 +219,12 @@ static inline bool WARN_ON(bool expr) { (inode)->i_version = (version); \ } while (0) +struct inode; +struct user_namespace; + +void inode_init_owner(struct user_namespace *mnt_userns, struct inode *inode, + const struct inode *dir, umode_t mode); + #define __must_check __attribute__((__warn_unused_result__)) /* From patchwork Fri Dec 30 22:19:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085580 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 9432DC4332F for ; Sat, 31 Dec 2022 02:06:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231473AbiLaCGq (ORCPT ); Fri, 30 Dec 2022 21:06:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231466AbiLaCGo (ORCPT ); Fri, 30 Dec 2022 21:06:44 -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 40BFE6241 for ; Fri, 30 Dec 2022 18:06: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 dfw.source.kernel.org (Postfix) with ESMTPS id C244461CBE for ; Sat, 31 Dec 2022 02:06:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2FF92C433D2; Sat, 31 Dec 2022 02:06:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452402; bh=6p/HQENhwwRwAc3lTMystmH8qmDZTk+GRDPJX/K5PO0=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=NQhQAYcbQfe/oJS+uMNp2/QAcC++mgYdN+I9WNnumXjqny72oZdjLuytavBjgtTJB DOI3lGtNigWOO9n+xaf7DklHY/CdWWdY1nHnZCeB+L0P0XkLYn+MUw+84VwWbf9Juk mY/qjy83mPK6XHQKwo8D6ZodArC35dH40z8cptMVkmuQrWR1aJu8HKFYUBXg9je/dh HFwpRbCSp2+iKvPziPAu4jPMJ18AZ/q5FDH9OQG1GjeE6BPxdihIukNQfDOxZBgP3p byHBco1NNSMYQ2Y7hVDaujCKDgmrWf+EcFJ++05vdUJIpdQxflfdGxyFIg6V7Si1df RH3xUBKTAPvlw== Subject: [PATCH 14/26] libxfs: remove libxfs_dir_ialloc From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:14 -0800 Message-ID: <167243875488.723621.14958888136379368561.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong This function no longer exists in the kernel, and it's not really needed in userspace either. There are two users of it: repair and mkfs. Repair passes in zeroed cred and fsxattr structures so it can call libxfs_dialloc and libxfs_icreate directly. For mkfs we'll move the guts of libxfs_dir_ialloc into proto.c as a creatproto function that takes care of all that, and move struct cred to mkfs since it's now the only user. This gets us ready to hoist the rest of the inode initialization code to libxfs for metadata directories. Signed-off-by: Darrick J. Wong --- include/xfs_inode.h | 15 ++----- libxfs/inode.c | 79 ++++++++------------------------------- libxfs/libxfs_api_defs.h | 1 mkfs/proto.c | 94 +++++++++++++++++++++++++++++++++++++--------- repair/phase6.c | 48 +++++++++++++---------- 5 files changed, 124 insertions(+), 113 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 4e8a3dc6fd8..03add740fa7 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -268,17 +268,6 @@ static inline bool xfs_is_always_cow_inode(struct xfs_inode *ip) return false; } -/* Always set the child's GID to this value, even if the parent is setgid. */ -#define CRED_FORCE_GID (1U << 0) -struct cred { - uid_t cr_uid; - gid_t cr_gid; - unsigned int cr_flags; -}; - -extern int libxfs_dir_ialloc (struct xfs_trans **, struct xfs_inode *, - mode_t, nlink_t, xfs_dev_t, struct cred *, - struct fsxattr *, struct xfs_inode **); extern void libxfs_trans_inode_alloc_buf (struct xfs_trans *, struct xfs_buf *); @@ -286,6 +275,10 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); extern int libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *); +int libxfs_icreate(struct xfs_trans *tp, xfs_ino_t ino, + const struct xfs_icreate_args *args, struct xfs_inode **ipp); +void libxfs_icreate_args_rootfile(struct xfs_icreate_args *args, umode_t mode); + extern struct timespec64 current_time(struct inode *inode); /* Inode Cache Interfaces */ diff --git a/libxfs/inode.c b/libxfs/inode.c index d311abafd79..c1fb622f306 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -179,7 +179,7 @@ xfs_inode_init( * Initialise a newly allocated inode and return the in-core inode to the * caller locked exclusively. */ -static int +int libxfs_icreate( struct xfs_trans *tp, xfs_ino_t ino, @@ -198,6 +198,22 @@ libxfs_icreate( return 0; } +/* Set up inode attributes for newly created internal files. */ +void +libxfs_icreate_args_rootfile( + struct xfs_icreate_args *args, + umode_t mode) +{ + args->mnt_userns = NULL; + args->uid = make_kuid(0); + args->gid = make_kgid(0); + args->prid = 0; + args->mode = mode; + args->flags = XFS_ICREATE_ARGS_FORCE_UID | + XFS_ICREATE_ARGS_FORCE_GID | + XFS_ICREATE_ARGS_FORCE_MODE; +} + /* * Writes a modified inode's changes out to the inode's on disk home. * Originally based on xfs_iflush_int() from xfs_inode.c in the kernel. @@ -265,67 +281,6 @@ libxfs_iflush_int( return 0; } -/* - * Wrapper around call to libxfs_ialloc. Takes care of committing and - * allocating a new transaction as needed. - * - * Originally there were two copies of this code - one in mkfs, the - * other in repair - now there is just the one. - */ -int -libxfs_dir_ialloc( - struct xfs_trans **tpp, - struct xfs_inode *dp, - mode_t mode, - nlink_t nlink, - xfs_dev_t rdev, - struct cred *cr, - struct fsxattr *fsx, - struct xfs_inode **ipp) -{ - struct xfs_icreate_args args = { - .pip = dp, - .uid = make_kuid(cr->cr_uid), - .gid = make_kgid(cr->cr_gid), - .prid = dp ? libxfs_get_initial_prid(dp) : 0, - .nlink = nlink, - .rdev = rdev, - .mode = mode, - .flags = XFS_ICREATE_ARGS_FORCE_UID | - XFS_ICREATE_ARGS_FORCE_GID | - XFS_ICREATE_ARGS_FORCE_MODE, - }; - struct xfs_inode *ip; - xfs_ino_t parent_ino = dp ? dp->i_ino : 0; - xfs_ino_t ino; - int error; - - /* - * Call the space management code to pick the on-disk inode to be - * allocated. - */ - error = xfs_dialloc(tpp, parent_ino, mode, &ino); - if (error) - return error; - - error = libxfs_icreate(*tpp, ino, &args, ipp); - if (error || dp) - return error; - - /* If there is no parent dir, initialize the file from fsxattr data. */ - ip = *ipp; - ip->i_projid = fsx->fsx_projid; - ip->i_extsize = fsx->fsx_extsize; - ip->i_diflags = xfs_flags2diflags(ip, fsx->fsx_xflags); - - if (xfs_has_v3inodes(ip->i_mount)) { - ip->i_diflags2 = xfs_flags2diflags2(ip, fsx->fsx_xflags); - ip->i_cowextsize = fsx->fsx_cowextsize; - } - xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); - return 0; -} - /* * Inode cache stubs. */ diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 5752733a833..782a551ee1c 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -91,6 +91,7 @@ #define xfs_da_shrink_inode libxfs_da_shrink_inode #define xfs_defer_cancel libxfs_defer_cancel #define xfs_defer_finish libxfs_defer_finish +#define xfs_dialloc libxfs_dialloc #define xfs_dinode_calc_crc libxfs_dinode_calc_crc #define xfs_dinode_good_version libxfs_dinode_good_version #define xfs_dinode_verify libxfs_dinode_verify diff --git a/mkfs/proto.c b/mkfs/proto.c index bd306f95568..b60def70652 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -351,6 +351,65 @@ newdirectory( fail(_("directory create error"), error); } +struct cred { + uid_t cr_uid; + gid_t cr_gid; +}; + +static int +creatproto( + struct xfs_trans **tpp, + struct xfs_inode *dp, + mode_t mode, + nlink_t nlink, + xfs_dev_t rdev, + struct cred *cr, + struct fsxattr *fsx, + struct xfs_inode **ipp) +{ + struct xfs_icreate_args args = { + .pip = dp, + .uid = make_kuid(cr->cr_uid), + .gid = make_kgid(cr->cr_gid), + .prid = dp ? libxfs_get_initial_prid(dp) : 0, + .nlink = nlink, + .rdev = rdev, + .mode = mode, + .flags = XFS_ICREATE_ARGS_FORCE_UID | + XFS_ICREATE_ARGS_FORCE_GID | + XFS_ICREATE_ARGS_FORCE_MODE, + }; + struct xfs_inode *ip; + xfs_ino_t parent_ino = dp ? dp->i_ino : 0; + xfs_ino_t ino; + int error; + + /* + * Call the space management code to pick the on-disk inode to be + * allocated. + */ + error = -libxfs_dialloc(tpp, parent_ino, mode, &ino); + if (error) + return error; + + error = -libxfs_icreate(*tpp, ino, &args, ipp); + if (error || dp) + return error; + + /* If there is no parent dir, initialize the file from fsxattr data. */ + ip = *ipp; + ip->i_projid = fsx->fsx_projid; + ip->i_extsize = fsx->fsx_extsize; + ip->i_diflags = xfs_flags2diflags(ip, fsx->fsx_xflags); + + if (xfs_has_v3inodes(ip->i_mount)) { + ip->i_diflags2 = xfs_flags2diflags2(ip, fsx->fsx_xflags); + ip->i_cowextsize = fsx->fsx_cowextsize; + } + libxfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); + return 0; +} + static void parseproto( xfs_mount_t *mp, @@ -450,7 +509,6 @@ parseproto( mode |= val; creds.cr_uid = (int)getnum(getstr(pp), 0, 0, false); creds.cr_gid = (int)getnum(getstr(pp), 0, 0, false); - creds.cr_flags = CRED_FORCE_GID; xname.name = (unsigned char *)name; xname.len = name ? strlen(name) : 0; xname.type = 0; @@ -459,8 +517,8 @@ parseproto( case IF_REGULAR: buf = newregfile(pp, &len); tp = getres(mp, XFS_B_TO_FSB(mp, len)); - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0, - &creds, fsxp, &ip); + error = creatproto(&tp, pip, mode | S_IFREG, 1, 0, &creds, + fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); writefile(tp, ip, buf, len); @@ -483,8 +541,8 @@ parseproto( } tp = getres(mp, XFS_B_TO_FSB(mp, llen)); - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFREG, 1, 0, - &creds, fsxp, &ip); + error = creatproto(&tp, pip, mode | S_IFREG, 1, 0, &creds, + fsxp, &ip); if (error) fail(_("Inode pre-allocation failed"), error); @@ -504,7 +562,7 @@ parseproto( tp = getres(mp, 0); majdev = getnum(getstr(pp), 0, 0, false); mindev = getnum(getstr(pp), 0, 0, false); - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFBLK, 1, + error = creatproto(&tp, pip, mode | S_IFBLK, 1, IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip); if (error) { fail(_("Inode allocation failed"), error); @@ -519,7 +577,7 @@ parseproto( tp = getres(mp, 0); majdev = getnum(getstr(pp), 0, 0, false); mindev = getnum(getstr(pp), 0, 0, false); - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFCHR, 1, + error = creatproto(&tp, pip, mode | S_IFCHR, 1, IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); @@ -531,8 +589,8 @@ parseproto( case IF_FIFO: tp = getres(mp, 0); - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFIFO, 1, 0, - &creds, fsxp, &ip); + error = creatproto(&tp, pip, mode | S_IFIFO, 1, 0, &creds, + fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); libxfs_trans_ijoin(tp, pip, 0); @@ -543,8 +601,8 @@ parseproto( buf = getstr(pp); len = (int)strlen(buf); tp = getres(mp, XFS_B_TO_FSB(mp, len)); - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFLNK, 1, 0, - &creds, fsxp, &ip); + error = creatproto(&tp, pip, mode | S_IFLNK, 1, 0, &creds, + fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); writesymlink(tp, ip, buf, len); @@ -554,8 +612,8 @@ parseproto( break; case IF_DIRECTORY: tp = getres(mp, 0); - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFDIR, 1, 0, - &creds, fsxp, &ip); + error = creatproto(&tp, pip, mode | S_IFDIR, 1, 0, &creds, + fsxp, &ip); if (error) fail(_("Inode allocation failed"), error); inc_nlink(VFS_I(ip)); /* account for . */ @@ -646,14 +704,14 @@ rtinit( memset(&creds, 0, sizeof(creds)); memset(&fsxattrs, 0, sizeof(fsxattrs)); - error = -libxfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, - &creds, &fsxattrs, &rbmip); + error = creatproto(&tp, NULL, S_IFREG, 1, 0, &creds, &fsxattrs, + &rbmip); if (error) { fail(_("Realtime bitmap inode allocation failed"), error); } /* * Do our thing with rbmip before allocating rsumip, - * because the next call to ialloc() may + * because the next call to createproto may * commit the transaction in which rbmip was allocated. */ mp->m_sb.sb_rbmino = rbmip->i_ino; @@ -663,8 +721,8 @@ rtinit( libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE); libxfs_log_sb(tp); mp->m_rbmip = rbmip; - error = -libxfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, - &creds, &fsxattrs, &rsumip); + error = creatproto(&tp, NULL, S_IFREG, 1, 0, &creds, &fsxattrs, + &rsumip); if (error) { fail(_("Realtime summary inode allocation failed"), error); } diff --git a/repair/phase6.c b/repair/phase6.c index 75b0e06b31a..e7e2bf3f475 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -19,8 +19,6 @@ #include "progress.h" #include "versions.h" -static struct cred zerocr; -static struct fsxattr zerofsx; static xfs_ino_t orphanage_ino; /* @@ -873,19 +871,25 @@ mk_root_dir(xfs_mount_t *mp) * orphanage name == lost+found */ static xfs_ino_t -mk_orphanage(xfs_mount_t *mp) +mk_orphanage( + struct xfs_mount *mp) { - xfs_ino_t ino; - xfs_trans_t *tp; - xfs_inode_t *ip; - xfs_inode_t *pip; - ino_tree_node_t *irec; - int ino_offset = 0; - int i; - int error; - const int mode = 0755; - int nres; - struct xfs_name xname; + struct xfs_icreate_args args = { + .nlink = 2, + }; + struct xfs_trans *tp; + struct xfs_inode *ip; + struct xfs_inode *pip; + struct ino_tree_node *irec; + xfs_ino_t ino; + int ino_offset = 0; + int i; + int error; + int nres; + const umode_t mode = S_IFDIR | 0755; + struct xfs_name xname; + + libxfs_icreate_args_rootfile(&args, mode); /* * check for an existing lost+found first, if it exists, return @@ -898,6 +902,7 @@ mk_orphanage(xfs_mount_t *mp) do_error(_("%d - couldn't iget root inode to obtain %s\n"), i, ORPHANAGE); + args.pip = pip; xname.name = (unsigned char *)ORPHANAGE; xname.len = strlen(ORPHANAGE); xname.type = XFS_DIR3_FT_DIR; @@ -922,14 +927,15 @@ mk_orphanage(xfs_mount_t *mp) do_error(_("%d - couldn't iget root inode to make %s\n"), i, ORPHANAGE);*/ - error = -libxfs_dir_ialloc(&tp, pip, mode|S_IFDIR, - 1, 0, &zerocr, &zerofsx, &ip); - if (error) { + error = -libxfs_dialloc(&tp, mp->m_sb.sb_rootino, mode, &ino); + if (error) do_error(_("%s inode allocation failed %d\n"), ORPHANAGE, error); - } - inc_nlink(VFS_I(ip)); /* account for . */ - ino = ip->i_ino; + + error = -libxfs_icreate(tp, ino, &args, &ip); + if (error) + do_error(_("%s inode initialization failed %d\n"), + ORPHANAGE, error); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, ino), @@ -3207,8 +3213,6 @@ phase6(xfs_mount_t *mp) ino_tree_node_t *irec; int i; - memset(&zerocr, 0, sizeof(struct cred)); - memset(&zerofsx, 0, sizeof(struct fsxattr)); orphanage_ino = 0; do_log(_("Phase 6 - check inode connectivity...\n")); From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085581 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 14803C4332F for ; Sat, 31 Dec 2022 02:07:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231482AbiLaCHE (ORCPT ); Fri, 30 Dec 2022 21:07:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52538 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231466AbiLaCHD (ORCPT ); Fri, 30 Dec 2022 21:07:03 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D1FB13F97 for ; Fri, 30 Dec 2022 18:07: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 sin.source.kernel.org (Postfix) with ESMTPS id 7E863CE1926 for ; Sat, 31 Dec 2022 02:06:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B41D2C433D2; Sat, 31 Dec 2022 02:06:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452417; bh=rnXY4clo3E8DXP8DqT5Jyho3hnDJrM75c8/vuYS6LHQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=Di2E66foJQFe6CMmo7YFWOGdP1OsJ1E0KT/RE6vSc9EcrtpY7FM8hpCF2g1GVi8hQ I63fu51SHXyHxaXGQQo9QjPtEA4RBQ7FWIM9gbni7zaCdyjCkkA+Tkq+FOPbb5yOme I8Hx2n6+bnWjxwG8P1CTL7Wi39K36Sd+3R16VmHgH2zrQraYf4sXR/WD9Fr0F7OcQb DLMXsrDXXGGfyx+njdQ6gFZjmtNEPhHEHhKRwNNg5N9I6Xg4kzGWDvlDFtpMFUdqPj G/WNpUbBsCVIjr1pFnFBXX7FTBWQJqDG8dNMLVPiqKO/VaA/CZZOs6vOvfwq2pr09n RLazz/YzeF7aQ== Subject: [PATCH 15/26] xfs: hoist new inode initialization functions to libxfs From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875500.723621.16586773809404642237.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move all the code that initializes a new inode's attributes from the icreate_args structure and the parent directory into libxfs. Signed-off-by: Darrick J. Wong --- include/xfs_inode.h | 20 +++++ libxfs/inode.c | 153 ++---------------------------------- libxfs/xfs_inode_util.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_inode_util.h | 21 +++++ libxfs/xfs_shared.h | 8 -- repair/phase6.c | 3 - 6 files changed, 251 insertions(+), 154 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 03add740fa7..5c806b3a58c 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -94,6 +94,20 @@ static inline void ihold(struct inode *inode) inode->i_count++; } +static inline void +inode_fsuid_set( + struct inode *inode, + struct user_namespace *mnt_userns) +{ + inode->i_uid = make_kuid(0); +} + +static inline void +inode_set_iversion(struct inode *inode, uint64_t version) +{ + inode->i_version = version; +} + typedef struct xfs_inode { struct cache_node i_node; struct xfs_mount *i_mount; /* fs mount struct ptr */ @@ -290,4 +304,10 @@ extern void libxfs_irele(struct xfs_inode *ip); #define XFS_INHERIT_GID(pip) (VFS_I(pip)->i_mode & S_ISGID) +#define xfs_inherit_noatime (false) +#define xfs_inherit_nodump (false) +#define xfs_inherit_sync (false) +#define xfs_inherit_nosymlinks (false) +#define xfs_inherit_nodefrag (false) + #endif /* __XFS_INODE_H__ */ diff --git a/libxfs/inode.c b/libxfs/inode.c index c1fb622f306..8ef2b654769 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -29,150 +29,11 @@ #include "xfs_da_btree.h" #include "xfs_dir2_priv.h" -/* Propagate di_flags from a parent inode to a child inode. */ -static void -xfs_inode_inherit_flags( - struct xfs_inode *ip, - const struct xfs_inode *pip) -{ - unsigned int di_flags = 0; - umode_t mode = VFS_I(ip)->i_mode; - - if ((mode & S_IFMT) == S_IFDIR) { - if (pip->i_diflags & XFS_DIFLAG_RTINHERIT) - di_flags |= XFS_DIFLAG_RTINHERIT; - if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { - di_flags |= XFS_DIFLAG_EXTSZINHERIT; - ip->i_extsize = pip->i_extsize; - } - } else { - if ((pip->i_diflags & XFS_DIFLAG_RTINHERIT) && - xfs_has_realtime(ip->i_mount)) - di_flags |= XFS_DIFLAG_REALTIME; - if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { - di_flags |= XFS_DIFLAG_EXTSIZE; - ip->i_extsize = pip->i_extsize; - } - } - if (pip->i_diflags & XFS_DIFLAG_PROJINHERIT) - di_flags |= XFS_DIFLAG_PROJINHERIT; - ip->i_diflags |= di_flags; -} - -/* Propagate di_flags2 from a parent inode to a child inode. */ -static void -xfs_inode_inherit_flags2( - struct xfs_inode *ip, - const struct xfs_inode *pip) -{ - if (pip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) { - ip->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE; - ip->i_cowextsize = pip->i_cowextsize; - } - if (pip->i_diflags2 & XFS_DIFLAG2_DAX) - ip->i_diflags2 |= XFS_DIFLAG2_DAX; -} - -/* Initialise an inode's attributes. */ -static void -xfs_inode_init( - struct xfs_trans *tp, - const struct xfs_icreate_args *args, +void +xfs_setup_inode( struct xfs_inode *ip) { - struct xfs_inode *pip = args->pip; - struct inode *dir = pip ? VFS_I(pip) : NULL; - struct xfs_mount *mp = tp->t_mountp; - struct inode *inode = VFS_I(ip); - unsigned int flags; - int times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG | - XFS_ICHGTIME_ACCESS; - - set_nlink(inode, args->nlink); - inode->i_rdev = args->rdev; - ip->i_projid = args->prid; - - if (dir && !(dir->i_mode & S_ISGID) && - xfs_has_grpid(mp)) { - inode->i_uid = args->uid; - inode->i_gid = dir->i_gid; - inode->i_mode = args->mode; - } else { - inode_init_owner(args->mnt_userns, inode, dir, args->mode); - } - - /* struct copies */ - if (args->flags & XFS_ICREATE_ARGS_FORCE_UID) - inode->i_uid = args->uid; - else - ASSERT(uid_eq(inode->i_uid, args->uid)); - if (args->flags & XFS_ICREATE_ARGS_FORCE_GID) - inode->i_gid = args->gid; - else if (!pip || !XFS_INHERIT_GID(pip)) - ASSERT(gid_eq(inode->i_gid, args->gid)); - if (args->flags & XFS_ICREATE_ARGS_FORCE_MODE) - inode->i_mode = args->mode; - - ip->i_disk_size = 0; - ip->i_df.if_nextents = 0; - ASSERT(ip->i_nblocks == 0); - - ip->i_extsize = 0; - ip->i_diflags = 0; - - if (xfs_has_v3inodes(ip->i_mount)) { - VFS_I(ip)->i_version = 1; - ip->i_cowextsize = 0; - times |= XFS_ICHGTIME_CREATE; - } - - xfs_trans_ichgtime(tp, ip, times); - - flags = XFS_ILOG_CORE; - switch (args->mode & S_IFMT) { - case S_IFIFO: - case S_IFSOCK: - case S_IFCHR: - case S_IFBLK: - ip->i_df.if_format = XFS_DINODE_FMT_DEV; - flags |= XFS_ILOG_DEV; - break; - case S_IFREG: - case S_IFDIR: - if (pip && (pip->i_diflags & XFS_DIFLAG_ANY)) - xfs_inode_inherit_flags(ip, pip); - if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY)) - xfs_inode_inherit_flags2(ip, pip); - /* FALLTHROUGH */ - case S_IFLNK: - ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; - ip->i_df.if_bytes = 0; - ip->i_df.if_u1.if_root = NULL; - break; - default: - ASSERT(0); - } - - /* - * If we need to create attributes immediately after allocating the - * inode, initialise an empty attribute fork right now. We use the - * default fork offset for attributes here as we don't know exactly what - * size or how many attributes we might be adding. We can do this - * safely here because we know the data fork is completely empty and - * this saves us from needing to run a separate transaction to set the - * fork offset in the immediate future. - */ - if ((args->flags & XFS_ICREATE_ARGS_INIT_XATTRS) && - xfs_has_attr(mp)) { - ip->i_forkoff = xfs_default_attroffset(ip) >> 3; - xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0); - } - - /* - * Log the new values stuffed into the inode. - */ - xfs_trans_ijoin(tp, ip, 0); - xfs_trans_log_inode(tp, ip, flags); + /* empty */ } /* @@ -386,10 +247,12 @@ libxfs_irele( } } -static inline void inode_fsuid_set(struct inode *inode, - struct user_namespace *mnt_userns) +void +xfs_inode_sgid_inherit( + const struct xfs_icreate_args *args, + struct xfs_inode *ip) { - inode->i_uid = make_kuid(0); + /* empty */ } static inline void inode_fsgid_set(struct inode *inode, diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c index 89fb58807a1..21196a899da 100644 --- a/libxfs/xfs_inode_util.c +++ b/libxfs/xfs_inode_util.c @@ -13,6 +13,10 @@ #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_inode_util.h" +#include "xfs_trans.h" +#include "xfs_ialloc.h" +#include "xfs_health.h" +#include "xfs_bmap.h" uint16_t xfs_flags2diflags( @@ -133,3 +137,199 @@ xfs_get_initial_prid(struct xfs_inode *dp) return XFS_PROJID_DEFAULT; } + +/* Propagate di_flags from a parent inode to a child inode. */ +static inline void +xfs_inode_inherit_flags( + struct xfs_inode *ip, + const struct xfs_inode *pip) +{ + unsigned int di_flags = 0; + xfs_failaddr_t failaddr; + umode_t mode = VFS_I(ip)->i_mode; + + if (S_ISDIR(mode)) { + if (pip->i_diflags & XFS_DIFLAG_RTINHERIT) + di_flags |= XFS_DIFLAG_RTINHERIT; + if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { + di_flags |= XFS_DIFLAG_EXTSZINHERIT; + ip->i_extsize = pip->i_extsize; + } + if (pip->i_diflags & XFS_DIFLAG_PROJINHERIT) + di_flags |= XFS_DIFLAG_PROJINHERIT; + } else if (S_ISREG(mode)) { + if ((pip->i_diflags & XFS_DIFLAG_RTINHERIT) && + xfs_has_realtime(ip->i_mount)) + di_flags |= XFS_DIFLAG_REALTIME; + if (pip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) { + di_flags |= XFS_DIFLAG_EXTSIZE; + ip->i_extsize = pip->i_extsize; + } + } + if ((pip->i_diflags & XFS_DIFLAG_NOATIME) && + xfs_inherit_noatime) + di_flags |= XFS_DIFLAG_NOATIME; + if ((pip->i_diflags & XFS_DIFLAG_NODUMP) && + xfs_inherit_nodump) + di_flags |= XFS_DIFLAG_NODUMP; + if ((pip->i_diflags & XFS_DIFLAG_SYNC) && + xfs_inherit_sync) + di_flags |= XFS_DIFLAG_SYNC; + if ((pip->i_diflags & XFS_DIFLAG_NOSYMLINKS) && + xfs_inherit_nosymlinks) + di_flags |= XFS_DIFLAG_NOSYMLINKS; + if ((pip->i_diflags & XFS_DIFLAG_NODEFRAG) && + xfs_inherit_nodefrag) + di_flags |= XFS_DIFLAG_NODEFRAG; + if (pip->i_diflags & XFS_DIFLAG_FILESTREAM) + di_flags |= XFS_DIFLAG_FILESTREAM; + + ip->i_diflags |= di_flags; + + /* + * Inode verifiers on older kernels only check that the extent size + * hint is an integer multiple of the rt extent size on realtime files. + * They did not check the hint alignment on a directory with both + * rtinherit and extszinherit flags set. If the misaligned hint is + * propagated from a directory into a new realtime file, new file + * allocations will fail due to math errors in the rt allocator and/or + * trip the verifiers. Validate the hint settings in the new file so + * that we don't let broken hints propagate. + */ + failaddr = xfs_inode_validate_extsize(ip->i_mount, ip->i_extsize, + VFS_I(ip)->i_mode, ip->i_diflags); + if (failaddr) { + ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE | + XFS_DIFLAG_EXTSZINHERIT); + ip->i_extsize = 0; + } +} + +/* Propagate di_flags2 from a parent inode to a child inode. */ +static inline void +xfs_inode_inherit_flags2( + struct xfs_inode *ip, + const struct xfs_inode *pip) +{ + xfs_failaddr_t failaddr; + + if (pip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) { + ip->i_diflags2 |= XFS_DIFLAG2_COWEXTSIZE; + ip->i_cowextsize = pip->i_cowextsize; + } + if (pip->i_diflags2 & XFS_DIFLAG2_DAX) + ip->i_diflags2 |= XFS_DIFLAG2_DAX; + + /* Don't let invalid cowextsize hints propagate. */ + failaddr = xfs_inode_validate_cowextsize(ip->i_mount, ip->i_cowextsize, + VFS_I(ip)->i_mode, ip->i_diflags, ip->i_diflags2); + if (failaddr) { + ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE; + ip->i_cowextsize = 0; + } +} + +/* Initialise an inode's attributes. */ +void +xfs_inode_init( + struct xfs_trans *tp, + const struct xfs_icreate_args *args, + struct xfs_inode *ip) +{ + struct xfs_inode *pip = args->pip; + struct inode *dir = pip ? VFS_I(pip) : NULL; + struct xfs_mount *mp = tp->t_mountp; + struct inode *inode = VFS_I(ip); + unsigned int flags; + int times = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG | + XFS_ICHGTIME_ACCESS; + + set_nlink(inode, args->nlink); + inode->i_rdev = args->rdev; + ip->i_projid = args->prid; + + if (dir && !(dir->i_mode & S_ISGID) && xfs_has_grpid(mp)) { + inode_fsuid_set(inode, args->mnt_userns); + inode->i_gid = dir->i_gid; + inode->i_mode = args->mode; + } else { + inode_init_owner(args->mnt_userns, inode, dir, args->mode); + } + xfs_inode_sgid_inherit(args, ip); + + /* struct copies */ + if (args->flags & XFS_ICREATE_ARGS_FORCE_UID) + inode->i_uid = args->uid; + else + ASSERT(uid_eq(inode->i_uid, args->uid)); + if (args->flags & XFS_ICREATE_ARGS_FORCE_GID) + inode->i_gid = args->gid; + else if (!pip || !XFS_INHERIT_GID(pip)) + ASSERT(gid_eq(inode->i_gid, args->gid)); + if (args->flags & XFS_ICREATE_ARGS_FORCE_MODE) + inode->i_mode = args->mode; + + ip->i_disk_size = 0; + ip->i_df.if_nextents = 0; + ASSERT(ip->i_nblocks == 0); + + ip->i_extsize = 0; + ip->i_diflags = 0; + + if (xfs_has_v3inodes(mp)) { + inode_set_iversion(inode, 1); + ip->i_cowextsize = 0; + times |= XFS_ICHGTIME_CREATE; + } + + xfs_trans_ichgtime(tp, ip, times); + + flags = XFS_ILOG_CORE; + switch (args->mode & S_IFMT) { + case S_IFIFO: + case S_IFCHR: + case S_IFBLK: + case S_IFSOCK: + ip->i_df.if_format = XFS_DINODE_FMT_DEV; + flags |= XFS_ILOG_DEV; + break; + case S_IFREG: + case S_IFDIR: + if (pip && (pip->i_diflags & XFS_DIFLAG_ANY)) + xfs_inode_inherit_flags(ip, pip); + if (pip && (pip->i_diflags2 & XFS_DIFLAG2_ANY)) + xfs_inode_inherit_flags2(ip, pip); + fallthrough; + case S_IFLNK: + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; + ip->i_df.if_bytes = 0; + ip->i_df.if_u1.if_root = NULL; + break; + default: + ASSERT(0); + } + + /* + * If we need to create attributes immediately after allocating the + * inode, initialise an empty attribute fork right now. We use the + * default fork offset for attributes here as we don't know exactly what + * size or how many attributes we might be adding. We can do this + * safely here because we know the data fork is completely empty and + * this saves us from needing to run a separate transaction to set the + * fork offset in the immediate future. + */ + if ((args->flags & XFS_ICREATE_ARGS_INIT_XATTRS) && + xfs_has_attr(mp)) { + ip->i_forkoff = xfs_default_attroffset(ip) >> 3; + xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0); + } + + /* + * Log the new values stuffed into the inode. + */ + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + xfs_trans_log_inode(tp, ip, flags); + + /* now that we have an i_mode we can setup the inode structure */ + xfs_setup_inode(ip); +} diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h index 466f0767ab5..a73ccaea558 100644 --- a/libxfs/xfs_inode_util.h +++ b/libxfs/xfs_inode_util.h @@ -44,4 +44,25 @@ struct xfs_icreate_args { uint16_t flags; }; +/* + * Flags for xfs_trans_ichgtime(). + */ +#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ +#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ +#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */ +#define XFS_ICHGTIME_ACCESS 0x8 /* last access timestamp */ +void xfs_trans_ichgtime(struct xfs_trans *tp, struct xfs_inode *ip, int flags); + +void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args, + struct xfs_inode *ip); + +/* The libxfs client must provide this group of helper functions. */ + +/* Handle legacy Irix sgid inheritance quirks. */ +void xfs_inode_sgid_inherit(const struct xfs_icreate_args *args, + struct xfs_inode *ip); + +/* Initialize the incore inode. */ +void xfs_setup_inode(struct xfs_inode *ip); + #endif /* __XFS_INODE_UTIL_H__ */ diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h index acf527eb0e1..46754fe5736 100644 --- a/libxfs/xfs_shared.h +++ b/libxfs/xfs_shared.h @@ -131,14 +131,6 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp, #define XFS_RCBAG_BTREE_REF 1 #define XFS_SSB_REF 0 -/* - * Flags for xfs_trans_ichgtime(). - */ -#define XFS_ICHGTIME_MOD 0x1 /* data fork modification timestamp */ -#define XFS_ICHGTIME_CHG 0x2 /* inode field change timestamp */ -#define XFS_ICHGTIME_CREATE 0x4 /* inode create timestamp */ -#define XFS_ICHGTIME_ACCESS 0x8 /* last access timestamp */ - /* Computed inode geometry for the filesystem. */ struct xfs_ino_geometry { /* Maximum inode count in this filesystem. */ diff --git a/repair/phase6.c b/repair/phase6.c index e7e2bf3f475..0c24cfbf144 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -824,7 +824,8 @@ mk_root_dir(xfs_mount_t *mp) } /* - * take care of the core -- initialization from xfs_ialloc() + * take care of the core since we didn't call the libxfs ialloc function + * (comment changed to avoid tangling xfs/437) */ reset_inode_fields(ip); From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085582 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 92CBFC4332F for ; Sat, 31 Dec 2022 02:07:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231466AbiLaCHT (ORCPT ); Fri, 30 Dec 2022 21:07:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCHP (ORCPT ); Fri, 30 Dec 2022 21:07:15 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67A7513F97 for ; Fri, 30 Dec 2022 18:07:14 -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 E9B1F61CC1 for ; Sat, 31 Dec 2022 02:07:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4D8E2C433D2; Sat, 31 Dec 2022 02:07:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452433; bh=am35Sg+RprmpKPpuBQUNVLKputXg7NPJ2gHfdcpeLTc=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=IP2l7QLOAg3nNYXzPbU+9HuUIP9uYxqvRfTqXo6y7zEo1hSFaWPRh3ar8SF4i0cVL 9mVaxg769t3EY9KgvpzkS1TiqiZGVfmgh8bZM4i4dkJB5pZdLi6y9njmynGnKddWuI kRs6sM9/BX/od6+cko+ym/1dajUEVKZovRecY/8CrqEQ82CNclcWV7zA3nADPSQ6z0 7FHQvVPXLg29DMnjzwS2TGVhQbeE7H9Z/tVrZxNFyaHy0aJRjDyciY1EwL6l7U5eb9 MrZa4RyTkuEB/PQXiolgjsVk6Q5bpBLqTagzQnVK5hoSt1oyyUUx25K+zyhibym0I2 AORrYsBAZWPpQ== Subject: [PATCH 16/26] xfs: hoist xfs_iunlink to libxfs From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875512.723621.5748794528457709093.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move xfs_iunlink and xfs_iunlink_remove to libxfs. Signed-off-by: Darrick J. Wong --- include/xfs_inode.h | 1 include/xfs_trace.h | 6 + libxfs/Makefile | 2 libxfs/inode.c | 2 libxfs/iunlink.c | 126 ++++++++++++++++++++++ libxfs/iunlink.h | 22 ++++ libxfs/libxfs_priv.h | 28 +++++ libxfs/xfs_inode_util.c | 275 +++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_inode_util.h | 4 + 9 files changed, 466 insertions(+) create mode 100644 libxfs/iunlink.c create mode 100644 libxfs/iunlink.h diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 5c806b3a58c..234f8d3affa 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -135,6 +135,7 @@ typedef struct xfs_inode { /* unlinked list pointers */ xfs_agino_t i_next_unlinked; + xfs_agino_t i_prev_unlinked; xfs_extnum_t i_cnextents; /* # of extents in cow fork */ unsigned int i_cformat; /* format of cow fork */ diff --git a/include/xfs_trace.h b/include/xfs_trace.h index a6ba6fc93bf..d94d8d29bed 100644 --- a/include/xfs_trace.h +++ b/include/xfs_trace.h @@ -349,4 +349,10 @@ #define trace_xfs_perag_get_tag(a,b,c,d) ((c) = (c)) #define trace_xfs_perag_put(a,b,c,d) ((c) = (c)) +#define trace_xfs_iunlink_update_bucket(...) ((void) 0) +#define trace_xfs_iunlink_update_dinode(...) ((void) 0) +#define trace_xfs_iunlink(...) ((void) 0) +#define trace_xfs_iunlink_remove(...) ((void) 0) +#define trace_xfs_iunlink_map_prev_fallback(...) ((void) 0) + #endif /* __TRACE_H__ */ diff --git a/libxfs/Makefile b/libxfs/Makefile index f9bc82cc9e8..94f5968e862 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -23,6 +23,7 @@ HFILES = \ libxfs_io.h \ libxfs_api_defs.h \ init.h \ + iunlink.h \ libxfs_priv.h \ linux-err.h \ topology.h \ @@ -65,6 +66,7 @@ CFILES = cache.c \ defer_item.c \ init.c \ inode.c \ + iunlink.c \ kmem.c \ logitem.c \ rdwr.c \ diff --git a/libxfs/inode.c b/libxfs/inode.c index 8ef2b654769..1a27016a763 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -169,6 +169,8 @@ libxfs_iget( ip->i_mount = mp; ip->i_diflags2 = mp->m_ino_geo.new_diflags2; ip->i_af.if_format = XFS_DINODE_FMT_EXTENTS; + ip->i_next_unlinked = NULLAGINO; + ip->i_prev_unlinked = NULLAGINO; spin_lock_init(&VFS_I(ip)->i_lock); error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, 0); diff --git a/libxfs/iunlink.c b/libxfs/iunlink.c new file mode 100644 index 00000000000..2123dfdcbbf --- /dev/null +++ b/libxfs/iunlink.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2022, Red Hat, Inc. + * All Rights Reserved. + */ + +#include "libxfs_priv.h" +#include "libxfs.h" +#include "libxfs_io.h" +#include "init.h" +#include "xfs_fs.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.h" +#include "xfs_ag.h" +#include "iunlink.h" +#include "xfs_trace.h" + +/* in memory log item structure */ +struct xfs_iunlink_item { + struct xfs_inode *ip; + struct xfs_perag *pag; + xfs_agino_t next_agino; + xfs_agino_t old_agino; +}; + +/* + * Look up the inode cluster buffer and log the on-disk unlinked inode change + * we need to make. + */ +static int +xfs_iunlink_log_dinode( + struct xfs_trans *tp, + struct xfs_iunlink_item *iup) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_inode *ip = iup->ip; + struct xfs_dinode *dip; + struct xfs_buf *ibp; + int offset; + int error; + + error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &ibp); + if (error) + return error; + /* + * Don't log the unlinked field on stale buffers as this may be the + * transaction that frees the inode cluster and relogging the buffer + * here will incorrectly remove the stale state. + */ + if (ibp->b_flags & LIBXFS_B_STALE) + goto out; + + dip = xfs_buf_offset(ibp, ip->i_imap.im_boffset); + + /* Make sure the old pointer isn't garbage. */ + if (be32_to_cpu(dip->di_next_unlinked) != iup->old_agino) { + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, + sizeof(*dip), __this_address); + error = -EFSCORRUPTED; + goto out; + } + + trace_xfs_iunlink_update_dinode(mp, iup->pag->pag_agno, + XFS_INO_TO_AGINO(mp, ip->i_ino), + be32_to_cpu(dip->di_next_unlinked), iup->next_agino); + + dip->di_next_unlinked = cpu_to_be32(iup->next_agino); + offset = ip->i_imap.im_boffset + + offsetof(struct xfs_dinode, di_next_unlinked); + + xfs_dinode_calc_crc(mp, dip); + xfs_trans_inode_buf(tp, ibp); + xfs_trans_log_buf(tp, ibp, offset, offset + sizeof(xfs_agino_t) - 1); + return 0; +out: + xfs_trans_brelse(tp, ibp); + return error; +} + +/* + * Initialize the inode log item for a newly allocated (in-core) inode. + * + * Inode extents can only reside within an AG. Hence specify the starting + * block for the inode chunk by offset within an AG as well as the + * length of the allocated extent. + * + * This joins the item to the transaction and marks it dirty so + * that we don't need a separate call to do this, nor does the + * caller need to know anything about the iunlink item. + */ +int +xfs_iunlink_log_inode( + struct xfs_trans *tp, + struct xfs_inode *ip, + struct xfs_perag *pag, + xfs_agino_t next_agino) +{ + struct xfs_iunlink_item iup = { + .ip = ip, + .pag = pag, + .next_agino = next_agino, + .old_agino = ip->i_next_unlinked, + }; + + ASSERT(xfs_verify_agino_or_null(pag, next_agino)); + ASSERT(xfs_verify_agino_or_null(pag, ip->i_next_unlinked)); + + /* + * Since we're updating a linked list, we should never find that the + * current pointer is the same as the new value, unless we're + * terminating the list. + */ + if (ip->i_next_unlinked == next_agino) { + if (next_agino != NULLAGINO) + return -EFSCORRUPTED; + return 0; + } + + return xfs_iunlink_log_dinode(tp, &iup); +} + diff --git a/libxfs/iunlink.h b/libxfs/iunlink.h new file mode 100644 index 00000000000..fec6a515181 --- /dev/null +++ b/libxfs/iunlink.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2022, Red Hat, Inc. + * All Rights Reserved. + */ +#ifndef XFS_IUNLINK_ITEM_H +#define XFS_IUNLINK_ITEM_H 1 + +struct xfs_trans; +struct xfs_inode; +struct xfs_perag; + +static inline struct xfs_inode * +xfs_iunlink_lookup(struct xfs_perag *pag, xfs_agino_t agino) +{ + return NULL; +} + +int xfs_iunlink_log_inode(struct xfs_trans *tp, struct xfs_inode *ip, + struct xfs_perag *pag, xfs_agino_t next_agino); + +#endif /* XFS_IUNLINK_ITEM_H */ diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index acad5ccd228..90335331cde 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -518,6 +518,8 @@ void __xfs_buf_mark_corrupt(struct xfs_buf *bp, xfs_failaddr_t fa); #define xfs_filestream_lookup_ag(ip) (0) #define xfs_filestream_new_ag(ip,ag) (0) +#define xfs_trans_inode_buf(tp, bp) ((void) 0) + /* quota bits */ #define xfs_trans_mod_dquot_byino(t,i,f,d) ((void) 0) #define xfs_trans_reserve_quota_nblks(t,i,b,n,f) (0) @@ -690,6 +692,32 @@ static inline void xfs_buf_hash_destroy(struct xfs_perag *pag) { } static inline int xfs_iunlink_init(struct xfs_perag *pag) { return 0; } static inline void xfs_iunlink_destroy(struct xfs_perag *pag) { } +static inline xfs_agino_t +xfs_iunlink_lookup_backref( + struct xfs_perag *pag, + xfs_agino_t agino) +{ + return NULLAGINO; +} + +static inline int +xfs_iunlink_add_backref( + struct xfs_perag *pag, + xfs_agino_t prev_agino, + xfs_agino_t this_agino) +{ + return 0; +} + +static inline int +xfs_iunlink_change_backref( + struct xfs_perag *pag, + xfs_agino_t agino, + xfs_agino_t next_unlinked) +{ + return 0; +} + xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *mp, xfs_agnumber_t agcount); diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c index 21196a899da..4b19edd9ab1 100644 --- a/libxfs/xfs_inode_util.c +++ b/libxfs/xfs_inode_util.c @@ -17,6 +17,9 @@ #include "xfs_ialloc.h" #include "xfs_health.h" #include "xfs_bmap.h" +#include "xfs_trace.h" +#include "xfs_ag.h" +#include "iunlink.h" uint16_t xfs_flags2diflags( @@ -333,3 +336,275 @@ xfs_inode_init( /* now that we have an i_mode we can setup the inode structure */ xfs_setup_inode(ip); } + +/* + * In-Core Unlinked List Lookups + * ============================= + * + * Every inode is supposed to be reachable from some other piece of metadata + * with the exception of the root directory. Inodes with a connection to a + * file descriptor but not linked from anywhere in the on-disk directory tree + * are collectively known as unlinked inodes, though the filesystem itself + * maintains links to these inodes so that on-disk metadata are consistent. + * + * XFS implements a per-AG on-disk hash table of unlinked inodes. The AGI + * header contains a number of buckets that point to an inode, and each inode + * record has a pointer to the next inode in the hash chain. This + * singly-linked list causes scaling problems in the iunlink remove function + * because we must walk that list to find the inode that points to the inode + * being removed from the unlinked hash bucket list. + * + * Hence we keep an in-memory double linked list to link each inode on an + * unlinked list. Because there are 64 unlinked lists per AGI, keeping pointer + * based lists would require having 64 list heads in the perag, one for each + * list. This is expensive in terms of memory (think millions of AGs) and cache + * misses on lookups. Instead, use the fact that inodes on the unlinked list + * must be referenced at the VFS level to keep them on the list and hence we + * have an existence guarantee for inodes on the unlinked list. + * + * Given we have an existence guarantee, we can use lockless inode cache lookups + * to resolve aginos to xfs inodes. This means we only need 8 bytes per inode + * for the double linked unlinked list, and we don't need any extra locking to + * keep the list safe as all manipulations are done under the AGI buffer lock. + * Keeping the list up to date does not require memory allocation, just finding + * the XFS inode and updating the next/prev unlinked list aginos. + */ + +/* Update the prev pointer of the next agino. */ +static int +xfs_iunlink_update_backref( + struct xfs_perag *pag, + xfs_agino_t prev_agino, + xfs_agino_t next_agino) +{ + struct xfs_inode *ip; + + /* No update necessary if we are at the end of the list. */ + if (next_agino == NULLAGINO) + return 0; + + ip = xfs_iunlink_lookup(pag, next_agino); + if (!ip) { + xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI); + return -EFSCORRUPTED; + } + + ip->i_prev_unlinked = prev_agino; + return 0; +} + +/* + * Point the AGI unlinked bucket at an inode and log the results. The caller + * is responsible for validating the old value. + */ +STATIC int +xfs_iunlink_update_bucket( + struct xfs_trans *tp, + struct xfs_perag *pag, + struct xfs_buf *agibp, + unsigned int bucket_index, + xfs_agino_t new_agino) +{ + struct xfs_agi *agi = agibp->b_addr; + xfs_agino_t old_value; + int offset; + + ASSERT(xfs_verify_agino_or_null(pag, new_agino)); + + old_value = be32_to_cpu(agi->agi_unlinked[bucket_index]); + trace_xfs_iunlink_update_bucket(tp->t_mountp, pag->pag_agno, bucket_index, + old_value, new_agino); + + /* + * We should never find the head of the list already set to the value + * passed in because either we're adding or removing ourselves from the + * head of the list. + */ + if (old_value == new_agino) { + xfs_buf_mark_corrupt(agibp); + xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI); + return -EFSCORRUPTED; + } + + agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino); + offset = offsetof(struct xfs_agi, agi_unlinked) + + (sizeof(xfs_agino_t) * bucket_index); + xfs_trans_log_buf(tp, agibp, offset, offset + sizeof(xfs_agino_t) - 1); + return 0; +} + +static int +xfs_iunlink_insert_inode( + struct xfs_trans *tp, + struct xfs_perag *pag, + struct xfs_buf *agibp, + struct xfs_inode *ip) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_agi *agi = agibp->b_addr; + xfs_agino_t next_agino; + xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); + short bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; + int error; + + /* + * Get the index into the agi hash table for the list this inode will + * go on. Make sure the pointer isn't garbage and that this inode + * isn't already on the list. + */ + next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); + if (next_agino == agino || + !xfs_verify_agino_or_null(pag, next_agino)) { + xfs_buf_mark_corrupt(agibp); + xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI); + return -EFSCORRUPTED; + } + + /* + * Update the prev pointer in the next inode to point back to this + * inode. + */ + error = xfs_iunlink_update_backref(pag, agino, next_agino); + if (error) + return error; + + if (next_agino != NULLAGINO) { + /* + * There is already another inode in the bucket, so point this + * inode to the current head of the list. + */ + error = xfs_iunlink_log_inode(tp, ip, pag, next_agino); + if (error) + return error; + ip->i_next_unlinked = next_agino; + } + + /* Point the head of the list to point to this inode. */ + ip->i_prev_unlinked = NULLAGINO; + return xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, agino); +} + +/* + * This is called when the inode's link count has gone to 0 or we are creating + * a tmpfile via O_TMPFILE. The inode @ip must have nlink == 0. + * + * We place the on-disk inode on a list in the AGI. It will be pulled from this + * list when the inode is freed. + */ +int +xfs_iunlink( + struct xfs_trans *tp, + struct xfs_inode *ip) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_perag *pag; + struct xfs_buf *agibp; + int error; + + ASSERT(VFS_I(ip)->i_nlink == 0); + ASSERT(VFS_I(ip)->i_mode != 0); + trace_xfs_iunlink(ip); + + pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); + + /* Get the agi buffer first. It ensures lock ordering on the list. */ + error = xfs_read_agi(pag, tp, &agibp); + if (error) + goto out; + + error = xfs_iunlink_insert_inode(tp, pag, agibp, ip); +out: + xfs_perag_put(pag); + return error; +} + +static int +xfs_iunlink_remove_inode( + struct xfs_trans *tp, + struct xfs_perag *pag, + struct xfs_buf *agibp, + struct xfs_inode *ip) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_agi *agi = agibp->b_addr; + xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); + xfs_agino_t head_agino; + short bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; + int error; + + trace_xfs_iunlink_remove(ip); + + /* + * Get the index into the agi hash table for the list this inode will + * go on. Make sure the head pointer isn't garbage. + */ + head_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); + if (!xfs_verify_agino(pag, head_agino)) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + agi, sizeof(*agi)); + xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI); + return -EFSCORRUPTED; + } + + /* + * Set our inode's next_unlinked pointer to NULL and then return + * the old pointer value so that we can update whatever was previous + * to us in the list to point to whatever was next in the list. + */ + error = xfs_iunlink_log_inode(tp, ip, pag, NULLAGINO); + if (error) + return error; + + /* + * Update the prev pointer in the next inode to point back to previous + * inode in the chain. + */ + error = xfs_iunlink_update_backref(pag, ip->i_prev_unlinked, + ip->i_next_unlinked); + if (error) + return error; + + if (head_agino != agino) { + struct xfs_inode *prev_ip; + + prev_ip = xfs_iunlink_lookup(pag, ip->i_prev_unlinked); + if (!prev_ip) { + xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE); + return -EFSCORRUPTED; + } + + error = xfs_iunlink_log_inode(tp, prev_ip, pag, + ip->i_next_unlinked); + prev_ip->i_next_unlinked = ip->i_next_unlinked; + } else { + /* Point the head of the list to the next unlinked inode. */ + error = xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, + ip->i_next_unlinked); + } + + ip->i_next_unlinked = NULLAGINO; + ip->i_prev_unlinked = 0; + return error; +} + +/* + * Pull the on-disk inode from the AGI unlinked list. + */ +int +xfs_iunlink_remove( + struct xfs_trans *tp, + struct xfs_perag *pag, + struct xfs_inode *ip) +{ + struct xfs_buf *agibp; + int error; + + trace_xfs_iunlink_remove(ip); + + /* Get the agi buffer first. It ensures lock ordering on the list. */ + error = xfs_read_agi(pag, tp, &agibp); + if (error) + return error; + + return xfs_iunlink_remove_inode(tp, pag, agibp, ip); +} diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h index a73ccaea558..e15cf94e094 100644 --- a/libxfs/xfs_inode_util.h +++ b/libxfs/xfs_inode_util.h @@ -56,6 +56,10 @@ void xfs_trans_ichgtime(struct xfs_trans *tp, struct xfs_inode *ip, int flags); void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args, struct xfs_inode *ip); +int xfs_iunlink(struct xfs_trans *tp, struct xfs_inode *ip); +int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_inode *ip); + /* The libxfs client must provide this group of helper functions. */ /* Handle legacy Irix sgid inheritance quirks. */ From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085583 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 32B35C4332F for ; Sat, 31 Dec 2022 02:07:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236158AbiLaCHf (ORCPT ); Fri, 30 Dec 2022 21:07:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCHc (ORCPT ); Fri, 30 Dec 2022 21:07:32 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9767013F97 for ; Fri, 30 Dec 2022 18:07:31 -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 409C3B81DF6 for ; Sat, 31 Dec 2022 02:07:30 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E82BCC433EF; Sat, 31 Dec 2022 02:07:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452449; bh=oGaddjt9rNXM/L+GJHQg7X4/80N7MNEwwi7go3OihOc=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=RukjPnY1QdQjBzj3JmftckBnSg2Vmp/33/L3PZlKURkxuji94RdBTNNamfg3Ngo4u K6i8YAQI4tst1oQIGn8HRsFvZzRSzu5NzYpUklp2opX83BTreJ7O759UxX4fDzASbJ 6m764tUE69rJLXupv9ooxxG99GapfcQ8j1SxzMImS4W8q3xjVhFThm7qkSvZaeawwC 3Jz7OTKqkbPNQKyc0hnKfmfAHM5DVQWgASs5w7PcTAf0QK/Xj1azfmOWENc8mqS/pF d7brruWubafGvdpltUub1BAN5YYF9sHIQysjnEVM74+9VJ3dMV+azgTHhzxk5fTJmA 9Efgoj8henQxw== Subject: [PATCH 17/26] xfs: hoist xfs_{bump,drop}link to libxfs From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875524.723621.513390509314496204.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Move xfs_bumplink and xfs_droplink to libxfs. Signed-off-by: Darrick J. Wong --- include/xfs_inode.h | 4 ++++ libxfs/xfs_inode_util.c | 35 +++++++++++++++++++++++++++++++++++ libxfs/xfs_inode_util.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 234f8d3affa..ccd19e5ee5b 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -257,6 +257,10 @@ static inline void inc_nlink(struct inode *inode) { inode->i_nlink++; } +static inline void drop_nlink(struct inode *inode) +{ + inode->i_nlink--; +} static inline bool xfs_is_reflink_inode(struct xfs_inode *ip) { diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c index 4b19edd9ab1..e12c43954cf 100644 --- a/libxfs/xfs_inode_util.c +++ b/libxfs/xfs_inode_util.c @@ -608,3 +608,38 @@ xfs_iunlink_remove( return xfs_iunlink_remove_inode(tp, pag, agibp, ip); } + +/* + * Decrement the link count on an inode & log the change. If this causes the + * link count to go to zero, move the inode to AGI unlinked list so that it can + * be freed when the last active reference goes away via xfs_inactive(). + */ +int +xfs_droplink( + struct xfs_trans *tp, + struct xfs_inode *ip) +{ + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); + + drop_nlink(VFS_I(ip)); + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + + if (VFS_I(ip)->i_nlink) + return 0; + + return xfs_iunlink(tp, ip); +} + +/* + * Increment the link count on an inode & log the change. + */ +void +xfs_bumplink( + struct xfs_trans *tp, + struct xfs_inode *ip) +{ + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); + + inc_nlink(VFS_I(ip)); + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); +} diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h index e15cf94e094..f92b14a6fbe 100644 --- a/libxfs/xfs_inode_util.h +++ b/libxfs/xfs_inode_util.h @@ -59,6 +59,8 @@ void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args, int xfs_iunlink(struct xfs_trans *tp, struct xfs_inode *ip); int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag, struct xfs_inode *ip); +int xfs_droplink(struct xfs_trans *tp, struct xfs_inode *ip); +void xfs_bumplink(struct xfs_trans *tp, struct xfs_inode *ip); /* The libxfs client must provide this group of helper functions. */ From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085584 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 08AA4C4332F for ; Sat, 31 Dec 2022 02:07:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236162AbiLaCHr (ORCPT ); Fri, 30 Dec 2022 21:07:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52682 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCHq (ORCPT ); Fri, 30 Dec 2022 21:07:46 -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 8017B1C430 for ; Fri, 30 Dec 2022 18:07:45 -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 2524861CC2 for ; Sat, 31 Dec 2022 02:07:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7C857C433EF; Sat, 31 Dec 2022 02:07:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452464; bh=XQifu2S0REiqLMQAKODpExBnNIuq2MHCVVL0PoRnUw0=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=n86MZD1y+MBz9WFtBeM4T1kZdyFoiO1zK01FkgRbdeRLM4L7whLeSmdpTKz0R5sG+ +uKCwPJiHc21dyw8flahnyK3CAJ/gqZW2MzAy3SVsUdKcXu9ECPwsrCzZhO9AuB3Ix lmhfjy4K2hvvzsXd9SqufFOdz8/2lX5maFlxpG7zHquiRIu5HrOmBlwccLl1D1JTYK l9RyuI1YDwdVpHgr/jVnzKFlSVPAVRuim6xXWIbJJntkRkQagVlAjk/9ITvkHuF+Of zeBVFpE27KwfPWNay4N1KPh60Y41XTMJUmKVhT4PK+9S0jQpZ4jMIYWpoBPMpz2SWv jJR986fxHiYGA== Subject: [PATCH 18/26] xfs: create libxfs helper to link a new inode into a directory From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875535.723621.9136738856135046159.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create a new libxfs function to link a newly created inode into a directory. The upcoming metadata directory feature will need this to create a metadata directory tree. Signed-off-by: Darrick J. Wong --- libxfs/xfs_dir2.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_dir2.h | 4 ++++ 2 files changed, 49 insertions(+) diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 460b64339d7..ed52969b45d 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -18,6 +18,9 @@ #include "xfs_errortag.h" #include "xfs_trace.h" #include "xfs_health.h" +#include "xfs_shared.h" +#include "xfs_bmap_btree.h" +#include "xfs_trans_space.h" const struct xfs_name xfs_name_dotdot = { .name = (const unsigned char *)"..", @@ -780,3 +783,45 @@ xfs_dir2_compname( return xfs_ascii_ci_compname(args, name, len); return xfs_da_compname(args, name, len); } + +/* + * Given a directory @dp, a newly allocated inode @ip, and a @name, link @ip + * into @dp under the given @name. If @ip is a directory, it will be + * initialized. Both inodes must have the ILOCK held and the transaction must + * have sufficient blocks reserved. + */ +int +xfs_dir_create_new_child( + struct xfs_trans *tp, + uint resblks, + struct xfs_inode *dp, + struct xfs_name *name, + struct xfs_inode *ip) +{ + struct xfs_mount *mp = tp->t_mountp; + int error; + + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + ASSERT(xfs_isilocked(dp, XFS_ILOCK_EXCL)); + ASSERT(resblks == 0 || resblks > XFS_IALLOC_SPACE_RES(mp)); + + error = xfs_dir_createname(tp, dp, name, ip->i_ino, + resblks - XFS_IALLOC_SPACE_RES(mp)); + if (error) { + ASSERT(error != -ENOSPC); + return error; + } + + xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); + xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); + + if (!S_ISDIR(VFS_I(ip)->i_mode)) + return 0; + + error = xfs_dir_init(tp, ip, dp); + if (error) + return error; + + xfs_bumplink(tp, dp); + return 0; +} diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index 7322284f61a..d3e7607c0e9 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -253,4 +253,8 @@ unsigned int xfs_dir3_data_end_offset(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr); bool xfs_dir2_namecheck(const void *name, size_t length); +int xfs_dir_create_new_child(struct xfs_trans *tp, uint resblks, + struct xfs_inode *dp, struct xfs_name *name, + struct xfs_inode *ip); + #endif /* __XFS_DIR2_H__ */ From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085585 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 A0DD9C4332F for ; Sat, 31 Dec 2022 02:08:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236159AbiLaCID (ORCPT ); Fri, 30 Dec 2022 21:08:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCIB (ORCPT ); Fri, 30 Dec 2022 21:08:01 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13724140F1 for ; Fri, 30 Dec 2022 18:08: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 dfw.source.kernel.org (Postfix) with ESMTPS id AD5FF61CCE for ; Sat, 31 Dec 2022 02:08:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 120EEC433D2; Sat, 31 Dec 2022 02:08:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452480; bh=NDT3Q8Uwyhg7qsE1y5Iv2NjbEs2ENum1dNZ2nyCaojA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=i9NsEMcEXXOnXLpZFBAQbIXFOG8iEHeFpsUAV5ApFmas9b/gjfoXtI2NA6mWua+DG M/7kxUSHYp4Z+FE26JBLjL18ToguYjgQltud14k8hZAIQTE2AHtEZnCCflDukh11Al 5vBhXDfhk3mcSUuY+8IwIJIz9187C7xScqsJVV0lajouSNgC6EWiPQH/RefyVR3BIV L5lZXEpT8hRH/d0u3y19cme3vnxxBmKiJi84/wK5MmUfk8IPp+yRvuJkMX1bYplFxG VVMkQn/i09JnZ69PpFZNBdThsHnpDGs/E9ck30B6JzAflDoNAX3zzrZWsLtmt5M9sL M4fC1pM/rCIxA== Subject: [PATCH 19/26] xfs: create libxfs helper to link an existing inode into a directory From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875547.723621.11413859898250059295.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create a new libxfs function to link an existing inode into a directory. The upcoming metadata directory feature will need this to create a metadata directory tree. Signed-off-by: Darrick J. Wong --- libxfs/xfs_dir2.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_dir2.h | 3 +++ 2 files changed, 54 insertions(+) diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index ed52969b45d..8755ef615f8 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -21,6 +21,7 @@ #include "xfs_shared.h" #include "xfs_bmap_btree.h" #include "xfs_trans_space.h" +#include "xfs_ag.h" const struct xfs_name xfs_name_dotdot = { .name = (const unsigned char *)"..", @@ -825,3 +826,53 @@ xfs_dir_create_new_child( xfs_bumplink(tp, dp); return 0; } + +/* + * Given a directory @dp, an existing non-directory inode @ip, and a @name, + * link @ip into @dp under the given @name. Both inodes must have the ILOCK + * held. + */ +int +xfs_dir_link_existing_child( + struct xfs_trans *tp, + uint resblks, + struct xfs_inode *dp, + struct xfs_name *name, + struct xfs_inode *ip) +{ + struct xfs_mount *mp = tp->t_mountp; + int error; + + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + ASSERT(xfs_isilocked(dp, XFS_ILOCK_EXCL)); + ASSERT(!S_ISDIR(VFS_I(ip)->i_mode)); + + if (!resblks) { + error = xfs_dir_canenter(tp, dp, name); + if (error) + return error; + } + + /* + * Handle initial link state of O_TMPFILE inode + */ + if (VFS_I(ip)->i_nlink == 0) { + struct xfs_perag *pag; + + pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); + error = xfs_iunlink_remove(tp, pag, ip); + xfs_perag_put(pag); + if (error) + return error; + } + + error = xfs_dir_createname(tp, dp, name, ip->i_ino, resblks); + if (error) + return error; + + xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); + xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); + + xfs_bumplink(tp, ip); + return 0; +} diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index d3e7607c0e9..4afade8b087 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -256,5 +256,8 @@ bool xfs_dir2_namecheck(const void *name, size_t length); int xfs_dir_create_new_child(struct xfs_trans *tp, uint resblks, struct xfs_inode *dp, struct xfs_name *name, struct xfs_inode *ip); +int xfs_dir_link_existing_child(struct xfs_trans *tp, uint resblks, + struct xfs_inode *dp, struct xfs_name *name, + struct xfs_inode *ip); #endif /* __XFS_DIR2_H__ */ From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085586 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 1E1F0C4332F for ; Sat, 31 Dec 2022 02:08:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236160AbiLaCIS (ORCPT ); Fri, 30 Dec 2022 21:08:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52762 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCIR (ORCPT ); Fri, 30 Dec 2022 21:08: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 AAC4D140F1 for ; Fri, 30 Dec 2022 18:08:16 -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 46BE961CCE for ; Sat, 31 Dec 2022 02:08:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3CA1C433D2; Sat, 31 Dec 2022 02:08:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452495; bh=H+EcAR2ZdCeEoQ8JZiJIp4qEv0NEa5hwniJJSDUhis8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=f0kBvZ/Zw6PeURL5fJK/Sw/9CVEah2/1IpiSnbpIb4rihvNh52/zdZdLE5/m1AFpy uBl1G2JSYagNGtMmAd5mxbW1sAHupAbhGnlRNiykTsz+tl2nkGFNdT+0OyHS2Nq9GU XVfxt7bYZiF9Sa04pecuDFAQbLxGZ5VpJwyXG1dtPd2685lwK50932E063s2a3GnWO lYj8CVEkKDDc6IcYGIERuZ3OQiR+8z/EcLt1k3kAuyFh5KJPMYkzkpHa4ZKaheJ2Es fRuQSFmRMdaSFNqU4wr3HB007GsMHtwmcMHNiWzYzAFfHPxuZg6OXE6ckZ/+6zzNXb qyU7dSgD+7UHw== Subject: [PATCH 20/26] xfs: hoist inode free function to libxfs From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875558.723621.14021574407372540466.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create a libxfs helper function that marks an inode free on disk. Signed-off-by: Darrick J. Wong --- libxfs/xfs_inode_util.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_inode_util.h | 5 +++++ 2 files changed, 55 insertions(+) diff --git a/libxfs/xfs_inode_util.c b/libxfs/xfs_inode_util.c index e12c43954cf..65c025f3573 100644 --- a/libxfs/xfs_inode_util.c +++ b/libxfs/xfs_inode_util.c @@ -643,3 +643,53 @@ xfs_bumplink( inc_nlink(VFS_I(ip)); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } + +/* Mark an inode free on disk. */ +int +xfs_dir_ifree( + struct xfs_trans *tp, + struct xfs_perag *pag, + struct xfs_inode *ip, + struct xfs_icluster *xic) +{ + int error; + + /* + * Free the inode first so that we guarantee that the AGI lock is going + * to be taken before we remove the inode from the unlinked list. This + * makes the AGI lock -> unlinked list modification order the same as + * used in O_TMPFILE creation. + */ + error = xfs_difree(tp, pag, ip->i_ino, xic); + if (error) + return error; + + error = xfs_iunlink_remove(tp, pag, ip); + if (error) + return error; + + /* + * Free any local-format data sitting around before we reset the + * data fork to extents format. Note that the attr fork data has + * already been freed by xfs_attr_inactive. + */ + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) { + kmem_free(ip->i_df.if_u1.if_data); + ip->i_df.if_u1.if_data = NULL; + ip->i_df.if_bytes = 0; + } + + VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ + ip->i_diflags = 0; + ip->i_diflags2 = ip->i_mount->m_ino_geo.new_diflags2; + ip->i_forkoff = 0; /* mark the attr fork not in use */ + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; + + /* + * Bump the generation count so no one will be confused + * by reincarnations of this inode. + */ + VFS_I(ip)->i_generation++; + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + return 0; +} diff --git a/libxfs/xfs_inode_util.h b/libxfs/xfs_inode_util.h index f92b14a6fbe..fcddaa6f738 100644 --- a/libxfs/xfs_inode_util.h +++ b/libxfs/xfs_inode_util.h @@ -6,6 +6,8 @@ #ifndef __XFS_INODE_UTIL_H__ #define __XFS_INODE_UTIL_H__ +struct xfs_icluster; + uint16_t xfs_flags2diflags(struct xfs_inode *ip, unsigned int xflags); uint64_t xfs_flags2diflags2(struct xfs_inode *ip, unsigned int xflags); uint32_t xfs_dic2xflags(struct xfs_inode *ip); @@ -56,6 +58,9 @@ void xfs_trans_ichgtime(struct xfs_trans *tp, struct xfs_inode *ip, int flags); void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args, struct xfs_inode *ip); +int xfs_dir_ifree(struct xfs_trans *tp, struct xfs_perag *pag, + struct xfs_inode *ip, struct xfs_icluster *xic); + int xfs_iunlink(struct xfs_trans *tp, struct xfs_inode *ip); int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag, struct xfs_inode *ip); From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085587 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 96958C4332F for ; Sat, 31 Dec 2022 02:08:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236161AbiLaCIf (ORCPT ); Fri, 30 Dec 2022 21:08:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52778 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCIf (ORCPT ); Fri, 30 Dec 2022 21:08:35 -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 C6EBE140F1 for ; Fri, 30 Dec 2022 18:08:33 -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 7AF56B81DFC for ; Sat, 31 Dec 2022 02:08:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3FFC8C433EF; Sat, 31 Dec 2022 02:08:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452511; bh=WY5T3QfqkgcBF60UDrXmPx9BWXUtm3/nvTMT+E/tA4c=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=UYmSspGCcT08F4A/lkcJxfZ2WZ8GrSNrjixljiktXGqrLAifr7hjfOZhfUrbaUKkj FnGufMYUXA2fN3j5ExK00KnF5ASt8TD5lXS4O/CmWe6C/C9VI1kTeJ/1AW2BiXJjlW VA8Fi53/tjiPm08eTUzPxOKVb/vmjBqYW0nVwP2A7X0+DOQ7kGuNUhtJrIAPFydSs/ OSBoqaE9I/+VL3HscrV07x0/LSXk/BH5VTQ3rhmPLcguMjZKK+z3iE1nwuvRGKB+Jd I46UTbapyVJle0UqJRualWJvzobLwZTEgKWNz9R5MroRQ05rbAI8UsNFRO9ye5n0HF 5ugOC3UhBKemQ== Subject: [PATCH 21/26] xfs: create libxfs helper to remove an existing inode/name from a directory From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875570.723621.17672686424212927777.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create a new libxfs function to remove a (name, inode) entry from a directory. The upcoming metadata directory feature will need this to create a metadata directory tree. Signed-off-by: Darrick J. Wong --- libxfs/xfs_dir2.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_dir2.h | 3 ++ 2 files changed, 76 insertions(+) diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 8755ef615f8..a0853d766f2 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -876,3 +876,76 @@ xfs_dir_link_existing_child( xfs_bumplink(tp, ip); return 0; } + +/* + * Given a directory @dp, a child @ip, and a @name, remove the (@name, @ip) + * entry from the directory. Both inodes must have the ILOCK held. + */ +int +xfs_dir_remove_child( + struct xfs_trans *tp, + uint resblks, + struct xfs_inode *dp, + struct xfs_name *name, + struct xfs_inode *ip) +{ + int error; + + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + ASSERT(xfs_isilocked(dp, XFS_ILOCK_EXCL)); + + /* + * If we're removing a directory perform some additional validation. + */ + if (S_ISDIR(VFS_I(ip)->i_mode)) { + ASSERT(VFS_I(ip)->i_nlink >= 2); + if (VFS_I(ip)->i_nlink != 2) + return -ENOTEMPTY; + if (!xfs_dir_isempty(ip)) + return -ENOTEMPTY; + + /* Drop the link from ip's "..". */ + error = xfs_droplink(tp, dp); + if (error) + return error; + + /* Drop the "." link from ip to self. */ + error = xfs_droplink(tp, ip); + if (error) + return error; + + /* + * Point the unlinked child directory's ".." entry to the root + * directory to eliminate back-references to inodes that may + * get freed before the child directory is closed. If the fs + * gets shrunk, this can lead to dirent inode validation errors. + */ + if (dp->i_ino != tp->t_mountp->m_sb.sb_rootino) { + error = xfs_dir_replace(tp, ip, &xfs_name_dotdot, + tp->t_mountp->m_sb.sb_rootino, 0); + if (error) + return error; + } + } else { + /* + * When removing a non-directory we need to log the parent + * inode here. For a directory this is done implicitly + * by the xfs_droplink call for the ".." entry. + */ + xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); + } + xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); + + /* Drop the link from dp to ip. */ + error = xfs_droplink(tp, ip); + if (error) + return error; + + error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks); + if (error) { + ASSERT(error != -ENOENT); + return error; + } + + return 0; +} diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index 4afade8b087..e35deb273d8 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -259,5 +259,8 @@ int xfs_dir_create_new_child(struct xfs_trans *tp, uint resblks, int xfs_dir_link_existing_child(struct xfs_trans *tp, uint resblks, struct xfs_inode *dp, struct xfs_name *name, struct xfs_inode *ip); +int xfs_dir_remove_child(struct xfs_trans *tp, uint resblks, + struct xfs_inode *dp, struct xfs_name *name, + struct xfs_inode *ip); #endif /* __XFS_DIR2_H__ */ From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085588 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 41BCCC4332F for ; Sat, 31 Dec 2022 02:08:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236163AbiLaCIt (ORCPT ); Fri, 30 Dec 2022 21:08:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCIs (ORCPT ); Fri, 30 Dec 2022 21:08:48 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC443140F1 for ; Fri, 30 Dec 2022 18:08: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 6819661CD3 for ; Sat, 31 Dec 2022 02:08:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C004BC433D2; Sat, 31 Dec 2022 02:08:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452526; bh=D5q96YaFc/DCP0jlaRAH3qdNUF77gERh0mnNLbhv0xU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=V9Wi8/dh4c+VsjPuSoQneMmGRTV7V0M/bxAEgwBT2SZfaa6KsvvBTyt7O+QiA8X7Q CUOchI46Zh+bSVCO7MPKrB24nDpVuwN9PZ6tZZA2PVMT2utlkX5BobNH0HezIP3JMO PdCgUFUETsg4KjNP1PEOX9QULOazhi8DOEc2fqIPUVgz/NZ/iJyVIklCGNeca4tBV4 Feiq3kcVd83zuXo7P3MvXrdqNWf318y5TGFUyzZ1Ud5g1MfyczT8foRxQQmR90KXOv 9OMhlF19ByVpMFr8oM5sO7G1zujZLm5BYc5Yf9GmhUTzkHijHDwwMBSJaQULyZO5jz L2BlestaU28Rw== Subject: [PATCH 22/26] xfs: create libxfs helper to exchange two directory entries From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875581.723621.10793024373873352545.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create a new libxfs function to exchange two directory entries. The upcoming metadata directory feature will need this to replace a metadata inode directory entry. Signed-off-by: Darrick J. Wong --- libxfs/xfs_dir2.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_dir2.h | 4 ++ 2 files changed, 112 insertions(+) diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index a0853d766f2..b0bb22ac506 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -949,3 +949,111 @@ xfs_dir_remove_child( return 0; } + +/* + * Exchange the entry (@name1, @ip1) in directory @dp1 with the entry (@name2, + * @ip2) in directory @dp2, and update '..' @ip1 and @ip2's entries as needed. + * @ip1 and @ip2 need not be of the same type. + * + * All inodes must have the ILOCK held, and both entries must already exist. + */ +int +xfs_dir_exchange( + struct xfs_trans *tp, + struct xfs_inode *dp1, + struct xfs_name *name1, + struct xfs_inode *ip1, + struct xfs_inode *dp2, + struct xfs_name *name2, + struct xfs_inode *ip2, + unsigned int spaceres) +{ + int ip1_flags = 0; + int ip2_flags = 0; + int dp2_flags = 0; + int error; + + /* Swap inode number for dirent in first parent */ + error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, spaceres); + if (error) + return error; + + /* Swap inode number for dirent in second parent */ + error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, spaceres); + if (error) + return error; + + /* + * If we're renaming one or more directories across different parents, + * update the respective ".." entries (and link counts) to match the new + * parents. + */ + if (dp1 != dp2) { + dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; + + if (S_ISDIR(VFS_I(ip2)->i_mode)) { + error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, + dp1->i_ino, spaceres); + if (error) + return error; + + /* transfer ip2 ".." reference to dp1 */ + if (!S_ISDIR(VFS_I(ip1)->i_mode)) { + error = xfs_droplink(tp, dp2); + if (error) + return error; + xfs_bumplink(tp, dp1); + } + + /* + * Although ip1 isn't changed here, userspace needs + * to be warned about the change, so that applications + * relying on it (like backup ones), will properly + * notify the change + */ + ip1_flags |= XFS_ICHGTIME_CHG; + ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; + } + + if (S_ISDIR(VFS_I(ip1)->i_mode)) { + error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, + dp2->i_ino, spaceres); + if (error) + return error; + + /* transfer ip1 ".." reference to dp2 */ + if (!S_ISDIR(VFS_I(ip2)->i_mode)) { + error = xfs_droplink(tp, dp1); + if (error) + return error; + xfs_bumplink(tp, dp2); + } + + /* + * Although ip2 isn't changed here, userspace needs + * to be warned about the change, so that applications + * relying on it (like backup ones), will properly + * notify the change + */ + ip1_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; + ip2_flags |= XFS_ICHGTIME_CHG; + } + } + + if (ip1_flags) { + xfs_trans_ichgtime(tp, ip1, ip1_flags); + xfs_trans_log_inode(tp, ip1, XFS_ILOG_CORE); + } + if (ip2_flags) { + xfs_trans_ichgtime(tp, ip2, ip2_flags); + xfs_trans_log_inode(tp, ip2, XFS_ILOG_CORE); + } + if (dp2_flags) { + xfs_trans_ichgtime(tp, dp2, dp2_flags); + xfs_trans_log_inode(tp, dp2, XFS_ILOG_CORE); + } + xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); + xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE); + + return 0; +} diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index e35deb273d8..f63390236f0 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -262,5 +262,9 @@ int xfs_dir_link_existing_child(struct xfs_trans *tp, uint resblks, int xfs_dir_remove_child(struct xfs_trans *tp, uint resblks, struct xfs_inode *dp, struct xfs_name *name, struct xfs_inode *ip); +int xfs_dir_exchange(struct xfs_trans *tp, struct xfs_inode *dp1, + struct xfs_name *name1, struct xfs_inode *ip1, + struct xfs_inode *dp2, struct xfs_name *name2, + struct xfs_inode *ip2, unsigned int spaceres); #endif /* __XFS_DIR2_H__ */ From patchwork Fri Dec 30 22:19:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085589 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 960FDC4332F for ; Sat, 31 Dec 2022 02:09:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236164AbiLaCJG (ORCPT ); Fri, 30 Dec 2022 21:09:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCJG (ORCPT ); Fri, 30 Dec 2022 21:09:06 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0930F140F1 for ; Fri, 30 Dec 2022 18:09:05 -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 BB1CCB81E00 for ; Sat, 31 Dec 2022 02:09:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 83393C433EF; Sat, 31 Dec 2022 02:09:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452542; bh=0aHUHx5/xkOnN4tnRVs+IxrB4grTH3jRhmKoLekqeOo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=pG3wU+ETE3yJzqgkITO40sZ65ynzaH/CzKWuREJ8tQ5WA27CZJa0TNLNVH0j5h6Ae JcXeb365iy2iAaavcDD98A5cWzsXaAufQl9GhzY++BwDfhEYi/f96AUBan4caPQPSO MQADZhHtyaQkwH7A6CM4qgqkKgY8uOIWfaNjc6Wonu7iuR7FgZhJIublcSGCZLD2na 3CFdjMZ9p2iVrWF/4nRCV1Zn66GYfCUc4EtHKSFs3TXx1rXMK2gI1dMws1QUN1BTSi D5KZUNn8eorHZHHLz38/GI9E0ewD+91mR/KWjdqcA9W76r40hv/C8EjDJ6IeVNbj34 8pXGPKYTfKXng== Subject: [PATCH 23/26] xfs: create libxfs helper to rename two directory entries From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:15 -0800 Message-ID: <167243875592.723621.16095946193604750197.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Create a new libxfs function to rename two directory entries. The upcoming metadata directory feature will need this to replace a metadata inode directory entry. Signed-off-by: Darrick J. Wong --- libxfs/xfs_dir2.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_dir2.h | 5 + 2 files changed, 208 insertions(+) diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index b0bb22ac506..ae91fc48d79 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -22,6 +22,7 @@ #include "xfs_bmap_btree.h" #include "xfs_trans_space.h" #include "xfs_ag.h" +#include "xfs_ialloc.h" const struct xfs_name xfs_name_dotdot = { .name = (const unsigned char *)"..", @@ -1057,3 +1058,205 @@ xfs_dir_exchange( return 0; } + +/* + * Given an entry (@src_name, @src_ip) in directory @src_dp, make the entry + * @target_name in directory @target_dp point to @src_ip and remove the + * original entry, cleaning up everything left behind. + * + * Cleanup involves dropping a link count on @target_ip, and either removing + * the (@src_name, @src_ip) entry from @src_dp or simply replacing the entry + * with (@src_name, @wip) if a whiteout inode @wip is supplied. + * + * All inodes must have the ILOCK held. We assume that if @src_ip is a + * directory then its '..' doesn't already point to @target_dp, and that @wip + * is a freshly allocated whiteout. + */ +int +xfs_dir_rename( + struct xfs_trans *tp, + struct xfs_inode *src_dp, + struct xfs_name *src_name, + struct xfs_inode *src_ip, + struct xfs_inode *target_dp, + struct xfs_name *target_name, + struct xfs_inode *target_ip, + unsigned int spaceres, + struct xfs_inode *wip) +{ + struct xfs_mount *mp = tp->t_mountp; + bool new_parent = (src_dp != target_dp); + bool src_is_directory; + int error; + + src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode); + + /* + * Check for expected errors before we dirty the transaction + * so we can return an error without a transaction abort. + */ + if (target_ip == NULL) { + /* + * If there's no space reservation, check the entry will + * fit before actually inserting it. + */ + if (!spaceres) { + error = xfs_dir_canenter(tp, target_dp, target_name); + if (error) + return error; + } + } else { + /* + * If target exists and it's a directory, check that whether + * it can be destroyed. + */ + if (S_ISDIR(VFS_I(target_ip)->i_mode) && + (!xfs_dir_isempty(target_ip) || + (VFS_I(target_ip)->i_nlink > 2))) + return -EEXIST; + } + + /* + * Directory entry creation below may acquire the AGF. Remove + * the whiteout from the unlinked list first to preserve correct + * AGI/AGF locking order. This dirties the transaction so failures + * after this point will abort and log recovery will clean up the + * mess. + * + * For whiteouts, we need to bump the link count on the whiteout + * inode. After this point, we have a real link, clear the tmpfile + * state flag from the inode so it doesn't accidentally get misused + * in future. + */ + if (wip) { + struct xfs_perag *pag; + + ASSERT(VFS_I(wip)->i_nlink == 0); + + pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, wip->i_ino)); + error = xfs_iunlink_remove(tp, pag, wip); + xfs_perag_put(pag); + if (error) + return error; + + xfs_bumplink(tp, wip); + } + + /* + * Set up the target. + */ + if (target_ip == NULL) { + /* + * If target does not exist and the rename crosses + * directories, adjust the target directory link count + * to account for the ".." reference from the new entry. + */ + error = xfs_dir_createname(tp, target_dp, target_name, + src_ip->i_ino, spaceres); + if (error) + return error; + + xfs_trans_ichgtime(tp, target_dp, + XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); + + if (new_parent && src_is_directory) { + xfs_bumplink(tp, target_dp); + } + } else { /* target_ip != NULL */ + /* + * Link the source inode under the target name. + * If the source inode is a directory and we are moving + * it across directories, its ".." entry will be + * inconsistent until we replace that down below. + * + * In case there is already an entry with the same + * name at the destination directory, remove it first. + */ + error = xfs_dir_replace(tp, target_dp, target_name, + src_ip->i_ino, spaceres); + if (error) + return error; + + xfs_trans_ichgtime(tp, target_dp, + XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); + + /* + * Decrement the link count on the target since the target + * dir no longer points to it. + */ + error = xfs_droplink(tp, target_ip); + if (error) + return error; + + if (src_is_directory) { + /* + * Drop the link from the old "." entry. + */ + error = xfs_droplink(tp, target_ip); + if (error) + return error; + } + } /* target_ip != NULL */ + + /* + * Remove the source. + */ + if (new_parent && src_is_directory) { + /* + * Rewrite the ".." entry to point to the new + * directory. + */ + error = xfs_dir_replace(tp, src_ip, &xfs_name_dotdot, + target_dp->i_ino, spaceres); + ASSERT(error != -EEXIST); + if (error) + return error; + } + + /* + * We always want to hit the ctime on the source inode. + * + * This isn't strictly required by the standards since the source + * inode isn't really being changed, but old unix file systems did + * it and some incremental backup programs won't work without it. + */ + xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG); + xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE); + + /* + * Adjust the link count on src_dp. This is necessary when + * renaming a directory, either within one parent when + * the target existed, or across two parent directories. + */ + if (src_is_directory && (new_parent || target_ip != NULL)) { + + /* + * Decrement link count on src_directory since the + * entry that's moved no longer points to it. + */ + error = xfs_droplink(tp, src_dp); + if (error) + return error; + } + + /* + * For whiteouts, we only need to update the source dirent with the + * inode number of the whiteout inode rather than removing it + * altogether. + */ + if (wip) + error = xfs_dir_replace(tp, src_dp, src_name, wip->i_ino, + spaceres); + else + error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, + spaceres); + if (error) + return error; + + xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); + xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE); + if (new_parent) + xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE); + + return 0; +} diff --git a/libxfs/xfs_dir2.h b/libxfs/xfs_dir2.h index f63390236f0..00b4642bc8a 100644 --- a/libxfs/xfs_dir2.h +++ b/libxfs/xfs_dir2.h @@ -266,5 +266,10 @@ int xfs_dir_exchange(struct xfs_trans *tp, struct xfs_inode *dp1, struct xfs_name *name1, struct xfs_inode *ip1, struct xfs_inode *dp2, struct xfs_name *name2, struct xfs_inode *ip2, unsigned int spaceres); +int xfs_dir_rename(struct xfs_trans *tp, struct xfs_inode *src_dp, + struct xfs_name *src_name, struct xfs_inode *src_ip, + struct xfs_inode *target_dp, struct xfs_name *target_name, + struct xfs_inode *target_ip, unsigned int spaceres, + struct xfs_inode *wip); #endif /* __XFS_DIR2_H__ */ From patchwork Fri Dec 30 22:19:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085590 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 E0B97C4332F for ; Sat, 31 Dec 2022 02:09:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236165AbiLaCJX (ORCPT ); Fri, 30 Dec 2022 21:09:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCJV (ORCPT ); Fri, 30 Dec 2022 21:09:21 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD872140F1 for ; Fri, 30 Dec 2022 18:09:20 -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 7A9E5B81E02 for ; Sat, 31 Dec 2022 02:09:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 13F11C433EF; Sat, 31 Dec 2022 02:09:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452558; bh=/eAMeapHbzEHWsQ9owPQhdSkQR/IYFc7PaX9DZpaQOs=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=eQYwshUdi+7WvbOqIcbEhDh4gjsd/+H2aNvC0hF5Zctkiqd/D7RjLxy8vwlXliFx5 zqOE9yBsyBttjWJXwT/MNWr0MgSfEmgME6R1LvLJp6k4eNiMTC/MKqezDd1Wuxm3bB gvpZVpYHiTaXbX+jZOLlt1MsjdUz/dE+f39BDHUpYqIjOl0yHLv4ZaFEmLfSeuWCE4 qcrYqg/PJIuCuPmGQzvjIHbRfWw1Qlej4dsn5+k4wEX+SKuP6ZAlgX93wR3KWDiz0C xAVhtAmzflyaBF8Bz6wZY3+9uALqYTUrUARnajfN+DMUHnFKyR0H/Z1dISkQN/kO9U Gu1vemRy2gFdg== Subject: [PATCH 24/26] xfs: don't use the incore struct xfs_sb for offsets into struct xfs_dsb From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:16 -0800 Message-ID: <167243875604.723621.9882135567786591664.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Currently, the XFS_SB_CRC_OFF macro uses the incore superblock struct (xfs_sb) to compute the address of sb_crc within the ondisk superblock struct (xfs_dsb). This is a landmine if we ever change the layout of the incore superblock (as we're about to do), so redefine the macro to use xfs_dsb to compute the layout of xfs_dsb. Signed-off-by: Darrick J. Wong --- db/sb.c | 4 ++-- libxfs/xfs_format.h | 9 ++++----- mdrestore/xfs_mdrestore.c | 6 ++---- repair/agheader.c | 12 ++++++------ 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/db/sb.c b/db/sb.c index fd81286cd60..095c59596a4 100644 --- a/db/sb.c +++ b/db/sb.c @@ -50,8 +50,8 @@ sb_init(void) add_command(&version_cmd); } -#define OFF(f) bitize(offsetof(xfs_sb_t, sb_ ## f)) -#define SZC(f) szcount(xfs_sb_t, sb_ ## f) +#define OFF(f) bitize(offsetof(struct xfs_dsb, sb_ ## f)) +#define SZC(f) szcount(struct xfs_dsb, sb_ ## f) const field_t sb_flds[] = { { "magicnum", FLDT_UINT32X, OI(OFF(magicnum)), C1, 0, TYP_NONE }, { "blocksize", FLDT_UINT32D, OI(OFF(blocksize)), C1, 0, TYP_NONE }, diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index 0c457905cce..abd75b3091e 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -90,8 +90,7 @@ struct xfs_ifork; #define XFSLABEL_MAX 12 /* - * Superblock - in core version. Must match the ondisk version below. - * Must be padded to 64 bit alignment. + * Superblock - in core version. Must be padded to 64 bit alignment. */ typedef struct xfs_sb { uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ @@ -178,10 +177,8 @@ typedef struct xfs_sb { /* must be padded to 64 bit alignment */ } xfs_sb_t; -#define XFS_SB_CRC_OFF offsetof(struct xfs_sb, sb_crc) - /* - * Superblock - on disk version. Must match the in core version above. + * Superblock - on disk version. * Must be padded to 64 bit alignment. */ struct xfs_dsb { @@ -265,6 +262,8 @@ struct xfs_dsb { /* must be padded to 64 bit alignment */ }; +#define XFS_SB_CRC_OFF offsetof(struct xfs_dsb, sb_crc) + /* * Misc. Flags - warning - these will be cleared by xfs_repair unless * a feature bit is set when the flag is used. diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c index 7c1a66c4001..9f8cbe98cd6 100644 --- a/mdrestore/xfs_mdrestore.c +++ b/mdrestore/xfs_mdrestore.c @@ -164,10 +164,8 @@ perform_restore( memset(block_buffer, 0, sb.sb_sectsize); sb.sb_inprogress = 0; libxfs_sb_to_disk((struct xfs_dsb *)block_buffer, &sb); - if (xfs_sb_version_hascrc(&sb)) { - xfs_update_cksum(block_buffer, sb.sb_sectsize, - offsetof(struct xfs_sb, sb_crc)); - } + if (xfs_sb_version_hascrc(&sb)) + xfs_update_cksum(block_buffer, sb.sb_sectsize, XFS_SB_CRC_OFF); if (pwrite(dst_fd, block_buffer, sb.sb_sectsize, 0) < 0) fatal("error writing primary superblock: %s\n", strerror(errno)); diff --git a/repair/agheader.c b/repair/agheader.c index 762901581e1..3930a0ac091 100644 --- a/repair/agheader.c +++ b/repair/agheader.c @@ -358,22 +358,22 @@ secondary_sb_whack( * size is the size of data which is valid for this sb. */ if (xfs_sb_version_hasmetauuid(sb)) - size = offsetof(xfs_sb_t, sb_meta_uuid) + size = offsetof(struct xfs_dsb, sb_meta_uuid) + sizeof(sb->sb_meta_uuid); else if (xfs_sb_version_hascrc(sb)) - size = offsetof(xfs_sb_t, sb_lsn) + size = offsetof(struct xfs_dsb, sb_lsn) + sizeof(sb->sb_lsn); else if (xfs_sb_version_hasmorebits(sb)) - size = offsetof(xfs_sb_t, sb_bad_features2) + size = offsetof(struct xfs_dsb, sb_bad_features2) + sizeof(sb->sb_bad_features2); else if (xfs_sb_version_haslogv2(sb)) - size = offsetof(xfs_sb_t, sb_logsunit) + size = offsetof(struct xfs_dsb, sb_logsunit) + sizeof(sb->sb_logsunit); else if (xfs_sb_version_hassector(sb)) - size = offsetof(xfs_sb_t, sb_logsectsize) + size = offsetof(struct xfs_dsb, sb_logsectsize) + sizeof(sb->sb_logsectsize); else /* only support dirv2 or more recent */ - size = offsetof(xfs_sb_t, sb_dirblklog) + size = offsetof(struct xfs_dsb, sb_dirblklog) + sizeof(sb->sb_dirblklog); /* Check the buffer we read from disk for garbage outside size */ From patchwork Fri Dec 30 22:19:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085591 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 C23F7C4332F for ; Sat, 31 Dec 2022 02:09:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236166AbiLaCJi (ORCPT ); Fri, 30 Dec 2022 21:09:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52846 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCJh (ORCPT ); Fri, 30 Dec 2022 21:09:37 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39329140F1 for ; Fri, 30 Dec 2022 18:09: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 E7820B81DFC for ; Sat, 31 Dec 2022 02:09:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A2701C433D2; Sat, 31 Dec 2022 02:09:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452573; bh=LQqOvMlEi3PkCBFvlEluAMPPlFqrq368itpPuJd+jjY=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=RQP8SOR7HVtBVdBHWQ9Eeh2vUXZO55/UFpwTX8yP8e2jv8DH1z7a8ksMeQG8+vvWZ xZAKBwdo6rUCo9sgsbWnJzne6cpPvjQSAJSXI+zIRWQlwe2tzwnUFiEUHsDyFJX4bi ci3dxS/XqB54TU4gdwFQhfjCNdBFOcu8UxwokDX/cSpxN3p3hR5rQjWjFC6rUNyRYc prNpKzw5Iw/Up5bB+kwQdliW0Ove3x9tptzeXVKl4CFNTIErIXMhcxiioDDzzeE0XG 9JCGykf9zHL/u8/rCgG9H6NW/S/Dnq+oFmcSLNadQU7yTepPqwFhOC89aN1KEmHhJa TGNW/yOAFpbwQ== Subject: [PATCH 25/26] xfs_repair: use library functions to reset root/rbm/rsum inodes From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:16 -0800 Message-ID: <167243875616.723621.2958131470455642479.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Use the iroot reset function to reset root inodes instead of open-coding the reset routine. While we're at it, fix a longstanding memory leak if the inode being reset actually had an xattr fork full of mappings. Signed-off-by: Darrick J. Wong --- libxfs/libxfs_api_defs.h | 2 + repair/phase6.c | 126 +++++++++------------------------------------- 2 files changed, 28 insertions(+), 100 deletions(-) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 782a551ee1c..2b2b958d8a9 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -133,6 +133,7 @@ #define xfs_dquot_verify libxfs_dquot_verify #define xfs_finobt_calc_reserves libxfs_finobt_calc_reserves +#define xfs_fixed_inode_reset libxfs_fixed_inode_reset #define xfs_free_extent libxfs_free_extent #define xfs_free_perag libxfs_free_perag #define xfs_fs_geometry libxfs_fs_geometry @@ -159,6 +160,7 @@ #define xfs_inobt_stage_cursor libxfs_inobt_stage_cursor #define xfs_inode_from_disk libxfs_inode_from_disk #define xfs_inode_from_disk_ts libxfs_inode_from_disk_ts +#define xfs_inode_init libxfs_inode_init #define xfs_inode_to_disk libxfs_inode_to_disk #define xfs_inode_validate_cowextsize libxfs_inode_validate_cowextsize #define xfs_inode_validate_extsize libxfs_inode_validate_extsize diff --git a/repair/phase6.c b/repair/phase6.c index 0c24cfbf144..5765c2b1250 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -445,20 +445,28 @@ res_failed( do_error(_("xfs_trans_reserve returned %d\n"), err); } -static inline void -reset_inode_fields(struct xfs_inode *ip) +/* + * Forcibly reinitialize a fixed-location inode, such as a filesystem root + * directory or the realtime metadata inodes. The inode must not otherwise be + * in use; the data fork must be empty, and the attr fork will be reset. + */ +static void +reset_root_ino( + struct xfs_trans *tp, + umode_t mode, + struct xfs_inode *ip) { - ip->i_projid = 0; - ip->i_disk_size = 0; - ip->i_nblocks = 0; - ip->i_extsize = 0; - ip->i_cowextsize = 0; - ip->i_flushiter = 0; + struct xfs_icreate_args args = { + .nlink = S_ISDIR(mode) ? 2 : 1, + }; + + libxfs_icreate_args_rootfile(&args, mode); + + /* Erase the attr fork since libxfs_inode_init won't do it for us. */ ip->i_forkoff = 0; - ip->i_diflags = 0; - ip->i_diflags2 = 0; - ip->i_crtime.tv_sec = 0; - ip->i_crtime.tv_nsec = 0; + libxfs_ifork_zap_attr(ip); + + libxfs_inode_init(tp, &args, ip); } static void @@ -472,7 +480,6 @@ mk_rbmino(xfs_mount_t *mp) int error; xfs_fileoff_t bno; xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; - int times; uint blocks; /* @@ -489,34 +496,9 @@ mk_rbmino(xfs_mount_t *mp) error); } - reset_inode_fields(ip); - - VFS_I(ip)->i_mode = S_IFREG; - ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; - libxfs_ifork_zap_attr(ip); - - set_nlink(VFS_I(ip), 1); /* account for sb ptr */ - - times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD; - if (xfs_has_v3inodes(mp)) { - VFS_I(ip)->i_version = 1; - ip->i_diflags2 = 0; - times |= XFS_ICHGTIME_CREATE; - } - libxfs_trans_ichgtime(tp, ip, times); - - /* - * now the ifork - */ - ip->i_df.if_bytes = 0; - ip->i_df.if_u1.if_root = NULL; - + /* Reset the realtime bitmap inode. */ + reset_root_ino(tp, S_IFREG, ip); ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize; - - /* - * commit changes - */ - libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = -libxfs_trans_commit(tp); if (error) @@ -711,7 +693,6 @@ mk_rsumino(xfs_mount_t *mp) int nsumblocks; xfs_fileoff_t bno; xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP]; - int times; uint blocks; /* @@ -728,34 +709,9 @@ mk_rsumino(xfs_mount_t *mp) error); } - reset_inode_fields(ip); - - VFS_I(ip)->i_mode = S_IFREG; - ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; - libxfs_ifork_zap_attr(ip); - - set_nlink(VFS_I(ip), 1); /* account for sb ptr */ - - times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD; - if (xfs_has_v3inodes(mp)) { - VFS_I(ip)->i_version = 1; - ip->i_diflags2 = 0; - times |= XFS_ICHGTIME_CREATE; - } - libxfs_trans_ichgtime(tp, ip, times); - - /* - * now the ifork - */ - ip->i_df.if_bytes = 0; - ip->i_df.if_u1.if_root = NULL; - + /* Reset the rt summary inode. */ + reset_root_ino(tp, S_IFREG, ip); ip->i_disk_size = mp->m_rsumsize; - - /* - * commit changes - */ - libxfs_trans_ijoin(tp, ip, 0); libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = -libxfs_trans_commit(tp); if (error) @@ -811,7 +767,6 @@ mk_root_dir(xfs_mount_t *mp) int error; const mode_t mode = 0755; ino_tree_node_t *irec; - int times; ip = NULL; i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp); @@ -823,37 +778,8 @@ mk_root_dir(xfs_mount_t *mp) do_error(_("could not iget root inode -- error - %d\n"), error); } - /* - * take care of the core since we didn't call the libxfs ialloc function - * (comment changed to avoid tangling xfs/437) - */ - reset_inode_fields(ip); - - VFS_I(ip)->i_mode = mode|S_IFDIR; - ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; - libxfs_ifork_zap_attr(ip); - - set_nlink(VFS_I(ip), 2); /* account for . and .. */ - - times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD; - if (xfs_has_v3inodes(mp)) { - VFS_I(ip)->i_version = 1; - ip->i_diflags2 = 0; - times |= XFS_ICHGTIME_CREATE; - } - libxfs_trans_ichgtime(tp, ip, times); - libxfs_trans_ijoin(tp, ip, 0); - libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - - /* - * now the ifork - */ - ip->i_df.if_bytes = 0; - ip->i_df.if_u1.if_root = NULL; - - /* - * initialize the directory - */ + /* Reset the root directory. */ + reset_root_ino(tp, mode | S_IFDIR, ip); libxfs_dir_init(tp, ip, ip); error = -libxfs_trans_commit(tp); From patchwork Fri Dec 30 22:19:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085592 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 C4794C4332F for ; Sat, 31 Dec 2022 02:09:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236167AbiLaCJx (ORCPT ); Fri, 30 Dec 2022 21:09:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231494AbiLaCJx (ORCPT ); Fri, 30 Dec 2022 21:09:53 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD94B140F1 for ; Fri, 30 Dec 2022 18:09: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 7A277B81E00 for ; Sat, 31 Dec 2022 02:09:50 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3C629C433EF; Sat, 31 Dec 2022 02:09:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672452589; bh=6iLz3kl0MA3aOKqY0S7feDtba5Yf0eL9+N61uCVmTsU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=NL61b+8guZjt/Gb/Jo4tDA1FpZJNxNWR5uPUPriYLcgpw1t15jnOsukCMKyrhaiEV 8vIw0rRY6xO3Ol+lTzaeZgsmFUyye7OU6NHr9Ky2vzoZnQYd6bO0L/Rs/czoLW8Dac t8wgU7ZV+zALJ/nwwmz/t6r/c0OijeX3+OYjC8kCExG6uVoyyets3h+0boOUf9FpbJ mm08AzItWJhJMA943yJ/wpRW2MHGCZd7Ybk83OzwlFf3vJIQzBO/a02y50FwHQt0xT 7vlpzVg3rMWNFjXhjyvkkw2tJRiUoywIOeGTLnEr3K2uhP/dlINkfzyK+ulKyjmuU7 mmOwWAOZrdoiQ== Subject: [PATCH 26/26] xfs_repair: use library functions for orphanage creation From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:19:16 -0800 Message-ID: <167243875627.723621.10704668689659836913.stgit@magnolia> In-Reply-To: <167243875315.723621.17759760420120912799.stgit@magnolia> References: <167243875315.723621.17759760420120912799.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Use new library functions to create lost+found. Signed-off-by: Darrick J. Wong --- libxfs/libxfs_api_defs.h | 1 + repair/phase6.c | 28 ++++++++-------------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 2b2b958d8a9..a5f9c6006f6 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -123,6 +123,7 @@ #define xfs_dir2_shrink_inode libxfs_dir2_shrink_inode #define xfs_dir_createname libxfs_dir_createname +#define xfs_dir_create_new_child libxfs_dir_create_new_child #define xfs_dir_init libxfs_dir_init #define xfs_dir_ino_validate libxfs_dir_ino_validate #define xfs_dir_lookup libxfs_dir_lookup diff --git a/repair/phase6.c b/repair/phase6.c index 5765c2b1250..f8f42eb6e29 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -804,6 +804,11 @@ mk_orphanage( struct xfs_icreate_args args = { .nlink = 2, }; + struct xfs_name xname = { + .name = ORPHANAGE, + .len = strlen(ORPHANAGE), + .type = XFS_DIR3_FT_DIR, + }; struct xfs_trans *tp; struct xfs_inode *ip; struct xfs_inode *pip; @@ -814,7 +819,6 @@ mk_orphanage( int error; int nres; const umode_t mode = S_IFDIR | 0755; - struct xfs_name xname; libxfs_icreate_args_rootfile(&args, mode); @@ -830,9 +834,6 @@ mk_orphanage( i, ORPHANAGE); args.pip = pip; - xname.name = (unsigned char *)ORPHANAGE; - xname.len = strlen(ORPHANAGE); - xname.type = XFS_DIR3_FT_DIR; if (libxfs_dir_lookup(NULL, pip, &xname, &ino, NULL) == 0) return ino; @@ -845,15 +846,6 @@ mk_orphanage( if (i) res_failed(i); - /* - * use iget/ijoin instead of trans_iget because the ialloc - * wrapper can commit the transaction and start a new one - */ -/* i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip); - if (i) - do_error(_("%d - couldn't iget root inode to make %s\n"), - i, ORPHANAGE);*/ - error = -libxfs_dialloc(&tp, mp->m_sb.sb_rootino, mode, &ino); if (error) do_error(_("%s inode allocation failed %d\n"), @@ -902,26 +894,22 @@ mk_orphanage( /* * create the actual entry */ - error = -libxfs_dir_createname(tp, pip, &xname, ip->i_ino, nres); + error = -libxfs_dir_create_new_child(tp, nres, pip, &xname, ip); if (error) do_error( _("can't make %s, createname error %d\n"), ORPHANAGE, error); /* - * bump up the link count in the root directory to account - * for .. in the new directory, and update the irec copy of the + * We bumped up the link count in the root directory to account + * for .. in the new directory, so now update the irec copy of the * on-disk nlink so we don't fail the link count check later. */ - inc_nlink(VFS_I(pip)); irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino), XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)); add_inode_ref(irec, 0); set_inode_disk_nlinks(irec, 0, get_inode_disk_nlinks(irec, 0) + 1); - libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE); - libxfs_dir_init(tp, ip, pip); - libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); error = -libxfs_trans_commit(tp); if (error) { do_error(_("%s directory creation failed -- bmapf error %d\n"),