From patchwork Thu Apr 25 13:16: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: 13643334 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 294D01494B4 for ; Thu, 25 Apr 2024 13:17: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=1714051031; cv=none; b=ko1QelAioiMkkuoky5ZG1Id3EJPaALJhAX72K8fXn+FA/S7hLXTQaRvHHX5+B13Vm7jz+yVjUPq0o5NnNPKe8gTKhR9Q4aEpeYAKBt/qc6L9l5XMSK8bhjgVGwbGU41Ls2jBDGmv64e2jok9SsMJMZwznUBUSxUqAeozPe716fE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714051031; c=relaxed/simple; bh=C1albHJd/WmRn+TS4wqB3fdwY5iEd+TUtbSUiPrRTrU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mVcx0vu1i+nLTiZJ2rAXNTtIVwH/Ih/w+UOrb8Ac/06Uo0YIXfKatyZr2Q9jeNSv0IqkpxWQbpGSMVPCz6/OUSky7BkR4YOPJV2/XfHGmODznYL4rJojBrTS072sUWyBCQjPevniVQNHXCYlNt+30FCw74MpWSlao/P6RBE8sqA= 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=ddOqLBXN; 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="ddOqLBXN" 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=DO85Hx0gB6R31990IWHGGl8RMK6rYst4Iy3T4KZLg84=; b=ddOqLBXNUPlcDbrIg2qSaqo/uC 2T6mR5n/D+4VllHDzzw0n+YdeqrekuyxnU4Uws28QNPr7l5TlwyqHqb+FH4AAkxLoB8wivdQDIWi/ fwnAZ+Z5EMbC5o1TKHuNOUAildfDuLzipis0HEUAatGrDXdYOshi/G86Rr5U7rV4xm7RBaHUgEhdJ YXQIWNDfiVJs13gCpr2gGV7pBOcxDNkjw8By3KzscQGRjVNsHYTRoVp5GGDZ6JcuM+6ReYxZSMAlM KCmVWkG609evFWIDoNgnykFLz5pmGixK/kKnGicBPnSJGzBWgKuo1gwpPO3zJPD32vQ2BXFYGmY3x rFsFsGbA==; 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 1rzyyL-00000008Rao-1Is5; Thu, 25 Apr 2024 13:17:09 +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: Thu, 25 Apr 2024 15:16:59 +0200 Message-Id: <20240425131703.928936-2-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240425131703.928936-1-hch@lst.de> References: <20240425131703.928936-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 --- 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 Thu Apr 25 13:17: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: 13643335 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 B7FCA1494B4 for ; Thu, 25 Apr 2024 13:17: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=1714051034; cv=none; b=fTV8jdS20syFLDQNT/ldgmHFA9lgDQIfVlzq9EHQ9yIyDbqtS38it1QJQ7JoLVE02O25vexrM30Z2IaS4X+1dkJ3wsHyowm1r6yBxKd356n2rN0E1tdn+UBeWMx+QOOVFHhvl/EAc4uHaLw4axe6UoaUs792EWqDvYNcBkvF93Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714051034; c=relaxed/simple; bh=Yc/DZrNE3ahnxwzJeLLb4KDTrytwA1yS5YIu4EyntYQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=A0TCQH5OOEppTPi5xyEuWuiyFVxAsd/ktP6fIk54M8FyRXxdl1TPEuuRQtF5n1m17m95e2iI4baC4mYYmGj2N4Wfv6j7kXK+NtDITM341+iDVE/qZSgfggrz55Ti4jcVg9kKdIUKrUnpZVQD5eBVuyb6vngYO9anQhPoxmYydiw= 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=COSv4IM8; 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="COSv4IM8" 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=YvEPoS05Iqugz6R7olDfJyEpQnnjPC0xdHRyOCRkY3U=; b=COSv4IM8E5cUhTabBZcryh+SCo 4mcOo7eQrl7iXcVojvC2CuPReqMvISvVBUT/ZoZckY/LsxV5BIyQ+CJam3YjQYaEYhL4iJOBBTRvi EI1MgvMBqvNkiXQggRKBoRpRwtUiwJTf04ncc8T31r9EhgI3yWV4aopi98OiNPuC0CfxI70JEWdR0 unZ8sQrsmln6VOBIpOuTRBvGOg6Z/r92Q55hDVrQ7K5VwtAo8A0Er7UQR9idp+YVLgoc+SkmOaaPj qd6oDOPoDfFzna4WSYvzCn3O3PGjexRGz1b+9JK5QDsUnHzJy+wNDQ5DfeViTym7gpi03D1AJaEt9 QYhMQYkQ==; 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 1rzyyN-00000008RbY-3UCD; Thu, 25 Apr 2024 13:17:12 +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: Thu, 25 Apr 2024 15:17:00 +0200 Message-Id: <20240425131703.928936-3-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240425131703.928936-1-hch@lst.de> References: <20240425131703.928936-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 --- 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 6ad40f8aafb826..4cad98243d7be8 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -708,7 +708,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)); @@ -723,23 +722,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 Thu Apr 25 13:17:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13643336 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 27D651494B4 for ; Thu, 25 Apr 2024 13:17: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=1714051036; cv=none; b=P+CKNWFlQXPUbUTeF4Z8Vwkrm5h8XLfRGJ6BKUCj/KVfjelT+xw9X2jJh9rSxAKbkCwHQygGYg0gfRB760+LcGX4QjFT1gCSI/qxMZ5m5UbZ7TcWTQgEol2H0yTKthTJ8CCkYcIBwpCqypAABwwBKcm8DCq33A3zI70KZAGWsY0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714051036; c=relaxed/simple; bh=5S6XMHyBYka/JzwNat/D3Z8mq3HOyKtm19BuVCNAFBQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=t+TQFRdo5tC9v00AAnYooa0Z7WSPI/DoTh1lZIZS8kt53orz7iIsa6NpaHadX9Rhq1YczrdRg286eBpvhTohwqPXflCL7V943Rwx5YsTHKNBwTSHTB//YYIu2DeqejzTqVEejLgVQuj/A5EFgdZTQa7eYKx0o9KATdWljtFruoY= 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=V4/zcp1G; 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="V4/zcp1G" 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=jHBQWo/etNVXOy3jH9aSywhD2FcYXDbQ3UbdPz0EZiI=; b=V4/zcp1Glq55ErTNHUtGKFj4k9 9oqMPZnHCzUuBRlol/+aybLNwwRAGatLuwUObJwmZ0HBWiwRxVw7PfTVCtbbZlZEi+3YKD608Ofgb usgAnt+2ucVNnCQ/1eaynMCIwKlinO+vi+jnK5Y15S1ESHY176E4B96jeysSz8WOuu3POK22AvlqM HnSxXA6pBJZpkbyLFwu3G8qfFcK15Oa7lm1MoAsd/uJPUKuaeuXqp9lMVMzhK/4S7NIQtR657xyNO xx99AztXLQlZX8GeM1CcFJ/szSZMy5v9ZDnMi7Gl1Y0LkcMxI3R0ILHm5PexP65QDUwojWrYvqq6M oAHq7Q2g==; 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 1rzyyQ-00000008RcI-1dnT; Thu, 25 Apr 2024 13:17:14 +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: Thu, 25 Apr 2024 15:17:01 +0200 Message-Id: <20240425131703.928936-4-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240425131703.928936-1-hch@lst.de> References: <20240425131703.928936-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 --- 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 4cad98243d7be8..ce22c0d3571d2d 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -733,8 +733,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)); @@ -743,23 +741,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 Thu Apr 25 13:17:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13643337 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 7F0961494B4 for ; Thu, 25 Apr 2024 13:17:17 +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=1714051038; cv=none; b=KczLDp0D5Dgm5fVFiqKx9JfISHzeiuRQWfWVGHYADh84BnXU6zEDu1z68ijBf1k6mPdADtukLrnMimuXORcAfvzhK8bDazDGFwFZLe6/4f5RtuE9af6akYmWKgprYJPNQVxuEG3xiCmHTbxgDb+2dwTxc3wTY8OFHCMazvo9p9g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714051038; c=relaxed/simple; bh=DVHVr5crb/iChG7FbXvbXh2VrYx7a6scPD9XYIcC0To=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZxG5atXByWjtVLKXrauJvXF4lZrxNWyOinZuz1ottgfhyHD4FNIlhEKZNAhNuiz8c0F60WXD38ROsM1ldCWqRUrnbdVypxJV/Bkz8+kuGa4whZCEVL4kc09+JVYoUVM2SV2oOiFm+B02YaZOiYZ0bfJx5jAqQJeUWFEXJkSzkl8= 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=Xh3XZXyW; 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="Xh3XZXyW" 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=p07UfNpckEe8L5VHZl6dPcCljLbyg3FxeLHMTzSBTMI=; b=Xh3XZXyWtqsLj4YcCN5SRvPnPr em0t/9/nqbYk3Qk6WgwcPQ3eKVUhIRdf3fXaWm/teWT3PJcc7WTpU1GolOr1lqSVoZpFkYMj+avV3 q/btyFAoZiqEc9npdIrNVwCuzWxOWl4MlxnUGKmWrN9o6Ffx/Z/mzHeOXRpwRzyReR3VQGeoSlv/T HooWr7BZDXRuHU869PO/g9Ap9WXY5VHDo44uvSJl9l8AaNHlrg7BbTlRlD+6xkLtdINOlir7ipB9r YkgobW7WMuTfzzC+/z9s5fhDcMp9ErAZCX9BhunnAELZVv9aKg+Dy5bgFWNv0FmdLO6+/ovXV7Cfv yQEcQ4TA==; 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 1rzyyS-00000008Rcr-3Jq3; Thu, 25 Apr 2024 13:17:17 +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: Thu, 25 Apr 2024 15:17:02 +0200 Message-Id: <20240425131703.928936-5-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240425131703.928936-1-hch@lst.de> References: <20240425131703.928936-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 --- 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 ce22c0d3571d2d..09fd0b76516e03 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -1534,7 +1534,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)); @@ -1546,23 +1545,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 Thu Apr 25 13:17:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 13643338 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 5FB561494B4 for ; Thu, 25 Apr 2024 13:17:20 +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=1714051041; cv=none; b=KxWudw0PYLafEa0esOJJVRkuuq53pzZE5YmOkbZ8CIKCVl7NFndumGb62qKly8NGsy55I6jqD1TRwIXL2GuFiV0bCa6HMaXLBlGAqinanajIncDi2iDW69TSswW2/TL87zMYqt0tlaXv6N3LFXl/cZ4LFcFvnC0P5/JFoW0MrPI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714051041; c=relaxed/simple; bh=UZ4hNf0yfJfeINCNrhyY5n/fSa0J7fL4pcf+jPQY7N8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nj3t9IKi1I+Ume7VFImMsKIcVx5S/BS13898ei5ZT+bxGdFsKrMnj52WonN8sHsgn1EsexXzFVNDL8mMP0puo45iGumt11m7Aa8GWjkxShTiwWfBX/kzFmJMJwZATEliethMfmE6d17ngDvKxLrfgn0KqqWtRSr0xPdFn00d3/E= 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=e/5soUPo; 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="e/5soUPo" 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=UM+4xBPGLAMlG8WIcgQZePAoNeVAkaSEeGJayHkzWfE=; b=e/5soUPoROlWxeG5oCmDxYP655 6hz8RM3JmARfm0ZB/MNQC60ITvJO1p+W66uFE/JDQ5e3w5ZLtPWX5JNm1/MquChmD9XKNvr8DYGW2 Uz4syG4sctxh7vOaNF13XKAhWtuTBmjzEoYE6kN8wSjmoPlpHMsZ/LXzRR6lRav2Y/GRlMnuI1D2X 42hMths8smEM5SmpzQJNFnVBK+1b55pfhjjiWqTCNtYnVBzW9NBObrPNK0K6pyYKVQHu9I+dusc9h JWLL77iKiVElG+0vyDQWEig1OKEKn+xsKPpqbHiOCKRka/4tPNcf8+03XLNGoo9t2FwwlhvxJ5IWZ x7CsikFA==; 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 1rzyyV-00000008Rdf-2EjY; Thu, 25 Apr 2024 13:17:19 +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: Thu, 25 Apr 2024 15:17:03 +0200 Message-Id: <20240425131703.928936-6-hch@lst.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240425131703.928936-1-hch@lst.de> References: <20240425131703.928936-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 --- 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..e3881bbad0a01c 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;