From patchwork Tue Jul 30 00:54:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746039 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2FE94C96 for ; Tue, 30 Jul 2024 00:54:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300842; cv=none; b=rwObBWOOmuMFeJBGbmtQWgbU15o9NBRRWh+LuyVYAZBHEJM/Lu2idpQtSMsRpQN3Rzn9dXRu+NcDhVIVyhPbFKHT2K3oAQZfLxmMEz0L6Mh8wR07vWR9EDSgiRXjlbp4Q6U0AqPTSsJLffVBsmduFy02OPeBA8St7peaWb6vQn4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300842; c=relaxed/simple; bh=I99bfiMLejt5Hi6gGN3eO/DX/MGIcHk7Wj5IGm/4uaI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Rzk0WDmHqkM8aAWW34neQ8XGta9lS7q7g0epfPyN55A5GdTidygrPK7iN0XolATTBKBJ+AiNQNC4iZL5Gfeap7ji5wEydp2viXHL4K2APKSnhJNm3qgcerRD9WQJZkZKT/jz0X8Lq+jJqxBzdGTAJ4bI1ODyMxXXHMrNZjxMuRw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Az1g8j54; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Az1g8j54" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 927D1C32786; Tue, 30 Jul 2024 00:54:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300842; bh=I99bfiMLejt5Hi6gGN3eO/DX/MGIcHk7Wj5IGm/4uaI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Az1g8j54DgTO2sYiibkhbjc0l7Y61hBpkUtW6twV9se1MOZnEoksm+wLZUE8r9xwP p+/8J8zzPfaM+3KaIJLN6OzlBSkT7ItiaAiXUK7wlr7dnvNbUi5kUSJC0OqKqb6C5y rJG6SBDVFG79TwsjIb/eNIO8L27vGYycmccPXpCUSN3YkO54MN4Y4EarWKKzIk+jUm L/IZim5Z4mpP5r9+yIxX3YQi8VxSsASI/RhOZcPVJ0YPWmUvyEyTqfwwa1NR64+mFg dbMV1Tlk+Awis1BzwJlvNu08O7watOcNEjO/OvkyFYtLMPnnjEBFzDVk6kRHj1zJ7t ScGOYKUf1RK1g== Date: Mon, 29 Jul 2024 17:54:02 -0700 Subject: [PATCH 01/12] man: document the exchange-range ioctl From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844420.1344699.8776197084743871916.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Document the new file data exchange ioctl. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- man/man2/ioctl_xfs_exchange_range.2 | 278 +++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 man/man2/ioctl_xfs_exchange_range.2 diff --git a/man/man2/ioctl_xfs_exchange_range.2 b/man/man2/ioctl_xfs_exchange_range.2 new file mode 100644 index 000000000..450db9c25 --- /dev/null +++ b/man/man2/ioctl_xfs_exchange_range.2 @@ -0,0 +1,278 @@ +.\" Copyright (c) 2020-2024 Oracle. All rights reserved. +.\" +.\" %%%LICENSE_START(GPLv2+_DOC_FULL) +.\" This is free documentation; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of +.\" the License, or (at your option) any later version. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with this manual; if not, see +.\" . +.\" %%%LICENSE_END +.TH IOCTL-XFS-EXCHANGE-RANGE 2 2024-02-10 "XFS" +.SH NAME +ioctl_xfs_exchange_range \- exchange the contents of parts of two files +.SH SYNOPSIS +.br +.B #include +.br +.B #include +.PP +.BI "int ioctl(int " file2_fd ", XFS_IOC_EXCHANGE_RANGE, struct xfs_exchange_range *" arg ); +.SH DESCRIPTION +Given a range of bytes in a first file +.B file1_fd +and a second range of bytes in a second file +.BR file2_fd , +this +.BR ioctl (2) +exchanges the contents of the two ranges. +.PP +Exchanges are atomic with regards to concurrent file operations. +Implementations must guarantee that readers see either the old contents or the +new contents in their entirety, even if the system fails. +.PP +The system call parameters are conveyed in structures of the following form: +.PP +.in +4n +.EX +struct xfs_exchange_range { + __s32 file1_fd; + __u32 pad; + __u64 file1_offset; + __u64 file2_offset; + __u64 length; + __u64 flags; +}; +.EE +.in +.PP +The field +.I pad +must be zero. +.PP +The fields +.IR file1_fd ", " file1_offset ", and " length +define the first range of bytes to be exchanged. +.PP +The fields +.IR file2_fd ", " file2_offset ", and " length +define the second range of bytes to be exchanged. +.PP +Both files must be from the same filesystem mount. +If the two file descriptors represent the same file, the byte ranges must not +overlap. +Most disk-based filesystems require that the starts of both ranges must be +aligned to the file block size. +If this is the case, the ends of the ranges must also be so aligned unless the +.B XFS_EXCHANGE_RANGE_TO_EOF +flag is set. + +.PP +The field +.I flags +control the behavior of the exchange operation. +.RS 0.4i +.TP +.B XFS_EXCHANGE_RANGE_TO_EOF +Ignore the +.I length +parameter. +All bytes in +.I file1_fd +from +.I file1_offset +to EOF are moved to +.IR file2_fd , +and file2's size is set to +.RI ( file2_offset "+(" file1_length - file1_offset )). +Meanwhile, all bytes in file2 from +.I file2_offset +to EOF are moved to file1 and file1's size is set to +.RI ( file1_offset "+(" file2_length - file2_offset )). +.TP +.B XFS_EXCHANGE_RANGE_DSYNC +Ensure that all modified in-core data in both file ranges and all metadata +updates pertaining to the exchange operation are flushed to persistent storage +before the call returns. +Opening either file descriptor with +.BR O_SYNC " or " O_DSYNC +will have the same effect. +.TP +.B XFS_EXCHANGE_RANGE_FILE1_WRITTEN +Only exchange sub-ranges of +.I file1_fd +that are known to contain data written by application software. +Each sub-range may be expanded (both upwards and downwards) to align with the +file allocation unit. +For files on the data device, this is one filesystem block. +For files on the realtime device, this is the realtime extent size. +This facility can be used to implement fast atomic scatter-gather writes of any +complexity for software-defined storage targets if all writes are aligned to +the file allocation unit. +.TP +.B XFS_EXCHANGE_RANGE_DRY_RUN +Check the parameters and the feasibility of the operation, but do not change +anything. +.RE +.PP +.SH RETURN VALUE +On error, \-1 is returned, and +.I errno +is set to indicate the error. +.PP +.SH ERRORS +Error codes can be one of, but are not limited to, the following: +.TP +.B EBADF +.IR file1_fd +is not open for reading and writing or is open for append-only writes; or +.IR file2_fd +is not open for reading and writing or is open for append-only writes. +.TP +.B EINVAL +The parameters are not correct for these files. +This error can also appear if either file descriptor represents +a device, FIFO, or socket. +Disk filesystems generally require the offset and length arguments +to be aligned to the fundamental block sizes of both files. +.TP +.B EIO +An I/O error occurred. +.TP +.B EISDIR +One of the files is a directory. +.TP +.B ENOMEM +The kernel was unable to allocate sufficient memory to perform the +operation. +.TP +.B ENOSPC +There is not enough free space in the filesystem exchange the contents safely. +.TP +.B EOPNOTSUPP +The filesystem does not support exchanging bytes between the two +files. +.TP +.B EPERM +.IR file1_fd " or " file2_fd +are immutable. +.TP +.B ETXTBSY +One of the files is a swap file. +.TP +.B EUCLEAN +The filesystem is corrupt. +.TP +.B EXDEV +.IR file1_fd " and " file2_fd +are not on the same mounted filesystem. +.SH CONFORMING TO +This API is XFS-specific. +.SH USE CASES +.PP +Several use cases are imagined for this system call. +In all cases, application software must coordinate updates to the file +because the exchange is performed unconditionally. +.PP +The first is a data storage program that wants to commit non-contiguous updates +to a file atomically and coordinates write access to that file. +This can be done by creating a temporary file, calling +.BR FICLONE (2) +to share the contents, and staging the updates into the temporary file. +The +.B FULL_FILES +flag is recommended for this purpose. +The temporary file can be deleted or punched out afterwards. +.PP +An example program might look like this: +.PP +.in +4n +.EX +int fd = open("/some/file", O_RDWR); +int temp_fd = open("/some", O_TMPFILE | O_RDWR); + +ioctl(temp_fd, FICLONE, fd); + +/* append 1MB of records */ +lseek(temp_fd, 0, SEEK_END); +write(temp_fd, data1, 1000000); + +/* update record index */ +pwrite(temp_fd, data1, 600, 98765); +pwrite(temp_fd, data2, 320, 54321); +pwrite(temp_fd, data2, 15, 0); + +/* commit the entire update */ +struct xfs_exchange_range args = { + .file1_fd = temp_fd, + .flags = XFS_EXCHANGE_RANGE_TO_EOF, +}; + +ioctl(fd, XFS_IOC_EXCHANGE_RANGE, &args); +.EE +.in +.PP +The second is a software-defined storage host (e.g. a disk jukebox) which +implements an atomic scatter-gather write command. +Provided the exported disk's logical block size matches the file's allocation +unit size, this can be done by creating a temporary file and writing the data +at the appropriate offsets. +It is recommended that the temporary file be truncated to the size of the +regular file before any writes are staged to the temporary file to avoid issues +with zeroing during EOF extension. +Use this call with the +.B FILE1_WRITTEN +flag to exchange only the file allocation units involved in the emulated +device's write command. +The temporary file should be truncated or punched out completely before being +reused to stage another write. +.PP +An example program might look like this: +.PP +.in +4n +.EX +int fd = open("/some/file", O_RDWR); +int temp_fd = open("/some", O_TMPFILE | O_RDWR); +struct stat sb; +int blksz; + +fstat(fd, &sb); +blksz = sb.st_blksize; + +/* land scatter gather writes between 100fsb and 500fsb */ +pwrite(temp_fd, data1, blksz * 2, blksz * 100); +pwrite(temp_fd, data2, blksz * 20, blksz * 480); +pwrite(temp_fd, data3, blksz * 7, blksz * 257); + +/* commit the entire update */ +struct xfs_exchange_range args = { + .file1_fd = temp_fd, + .file1_offset = blksz * 100, + .file2_offset = blksz * 100, + .length = blksz * 400, + .flags = XFS_EXCHANGE_RANGE_FILE1_WRITTEN | + XFS_EXCHANGE_RANGE_FILE1_DSYNC, +}; + +ioctl(fd, XFS_IOC_EXCHANGE_RANGE, &args); +.EE +.in +.B +.SH NOTES +.PP +Some filesystems may limit the amount of data or the number of extents that can +be exchanged in a single call. +.SH SEE ALSO +.BR ioctl (2) From patchwork Tue Jul 30 00:54:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746040 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2A9F53BE for ; Tue, 30 Jul 2024 00:54:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300858; cv=none; b=o94r4/tcZwYFTEbbvWfckX2qQ8WO/cJsFK/vxi6gdCMXsdXq+YaxcgwptDNh+V0PHBuAKLFGqTvzMiYoHAAKlmBzZExSCuk7mVq1ryQSm/E1Olgf04qbZi9wJWrLDF80gijUDcRAuS/WF4YnAxM4yoOfaxGBm8WsD61Sd5KQ2QM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300858; c=relaxed/simple; bh=IAjA5NKtkvh4XQgQkOS7h2tbQNOuHu+9UVEv27woPZc=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QQQW8U5AWHtotRNXxTPBePMXxWHNOkX2V/aSHkQHan9zgT60YUt9cCgzbLXBPcvHjiJN/Vi/wISDMB6PtHv3/3/PVLyyVQvCDltZieyHgQYaKLVNOPTFdAr2zPVOFdbbkx0sTMCqrIAMrIkooTnAXlPpaOuhZtRTbODBhpwiWEY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=g/O3TZ1m; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="g/O3TZ1m" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 39F9DC32786; Tue, 30 Jul 2024 00:54:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300858; bh=IAjA5NKtkvh4XQgQkOS7h2tbQNOuHu+9UVEv27woPZc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=g/O3TZ1mPKDb4JOA2Pg/XaUNhXUkIw02y0siLP2XtvHB2ey+9KQDxjiAlGnPp9mEO T0UpUsGPk3NYxLwDezOyFq1vSbbxMSecG0BRN+EE3X3Wps66uv+NQSluI5vVTvmjhB LM06ld1gGGCIhcBy8bXgtIr4n4duBb5yhlBZ+RlImVRCITCKlbspTI9G/GmoOZvDuz K8h5pqzJ/WIigjiG3c2lgL6PWJrYHZmL3YchS2yOmUwnjAA7OTbjnwN8PgWcCVReOe MUhj5pG2zNm04+r2rCdEdfODgO62XuFOHBF2cCXHk8VGLYR2rGINKmEXoDrW+VFwqJ lVBnNo7X1RB6g== Date: Mon, 29 Jul 2024 17:54:17 -0700 Subject: [PATCH 02/12] man: document XFS_FSOP_GEOM_FLAGS_EXCHRANGE From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844432.1344699.803286273218599484.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Document this new feature flag in the fs geometry ioctl. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- man/man2/ioctl_xfs_fsgeometry.2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man/man2/ioctl_xfs_fsgeometry.2 b/man/man2/ioctl_xfs_fsgeometry.2 index f59a6e8a6..54fd89390 100644 --- a/man/man2/ioctl_xfs_fsgeometry.2 +++ b/man/man2/ioctl_xfs_fsgeometry.2 @@ -211,6 +211,9 @@ Filesystem stores reverse mappings of blocks to owners. .TP .B XFS_FSOP_GEOM_FLAGS_REFLINK Filesystem supports sharing blocks between files. +.TP +.B XFS_FSOP_GEOM_FLAGS_EXCHRANGE +Filesystem can exchange file contents atomically via XFS_IOC_EXCHANGE_RANGE. .RE .SH XFS METADATA HEALTH REPORTING .PP From patchwork Tue Jul 30 00:54:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746041 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54CB16FB0 for ; Tue, 30 Jul 2024 00:54:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300874; cv=none; b=ivfAKj7Wh9M6EPILKBAX1VJzhKyfbxs/EEhf4dllytNC9na+Wq17kZDNOjbmtxfQS1qsYOiP/glgQgbNbQSIJDjCUlLnmeIF+obXh10IIzYa8GIrU6zoIq4PfT0D1N8BY2qpVFmytSOD0jIu/m6pIHuINChz3eNtYrDj0m/Facs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300874; c=relaxed/simple; bh=HdF2u0jo98SS9YlYMpi1F4BNQoVpD/NM861VFK3fo7M=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eBIaTLt1dJmbmBrdhYvbqBBLiGw4UB9So2kVogBr6wlcZraaz0V6vEpn1iRPSlwxe0BCeJeWaQ3zV2Bq4kmw2Ug9WZypm4Ldtl8KNmWxOw7Q0FlKazRR2mcmPwxEea3yYzJRfLrhoTp/twqlVa+bUpq+9bNyzdqMBYR36PxwG7U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=h4M23bG9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="h4M23bG9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2F14C32786; Tue, 30 Jul 2024 00:54:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300874; bh=HdF2u0jo98SS9YlYMpi1F4BNQoVpD/NM861VFK3fo7M=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=h4M23bG9tflTmPTwmNF+2KntcVSoIEi5C65GKwiAeocGEoTXbhtdjncfCV3RkIU7u UEMJ5yTtPCZ04/3K5MFxF+D22gzxV/5RCHWBq0aM6ipzIh3lz8+GUvlUgNRVNlLBIZ 0TN0EbkZGNSgkQBttUfT43hJHr82EzenD5dlPedMS0n1uhwOylcKirMfYyQgLmMLnX eGP7c/9FepMaSAQeKpvJ39uqQMDIBpqSHCX2ViWTTy917QytXzzejJw5Rm/itiGWCP bSBliGijPXnq265PjtTyz69W5qE3USuyX4AEBhQjt/4L/YVCFj7NlvN9sV4UMf9mKW Es1GXJvisgsDA== Date: Mon, 29 Jul 2024 17:54:33 -0700 Subject: [PATCH 03/12] libhandle: add support for bulkstat v5 From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844444.1344699.4193753436678329494.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Add support to libhandle for generating file handles with bulkstat v5 structures. xfs_fsr will need this to be able to interface with the new vfs range swap ioctl, and other client programs will probably want this over time. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- include/jdm.h | 23 +++++++++++ libhandle/jdm.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) diff --git a/include/jdm.h b/include/jdm.h index c57fcae7f..50c2296b4 100644 --- a/include/jdm.h +++ b/include/jdm.h @@ -11,6 +11,7 @@ typedef void jdm_fshandle_t; /* filesystem handle */ typedef void jdm_filehandle_t; /* filehandle */ struct xfs_bstat; +struct xfs_bulkstat; struct attrlist_cursor; struct parent; @@ -23,6 +24,9 @@ jdm_new_filehandle( jdm_filehandle_t **handlep, /* new filehandle */ jdm_fshandle_t *fshandlep, /* filesystem filehandle */ struct xfs_bstat *sp); /* bulkstat info */ +void jdm_new_filehandle_v5(jdm_filehandle_t **handlep, size_t *hlen, + jdm_fshandle_t *fshandlep, struct xfs_bulkstat *sp); + extern void jdm_delete_filehandle( jdm_filehandle_t *handlep,/* filehandle to delete */ size_t hlen); /* filehandle size */ @@ -32,35 +36,54 @@ jdm_open( jdm_fshandle_t *fshandlep, struct xfs_bstat *sp, intgen_t oflags); +intgen_t jdm_open_v5(jdm_fshandle_t *fshandlep, struct xfs_bulkstat *sp, + intgen_t oflags); + extern intgen_t jdm_readlink( jdm_fshandle_t *fshandlep, struct xfs_bstat *sp, char *bufp, size_t bufsz); +intgen_t jdm_readlink_v5(jdm_fshandle_t *fshandlep, struct xfs_bulkstat *sp, + char *bufp, size_t bufsz); + extern intgen_t jdm_attr_multi( jdm_fshandle_t *fshp, struct xfs_bstat *statp, char *bufp, int rtrvcnt, int flags); +intgen_t jdm_attr_multi_v5(jdm_fshandle_t *fshp, struct xfs_bulkstat *statp, + char *bufp, int rtrvcnt, int flags); + extern intgen_t jdm_attr_list( jdm_fshandle_t *fshp, struct xfs_bstat *statp, char *bufp, size_t bufsz, int flags, struct attrlist_cursor *cursor); +intgen_t jdm_attr_list_v5(jdm_fshandle_t *fshp, struct xfs_bulkstat *statp, + char *bufp, size_t bufsz, int flags, + struct attrlist_cursor *cursor); + extern int jdm_parents( jdm_fshandle_t *fshp, struct xfs_bstat *statp, struct parent *bufp, size_t bufsz, unsigned int *count); +int jdm_parents_v5(jdm_fshandle_t *fshp, struct xfs_bulkstat *statp, + struct parent *bufp, size_t bufsz, unsigned int *count); + extern int jdm_parentpaths( jdm_fshandle_t *fshp, struct xfs_bstat *statp, struct parent *bufp, size_t bufsz, unsigned int *count); +int jdm_parentpaths_v5(jdm_fshandle_t *fshp, struct xfs_bulkstat *statp, + struct parent *bufp, size_t bufsz, unsigned int *count); + /* macro for determining the size of a structure member */ #define sizeofmember( t, m ) sizeof( ( ( t * )0 )->m ) diff --git a/libhandle/jdm.c b/libhandle/jdm.c index 07b0c6098..e21aff2b2 100644 --- a/libhandle/jdm.c +++ b/libhandle/jdm.c @@ -41,6 +41,19 @@ jdm_fill_filehandle( filehandle_t *handlep, handlep->fh_ino = statp->bs_ino; } +static void +jdm_fill_filehandle_v5( + struct filehandle *handlep, + struct fshandle *fshandlep, + struct xfs_bulkstat *statp) +{ + handlep->fh_fshandle = *fshandlep; + handlep->fh_sz_following = FILEHANDLE_SZ_FOLLOWING; + memset(handlep->fh_pad, 0, FILEHANDLE_SZ_PAD); + handlep->fh_gen = statp->bs_gen; + handlep->fh_ino = statp->bs_ino; +} + jdm_fshandle_t * jdm_getfshandle( char *mntpnt ) { @@ -90,6 +103,22 @@ jdm_new_filehandle( jdm_filehandle_t **handlep, jdm_fill_filehandle(*handlep, (fshandle_t *) fshandlep, statp); } +void +jdm_new_filehandle_v5( + jdm_filehandle_t **handlep, + size_t *hlen, + jdm_fshandle_t *fshandlep, + struct xfs_bulkstat *statp) +{ + /* allocate and fill filehandle */ + *hlen = sizeof(filehandle_t); + *handlep = (filehandle_t *) malloc(*hlen); + if (!*handlep) + return; + + jdm_fill_filehandle_v5(*handlep, (struct fshandle *)fshandlep, statp); +} + /* ARGSUSED */ void jdm_delete_filehandle( jdm_filehandle_t *handlep, size_t hlen ) @@ -111,6 +140,19 @@ jdm_open( jdm_fshandle_t *fshp, struct xfs_bstat *statp, intgen_t oflags ) return fd; } +intgen_t +jdm_open_v5( + jdm_fshandle_t *fshp, + struct xfs_bulkstat *statp, + intgen_t oflags) +{ + struct fshandle *fshandlep = (struct fshandle *)fshp; + struct filehandle filehandle; + + jdm_fill_filehandle_v5(&filehandle, fshandlep, statp); + return open_by_fshandle(&filehandle, sizeof(filehandle), oflags); +} + intgen_t jdm_readlink( jdm_fshandle_t *fshp, struct xfs_bstat *statp, @@ -128,6 +170,20 @@ jdm_readlink( jdm_fshandle_t *fshp, return rval; } +intgen_t +jdm_readlink_v5( + jdm_fshandle_t *fshp, + struct xfs_bulkstat *statp, + char *bufp, + size_t bufsz) +{ + struct fshandle *fshandlep = (struct fshandle *)fshp; + struct filehandle filehandle; + + jdm_fill_filehandle_v5(&filehandle, fshandlep, statp); + return readlink_by_handle(&filehandle, sizeof(filehandle), bufp, bufsz); +} + int jdm_attr_multi( jdm_fshandle_t *fshp, struct xfs_bstat *statp, @@ -145,6 +201,22 @@ jdm_attr_multi( jdm_fshandle_t *fshp, return rval; } +int +jdm_attr_multi_v5( + jdm_fshandle_t *fshp, + struct xfs_bulkstat *statp, + char *bufp, + int rtrvcnt, + int flags) +{ + struct fshandle *fshandlep = (struct fshandle *)fshp; + struct filehandle filehandle; + + jdm_fill_filehandle_v5(&filehandle, fshandlep, statp); + return attr_multi_by_handle(&filehandle, sizeof(filehandle), bufp, + rtrvcnt, flags); +} + int jdm_attr_list( jdm_fshandle_t *fshp, struct xfs_bstat *statp, @@ -166,6 +238,27 @@ jdm_attr_list( jdm_fshandle_t *fshp, return rval; } +int +jdm_attr_list_v5( + jdm_fshandle_t *fshp, + struct xfs_bulkstat *statp, + char *bufp, + size_t bufsz, + int flags, + struct attrlist_cursor *cursor) +{ + struct fshandle *fshandlep = (struct fshandle *)fshp; + struct filehandle filehandle; + + /* prevent needless EINVAL from the kernel */ + if (bufsz > XFS_XATTR_LIST_MAX) + bufsz = XFS_XATTR_LIST_MAX; + + jdm_fill_filehandle_v5(&filehandle, fshandlep, statp); + return attr_list_by_handle(&filehandle, sizeof(filehandle), bufp, + bufsz, flags, cursor); +} + int jdm_parents( jdm_fshandle_t *fshp, struct xfs_bstat *statp, @@ -176,6 +269,18 @@ jdm_parents( jdm_fshandle_t *fshp, return -1; } +int +jdm_parents_v5( + jdm_fshandle_t *fshp, + struct xfs_bulkstat *statp, + struct parent *bufp, + size_t bufsz, + unsigned int *count) +{ + errno = EOPNOTSUPP; + return -1; +} + int jdm_parentpaths( jdm_fshandle_t *fshp, struct xfs_bstat *statp, @@ -185,3 +290,15 @@ jdm_parentpaths( jdm_fshandle_t *fshp, errno = EOPNOTSUPP; return -1; } + +int +jdm_parentpaths_v5( + jdm_fshandle_t *fshp, + struct xfs_bulkstat *statp, + struct parent *bufp, + size_t bufsz, + unsigned int *count) +{ + errno = EOPNOTSUPP; + return -1; +} From patchwork Tue Jul 30 00:54:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746042 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BADC38C0B for ; Tue, 30 Jul 2024 00:54:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300889; cv=none; b=dsDpoXYgkbY5TfMzoXfTL5KXFCl53/DtFr6L9Rs5B14zIpf92rvvattgglBTA6FpGY94u32IpCsbkYEKPWfKw8nVCpfF+qMzqdl2bcxlVDKXIr0qd+t4jemTw/tInTdkXMn84clPKBVFXYOTyMC2/YJCLL90Pm+735IdoK2IzkU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300889; c=relaxed/simple; bh=kwbruGKyUStk+cHBcaDsrZqU1oe9/WDtbrVvc1bxna8=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nAgxaBu7R8lr8IBr4x4Ob1ayMs+gbvbhSIvXm6bkwVYfzvUaEq+CGr50cOXqPkLDmpbosmAURnPvmttqVY9DL2jUBWN9GXXYedpKnYTBcc2L9CBfc3qBHWWqqS7nAowtxt5Rb5PZMWUk2P0cxD0LG0FCdmXi2AdqKCPGayKqHrc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QbuBXO9n; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QbuBXO9n" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 96DFCC4AF07; Tue, 30 Jul 2024 00:54:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300889; bh=kwbruGKyUStk+cHBcaDsrZqU1oe9/WDtbrVvc1bxna8=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=QbuBXO9nTgqPlOwCc9d5sujDNrev7eEGyP5PXbaKSePm7uPv/GiGPuGhS+bnoblwQ wtpC87thsi8yuQAUWUn7GEeawjpPDnfs7Y/w1hK8S2Z8O6ClFjm64bAji3YxoTD+F/ yZcEKQikrHrPNU3eb1hi3LuDKUTgvVIcH61Z0WyC6aRZ4dAW3+Fq8hyHRd8DhN9hcO 0UWwoDzlfRrzWxj5K9DqsXeOXNQP3z8ViLCSzs6kKO7OFioLnmPQUaJVV1bp1OH1cf q0bsKI3r7fo5FGyvku9ZyalCSouMRnbrSpxvEv3NsSg/V4Eac1QmLzbj0j596VC2RI 9xPKlmxzOZMDg== Date: Mon, 29 Jul 2024 17:54:49 -0700 Subject: [PATCH 04/12] libfrog: add support for exchange range ioctl family From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844457.1344699.8587837512292274839.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Add some library code to support the new file range exchange and commit ioctls. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- libfrog/Makefile | 2 ++ libfrog/file_exchange.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ libfrog/file_exchange.h | 15 ++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 libfrog/file_exchange.c create mode 100644 libfrog/file_exchange.h diff --git a/libfrog/Makefile b/libfrog/Makefile index cafee073f..53e3c3492 100644 --- a/libfrog/Makefile +++ b/libfrog/Makefile @@ -18,6 +18,7 @@ bitmap.c \ bulkstat.c \ convert.c \ crc32.c \ +file_exchange.c \ fsgeom.c \ list_sort.c \ linux.c \ @@ -42,6 +43,7 @@ crc32defs.h \ crc32table.h \ dahashselftest.h \ div64.h \ +file_exchange.h \ fsgeom.h \ logging.h \ paths.h \ diff --git a/libfrog/file_exchange.c b/libfrog/file_exchange.c new file mode 100644 index 000000000..29fdc17e5 --- /dev/null +++ b/libfrog/file_exchange.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong + */ +#include +#include +#include +#include +#include +#include "xfs.h" +#include "fsgeom.h" +#include "bulkstat.h" +#include "libfrog/file_exchange.h" + +/* Prepare for a file contents exchange. */ +void +xfrog_exchangerange_prep( + struct xfs_exchange_range *fxr, + off_t file2_offset, + int file1_fd, + off_t file1_offset, + uint64_t length) +{ + memset(fxr, 0, sizeof(*fxr)); + + fxr->file1_fd = file1_fd; + fxr->file1_offset = file1_offset; + fxr->length = length; + fxr->file2_offset = file2_offset; +} + +/* + * Execute an exchange-range operation. Returns 0 for success or a negative + * errno. + */ +int +xfrog_exchangerange( + int file2_fd, + struct xfs_exchange_range *fxr, + uint64_t flags) +{ + int ret; + + fxr->flags = flags; + + ret = ioctl(file2_fd, XFS_IOC_EXCHANGE_RANGE, fxr); + if (ret) + return -errno; + + return 0; +} diff --git a/libfrog/file_exchange.h b/libfrog/file_exchange.h new file mode 100644 index 000000000..b6f6f9f69 --- /dev/null +++ b/libfrog/file_exchange.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2020-2024 Oracle. All rights reserved. + * All Rights Reserved. + */ +#ifndef __LIBFROG_FILE_EXCHANGE_H__ +#define __LIBFROG_FILE_EXCHANGE_H__ + +void xfrog_exchangerange_prep(struct xfs_exchange_range *fxr, + off_t file2_offset, int file1_fd, + off_t file1_offset, uint64_t length); +int xfrog_exchangerange(int file2_fd, struct xfs_exchange_range *fxr, + uint64_t flags); + +#endif /* __LIBFROG_FILE_EXCHANGE_H__ */ From patchwork Tue Jul 30 00:55:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746043 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 556EFD26D for ; Tue, 30 Jul 2024 00:55:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300905; cv=none; b=o7H5cknowQ26Y8Kj+II2N2SENeJp/02u4obniSozMl+aHR1ZxW9n0u82H97u3O/GUo0w+a+L+K2QE1aJwnq8mm2+tQBqWe8C6lgDPJG4LraC4pyB5C7Pj0M5jPl5ID90j3PpU0Pijgko7PeLp9yCtFWSHst7dgQQ3kKP56aMh1o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300905; c=relaxed/simple; bh=yynjWoQsjJVNqBigusQ8Wh5fVJ03wjYArxfI1d0A7j8=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LeY3Pixd1UCp60+UF1IB8YIpsDExu4SNQs9MtlH8+8dGg77SzN6a4Se/zCBvApl/tWYOofiatDYpXiquXUlJa797k79VzbIAI1mJPs6MFyXZIcAgdO7sBK7iVpdrqQHbqbxlvmb8RqkPQoB73Xoq5qeLuP9/LDyCdVA45JbDRw0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZbS8auM4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZbS8auM4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 33AC9C32786; Tue, 30 Jul 2024 00:55:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300905; bh=yynjWoQsjJVNqBigusQ8Wh5fVJ03wjYArxfI1d0A7j8=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=ZbS8auM4FEs5aGsvHP90kZgvC44w/3Fg/1rW0UmUEGv/Oa+dAMHkAex+UaluZXUWa gFbGEA4x/vxhY6jr8AYTQ+SVzLRnzCAI/wQlIVooAkFpbPd/yshPz+yFh7p60ujmkf RFxLS/U2RjxnFuJFRptE6VIfhbDiBfK5VTCr3SqBM6EVZMonYojRoJc3Mn5O/Ey0CH zg5R8H4tlMbLhjrXuw2yJBeYZUkHfRoB8HFWau236A9qFJT47ylj5o4si2UCj6P7tL Mou0NFRNTwEDwrYJ68l2QLan1aUFBVCJ+yZ5rUpeY/9NmvWz/CquQXil8lb5Vzryie ZZxMdAjjOM04g== Date: Mon, 29 Jul 2024 17:55:04 -0700 Subject: [PATCH 05/12] xfs_db: advertise exchange-range in the version command From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844469.1344699.9725818747080538227.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Amend the version command to advertise exchange-range support. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- db/sb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/sb.c b/db/sb.c index b48767f47..c39011634 100644 --- a/db/sb.c +++ b/db/sb.c @@ -706,6 +706,8 @@ version_string( strcat(s, ",NEEDSREPAIR"); if (xfs_has_large_extent_counts(mp)) strcat(s, ",NREXT64"); + if (xfs_has_exchange_range(mp)) + strcat(s, ",EXCHANGE"); return s; } From patchwork Tue Jul 30 00:55:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746044 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BB462563 for ; Tue, 30 Jul 2024 00:55:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300921; cv=none; b=dEcSMUWoBkwUMWKeOUL9Drc6oAuTOCqUC96TWiDv+0fbJN843tusfhOaNCbTibUHUJ238EpnCCs22kzh+j9L68IU1Ph5llT97/JGPZHQR0dECrI9EB9FjGTip1Bps9YKSJ4r7hd8UsDWnE7A/FUL9X8QgfaS4RDp9vTiaqN4eJQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300921; c=relaxed/simple; bh=SPBft8WWU9mXCvEeX86GqjGa3rST9tfj1uJJEKEzYVE=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lxiPNb7zpEoZPZ+bzNScFy6yGoJtMaZWbujQNkAEgi0sygzwFX9PZ0zbkMDg59XGJXaZuzd9YLACVkrb/nj3Vy7KPV571uFR1OEQMT9mv+r7mK4yxr1E+5wkZnNBo+0yFTPtMUiTMOVTXq95zoCxmwY+ndEQCocX/2KP8081G3E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hAEPGyzf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hAEPGyzf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BEB91C32786; Tue, 30 Jul 2024 00:55:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300920; bh=SPBft8WWU9mXCvEeX86GqjGa3rST9tfj1uJJEKEzYVE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=hAEPGyzfD9T0b1pAKBZ88E05JPg87GOeqwjA6cF3mN2ywwm+wvAqqXGjtfvh1dCYM kHGQS6Eky81fVXpp2k8as0m0hH8ZJmSskPFe1IcYiZV7Sj5HpS3jV1GYgEy0omgKQ3 NbDQ+1vc5/zl6brAVREPFQ9VKFg+jQ3sFpo7sxMbLreObkmY0ifcfk765izkoUOt4j L4rGecT1GVAhz/RJiOIomODP4rzhrRmcgvsNh6uiY0q4jtAzcZyCh+8pRVwEf/Zkvd rQRoEt7wyUUL06mmDn0egUKoS4ZACg37ZcTfCSgs9SmW+jexnMEkyMldqhOEZdtgdg 3+NkkGuM3LHYw== Date: Mon, 29 Jul 2024 17:55:20 -0700 Subject: [PATCH 06/12] xfs_logprint: support dumping exchmaps log items From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844483.1344699.8461872019513458698.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Support dumping exchmaps log items. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- logprint/log_misc.c | 11 ++++ logprint/log_print_all.c | 12 ++++ logprint/log_redo.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++ logprint/logprint.h | 6 ++ 4 files changed, 157 insertions(+) diff --git a/logprint/log_misc.c b/logprint/log_misc.c index 9d3811340..8e86ac347 100644 --- a/logprint/log_misc.c +++ b/logprint/log_misc.c @@ -1052,6 +1052,17 @@ xlog_print_record( be32_to_cpu(op_head->oh_len)); break; } + case XFS_LI_XMI: { + skip = xlog_print_trans_xmi(&ptr, + be32_to_cpu(op_head->oh_len), + continued); + break; + } + case XFS_LI_XMD: { + skip = xlog_print_trans_xmd(&ptr, + be32_to_cpu(op_head->oh_len)); + break; + } case XFS_LI_QUOTAOFF: { skip = xlog_print_trans_qoff(&ptr, be32_to_cpu(op_head->oh_len)); diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c index f436e1091..a4a5e41f1 100644 --- a/logprint/log_print_all.c +++ b/logprint/log_print_all.c @@ -440,6 +440,12 @@ xlog_recover_print_logitem( case XFS_LI_BUI: xlog_recover_print_bui(item); break; + case XFS_LI_XMD: + xlog_recover_print_xmd(item); + break; + case XFS_LI_XMI: + xlog_recover_print_xmi(item); + break; case XFS_LI_DQUOT: xlog_recover_print_dquot(item); break; @@ -498,6 +504,12 @@ xlog_recover_print_item( case XFS_LI_BUI: printf("BUI"); break; + case XFS_LI_XMD: + printf("XMD"); + break; + case XFS_LI_XMI: + printf("XMI"); + break; case XFS_LI_DQUOT: printf("DQ "); break; diff --git a/logprint/log_redo.c b/logprint/log_redo.c index edf7e0fbf..ca6dadd75 100644 --- a/logprint/log_redo.c +++ b/logprint/log_redo.c @@ -847,3 +847,131 @@ xlog_recover_print_attrd( f->alfd_size, (unsigned long long)f->alfd_alf_id); } + +/* Atomic Extent Swapping Items */ + +static int +xfs_xmi_copy_format( + struct xfs_xmi_log_format *xmi, + uint len, + struct xfs_xmi_log_format *dst_fmt, + int continued) +{ + if (len == sizeof(struct xfs_xmi_log_format) || continued) { + memcpy(dst_fmt, xmi, len); + return 0; + } + fprintf(stderr, _("%s: bad size of XMI format: %u; expected %zu\n"), + progname, len, sizeof(struct xfs_xmi_log_format)); + return 1; +} + +int +xlog_print_trans_xmi( + char **ptr, + uint src_len, + int continued) +{ + struct xfs_xmi_log_format *src_f, *f = NULL; + int error = 0; + + src_f = malloc(src_len); + if (src_f == NULL) { + fprintf(stderr, _("%s: %s: malloc failed\n"), + progname, __func__); + exit(1); + } + memcpy(src_f, *ptr, src_len); + *ptr += src_len; + + /* convert to native format */ + if (continued && src_len < sizeof(struct xfs_xmi_log_format)) { + printf(_("XMI: Not enough data to decode further\n")); + error = 1; + goto error; + } + + f = malloc(sizeof(struct xfs_xmi_log_format)); + if (f == NULL) { + fprintf(stderr, _("%s: %s: malloc failed\n"), + progname, __func__); + exit(1); + } + if (xfs_xmi_copy_format(src_f, src_len, f, continued)) { + error = 1; + goto error; + } + + printf(_("XMI: #regs: %d num_extents: 1 id: 0x%llx\n"), + f->xmi_size, (unsigned long long)f->xmi_id); + + if (continued) { + printf(_("XMI extent data skipped (CONTINUE set, no space)\n")); + goto error; + } + + printf("(ino1: 0x%llx, igen1: 0x%x, ino2: 0x%llx, igen2: 0x%x, off1: %lld, off2: %lld, len: %lld, flags: 0x%llx)\n", + (unsigned long long)f->xmi_inode1, + (unsigned int)f->xmi_igen1, + (unsigned long long)f->xmi_inode2, + (unsigned int)f->xmi_igen2, + (unsigned long long)f->xmi_startoff1, + (unsigned long long)f->xmi_startoff2, + (unsigned long long)f->xmi_blockcount, + (unsigned long long)f->xmi_flags); +error: + free(src_f); + free(f); + return error; +} + +void +xlog_recover_print_xmi( + struct xlog_recover_item *item) +{ + char *src_f; + uint src_len; + + src_f = item->ri_buf[0].i_addr; + src_len = item->ri_buf[0].i_len; + + xlog_print_trans_xmi(&src_f, src_len, 0); +} + +int +xlog_print_trans_xmd( + char **ptr, + uint len) +{ + struct xfs_xmd_log_format *f; + struct xfs_xmd_log_format lbuf; + + /* size without extents at end */ + uint core_size = sizeof(struct xfs_xmd_log_format); + + memcpy(&lbuf, *ptr, min(core_size, len)); + f = &lbuf; + *ptr += len; + if (len >= core_size) { + printf(_("XMD: #regs: %d id: 0x%llx\n"), + f->xmd_size, + (unsigned long long)f->xmd_xmi_id); + + /* don't print extents as they are not used */ + + return 0; + } else { + printf(_("XMD: Not enough data to decode further\n")); + return 1; + } +} + +void +xlog_recover_print_xmd( + struct xlog_recover_item *item) +{ + char *f; + + f = item->ri_buf[0].i_addr; + xlog_print_trans_xmd(&f, sizeof(struct xfs_xmd_log_format)); +} diff --git a/logprint/logprint.h b/logprint/logprint.h index b4479c240..25c043485 100644 --- a/logprint/logprint.h +++ b/logprint/logprint.h @@ -65,4 +65,10 @@ extern void xlog_recover_print_attri(struct xlog_recover_item *item); extern int xlog_print_trans_attrd(char **ptr, uint len); extern void xlog_recover_print_attrd(struct xlog_recover_item *item); extern void xlog_print_op_header(xlog_op_header_t *op_head, int i, char **ptr); + +int xlog_print_trans_xmi(char **ptr, uint src_len, int continued); +void xlog_recover_print_xmi(struct xlog_recover_item *item); +int xlog_print_trans_xmd(char **ptr, uint len); +void xlog_recover_print_xmd(struct xlog_recover_item *item); + #endif /* LOGPRINT_H */ From patchwork Tue Jul 30 00:55:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746045 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EAD6B1373 for ; Tue, 30 Jul 2024 00:55:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300937; cv=none; b=mo+SrbsP9UTqKvYec/FNnM6D3Jc0HPBGZC9Xyk4kKIA9s5svFVwRgPHgIqG7mq9upVjT5ISpH6IvyMGg5MYMmC6FdiO/cIuTuwZjsjzzrLDyLI96tmA1cImt2bgkfbKZLXwMRJTJybR66+VRctr/tDbHbwtyJoOAsm820K7TAdM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300937; c=relaxed/simple; bh=HMAsJixGhT1I22rB9xe+semq1rif4ihYuKm1bDPqlOQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GODvttV2mWpHDnr7ZG8UJMzxf5xg/dRHzK4w2Wv/TZldgv+Uxpcp3JQ2PCE6X+T6j4Ia6tNvY2XGLP+4dvhFP6q2vvvBZb0/0TiX5bbXk/qKnQYxms+wmmR3oE2QrpmQUNBpRWeozQ4TfkDdNlbyig8VCpdP+ocZCuBsn/ov5d0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cicftMVe; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cicftMVe" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6EE78C32786; Tue, 30 Jul 2024 00:55:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300936; bh=HMAsJixGhT1I22rB9xe+semq1rif4ihYuKm1bDPqlOQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=cicftMVesnygkux6SxYkMFnvZB5Yqu0QU04GWYyJ0476jWef1RvWK9FEZizB/KrIa TUaGIrX49ACw+J18HZRG5o/YpAC4kglLPgM0LGOGyX/G52eIqWvGuWT+lDpBp8Eedt EptU0A12EQLSpXaeFFlwLA8wWTEdElnewfSQfSrkP5zA2aeWUR0dz3eUCCqjJel1VD EPSrYmWfTMefbbNvgtf2f14Y7isk2sZNhn7r1HJ7rLQEPrE/70tp91lSUwUjBXKWLF mCEjYQ2u8kymogDR8axEmkI2YOXHwMEBfCPuWFfZFbk93KoouoNpWiR/Q6eXjRYkM9 4Je5kCekda8fw== Date: Mon, 29 Jul 2024 17:55:35 -0700 Subject: [PATCH 07/12] xfs_fsr: convert to bulkstat v5 ioctls From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844495.1344699.6815908404848304622.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Now that libhandle can, er, handle bulkstat information coming from the v5 bulkstat ioctl, port xfs_fsr to use the new interfaces instead of repeatedly converting things back and forth. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fsr/xfs_fsr.c | 153 +++++++++++++++++++++++++++++++----------------------- libfrog/fsgeom.c | 45 ++++++++++++---- libfrog/fsgeom.h | 1 3 files changed, 121 insertions(+), 78 deletions(-) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index 06cc0552f..c6dbfb22a 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -65,10 +65,10 @@ static int pagesize; void usage(int ret); static int fsrfile(char *fname, xfs_ino_t ino); -static int fsrfile_common( char *fname, char *tname, char *mnt, - int fd, struct xfs_bstat *statp); -static int packfile(char *fname, char *tname, int fd, - struct xfs_bstat *statp, struct fsxattr *fsxp); +static int fsrfile_common(char *fname, char *tname, char *mnt, + struct xfs_fd *file_fd, struct xfs_bulkstat *statp); +static int packfile(char *fname, char *tname, struct xfs_fd *file_fd, + struct xfs_bulkstat *statp, struct fsxattr *fsxp); static void fsrdir(char *dirname); static int fsrfs(char *mntdir, xfs_ino_t ino, int targetrange); static void initallfs(char *mtab); @@ -80,7 +80,7 @@ int xfs_getrt(int fd, struct statvfs *sfbp); char * gettmpname(char *fname); char * getparent(char *fname); int fsrprintf(const char *fmt, ...); -int read_fd_bmap(int, struct xfs_bstat *, int *); +int read_fd_bmap(int, struct xfs_bulkstat *, int *); static void tmp_init(char *mnt); static char * tmp_next(char *mnt); static void tmp_close(char *mnt); @@ -102,6 +102,26 @@ static int nfrags = 0; /* Debug option: Coerse into specific number * of extents */ static int openopts = O_CREAT|O_EXCL|O_RDWR|O_DIRECT; +/* + * Open a file on an XFS filesystem from file handle components and fs geometry + * data. Returns zero or a negative error code. + */ +static int +open_handle( + struct xfs_fd *xfd, + jdm_fshandle_t *fshandle, + struct xfs_bulkstat *bulkstat, + struct xfs_fsop_geom *fsgeom, + int flags) +{ + xfd->fd = jdm_open_v5(fshandle, bulkstat, flags); + if (xfd->fd < 0) + return errno; + + xfd_install_geometry(xfd, fsgeom); + return 0; +} + static int xfs_swapext(int fd, xfs_swapext_t *sx) { @@ -627,7 +647,6 @@ static int fsrfs(char *mntdir, xfs_ino_t startino, int targetrange) { struct xfs_fd fsxfd = XFS_FD_INIT_EMPTY; - int fd; int count = 0; int ret; char fname[64]; @@ -665,10 +684,10 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange) } while ((ret = -xfrog_bulkstat(&fsxfd, breq) == 0)) { - struct xfs_bstat bs1; struct xfs_bulkstat *buf = breq->bulkstat; struct xfs_bulkstat *p; struct xfs_bulkstat *endp; + struct xfs_fd file_fd = XFS_FD_INIT_EMPTY; uint32_t buflenout = breq->hdr.ocount; if (buflenout == 0) @@ -685,15 +704,9 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange) (p->bs_extents64 < 2)) continue; - ret = -xfrog_bulkstat_v5_to_v1(&fsxfd, &bs1, p); + ret = open_handle(&file_fd, fshandlep, p, + &fsxfd.fsgeom, O_RDWR | O_DIRECT); if (ret) { - fsrprintf(_("bstat conversion error: %s\n"), - strerror(ret)); - continue; - } - - fd = jdm_open(fshandlep, &bs1, O_RDWR | O_DIRECT); - if (fd < 0) { /* This probably means the file was * removed while in progress of handling * it. Just quietly ignore this file. @@ -710,11 +723,12 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange) /* Get a tmp file name */ tname = tmp_next(mntdir); - ret = fsrfile_common(fname, tname, mntdir, fd, &bs1); + ret = fsrfile_common(fname, tname, mntdir, &file_fd, + p); leftoffino = p->bs_ino; - close(fd); + xfd_close(&file_fd); if (ret == 0) { if (--count <= 0) @@ -762,9 +776,8 @@ fsrfile( { struct xfs_fd fsxfd = XFS_FD_INIT_EMPTY; struct xfs_bulkstat bulkstat; - struct xfs_bstat statbuf; + struct xfs_fd file_fd = XFS_FD_INIT_EMPTY; jdm_fshandle_t *fshandlep; - int fd = -1; int error = -1; char *tname; @@ -792,17 +805,12 @@ fsrfile( fname, strerror(error)); goto out; } - error = -xfrog_bulkstat_v5_to_v1(&fsxfd, &statbuf, &bulkstat); - if (error) { - fsrprintf(_("bstat conversion error on %s: %s\n"), - fname, strerror(error)); - goto out; - } - fd = jdm_open(fshandlep, &statbuf, O_RDWR|O_DIRECT); - if (fd < 0) { + error = open_handle(&file_fd, fshandlep, &bulkstat, &fsxfd.fsgeom, + O_RDWR | O_DIRECT); + if (error) { fsrprintf(_("unable to open handle %s: %s\n"), - fname, strerror(errno)); + fname, strerror(error)); goto out; } @@ -810,14 +818,13 @@ fsrfile( memcpy(&fsgeom, &fsxfd.fsgeom, sizeof(fsgeom)); tname = gettmpname(fname); - if (tname) - error = fsrfile_common(fname, tname, NULL, fd, &statbuf); + error = fsrfile_common(fname, tname, NULL, &file_fd, + &bulkstat); out: xfd_close(&fsxfd); - if (fd >= 0) - close(fd); + xfd_close(&file_fd); free(fshandlep); return error; @@ -843,8 +850,8 @@ fsrfile_common( char *fname, char *tname, char *fsname, - int fd, - struct xfs_bstat *statp) + struct xfs_fd *file_fd, + struct xfs_bulkstat *statp) { int error; struct statvfs vfss; @@ -854,7 +861,7 @@ fsrfile_common( if (vflag) fsrprintf("%s\n", fname); - if (fsync(fd) < 0) { + if (fsync(file_fd->fd) < 0) { fsrprintf(_("sync failed: %s: %s\n"), fname, strerror(errno)); return -1; } @@ -878,7 +885,7 @@ fsrfile_common( fl.l_whence = SEEK_SET; fl.l_start = (off_t)0; fl.l_len = 0; - if ((fcntl(fd, F_GETLK, &fl)) < 0 ) { + if ((fcntl(file_fd->fd, F_GETLK, &fl)) < 0 ) { if (vflag) fsrprintf(_("locking check failed: %s\n"), fname); @@ -896,7 +903,7 @@ fsrfile_common( /* * Check if there is room to copy the file. * - * Note that xfs_bstat.bs_blksize returns the filesystem blocksize, + * Note that xfs_bulkstat.bs_blksize returns the filesystem blocksize, * not the optimal I/O size as struct stat. */ if (statvfs(fsname ? fsname : fname, &vfss) < 0) { @@ -913,7 +920,7 @@ fsrfile_common( return 1; } - if ((ioctl(fd, FS_IOC_FSGETXATTR, &fsx)) < 0) { + if ((ioctl(file_fd->fd, FS_IOC_FSGETXATTR, &fsx)) < 0) { fsrprintf(_("failed to get inode attrs: %s\n"), fname); return(-1); } @@ -929,7 +936,7 @@ fsrfile_common( return(0); } if (fsx.fsx_xflags & FS_XFLAG_REALTIME) { - if (xfs_getrt(fd, &vfss) < 0) { + if (xfs_getrt(file_fd->fd, &vfss) < 0) { fsrprintf(_("cannot get realtime geometry for: %s\n"), fname); return(-1); @@ -955,7 +962,7 @@ fsrfile_common( * file we're defragging, in packfile(). */ - if ((error = packfile(fname, tname, fd, statp, &fsx))) + if ((error = packfile(fname, tname, file_fd, statp, &fsx))) return error; return -1; /* no error */ } @@ -979,7 +986,7 @@ static int fsr_setup_attr_fork( int fd, int tfd, - struct xfs_bstat *bstatp) + struct xfs_bulkstat *bstatp) { struct xfs_fd txfd = XFS_FD_INIT(tfd); struct stat tstatbuf; @@ -1161,23 +1168,28 @@ fsr_setup_attr_fork( * 1: No change / No Error */ static int -packfile(char *fname, char *tname, int fd, - struct xfs_bstat *statp, struct fsxattr *fsxp) +packfile( + char *fname, + char *tname, + struct xfs_fd *file_fd, + struct xfs_bulkstat *statp, + struct fsxattr *fsxp) { - int tfd = -1; - int srval; - int retval = -1; /* Failure is the default */ - int nextents, extent, cur_nextents, new_nextents; - unsigned blksz_dio; - unsigned dio_min; - struct dioattr dio; - static xfs_swapext_t sx; - struct xfs_flock64 space; - off_t cnt, pos; - void *fbuf = NULL; - int ct, wc, wc_b4; - char ffname[SMBUFSZ]; - int ffd = -1; + int tfd = -1; + int srval; + int retval = -1; /* Failure is the default */ + int nextents, extent, cur_nextents, new_nextents; + unsigned blksz_dio; + unsigned dio_min; + struct dioattr dio; + static xfs_swapext_t sx; + struct xfs_flock64 space; + off_t cnt, pos; + void *fbuf = NULL; + int ct, wc, wc_b4; + char ffname[SMBUFSZ]; + int ffd = -1; + int error; /* * Work out the extent map - nextents will be set to the @@ -1185,7 +1197,7 @@ packfile(char *fname, char *tname, int fd, * into account holes), cur_nextents is the current number * of extents. */ - nextents = read_fd_bmap(fd, statp, &cur_nextents); + nextents = read_fd_bmap(file_fd->fd, statp, &cur_nextents); if (cur_nextents == 1 || cur_nextents <= nextents) { if (vflag) @@ -1208,7 +1220,7 @@ packfile(char *fname, char *tname, int fd, unlink(tname); /* Setup extended attributes */ - if (fsr_setup_attr_fork(fd, tfd, statp) != 0) { + if (fsr_setup_attr_fork(file_fd->fd, tfd, statp) != 0) { fsrprintf(_("failed to set ATTR fork on tmp: %s:\n"), tname); goto out; } @@ -1266,6 +1278,8 @@ packfile(char *fname, char *tname, int fd, for (extent = 0; extent < nextents; extent++) { pos = outmap[extent].bmv_offset; if (outmap[extent].bmv_block == -1) { + off_t where; + space.l_whence = SEEK_SET; space.l_start = pos; space.l_len = outmap[extent].bmv_length; @@ -1273,7 +1287,8 @@ packfile(char *fname, char *tname, int fd, fsrprintf(_("could not trunc tmp %s\n"), tname); } - if (lseek(tfd, outmap[extent].bmv_length, SEEK_CUR) < 0) { + where = lseek(tfd, outmap[extent].bmv_length, SEEK_CUR); + if (where < 0) { fsrprintf(_("could not lseek in tmpfile: %s : %s\n"), tname, strerror(errno)); goto out; @@ -1326,7 +1341,7 @@ packfile(char *fname, char *tname, int fd, tname, strerror(errno)); goto out; } - if (lseek(fd, outmap[extent].bmv_length, SEEK_CUR) < 0) { + if (lseek(file_fd->fd, outmap[extent].bmv_length, SEEK_CUR) < 0) { fsrprintf(_("could not lseek in file: %s : %s\n"), fname, strerror(errno)); goto out; @@ -1346,7 +1361,7 @@ packfile(char *fname, char *tname, int fd, ct = min(cnt + dio_min - (cnt % dio_min), blksz_dio); } - ct = read(fd, fbuf, ct); + ct = read(file_fd->fd, fbuf, ct); if (ct == 0) { /* EOF, stop trying to read */ extent = nextents; @@ -1417,9 +1432,15 @@ packfile(char *fname, char *tname, int fd, goto out; } - sx.sx_stat = *statp; /* struct copy */ + error = -xfrog_bulkstat_v5_to_v1(file_fd, &sx.sx_stat, statp); + if (error) { + fsrprintf(_("bstat conversion error on %s: %s\n"), + fname, strerror(error)); + goto out; + } + sx.sx_version = XFS_SX_VERSION; - sx.sx_fdtarget = fd; + sx.sx_fdtarget = file_fd->fd; sx.sx_fdtmp = tfd; sx.sx_offset = 0; sx.sx_length = statp->bs_size; @@ -1433,7 +1454,7 @@ packfile(char *fname, char *tname, int fd, } /* Swap the extents */ - srval = xfs_swapext(fd, &sx); + srval = xfs_swapext(file_fd->fd, &sx); if (srval < 0) { if (errno == ENOTSUP) { if (vflag || dflag) @@ -1529,7 +1550,7 @@ getparent(char *fname) #define MAPSIZE 128 #define OUTMAP_SIZE_INCREMENT MAPSIZE -int read_fd_bmap(int fd, struct xfs_bstat *sin, int *cur_nextents) +int read_fd_bmap(int fd, struct xfs_bulkstat *sin, int *cur_nextents) { int i, cnt; struct getbmap map[MAPSIZE]; diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c index 3e7f0797d..6980d3ffa 100644 --- a/libfrog/fsgeom.c +++ b/libfrog/fsgeom.c @@ -102,29 +102,50 @@ xfrog_geometry( return -errno; } -/* - * Prepare xfs_fd structure for future ioctl operations by computing the xfs - * geometry for @xfd->fd. Returns zero or a negative error code. - */ -int -xfd_prepare_geometry( +/* Compute conversion factors of an xfs_fd structure. */ +static void +xfd_compute_conversion_factors( struct xfs_fd *xfd) { - int ret; - - ret = xfrog_geometry(xfd->fd, &xfd->fsgeom); - if (ret) - return ret; - xfd->agblklog = log2_roundup(xfd->fsgeom.agblocks); xfd->blocklog = highbit32(xfd->fsgeom.blocksize); xfd->inodelog = highbit32(xfd->fsgeom.inodesize); xfd->inopblog = xfd->blocklog - xfd->inodelog; xfd->aginolog = xfd->agblklog + xfd->inopblog; xfd->blkbb_log = xfd->blocklog - BBSHIFT; +} + +/* + * Prepare xfs_fd structure for future ioctl operations by computing the xfs + * geometry for @xfd->fd. Returns zero or a negative error code. + */ +int +xfd_prepare_geometry( + struct xfs_fd *xfd) +{ + int ret; + + ret = xfrog_geometry(xfd->fd, &xfd->fsgeom); + if (ret) + return ret; + + xfd_compute_conversion_factors(xfd); return 0; } +/* + * Prepare xfs_fd structure for future ioctl operations by computing the xfs + * geometry for @xfd->fd. Returns zero or a negative error code. + */ +void +xfd_install_geometry( + struct xfs_fd *xfd, + struct xfs_fsop_geom *fsgeom) +{ + memcpy(&xfd->fsgeom, fsgeom, sizeof(*fsgeom)); + xfd_compute_conversion_factors(xfd); +} + /* Open a file on an XFS filesystem. Returns zero or a negative error code. */ int xfd_open( diff --git a/libfrog/fsgeom.h b/libfrog/fsgeom.h index ca38324e8..f327dc7d7 100644 --- a/libfrog/fsgeom.h +++ b/libfrog/fsgeom.h @@ -55,6 +55,7 @@ struct xfs_fd { #define XFS_FD_INIT_EMPTY XFS_FD_INIT(-1) int xfd_prepare_geometry(struct xfs_fd *xfd); +void xfd_install_geometry(struct xfs_fd *xfd, struct xfs_fsop_geom *fsgeom); int xfd_open(struct xfs_fd *xfd, const char *pathname, int flags); int xfd_close(struct xfs_fd *xfd); From patchwork Tue Jul 30 00:55:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746046 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3EF6A33D5 for ; Tue, 30 Jul 2024 00:55:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300952; cv=none; b=AWkezCKYNLz9DeygN0B8jyOG75QDkXH56z3hPJgfBm8qlrbWzYNuwWJHJrr4n43TmJFC0bAPaTIpydN9hjbd6jABg3P3RMYI2MTrDbKzhqdfsB3DNZgIAsSrSBQTzujIgy+guEzCukkfX93+/8c954VJ4RPPB75lBfXE/pnEFE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300952; c=relaxed/simple; bh=GnAymvVKFVTj+0fzQyxe5pr8dmrMsCvFnOtVoCqCxko=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JpuDGZJ2KI/cJQXpy/fYmbz/hd/8itFPDdnZlfak7FZFtWLTPHeAa5xGX0SbjdHzo0cIdZWhTmtbhvdAA1OfsXLDpOMkLO6EAGZ3OAqs4pb2AvJuWxJ1jY8upE980MCFLv51IFUxJEnX+xEBymVF3DMTB1lwF9jFdovh8oSphBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f/H3eLpu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f/H3eLpu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1741DC32786; Tue, 30 Jul 2024 00:55:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300952; bh=GnAymvVKFVTj+0fzQyxe5pr8dmrMsCvFnOtVoCqCxko=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=f/H3eLpukOHFd1ljUleccKIVYzMYoJSLXmFQlxe0RPlCqQ2Zb7Rxb8p65q9JHpwxJ iE0qp0a2m2wixULIc7LLQxx0RioG3ocfk6Z2+De2FaHqiFixBif79L6UifMafcxNMm SlSUV2yVCgZL+szIyhoWPs4Yi2HZ8GXGRZzvnUcH2wFfmVOYOsUVmKRA3ab8qg3p7d i/pcMT/NtHLlKTc7KwnNBha49VJ0+5qF8CikCy5bBqgwsVlhl/TFFRvIW2O8beBI0m hITFuFxB2/+ejOi/w4+PrjkHRkkD5ZSrZKudhhEJ6qXfAU/J5GBSnDRcaNAc99p47h 2VMeC5uxGbt+g== Date: Mon, 29 Jul 2024 17:55:51 -0700 Subject: [PATCH 08/12] xfs_fsr: skip the xattr/forkoff levering with the newer swapext implementations From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844508.1344699.3886872839098101255.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong The newer swapext implementations in the kernel run at a high enough level (above the bmap layer) that it's no longer required to manipulate bs_forkoff by creating garbage xattrs to get the extent tree that we want. If we detect the newer algorithms, skip this error prone step. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fsr/xfs_fsr.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index c6dbfb22a..22e134adf 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -999,6 +999,20 @@ fsr_setup_attr_fork( if (!(bstatp->bs_xflags & FS_XFLAG_HASATTR)) return 0; + /* + * If the filesystem has the ability to perform atomic file mapping + * exchanges, the file extent swap implementation uses a higher level + * algorithm that calls into the bmap code instead of playing games + * with swapping the extent forks. + * + * This new functionality does not require specific values of + * bs_forkoff, unlike the old fork swap code. Leave the extended + * attributes alone if we know we're not using the old fork swap + * strategy. This eliminates a major source of runtime errors in fsr. + */ + if (fsgeom.flags & XFS_FSOP_GEOM_FLAGS_EXCHANGE_RANGE) + return 0; + /* * use the old method if we have attr1 or the kernel does not yet * support passing the fork offset in the bulkstat data. From patchwork Tue Jul 30 00:56:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746047 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E62FB23C9 for ; Tue, 30 Jul 2024 00:56:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300968; cv=none; b=mt73uxUP/JOQ1AK1vNiEmd3okaIKY3fx/oW4n4yLrAPqTvTA60e1T2Xf8Q7hdYcNMkp9wHpWZx1N7+03vknZUzO1xMSUacRq/9NS4sgWa4dLFrEwn5IiMJ1+o0tjpQFRA3upK8b0uq4jkW/kB+Qt+x96U+RTrifBbchzk3iCv/8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300968; c=relaxed/simple; bh=U8UvFlfqg2u32876VW/H5JrR8w6NZpa0j1D8E1sedeI=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XZdfmC/L9VQjCzJ5j94PIS4ESIM8xYl+/4M6ZrWsrWO1jW2Ghto9CxfpEeKCRXTewnfX7ol64eXjWY0Ofr/nZ484Fgfdl5DZGQJ3NIbP7kxgOPbKaWeLk4jLKoyz1oLDcuav24RntMVCMqUGt3rBDoYtBFe+MBCKcEB7iNqfJ30= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BzUaX0GZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BzUaX0GZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BE048C32786; Tue, 30 Jul 2024 00:56:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300967; bh=U8UvFlfqg2u32876VW/H5JrR8w6NZpa0j1D8E1sedeI=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=BzUaX0GZCcH/vMMmso5hFVwLrjXtoTTv2DXYM2YR2i0A+jN1kxjQ5yzOsOF8iKGeU NlnPynJoUcEMhWnr4f3h59hPV+3rFoaoaUMiM2zsW9Dt9QQ5K1gfmWNqSlJO9ac7U7 k0jG8qcRBTZ93qJ2nzt1+cT5Prqxmyt4jLiJ/DMdT03d+TVGQa02XQExLJmypoLGz3 z8hgccCm0QcHjTAowPFGXckhV8Q+Aob/UeosmgJM1mL1MRGvyaFPQYuRgMN15KsUDh haAtwCQZFOZt04Cyle74GFqZfU53na2dzFWmsGT8TKACvx43DUWMRR/dVe0kqo5NxJ +iXBd/O6kYwfg== Date: Mon, 29 Jul 2024 17:56:07 -0700 Subject: [PATCH 09/12] xfs_io: create exchangerange command to test file range exchange ioctl From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844522.1344699.3459136614879410955.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Create a new xfs_io command to make raw calls to the XFS_IOC_EXCHANGE_RANGE ioctl. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- io/Makefile | 48 ++++++++++++++-- io/exchrange.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++ io/init.c | 1 io/io.h | 1 man/man8/xfs_io.8 | 40 ++++++++++++++ 5 files changed, 239 insertions(+), 7 deletions(-) create mode 100644 io/exchrange.c diff --git a/io/Makefile b/io/Makefile index 17d499de9..3192b813c 100644 --- a/io/Makefile +++ b/io/Makefile @@ -8,13 +8,47 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_io LSRCFILES = xfs_bmap.sh xfs_freeze.sh xfs_mkfile.sh HFILES = init.h io.h -CFILES = init.c \ - attr.c bmap.c bulkstat.c crc32cselftest.c cowextsize.c encrypt.c \ - file.c freeze.c fsuuid.c fsync.c getrusage.c imap.c inject.c label.c \ - link.c mmap.c open.c parent.c pread.c prealloc.c pwrite.c reflink.c \ - resblks.c scrub.c seek.c shutdown.c stat.c swapext.c sync.c \ - truncate.c utimes.c fadvise.c sendfile.c madvise.c mincore.c fiemap.c \ - sync_file_range.c readdir.c +CFILES = \ + attr.c \ + bmap.c \ + bulkstat.c \ + cowextsize.c \ + crc32cselftest.c \ + encrypt.c \ + exchrange.c \ + fadvise.c \ + fiemap.c \ + file.c \ + freeze.c \ + fsuuid.c \ + fsync.c \ + getrusage.c \ + imap.c \ + init.c \ + inject.c \ + label.c \ + link.c \ + madvise.c \ + mincore.c \ + mmap.c \ + open.c \ + parent.c \ + pread.c \ + prealloc.c \ + pwrite.c \ + readdir.c \ + reflink.c \ + resblks.c \ + scrub.c \ + seek.c \ + sendfile.c \ + shutdown.c \ + stat.c \ + swapext.c \ + sync.c \ + sync_file_range.c \ + truncate.c \ + utimes.c LLDLIBS = $(LIBXCMD) $(LIBHANDLE) $(LIBFROG) $(LIBPTHREAD) $(LIBUUID) LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE) $(LIBFROG) diff --git a/io/exchrange.c b/io/exchrange.c new file mode 100644 index 000000000..016429280 --- /dev/null +++ b/io/exchrange.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong + */ +#include "command.h" +#include "input.h" +#include "init.h" +#include "io.h" +#include "libfrog/logging.h" +#include "libfrog/fsgeom.h" +#include "libfrog/file_exchange.h" +#include "libfrog/bulkstat.h" + +static void +exchangerange_help(void) +{ + printf(_( +"\n" +" Exchange file data between the open file descriptor and the supplied filename.\n" +" -C -- Print timing information in a condensed format\n" +" -d N -- Start exchanging contents at this position in the open file\n" +" -f -- Flush changed file data and metadata to disk\n" +" -l N -- Exchange this many bytes between the two files instead of to EOF\n" +" -n -- Dry run; do all the parameter validation but do not change anything.\n" +" -s N -- Start exchanging contents at this position in the supplied file\n" +" -t -- Print timing information\n" +" -w -- Only exchange written ranges in the supplied file\n" +)); +} + +static int +exchangerange_f( + int argc, + char **argv) +{ + struct xfs_exchange_range fxr; + struct stat stat; + struct timeval t1, t2; + uint64_t flags = XFS_EXCHANGE_RANGE_TO_EOF; + int64_t src_offset = 0; + int64_t dest_offset = 0; + int64_t length = -1; + size_t fsblocksize, fssectsize; + int condensed = 0, quiet_flag = 1; + int c; + int fd; + int ret; + + init_cvtnum(&fsblocksize, &fssectsize); + while ((c = getopt(argc, argv, "Ccd:fl:ns:tw")) != -1) { + switch (c) { + case 'C': + condensed = 1; + break; + case 'd': + dest_offset = cvtnum(fsblocksize, fssectsize, optarg); + if (dest_offset < 0) { + printf( + _("non-numeric open file offset argument -- %s\n"), + optarg); + return 0; + } + break; + case 'f': + flags |= XFS_EXCHANGE_RANGE_DSYNC; + break; + case 'l': + length = cvtnum(fsblocksize, fssectsize, optarg); + if (length < 0) { + printf( + _("non-numeric length argument -- %s\n"), + optarg); + return 0; + } + flags &= ~XFS_EXCHANGE_RANGE_TO_EOF; + break; + case 'n': + flags |= XFS_EXCHANGE_RANGE_DRY_RUN; + break; + case 's': + src_offset = cvtnum(fsblocksize, fssectsize, optarg); + if (src_offset < 0) { + printf( + _("non-numeric supplied file offset argument -- %s\n"), + optarg); + return 0; + } + break; + case 't': + quiet_flag = 0; + break; + case 'w': + flags |= XFS_EXCHANGE_RANGE_FILE1_WRITTEN; + break; + default: + exchangerange_help(); + return 0; + } + } + if (optind != argc - 1) { + exchangerange_help(); + return 0; + } + + /* open the donor file */ + fd = openfile(argv[optind], NULL, 0, 0, NULL); + if (fd < 0) + return 0; + + ret = fstat(file->fd, &stat); + if (ret) { + perror("fstat"); + exitcode = 1; + goto out; + } + if (length < 0) + length = stat.st_size; + + xfrog_exchangerange_prep(&fxr, dest_offset, fd, src_offset, length); + ret = xfrog_exchangerange(file->fd, &fxr, flags); + if (ret) { + xfrog_perror(ret, "exchangerange"); + exitcode = 1; + goto out; + } + if (quiet_flag) + goto out; + + gettimeofday(&t2, NULL); + t2 = tsub(t2, t1); + + report_io_times("exchangerange", &t2, dest_offset, length, length, 1, + condensed); +out: + close(fd); + return 0; +} + +static struct cmdinfo exchangerange_cmd = { + .name = "exchangerange", + .cfunc = exchangerange_f, + .argmin = 1, + .argmax = -1, + .flags = CMD_FLAG_ONESHOT | CMD_NOMAP_OK, + .help = exchangerange_help, +}; + +void +exchangerange_init(void) +{ + exchangerange_cmd.args = _("[-Cfntw] [-d dest_offset] [-s src_offset] [-l length] "); + exchangerange_cmd.oneline = _("Exchange contents between files."); + + add_command(&exchangerange_cmd); +} diff --git a/io/init.c b/io/init.c index 104cd2c12..37e0f093c 100644 --- a/io/init.c +++ b/io/init.c @@ -88,6 +88,7 @@ init_commands(void) truncate_init(); utimes_init(); crc32cselftest_init(); + exchangerange_init(); } /* diff --git a/io/io.h b/io/io.h index e06dff53f..fdb715ff0 100644 --- a/io/io.h +++ b/io/io.h @@ -149,3 +149,4 @@ extern void scrub_init(void); extern void repair_init(void); extern void crc32cselftest_init(void); extern void bulkstat_init(void); +void exchangerange_init(void); diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 3ce280a75..2a7c67f7c 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -713,6 +713,46 @@ Swaps extent forks between files. The current open file is the target. The donor file is specified by path. Note that file data is not copied (file content moves with the fork(s)). .TP +.BI "exchangerange [OPTIONS]" donor_file " +Exchanges contents between files. +The current open file is the target. +The donor file is specified by path. +Note that file data is not copied (file content moves with the fork(s)). +Options include: +.RS 1.0i +.PD 0 +.TP 0.4i +.TP +.B \-C +Print timing information in a condensed format. +.TP +.BI \-d " dest_offset" +Swap extents with open file beginning at +.IR dest_offset . +.TP +.B \-f +Flush changed file data and file metadata to disk. +.TP +.BI \-l " length" +Swap up to +.I length +bytes of data. +.TP +.B \-n +Perform all the parameter validation checks but don't change anything. +.TP +.BI \-s " src_offset" +Swap extents with donor file beginning at +.IR src_offset . +.TP +.B \-t +Print timing information. +.TP +.B \-w +Only exchange written ranges in the supplied file. +.RE +.PD +.TP .BI "set_encpolicy [ \-c " mode " ] [ \-n " mode " ] [ \-f " flags " ] [ \-s " log2_dusize " ] [ \-v " version " ] [ " keyspec " ]" On filesystems that support encryption, assign an encryption policy to the current file. From patchwork Tue Jul 30 00:56:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746053 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4931323D for ; Tue, 30 Jul 2024 00:56:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300984; cv=none; b=nljtGNDYG84Br1X9kN5npqXy2vBbSPBl+LUGpQpGqu3Vqrl5mj+eQd/T2MV0shjxXzuNL2OK50LT9DDKExWK2RcpUabjmnLzZzQACgldWZ1noz9wprGgzdWsqpNCzqK2J1sStF6Wo4zwCMJq3G5CUwUCAgU8hjG1IZKMklP5yiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300984; c=relaxed/simple; bh=bKpFVeEdQ/4WiLcBiw4mHejnETOEopdYGH4ZRY6wUjk=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Bfb/nVD8Fb7gKvunQ651+njLpGoI+pFD3QL0dfrZhIcrQU0p7c3PKg/KdUxA9iMW1t0b6ZYj7E1fKcs8LmLK3llCcK7CnSApfkSdSplqZGt/REbhSxVEaLFDajsk6M1/sCjYyP81S5wvcxaznrZLd1MnyR6c9hypCGwnOlIdW+4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Spe0Lb/b; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Spe0Lb/b" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 67742C32786; Tue, 30 Jul 2024 00:56:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300983; bh=bKpFVeEdQ/4WiLcBiw4mHejnETOEopdYGH4ZRY6wUjk=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=Spe0Lb/bwTBbmPmUwnBFVia8NfOMlSgf3t6AHHiidEsiwU4o2u9m/567pIRPJDKjY gywPBsXu6iJZbNADy98Fv+8hSzTlHZJBko+1Jq/+9dq6Mye+Ow8hPu9NrmvWOlzjBr aGnAIiI2bQAzZhyJIeIhNEJ7l+q4S1/1YoSHSOdvVOhnlidJPOu9lHLtqA+je7gVWi wVPGAWxxr4ha/aW0g4f0YReXe5nxp8YzHvKlsSWlEsbcasdflRySGTSx2LSY4/rBR0 rTFPr/KnZrBQvjqVGE4dDxXS3kdWgfA0BXAovjx54O5i+sVk5FxZgcmm4ByRxAzCdP nYMtTaFDjfxyA== Date: Mon, 29 Jul 2024 17:56:22 -0700 Subject: [PATCH 10/12] libfrog: advertise exchange-range support From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844534.1344699.3298170994004880868.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Report the presence of exchange range for a given filesystem. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- libfrog/fsgeom.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c index 6980d3ffa..71a8e4bb9 100644 --- a/libfrog/fsgeom.c +++ b/libfrog/fsgeom.c @@ -31,6 +31,7 @@ xfs_report_geom( int bigtime_enabled; int inobtcount; int nrext64; + int exchangerange; isint = geo->logstart > 0; lazycount = geo->flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0; @@ -49,12 +50,14 @@ xfs_report_geom( bigtime_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_BIGTIME ? 1 : 0; inobtcount = geo->flags & XFS_FSOP_GEOM_FLAGS_INOBTCNT ? 1 : 0; nrext64 = geo->flags & XFS_FSOP_GEOM_FLAGS_NREXT64 ? 1 : 0; + exchangerange = geo->flags & XFS_FSOP_GEOM_FLAGS_EXCHANGE_RANGE ? 1 : 0; printf(_( "meta-data=%-22s isize=%-6d agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n" " =%-22s reflink=%-4u bigtime=%u inobtcount=%u nrext64=%u\n" +" =%-22s exchange=%-3u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d, ftype=%d\n" @@ -65,6 +68,7 @@ xfs_report_geom( "", geo->sectsize, attrversion, projid32bit, "", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled, "", reflink_enabled, bigtime_enabled, inobtcount, nrext64, + "", exchangerange, "", geo->blocksize, (unsigned long long)geo->datablocks, geo->imaxpct, "", geo->sunit, geo->swidth, From patchwork Tue Jul 30 00:56:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746054 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3CB634C97 for ; Tue, 30 Jul 2024 00:56:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300999; cv=none; b=q2zo9PiaskZpsDCcxu/F/Od/4oBZj7aHG2/jrir0xnWXsRldiZWQswps/PduEGUA8zGbKw2ufn1okYOXc0Ug0+pASQsFL9J/BztJ2r869OWoUpX1TgHTt+H2lyMfWr8WbQ7ctyBGrfgWiOoWxIjU46MSb36ad86UdlBd8DmCCfQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722300999; c=relaxed/simple; bh=a6XDW7ThXTEPTjjcy/LKjpcrKbtlSUqt7XVJ0fDUlOo=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NDhnq5/KeDG8Z/UuZlH7TjZXJHqKwfag4ECojzGZgHbb/VMq4iiAtFcBFa3FoyrKhvqO7b4nLC+IG9CtwAD0hrQFdeD1KybHloQZnDcFLZjBQwqX1lOKworwIVou6ViR7RYavJRfo8/w4qUQ2sprq4wJ81QZHrnDq1v6eSzpAzY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uJuowC2s; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="uJuowC2s" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1219BC32786; Tue, 30 Jul 2024 00:56:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722300999; bh=a6XDW7ThXTEPTjjcy/LKjpcrKbtlSUqt7XVJ0fDUlOo=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=uJuowC2sA8Y6evz6uXhLFMii1MSFghVVAK77unqZuFcn5TgbGVEwiWqmOjD3ytrrD Puo52pdtf7fbTPJBm4DSdrOAXRNrCjG4G/W9uTh+V8DHb6wY5wQtj4xjbeLy4sEOZx b8Pm58tHs/1QS4twh+9MO0udPS9U8nqxCwKHy0N5hUt8P7B/BQgE3SGs6rVED2Fmmp D1fRGNYR9QTfxqY/KFzDQBk9F/pYo+DE/mPH9xO1MXwDPq8N4Xe4KQF5aIf844iCIz V27pnefVle1OTOGDl0PalOZmT1SGjnF9PbqOkYSkXBC8aiZVubWuJu/A6Hd8McghJU i7EzraXPQN59w== Date: Mon, 29 Jul 2024 17:56:38 -0700 Subject: [PATCH 11/12] xfs_repair: add exchange-range to file systems From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844546.1344699.2406742125238441576.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Enable upgrading existing filesystems to support the file exchange range feature. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- man/man8/xfs_admin.8 | 7 +++++++ repair/globals.c | 1 + repair/globals.h | 1 + repair/phase2.c | 30 ++++++++++++++++++++++++++++++ repair/xfs_repair.c | 11 +++++++++++ 5 files changed, 50 insertions(+) diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8 index 4794d6774..63f8ee903 100644 --- a/man/man8/xfs_admin.8 +++ b/man/man8/xfs_admin.8 @@ -156,6 +156,13 @@ data fork extent count will be 2^48 - 1, while the maximum attribute fork extent count will be 2^32 - 1. The filesystem cannot be downgraded after this feature is enabled. Once enabled, the filesystem will not be mountable by older kernels. This feature was added to Linux 5.19. +.TP 0.4i +.B exchange +Upgrade a filesystem to support atomic file content exchanges through the +XFS_IOC_EXCHANGE_RANGE ioctl, and to support online repairs of directories, +extended attributes, symbolic links, and realtime free space metadata. +The filesystem cannot be downgraded after this feature is enabled. +Once enabled, the filesystem will not be mountable by older kernels. .RE .TP .BI \-U " uuid" diff --git a/repair/globals.c b/repair/globals.c index 24f720c46..c0c45df51 100644 --- a/repair/globals.c +++ b/repair/globals.c @@ -52,6 +52,7 @@ bool features_changed; /* did we change superblock feature bits? */ bool add_inobtcount; /* add inode btree counts to AGI */ bool add_bigtime; /* add support for timestamps up to 2486 */ bool add_nrext64; +bool add_exchrange; /* add file content exchange support */ /* misc status variables */ diff --git a/repair/globals.h b/repair/globals.h index b83a8ae65..1eadfdbf9 100644 --- a/repair/globals.h +++ b/repair/globals.h @@ -93,6 +93,7 @@ extern bool features_changed; /* did we change superblock feature bits? */ extern bool add_inobtcount; /* add inode btree counts to AGI */ extern bool add_bigtime; /* add support for timestamps up to 2486 */ extern bool add_nrext64; +extern bool add_exchrange; /* add file content exchange support */ /* misc status variables */ diff --git a/repair/phase2.c b/repair/phase2.c index 063748179..83f0c539b 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -182,6 +182,34 @@ set_nrext64( return true; } +static bool +set_exchrange( + struct xfs_mount *mp, + struct xfs_sb *new_sb) +{ + if (xfs_has_exchange_range(mp)) { + printf(_("Filesystem already supports exchange-range.\n")); + exit(0); + } + + if (!xfs_has_crc(mp)) { + printf( + _("File exchange-range feature only supported on V5 filesystems.\n")); + exit(0); + } + + if (!xfs_has_reflink(mp)) { + printf( + _("File exchange-range feature cannot be added without reflink.\n")); + exit(0); + } + + printf(_("Adding file exchange-range support to filesystem.\n")); + new_sb->sb_features_ro_compat |= XFS_SB_FEAT_INCOMPAT_EXCHRANGE; + new_sb->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR; + return true; +} + struct check_state { struct xfs_sb sb; uint64_t features; @@ -290,6 +318,8 @@ upgrade_filesystem( dirty |= set_bigtime(mp, &new_sb); if (add_nrext64) dirty |= set_nrext64(mp, &new_sb); + if (add_exchrange) + dirty |= set_exchrange(mp, &new_sb); if (!dirty) return; diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 88aa75542..e325d61f1 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -69,6 +69,7 @@ enum c_opt_nums { CONVERT_INOBTCOUNT, CONVERT_BIGTIME, CONVERT_NREXT64, + CONVERT_EXCHRANGE, C_MAX_OPTS, }; @@ -77,6 +78,7 @@ static char *c_opts[] = { [CONVERT_INOBTCOUNT] = "inobtcount", [CONVERT_BIGTIME] = "bigtime", [CONVERT_NREXT64] = "nrext64", + [CONVERT_EXCHRANGE] = "exchange", [C_MAX_OPTS] = NULL, }; @@ -360,6 +362,15 @@ process_args(int argc, char **argv) _("-c nrext64 only supports upgrades\n")); add_nrext64 = true; break; + case CONVERT_EXCHRANGE: + if (!val) + do_abort( + _("-c exchange requires a parameter\n")); + if (strtol(val, NULL, 0) != 1) + do_abort( + _("-c exchange only supports upgrades\n")); + add_exchrange = true; + break; default: unknown('c', val); break; From patchwork Tue Jul 30 00:56:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13746055 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C927F5C96 for ; Tue, 30 Jul 2024 00:56:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301014; cv=none; b=qv2sAf46VUBe3pur4fMLiYiTjKFxrpe2b+BwkgasMq9TxEcBZpeNBhubUPByB99YrblmfEoCTex9u+oD8+GK6DGP5G7YcRdW3/YKVTK3tDY10VofKh2+ibjzuqGHyHYDXoQh+DlQlF8bWFCK9uPPgxcCgbg4aIvJrvNVSGJ7ObE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722301014; c=relaxed/simple; bh=Of1454qtQuYHTSlU44/55KG47QLEKGaaki08MoIUd7A=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MYUE42pxx7LXiuyogDDvbzB6LpQxxns2e5vxDizQb9iR5sjd/SKHFLItFaR6Y4hFT6rEupzlK76Kd/gc0wd2IsRJcsqcBnmfyh0nytJ4SqaR7iHRo2mLbs5ryjX14PfpaKQ+WzgTt2iYP295EEhLrzS7I6a92EYbN63rFBo/CtA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kBqaOV2h; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kBqaOV2h" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5A03C32786; Tue, 30 Jul 2024 00:56:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722301014; bh=Of1454qtQuYHTSlU44/55KG47QLEKGaaki08MoIUd7A=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=kBqaOV2hXExW4uKdYkil1+nOv7D19+nP2OoD3PywMECfdfoj+QeJaOmqtzLAqejtl GkXEci3Y0MdsFItB5Th/jry2hSRr4TklNDRIKjQFtk8e+Mt351ilcxtOyyqqTLgrjf mO3W40aCnkuXDkFOe8nJOsArCwvIvqdLPaRTw7HoxKU932J1JRdroE+BKioTNNVubV umvuiIKDizscn9Xa5gydv76G8FqFRNOCVZV7iVtdUkoBBzmhR4pNebOK7qPUDELH9r 7YsYRoc157pAX9oMXAMd8d7WWaOSvmNTWX5qXAbFwxZloPHQbJiXwrxYOtgXTGlk9+ gKfX3Fl4xUf6w== Date: Mon, 29 Jul 2024 17:56:54 -0700 Subject: [PATCH 12/12] mkfs: add a formatting option for exchange-range From: "Darrick J. Wong" To: djwong@kernel.org, cem@kernel.org Cc: Christoph Hellwig , linux-xfs@vger.kernel.org Message-ID: <172229844560.1344699.13468796571019891277.stgit@frogsfrogsfrogs> In-Reply-To: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> References: <172229844398.1344699.10032784599013622964.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Allow users to enable the logged file mapping exchange intent items on a filesystem, which in turn enables XFS_IOC_EXCHANGE_RANGE and online repair of metadata that lives in files, e.g. directories and xattrs. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- man/man8/mkfs.xfs.8.in | 7 +++++++ mkfs/lts_4.19.conf | 1 + mkfs/lts_5.10.conf | 1 + mkfs/lts_5.15.conf | 1 + mkfs/lts_5.4.conf | 1 + mkfs/lts_6.1.conf | 1 + mkfs/lts_6.6.conf | 1 + mkfs/xfs_mkfs.c | 26 ++++++++++++++++++++++++-- 8 files changed, 37 insertions(+), 2 deletions(-) diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in index 8060d342c..d5a0783ac 100644 --- a/man/man8/mkfs.xfs.8.in +++ b/man/man8/mkfs.xfs.8.in @@ -670,6 +670,13 @@ If the value is omitted, 1 is assumed. This feature will be enabled when possible. This feature is only available for filesystems formatted with -m crc=1. .TP +.BI exchange[= value] +When enabled, application programs can exchange file contents atomically +via the XFS_IOC_EXCHANGE_RANGE ioctl. +Online repair uses this functionality to rebuild extended attributes, +directories, symbolic links, and realtime metadata files. +This feature is disabled by default. +This feature is only available for filesystems formatted with -m crc=1. .RE .PP .PD 0 diff --git a/mkfs/lts_4.19.conf b/mkfs/lts_4.19.conf index 8b2bdd7a3..92e8eba6b 100644 --- a/mkfs/lts_4.19.conf +++ b/mkfs/lts_4.19.conf @@ -12,3 +12,4 @@ rmapbt=0 [inode] sparse=1 nrext64=0 +exchange=0 diff --git a/mkfs/lts_5.10.conf b/mkfs/lts_5.10.conf index 40189310a..34e7662cd 100644 --- a/mkfs/lts_5.10.conf +++ b/mkfs/lts_5.10.conf @@ -12,3 +12,4 @@ rmapbt=0 [inode] sparse=1 nrext64=0 +exchange=0 diff --git a/mkfs/lts_5.15.conf b/mkfs/lts_5.15.conf index aeecc0355..a36a5c2b7 100644 --- a/mkfs/lts_5.15.conf +++ b/mkfs/lts_5.15.conf @@ -12,3 +12,4 @@ rmapbt=0 [inode] sparse=1 nrext64=0 +exchange=0 diff --git a/mkfs/lts_5.4.conf b/mkfs/lts_5.4.conf index 0a40718b8..4204d5b8f 100644 --- a/mkfs/lts_5.4.conf +++ b/mkfs/lts_5.4.conf @@ -12,3 +12,4 @@ rmapbt=0 [inode] sparse=1 nrext64=0 +exchange=0 diff --git a/mkfs/lts_6.1.conf b/mkfs/lts_6.1.conf index 452abdf82..9a90def8f 100644 --- a/mkfs/lts_6.1.conf +++ b/mkfs/lts_6.1.conf @@ -12,3 +12,4 @@ rmapbt=0 [inode] sparse=1 nrext64=0 +exchange=0 diff --git a/mkfs/lts_6.6.conf b/mkfs/lts_6.6.conf index 244f8eaf7..3f7fb6519 100644 --- a/mkfs/lts_6.6.conf +++ b/mkfs/lts_6.6.conf @@ -12,3 +12,4 @@ rmapbt=1 [inode] sparse=1 nrext64=1 +exchange=0 diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 6d2469c3c..991ecbdd0 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -90,6 +90,7 @@ enum { I_PROJID32BIT, I_SPINODES, I_NREXT64, + I_EXCHANGE, I_MAX_OPTS, }; @@ -469,6 +470,7 @@ static struct opt_params iopts = { [I_PROJID32BIT] = "projid32bit", [I_SPINODES] = "sparse", [I_NREXT64] = "nrext64", + [I_EXCHANGE] = "exchange", [I_MAX_OPTS] = NULL, }, .subopt_params = { @@ -523,7 +525,13 @@ static struct opt_params iopts = { .minval = 0, .maxval = 1, .defaultval = 1, - } + }, + { .index = I_EXCHANGE, + .conflicts = { { NULL, LAST_CONFLICT } }, + .minval = 0, + .maxval = 1, + .defaultval = 1, + }, }, }; @@ -889,6 +897,7 @@ struct sb_feat_args { bool nodalign; bool nortalign; bool nrext64; + bool exchrange; /* XFS_SB_FEAT_INCOMPAT_EXCHRANGE */ }; struct cli_params { @@ -1024,7 +1033,8 @@ usage( void ) sectsize=num,concurrency=num]\n\ /* force overwrite */ [-f]\n\ /* inode size */ [-i perblock=n|size=num,maxpct=n,attr=0|1|2,\n\ - projid32bit=0|1,sparse=0|1,nrext64=0|1]\n\ + projid32bit=0|1,sparse=0|1,nrext64=0|1,\n\ + exchange=0|1]\n\ /* no discard */ [-K]\n\ /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\ sunit=value|su=num,sectsize=num,lazy-count=0|1,\n\ @@ -1722,6 +1732,9 @@ inode_opts_parser( case I_NREXT64: cli->sb_feat.nrext64 = getnum(value, opts, subopt); break; + case I_EXCHANGE: + cli->sb_feat.exchrange = getnum(value, opts, subopt); + break; default: return -EINVAL; } @@ -2365,6 +2378,13 @@ _("64 bit extent count not supported without CRC support\n")); usage(); } cli->sb_feat.nrext64 = false; + + if (cli->sb_feat.exchrange && cli_opt_set(&iopts, I_EXCHANGE)) { + fprintf(stderr, +_("exchange-range not supported without CRC support\n")); + usage(); + } + cli->sb_feat.exchrange = false; } if (!cli->sb_feat.finobt) { @@ -3498,6 +3518,8 @@ sb_set_features( if (fp->nrext64) sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64; + if (fp->exchrange) + sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_EXCHRANGE; } /*