diff options
author | Darrick J. Wong <djwong@kernel.org> | 2024-04-15 14:54:14 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2024-04-15 14:54:14 -0700 |
commit | 9a64d9b3109d01cca0b83c1d36538b7a37c5284e (patch) | |
tree | c33eacfdac02eb3c34365fa448aaf7b2fab437fe /fs/xfs/xfs_exchrange.h | |
parent | 5b9932f6001c70b984e8c9c2fe09e443beb4baba (diff) |
xfs: introduce new file range exchange ioctl
Introduce a new ioctl to handle exchanging ranges of bytes
between files. The goal here is to perform the exchange atomically with
respect to applications -- either they see the file contents before the
exchange or they see that A-B is now B-A, even if the kernel crashes.
My original goal with all this code was to make it so that online repair
can build a replacement directory or xattr structure in a temporary file
and commit the repair by atomically exchanging all the data blocks
between the two files. However, I needed a way to test this mechanism
thoroughly, so I've been evolving an ioctl interface since then.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_exchrange.h')
-rw-r--r-- | fs/xfs/xfs_exchrange.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/xfs/xfs_exchrange.h b/fs/xfs/xfs_exchrange.h new file mode 100644 index 000000000000..f80369c7df5d --- /dev/null +++ b/fs/xfs/xfs_exchrange.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2020-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong <djwong@kernel.org> + */ +#ifndef __XFS_EXCHRANGE_H__ +#define __XFS_EXCHRANGE_H__ + +/* Update the mtime/cmtime of file1 and file2 */ +#define __XFS_EXCHANGE_RANGE_UPD_CMTIME1 (1ULL << 63) +#define __XFS_EXCHANGE_RANGE_UPD_CMTIME2 (1ULL << 62) + +#define XFS_EXCHANGE_RANGE_PRIV_FLAGS (__XFS_EXCHANGE_RANGE_UPD_CMTIME1 | \ + __XFS_EXCHANGE_RANGE_UPD_CMTIME2) + +struct xfs_exchrange { + struct file *file1; + struct file *file2; + + loff_t file1_offset; + loff_t file2_offset; + u64 length; + + u64 flags; /* XFS_EXCHANGE_RANGE flags */ +}; + +long xfs_ioc_exchange_range(struct file *file, + struct xfs_exchange_range __user *argp); + +#endif /* __XFS_EXCHRANGE_H__ */ |