From patchwork Sat Apr 27 05:03:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13645552 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8AFA37149 for ; Sat, 27 Apr 2024 05:04:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194250; cv=none; b=OAAMmNWEUsd8ZVivqY+eKRpBE/MeYA2QaT/KvH29trD60xajOsXyWLh+QSbzfIME1RMU1CTNCvCPp4USkLoP1b/7GF6PWzsTdnmC8d1IIsN2JpKZ+khkl9emAzAIEiZznTpM9gJlXuc4YFoDaVz3dGLVc5gVraSRk60bpvmwP90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194250; c=relaxed/simple; bh=dcm/ZXaUKw5FGeqtv8yEcTm3fuTTWH2FBccH9XZ6rfc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ONXYLf4ZjqQlwiLLid4AFLnSDB3jTJqSqi6GOMwCfp3a0IR+E9WSKSEbC0bQXoKkQSf0OpLlXMzFmlHVj6XCbRhGuEB614HbZHplukyh7P/uccTbgvj1B7qPJ4WTZsfrn9jLSiiAIZo3vwrFe5P71qk2KaZ6mksMKkqUW4/DEU8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=kINbMN4p; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="kINbMN4p" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=xba4HPApWMxFMi2Q2HKYUm7Cml5rpSKwxUv82M+luQ4=; b=kINbMN4pk9fKbANyl5COQadZ50 A7R206CJSNbHCXIUu9iLPeDE5ixwdauLtQMq88aPYdxIy0MSfGrp3F0+h85x4R0w/GPL4FXOUIKJt 0/GHjfX9ZNuc2+CDDGIDv7ySlfBW9q8Hdq4deOVpPOhdG9263iRPTkyjMeEZ7mLeXxWeMc4STSgv2 hkEo1PwgEPLGRROREr4lgivaNYgeby16IVGm4MydMVxljQN2HmRu9sQiS+xCHl6FjaXB9dyw2zCrJ GhsvmIL3wbx3Qnd5Z8ztpCBy2acNgLZUMDIH2LeHPySEZQepGVPPzsP5Xp/ETJIz4nTwMxEBVZ83R KJHV44Xw==; Received: from 2a02-8389-2341-5b80-39d3-4735-9a3c-88d8.cable.dynamic.v6.surfer.at ([2a02:8389:2341:5b80:39d3:4735:9a3c:88d8] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1s0aEI-0000000EqBd-3kwU; Sat, 27 Apr 2024 05:04:07 +0000 From: Christoph Hellwig To: Chandan Babu R , "Darrick J. Wong" Cc: linux-xfs@vger.kernel.org Subject: [PATCH 1/5] xfs: factor out a xfs_dir_lookup_args helper Date: Sat, 27 Apr 2024 07:03:56 +0200 Message-Id: <20240427050400.1126656-2-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240427050400.1126656-1-hch@lst.de> References: <20240427050400.1126656-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Add a helper to switch between the different directory formats for lookup and to handle the -EEXIST return for a successful lookup. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.c | 66 ++++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_dir2.h | 2 ++ fs/xfs/scrub/readdir.c | 35 +-------------------- 3 files changed, 43 insertions(+), 60 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 7634344dc51538..b4f9359089117e 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -352,6 +352,45 @@ xfs_dir_cilookup_result( return -EEXIST; } +int +xfs_dir_lookup_args( + struct xfs_da_args *args) +{ + bool is_block, is_leaf; + int error; + + if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { + error = xfs_dir2_sf_lookup(args); + goto out; + } + + /* dir2 functions require that the data fork is loaded */ + error = xfs_iread_extents(args->trans, args->dp, XFS_DATA_FORK); + if (error) + goto out; + + error = xfs_dir2_isblock(args, &is_block); + if (error) + goto out; + + if (is_block) { + error = xfs_dir2_block_lookup(args); + goto out; + } + + error = xfs_dir2_isleaf(args, &is_leaf); + if (error) + goto out; + if (is_leaf) + error = xfs_dir2_leaf_lookup(args); + else + error = xfs_dir2_node_lookup(args); +out: + if (error != -EEXIST) + return error; + return 0; +} + /* * Lookup a name in a directory, give back the inode number. * If ci_name is not NULL, returns the actual name in ci_name if it differs @@ -368,7 +407,6 @@ xfs_dir_lookup( { struct xfs_da_args *args; int rval; - bool v; int lock_mode; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -390,30 +428,7 @@ xfs_dir_lookup( args->op_flags |= XFS_DA_OP_CILOOKUP; lock_mode = xfs_ilock_data_map_shared(dp); - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { - rval = xfs_dir2_sf_lookup(args); - goto out_check_rval; - } - - rval = xfs_dir2_isblock(args, &v); - if (rval) - goto out_free; - if (v) { - rval = xfs_dir2_block_lookup(args); - goto out_check_rval; - } - - rval = xfs_dir2_isleaf(args, &v); - if (rval) - goto out_free; - if (v) - rval = xfs_dir2_leaf_lookup(args); - else - rval = xfs_dir2_node_lookup(args); - -out_check_rval: - if (rval == -EEXIST) - rval = 0; + rval = xfs_dir_lookup_args(args); if (!rval) { *inum = args->inumber; if (ci_name) { @@ -421,7 +436,6 @@ xfs_dir_lookup( ci_name->len = args->valuelen; } } -out_free: xfs_iunlock(dp, lock_mode); kfree(args); return rval; diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index b580a78bcf4fc2..982c2249bfa305 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -66,6 +66,8 @@ extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name); +int xfs_dir_lookup_args(struct xfs_da_args *args); + /* * Direct call from the bmap code, bypassing the generic directory layer. */ diff --git a/fs/xfs/scrub/readdir.c b/fs/xfs/scrub/readdir.c index 28a94c78b0b199..0ac77359d8e9f8 100644 --- a/fs/xfs/scrub/readdir.c +++ b/fs/xfs/scrub/readdir.c @@ -328,7 +328,6 @@ xchk_dir_lookup( .op_flags = XFS_DA_OP_OKNOENT, .owner = dp->i_ino, }; - bool isblock, isleaf; int error; if (xfs_is_shutdown(dp->i_mount)) @@ -344,39 +343,7 @@ xchk_dir_lookup( ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); xfs_assert_ilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL); - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { - error = xfs_dir2_sf_lookup(&args); - goto out_check_rval; - } - - /* dir2 functions require that the data fork is loaded */ - error = xfs_iread_extents(sc->tp, dp, XFS_DATA_FORK); - if (error) - return error; - - error = xfs_dir2_isblock(&args, &isblock); - if (error) - return error; - - if (isblock) { - error = xfs_dir2_block_lookup(&args); - goto out_check_rval; - } - - error = xfs_dir2_isleaf(&args, &isleaf); - if (error) - return error; - - if (isleaf) { - error = xfs_dir2_leaf_lookup(&args); - goto out_check_rval; - } - - error = xfs_dir2_node_lookup(&args); - -out_check_rval: - if (error == -EEXIST) - error = 0; + error = xfs_dir_lookup_args(&args); if (!error) *ino = args.inumber; return error; From patchwork Sat Apr 27 05:03:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13645553 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8779B3E476 for ; Sat, 27 Apr 2024 05:04:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194252; cv=none; b=npGXugo/cQ+aoo0K9Ser8bzeo1yvVlFN/Vj3h4DrZ1iVgMRnaPtMxzy4GXQVMclBpxYAB5EX8ehUrkQ55ocWU24ZOEiBSuadP5YJj+X8sSBQceWDHSLQmmxgtOcUG2CA2U19FQ8XB+SLUIKYifDgz1NS1cl+9KW62QRNlDzkL88= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194252; c=relaxed/simple; bh=8oSoNhm3XHFHTtgl3UvryDs83wBF+bSPWVFdDnnVKT0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QCcKOO4Jlcrp1H3Ojmld+/4ibyOzZ3Yx1nAICKfjEOP6vtOsBe+AOxo9iBP4TuOt/TTEeKTKtI4LzTRxkFdM4dKmwRpHewXVF3gm6qtzvYx/rusrM6I1oKZdx+E74Ko/lZYbz3l4HffQzatybHKDxKtiSC0TozjfhOJIvgsPQsY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=xpC4VlvY; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="xpC4VlvY" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=rFEOkL8elgIXkHyooX3gkugA7WUFv6Ar05xGFzpNEjQ=; b=xpC4VlvY3nlw1OurPIGfSw+QLF qR4QjIXwtTWrwKrGjnnkEHVLLWvHRRp6ZCTLIxH2d5NGHHX22+U+uYFWMgDqDfYM7L7KiLfLQiew5 gQ+BIDCwO9c2/HGmOlbamxnOVVPx/HOkNBEHb7PFJaxAc9QKLRoT/6n/pq8n2J9eeauTpRtoYig/2 K9uOWoHI/jASBEiGHKmzyauM4ejlpQIOSGe+E8ZjqklPQEjt39UYFW1ud1E60dUa8mye4hCbPle85 RoMjwDwTLoGPg1ADyeeiqof4oNsbQzRX/XQ6H4nztbSKuOm3wshmG68F7HiWa9fYAnMwAHgluGEZS VY2TuF9w==; Received: from 2a02-8389-2341-5b80-39d3-4735-9a3c-88d8.cable.dynamic.v6.surfer.at ([2a02:8389:2341:5b80:39d3:4735:9a3c:88d8] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1s0aEL-0000000EqC1-1MwM; Sat, 27 Apr 2024 05:04:09 +0000 From: Christoph Hellwig To: Chandan Babu R , "Darrick J. Wong" Cc: linux-xfs@vger.kernel.org Subject: [PATCH 2/5] xfs: factor out a xfs_dir_createname_args helper Date: Sat, 27 Apr 2024 07:03:57 +0200 Message-Id: <20240427050400.1126656-3-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240427050400.1126656-1-hch@lst.de> References: <20240427050400.1126656-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Add a helper to switch between the different directory formats for creating a directory entry and to handle the XFS_DA_OP_JUSTCHECK flag based on the passed in ino number field. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.c | 53 +++++++++++++++++++++------------------ fs/xfs/libxfs/xfs_dir2.h | 1 + fs/xfs/scrub/dir_repair.c | 19 +------------- 3 files changed, 30 insertions(+), 43 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index b4f9359089117e..e2727602d0479e 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -256,6 +256,33 @@ xfs_dir_init( return error; } +int +xfs_dir_createname_args( + struct xfs_da_args *args) +{ + bool is_block, is_leaf; + int error; + + if (!args->inumber) + args->op_flags |= XFS_DA_OP_JUSTCHECK; + + if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + return xfs_dir2_sf_addname(args); + + error = xfs_dir2_isblock(args, &is_block); + if (error) + return error; + if (is_block) + return xfs_dir2_block_addname(args); + + error = xfs_dir2_isleaf(args, &is_leaf); + if (error) + return error; + if (is_leaf) + return xfs_dir2_leaf_addname(args); + return xfs_dir2_node_addname(args); +} + /* * Enter a name in a directory, or check for available space. * If inum is 0, only the available space test is performed. @@ -270,7 +297,6 @@ xfs_dir_createname( { struct xfs_da_args *args; int rval; - bool v; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -297,31 +323,8 @@ xfs_dir_createname( args->trans = tp; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; args->owner = dp->i_ino; - if (!inum) - args->op_flags |= XFS_DA_OP_JUSTCHECK; - - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { - rval = xfs_dir2_sf_addname(args); - goto out_free; - } - rval = xfs_dir2_isblock(args, &v); - if (rval) - goto out_free; - if (v) { - rval = xfs_dir2_block_addname(args); - goto out_free; - } - - rval = xfs_dir2_isleaf(args, &v); - if (rval) - goto out_free; - if (v) - rval = xfs_dir2_leaf_addname(args); - else - rval = xfs_dir2_node_addname(args); - -out_free: + rval = xfs_dir_createname_args(args); kfree(args); return rval; } diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 982c2249bfa305..f5361dd7b90a93 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -67,6 +67,7 @@ extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, struct xfs_name *name); int xfs_dir_lookup_args(struct xfs_da_args *args); +int xfs_dir_createname_args(struct xfs_da_args *args); /* * Direct call from the bmap code, bypassing the generic directory layer. diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c index fa1a9954d48d93..a1e31b7827881c 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -687,7 +687,6 @@ xrep_dir_replay_createname( { struct xfs_scrub *sc = rd->sc; struct xfs_inode *dp = rd->sc->tempip; - bool is_block, is_leaf; int error; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -702,23 +701,7 @@ xrep_dir_replay_createname( rd->args.inumber = inum; rd->args.total = total; rd->args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; - - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) - return xfs_dir2_sf_addname(&rd->args); - - error = xfs_dir2_isblock(&rd->args, &is_block); - if (error) - return error; - if (is_block) - return xfs_dir2_block_addname(&rd->args); - - error = xfs_dir2_isleaf(&rd->args, &is_leaf); - if (error) - return error; - if (is_leaf) - return xfs_dir2_leaf_addname(&rd->args); - - return xfs_dir2_node_addname(&rd->args); + return xfs_dir_createname_args(&rd->args); } /* Replay a stashed removename onto the temporary directory. */ From patchwork Sat Apr 27 05:03:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13645554 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1A6E3E476 for ; Sat, 27 Apr 2024 05:04:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194254; cv=none; b=mZrbpnoG8yIvwxPYhbhGAHVMPT8QENg6ovvxp6VSoSKiUJB9gjSgoA9CbBesMt5csKg56pKye+9LeEIraW7beMs5zRxilPFs+caBwYjGymZ09k4pcWIskCPecqGGbp/yN3vuSVrEV/3R+JnDBVkTK1jPSye1SgAwDlOeCrbrQSs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194254; c=relaxed/simple; bh=bXyPUIxje8XjbwgZc+uecqpuif6vPki8nx5BnjVuN0w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Kb8k4HdC9f9Wgud+n3co7sxZ0d6FNGSARlJxEIERJUd775Bw2K+fbscGOrgG01h6wgdtkxtYU4MliF3JpB8HMkn4fYMSkdPSaENmYyT5eoAPggeTPFirjU3OzH2PLFvKyIbm2CrGTNhCANq9dXfbsKg3wIQrZ/t4HtMi5x6Ef50= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=JnSSTGrP; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="JnSSTGrP" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=NAd2bnYKUrarH/o65idq/6o/zou3eN7xWhIsyqFfMdU=; b=JnSSTGrP6pq4GLSeOKjHWRrbse xj2ULIVi16vZcgipQc6gG96jJCIHcOrqEfC/YINhF+wQvzYdtJ1ZghTRWGg58/RRjNrtAFnQ4RDJ3 7JLFWt2YztUhMR4jtVlD+4BzoqqaIauwCyjzmP4GQAwKBECs8DMeRI+Dqtw9dXyGeoIfKcujbbetB mJesSp6ZktYrd1lHNwQoYQ81LVfzRwg0TnOoTY1Y+RuoimsD7m1Z41i23/LZBE34GXqOpKi/aE+v6 au7im6wGUeVy5hf3oE/WPumlDNZme/0hKxyV3zJYimKuqNnzWzBvXEPPfN1Cd7z3c3/bcT8GzUGUU AccjrcaA==; Received: from 2a02-8389-2341-5b80-39d3-4735-9a3c-88d8.cable.dynamic.v6.surfer.at ([2a02:8389:2341:5b80:39d3:4735:9a3c:88d8] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1s0aEN-0000000EqCG-4Ar6; Sat, 27 Apr 2024 05:04:12 +0000 From: Christoph Hellwig To: Chandan Babu R , "Darrick J. Wong" Cc: linux-xfs@vger.kernel.org Subject: [PATCH 3/5] xfs: factor out a xfs_dir_removename_args helper Date: Sat, 27 Apr 2024 07:03:58 +0200 Message-Id: <20240427050400.1126656-4-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240427050400.1126656-1-hch@lst.de> References: <20240427050400.1126656-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Add a helper to switch between the different directory formats for removing a directory entry. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.c | 48 ++++++++++++++++++++------------------- fs/xfs/libxfs/xfs_dir2.h | 1 + fs/xfs/scrub/dir_repair.c | 20 +--------------- 3 files changed, 27 insertions(+), 42 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index e2727602d0479e..76aa11ade2e92d 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -444,6 +444,30 @@ xfs_dir_lookup( return rval; } +int +xfs_dir_removename_args( + struct xfs_da_args *args) +{ + bool is_block, is_leaf; + int error; + + if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + return xfs_dir2_sf_removename(args); + + error = xfs_dir2_isblock(args, &is_block); + if (error) + return error; + if (is_block) + return xfs_dir2_block_removename(args); + + error = xfs_dir2_isleaf(args, &is_leaf); + if (error) + return error; + if (is_leaf) + return xfs_dir2_leaf_removename(args); + return xfs_dir2_node_removename(args); +} + /* * Remove an entry from a directory. */ @@ -457,7 +481,6 @@ xfs_dir_removename( { struct xfs_da_args *args; int rval; - bool v; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); XFS_STATS_INC(dp->i_mount, xs_dir_remove); @@ -477,28 +500,7 @@ xfs_dir_removename( args->whichfork = XFS_DATA_FORK; args->trans = tp; args->owner = dp->i_ino; - - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { - rval = xfs_dir2_sf_removename(args); - goto out_free; - } - - rval = xfs_dir2_isblock(args, &v); - if (rval) - goto out_free; - if (v) { - rval = xfs_dir2_block_removename(args); - goto out_free; - } - - rval = xfs_dir2_isleaf(args, &v); - if (rval) - goto out_free; - if (v) - rval = xfs_dir2_leaf_removename(args); - else - rval = xfs_dir2_node_removename(args); -out_free: + rval = xfs_dir_removename_args(args); kfree(args); return rval; } diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index f5361dd7b90a93..3db54801d69ecd 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -68,6 +68,7 @@ extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, int xfs_dir_lookup_args(struct xfs_da_args *args); int xfs_dir_createname_args(struct xfs_da_args *args); +int xfs_dir_removename_args(struct xfs_da_args *args); /* * Direct call from the bmap code, bypassing the generic directory layer. diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c index a1e31b7827881c..98e4ed25cc2309 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -712,8 +712,6 @@ xrep_dir_replay_removename( xfs_extlen_t total) { struct xfs_inode *dp = rd->args.dp; - bool is_block, is_leaf; - int error; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -722,23 +720,7 @@ xrep_dir_replay_removename( rd->args.total = total; trace_xrep_dir_replay_removename(dp, name, 0); - - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) - return xfs_dir2_sf_removename(&rd->args); - - error = xfs_dir2_isblock(&rd->args, &is_block); - if (error) - return error; - if (is_block) - return xfs_dir2_block_removename(&rd->args); - - error = xfs_dir2_isleaf(&rd->args, &is_leaf); - if (error) - return error; - if (is_leaf) - return xfs_dir2_leaf_removename(&rd->args); - - return xfs_dir2_node_removename(&rd->args); + return xfs_dir_removename_args(&rd->args); } /* From patchwork Sat Apr 27 05:03:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13645555 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 485173BB50 for ; Sat, 27 Apr 2024 05:04:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194256; cv=none; b=arPb0SB+W40WiZwuWZBqbL782QLtgUyg5RC1ncUXPMYl9BMss7iAvDrBEP45WD0bHAB0vEW1KB6mLN0xNFrM0fwX1Pt9m85sJAsvxoN2vkeNOePZ5SQ1+i4TxUOOKDX47ELdvwRiQ8Nu/usgmALP1RVefXf9A7ROfwgGdVA4HAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194256; c=relaxed/simple; bh=+k3spCQtWBXQM4wgwTbxRPU4+fZgj9qTdSaMfOx+KJw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Rks8nNAjs2B8HZZa2Y6d2NHFE5uBafTcBuwav8YrnSSGOD2rklKKD/XTooBlZU1Jrv8EpkX+ZBQRi1IVskHVNwNe87juO4mbf02ZG4aLyMghkXx8rfJATlVRxD90Ryk69qutO/mhOjolbXK+9zWZT5fKl1tz+FHR7XfgOcUR92g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=bR6RwcaJ; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="bR6RwcaJ" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=zb75gW7eusoNmloUJLe8H8xYPEjIU7cMfjeims56Eko=; b=bR6RwcaJumZ3Trrq3kUBv/Rt8F 6X0ki02HN1Z43bD9wwp3Cnh1R+fqKydOooDJRGwQs49P5LwDxM16VOtTdlp8ZywqAMntynFeJOlIY CwEFl5C6ybgX8WFXImfaTDtUn1bA1rT2vNtu2SaQLOYz3vlFAXvKiGfNH+2XZZe+y8jQfj4/UME+h dfcZ+/hz6A0lt5gQid0PQXPHAbn5w0zCroyfVLE5UDDzbf8Er1Lh/E6x1pj6xte3TTnG5jPNKfq36 K0xWwJBYCZLos0VnKR9icylf4JtgfqLqetgb8CVT8FT926gxZqrDabZN7DcWnvaGVVlgFTLIC169V KgDz9j6w==; Received: from 2a02-8389-2341-5b80-39d3-4735-9a3c-88d8.cable.dynamic.v6.surfer.at ([2a02:8389:2341:5b80:39d3:4735:9a3c:88d8] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1s0aEQ-0000000EqCU-28Rs; Sat, 27 Apr 2024 05:04:14 +0000 From: Christoph Hellwig To: Chandan Babu R , "Darrick J. Wong" Cc: linux-xfs@vger.kernel.org Subject: [PATCH 4/5] xfs: factor out a xfs_dir_replace_args helper Date: Sat, 27 Apr 2024 07:03:59 +0200 Message-Id: <20240427050400.1126656-5-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240427050400.1126656-1-hch@lst.de> References: <20240427050400.1126656-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Add a helper to switch between the different directory formats for removing a directory entry. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.c | 49 +++++++++++++++++++++------------------ fs/xfs/libxfs/xfs_dir2.h | 1 + fs/xfs/scrub/dir_repair.c | 19 +-------------- 3 files changed, 28 insertions(+), 41 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 76aa11ade2e92d..d3d4d80c2098d3 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -505,6 +505,31 @@ xfs_dir_removename( return rval; } +int +xfs_dir_replace_args( + struct xfs_da_args *args) +{ + bool is_block, is_leaf; + int error; + + if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + return xfs_dir2_sf_replace(args); + + error = xfs_dir2_isblock(args, &is_block); + if (error) + return error; + if (is_block) + return xfs_dir2_block_replace(args); + + error = xfs_dir2_isleaf(args, &is_leaf); + if (error) + return error; + if (is_leaf) + return xfs_dir2_leaf_replace(args); + + return xfs_dir2_node_replace(args); +} + /* * Replace the inode number of a directory entry. */ @@ -518,7 +543,6 @@ xfs_dir_replace( { struct xfs_da_args *args; int rval; - bool v; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -541,28 +565,7 @@ xfs_dir_replace( args->whichfork = XFS_DATA_FORK; args->trans = tp; args->owner = dp->i_ino; - - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { - rval = xfs_dir2_sf_replace(args); - goto out_free; - } - - rval = xfs_dir2_isblock(args, &v); - if (rval) - goto out_free; - if (v) { - rval = xfs_dir2_block_replace(args); - goto out_free; - } - - rval = xfs_dir2_isleaf(args, &v); - if (rval) - goto out_free; - if (v) - rval = xfs_dir2_leaf_replace(args); - else - rval = xfs_dir2_node_replace(args); -out_free: + rval = xfs_dir_replace_args(args); kfree(args); return rval; } diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 3db54801d69ecd..6c00fe24a8987e 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -69,6 +69,7 @@ extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, int xfs_dir_lookup_args(struct xfs_da_args *args); int xfs_dir_createname_args(struct xfs_da_args *args); int xfs_dir_removename_args(struct xfs_da_args *args); +int xfs_dir_replace_args(struct xfs_da_args *args); /* * Direct call from the bmap code, bypassing the generic directory layer. diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c index 98e4ed25cc2309..64679fe0844650 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -1513,7 +1513,6 @@ xrep_dir_replace( xfs_extlen_t total) { struct xfs_scrub *sc = rd->sc; - bool is_block, is_leaf; int error; ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); @@ -1525,23 +1524,7 @@ xrep_dir_replace( xrep_dir_init_args(rd, dp, name); rd->args.inumber = inum; rd->args.total = total; - - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) - return xfs_dir2_sf_replace(&rd->args); - - error = xfs_dir2_isblock(&rd->args, &is_block); - if (error) - return error; - if (is_block) - return xfs_dir2_block_replace(&rd->args); - - error = xfs_dir2_isleaf(&rd->args, &is_leaf); - if (error) - return error; - if (is_leaf) - return xfs_dir2_leaf_replace(&rd->args); - - return xfs_dir2_node_replace(&rd->args); + return xfs_dir_replace_args(&rd->args); } /* From patchwork Sat Apr 27 05:04:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13645556 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C65CC3F9D4 for ; Sat, 27 Apr 2024 05:04:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194260; cv=none; b=SsAsMcZgWcB5ytLciPwWNuUuLRXhAvfvxTLSrUOPJF6lrHHrMotjSRHLU9AfZyzO05W50bx6oeB/unu/aTC3vdM4dMd78VfcMg5DfAe+aLdIQsZTSlJ2ekF+XYNeop+H53b6NRIv1buqJtqigDeTWIidN4NsPnyztFB9WShQLcg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714194260; c=relaxed/simple; bh=BonDpfRBwoIc8DV7Gx2T0UntdvbW9TeZYIsux3DFf9Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eFDmj+bXIpuQpVMqpaCprarigQXBEjUfcSYhuTccqLTzC4uxLTsYZ+j0TZuqEJO3kTPDwbls1W+wxbEmf57yiHbSgnJBVc77+FQwstzA5ZKRY3pS+acVSBchdMk1NjMf4ON5SuGKfc5q7Vl2zO/QH6+FtUAvtAKHGkZwIcG+AFM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de; spf=none smtp.mailfrom=bombadil.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=qI/WYdNq; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bombadil.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="qI/WYdNq" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=gRXSbaUQQsbACBnWBM3GF1q6Gx1sUOPDgf5Usj7JzzE=; b=qI/WYdNq9UkE/G/kr3fJlv0W3N 9DlovgcbmSeLOfSZrdk9NE4EGFG2JoCUPnKsjtSTdhHFGBVVQemdtVMJE4bA0BFJyBlKH7le4QB2+ ly7dSIiU3W7DqfljqKDYpVNvYdWpNL76eS/vtCaSeIECnDenZNllkhvfPSOXcmWPsWrlQ8YuQLKLY xwlJFVTK1fG+HnSfTZURTOU9+lTRn4QhZsvkk4/eQr8nWAzktivSmB91qSX4oy71H9WfcAh+kGT7M Uibg5lv+mVOmmY2d3OI4aAjbbCkDJhDZKzeh3hzWzRhY7R6mR0T8rk0vO+TcofMMa3GQFzWjM0wJk C+44Gp8Q==; Received: from 2a02-8389-2341-5b80-39d3-4735-9a3c-88d8.cable.dynamic.v6.surfer.at ([2a02:8389:2341:5b80:39d3:4735:9a3c:88d8] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1s0aET-0000000EqCt-33KC; Sat, 27 Apr 2024 05:04:18 +0000 From: Christoph Hellwig To: Chandan Babu R , "Darrick J. Wong" Cc: linux-xfs@vger.kernel.org Subject: [PATCH 5/5] xfs: refactor dir format helpers Date: Sat, 27 Apr 2024 07:04:00 +0200 Message-Id: <20240427050400.1126656-6-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240427050400.1126656-1-hch@lst.de> References: <20240427050400.1126656-1-hch@lst.de> Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Add a new enum and a xfs_dir2_format helper that returns it to allow the code to switch on the format of a directory in a single operation and switch all helpers of xfs_dir2_isblock and xfs_dir2_isleaf to it. This also removes the explicit xfs_iread_extents call in a few of the call sites given that xfs_bmap_last_offset already takes care of it underneath. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_dir2.c | 188 ++++++++++++++--------------------- fs/xfs/libxfs/xfs_dir2.h | 12 ++- fs/xfs/libxfs/xfs_exchmaps.c | 9 +- fs/xfs/scrub/dir.c | 3 +- fs/xfs/scrub/readdir.c | 24 ++--- fs/xfs/xfs_dir2_readdir.c | 19 ++-- 6 files changed, 105 insertions(+), 150 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index d3d4d80c2098d3..457f9a38f85045 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -256,31 +256,60 @@ xfs_dir_init( return error; } +enum xfs_dir2_fmt +xfs_dir2_format( + struct xfs_da_args *args, + int *error) +{ + struct xfs_inode *dp = args->dp; + struct xfs_mount *mp = dp->i_mount; + struct xfs_da_geometry *geo = mp->m_dir_geo; + xfs_fileoff_t eof; + + xfs_assert_ilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL); + + *error = 0; + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + return XFS_DIR2_FMT_SF; + + *error = xfs_bmap_last_offset(dp, &eof, XFS_DATA_FORK); + if (*error) + return XFS_DIR2_FMT_ERROR; + + if (eof == XFS_B_TO_FSB(mp, geo->blksize)) { + if (XFS_IS_CORRUPT(mp, dp->i_disk_size != geo->blksize)) { + xfs_da_mark_sick(args); + *error = -EFSCORRUPTED; + return XFS_DIR2_FMT_ERROR; + } + return XFS_DIR2_FMT_BLOCK; + } + if (eof == geo->leafblk + geo->fsbcount) + return XFS_DIR2_FMT_LEAF; + return XFS_DIR2_FMT_NODE; +} + int xfs_dir_createname_args( struct xfs_da_args *args) { - bool is_block, is_leaf; int error; if (!args->inumber) args->op_flags |= XFS_DA_OP_JUSTCHECK; - if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + switch (xfs_dir2_format(args, &error)) { + case XFS_DIR2_FMT_SF: return xfs_dir2_sf_addname(args); - - error = xfs_dir2_isblock(args, &is_block); - if (error) - return error; - if (is_block) + case XFS_DIR2_FMT_BLOCK: return xfs_dir2_block_addname(args); - - error = xfs_dir2_isleaf(args, &is_leaf); - if (error) - return error; - if (is_leaf) + case XFS_DIR2_FMT_LEAF: return xfs_dir2_leaf_addname(args); - return xfs_dir2_node_addname(args); + case XFS_DIR2_FMT_NODE: + return xfs_dir2_node_addname(args); + default: + return error; + } } /* @@ -359,36 +388,25 @@ int xfs_dir_lookup_args( struct xfs_da_args *args) { - bool is_block, is_leaf; int error; - if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { + switch (xfs_dir2_format(args, &error)) { + case XFS_DIR2_FMT_SF: error = xfs_dir2_sf_lookup(args); - goto out; - } - - /* dir2 functions require that the data fork is loaded */ - error = xfs_iread_extents(args->trans, args->dp, XFS_DATA_FORK); - if (error) - goto out; - - error = xfs_dir2_isblock(args, &is_block); - if (error) - goto out; - - if (is_block) { + break; + case XFS_DIR2_FMT_BLOCK: error = xfs_dir2_block_lookup(args); - goto out; - } - - error = xfs_dir2_isleaf(args, &is_leaf); - if (error) - goto out; - if (is_leaf) + break; + case XFS_DIR2_FMT_LEAF: error = xfs_dir2_leaf_lookup(args); - else + break; + case XFS_DIR2_FMT_NODE: error = xfs_dir2_node_lookup(args); -out: + break; + default: + break; + } + if (error != -EEXIST) return error; return 0; @@ -448,24 +466,20 @@ int xfs_dir_removename_args( struct xfs_da_args *args) { - bool is_block, is_leaf; int error; - if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + switch (xfs_dir2_format(args, &error)) { + case XFS_DIR2_FMT_SF: return xfs_dir2_sf_removename(args); - - error = xfs_dir2_isblock(args, &is_block); - if (error) - return error; - if (is_block) + case XFS_DIR2_FMT_BLOCK: return xfs_dir2_block_removename(args); - - error = xfs_dir2_isleaf(args, &is_leaf); - if (error) - return error; - if (is_leaf) + case XFS_DIR2_FMT_LEAF: return xfs_dir2_leaf_removename(args); - return xfs_dir2_node_removename(args); + case XFS_DIR2_FMT_NODE: + return xfs_dir2_node_removename(args); + default: + return error; + } } /* @@ -509,25 +523,20 @@ int xfs_dir_replace_args( struct xfs_da_args *args) { - bool is_block, is_leaf; int error; - if (args->dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + switch (xfs_dir2_format(args, &error)) { + case XFS_DIR2_FMT_SF: return xfs_dir2_sf_replace(args); - - error = xfs_dir2_isblock(args, &is_block); - if (error) - return error; - if (is_block) + case XFS_DIR2_FMT_BLOCK: return xfs_dir2_block_replace(args); - - error = xfs_dir2_isleaf(args, &is_leaf); - if (error) - return error; - if (is_leaf) + case XFS_DIR2_FMT_LEAF: return xfs_dir2_leaf_replace(args); - - return xfs_dir2_node_replace(args); + case XFS_DIR2_FMT_NODE: + return xfs_dir2_node_replace(args); + default: + return error; + } } /* @@ -633,57 +642,6 @@ xfs_dir2_grow_inode( return 0; } -/* - * See if the directory is a single-block form directory. - */ -int -xfs_dir2_isblock( - struct xfs_da_args *args, - bool *isblock) -{ - struct xfs_mount *mp = args->dp->i_mount; - xfs_fileoff_t eof; - int error; - - error = xfs_bmap_last_offset(args->dp, &eof, XFS_DATA_FORK); - if (error) - return error; - - *isblock = false; - if (XFS_FSB_TO_B(mp, eof) != args->geo->blksize) - return 0; - - *isblock = true; - if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize)) { - xfs_da_mark_sick(args); - return -EFSCORRUPTED; - } - return 0; -} - -/* - * See if the directory is a single-leaf form directory. - */ -int -xfs_dir2_isleaf( - struct xfs_da_args *args, - bool *isleaf) -{ - xfs_fileoff_t eof; - int error; - - error = xfs_bmap_last_offset(args->dp, &eof, XFS_DATA_FORK); - if (error) - return error; - - *isleaf = false; - if (eof != args->geo->leafblk + args->geo->fsbcount) - return 0; - - *isleaf = true; - return 0; -} - /* * Remove the given block from the directory. * This routine is used for data and free blocks, leaf/node are done diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 6c00fe24a8987e..6dbe6e9ecb491f 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -36,6 +36,16 @@ xfs_dir2_samename( return !memcmp(n1->name, n2->name, n1->len); } +enum xfs_dir2_fmt { + XFS_DIR2_FMT_SF, + XFS_DIR2_FMT_BLOCK, + XFS_DIR2_FMT_LEAF, + XFS_DIR2_FMT_NODE, + XFS_DIR2_FMT_ERROR, +}; + +enum xfs_dir2_fmt xfs_dir2_format(struct xfs_da_args *args, int *error); + /* * Convert inode mode to directory entry filetype */ @@ -79,8 +89,6 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); /* * Interface routines used by userspace utilities */ -extern int xfs_dir2_isblock(struct xfs_da_args *args, bool *isblock); -extern int xfs_dir2_isleaf(struct xfs_da_args *args, bool *isleaf); extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, struct xfs_buf *bp); diff --git a/fs/xfs/libxfs/xfs_exchmaps.c b/fs/xfs/libxfs/xfs_exchmaps.c index 44ab6a9235c0bd..2021396651de27 100644 --- a/fs/xfs/libxfs/xfs_exchmaps.c +++ b/fs/xfs/libxfs/xfs_exchmaps.c @@ -465,17 +465,12 @@ xfs_exchmaps_dir_to_sf( }; struct xfs_dir2_sf_hdr sfh; struct xfs_buf *bp; - bool isblock; int size; - int error; + int error = 0; - error = xfs_dir2_isblock(&args, &isblock); - if (error) + if (xfs_dir2_format(&args, &error) != XFS_DIR2_FMT_BLOCK) return error; - if (!isblock) - return 0; - error = xfs_dir3_block_read(tp, xmi->xmi_ip2, xmi->xmi_ip2->i_ino, &bp); if (error) return error; diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 62474d0557c41a..bf9199e8df633f 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -808,7 +808,8 @@ xchk_directory_blocks( free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET); /* Is this a block dir? */ - error = xfs_dir2_isblock(&args, &is_block); + if (xfs_dir2_format(&args, &error) == XFS_DIR2_FMT_BLOCK) + is_block = true; if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) goto out; diff --git a/fs/xfs/scrub/readdir.c b/fs/xfs/scrub/readdir.c index 0ac77359d8e9f8..01c9a2dc0f2c48 100644 --- a/fs/xfs/scrub/readdir.c +++ b/fs/xfs/scrub/readdir.c @@ -276,7 +276,6 @@ xchk_dir_walk( .trans = sc->tp, .owner = dp->i_ino, }; - bool isblock; int error; if (xfs_is_shutdown(dp->i_mount)) @@ -285,22 +284,17 @@ xchk_dir_walk( ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); xfs_assert_ilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL); - if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) + switch (xfs_dir2_format(&args, &error)) { + case XFS_DIR2_FMT_SF: return xchk_dir_walk_sf(sc, dp, dirent_fn, priv); - - /* dir2 functions require that the data fork is loaded */ - error = xfs_iread_extents(sc->tp, dp, XFS_DATA_FORK); - if (error) - return error; - - error = xfs_dir2_isblock(&args, &isblock); - if (error) - return error; - - if (isblock) + case XFS_DIR2_FMT_BLOCK: return xchk_dir_walk_block(sc, dp, dirent_fn, priv); - - return xchk_dir_walk_leaf(sc, dp, dirent_fn, priv); + case XFS_DIR2_FMT_LEAF: + case XFS_DIR2_FMT_NODE: + return xchk_dir_walk_leaf(sc, dp, dirent_fn, priv); + default: + return error; + } } /* diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index b3abad5a6cd800..06ac5a7de60a04 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -516,7 +516,6 @@ xfs_readdir( { struct xfs_da_args args = { NULL }; unsigned int lock_mode; - bool isblock; int error; trace_xfs_readdir(dp); @@ -539,18 +538,18 @@ xfs_readdir( return xfs_dir2_sf_getdents(&args, ctx); lock_mode = xfs_ilock_data_map_shared(dp); - error = xfs_dir2_isblock(&args, &isblock); - if (error) - goto out_unlock; - - if (isblock) { + switch (xfs_dir2_format(&args, &error)) { + case XFS_DIR2_FMT_BLOCK: error = xfs_dir2_block_getdents(&args, ctx, &lock_mode); - goto out_unlock; + break; + case XFS_DIR2_FMT_LEAF: + case XFS_DIR2_FMT_NODE: + error = xfs_dir2_leaf_getdents(&args, ctx, bufsize, &lock_mode); + break; + default: + break; } - error = xfs_dir2_leaf_getdents(&args, ctx, bufsize, &lock_mode); - -out_unlock: if (lock_mode) xfs_iunlock(dp, lock_mode); return error;