blob: 6a3ae8964d11426ba8a4000bb0993715f004daac [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
/*
* FIEXCHANGE ioctl definitions, to facilitate exchanging parts of files.
*
* Copyright (C) 2022 Oracle. All Rights Reserved.
*
* Author: Darrick J. Wong <djwong@kernel.org>
*/
#ifndef _LINUX_FIEXCHANGE_H
#define _LINUX_FIEXCHANGE_H
#include <linux/types.h>
/*
* Exchange part of file1 with part of the file that this ioctl that is being
* called against (which we'll call file2). Filesystems must be able to
* restart and complete the operation even after the system goes down.
*/
struct xfs_exch_range {
__s64 file1_fd;
__s64 file1_offset; /* file1 offset, bytes */
__s64 file2_offset; /* file2 offset, bytes */
__s64 length; /* bytes to exchange */
__u64 flags; /* see XFS_EXCH_RANGE_* below */
/* file2 metadata for optional freshness checks */
__s64 file2_ino; /* inode number */
__s64 file2_mtime; /* modification time */
__s64 file2_ctime; /* change time */
__s32 file2_mtime_nsec; /* mod time, nsec */
__s32 file2_ctime_nsec; /* change time, nsec */
__u64 pad[6]; /* must be zeroes */
};
/*
* Atomic exchange operations are not required. This relaxes the requirement
* that the filesystem must be able to complete the operation after a crash.
*/
#define XFS_EXCH_RANGE_NONATOMIC (1 << 0)
/*
* Check that file2's inode number, mtime, and ctime against the values
* provided, and return -EBUSY if there isn't an exact match.
*/
#define XFS_EXCH_RANGE_FILE2_FRESH (1 << 1)
/*
* Check that the file1's length is equal to file1_offset + length, and that
* file2's length is equal to file2_offset + length. Returns -EDOM if there
* isn't an exact match.
*/
#define XFS_EXCH_RANGE_FULL_FILES (1 << 2)
/*
* Exchange file data all the way to the ends of both files, and then exchange
* the file sizes. This flag can be used to replace a file's contents with a
* different amount of data. length will be ignored.
*/
#define XFS_EXCH_RANGE_TO_EOF (1 << 3)
/* Flush all changes in file data and file metadata to disk before returning. */
#define XFS_EXCH_RANGE_FSYNC (1 << 4)
/* Dry run; do all the parameter verification but do not change anything. */
#define XFS_EXCH_RANGE_DRY_RUN (1 << 5)
/*
* Only exchange ranges where file1's range maps to a written extent. This can
* be used to emulate scatter-gather atomic writes with a temp file.
*/
#define XFS_EXCH_RANGE_FILE1_WRITTEN (1 << 6)
/*
* Commit the contents of file1 into file2 if file2 has the same inode number,
* mtime, and ctime as the arguments provided to the call. The old contents of
* file2 will be moved to file1.
*
* With this flag, all committed information can be retrieved even if the
* system crashes or is rebooted. This includes writing through or flushing a
* disk cache if present. The call blocks until the device reports that the
* commit is complete.
*
* This flag should not be combined with NONATOMIC. It can be combined with
* FILE1_WRITTEN.
*/
#define XFS_EXCH_RANGE_COMMIT (XFS_EXCH_RANGE_FILE2_FRESH | \
XFS_EXCH_RANGE_FSYNC)
#define XFS_EXCH_RANGE_ALL_FLAGS (XFS_EXCH_RANGE_NONATOMIC | \
XFS_EXCH_RANGE_FILE2_FRESH | \
XFS_EXCH_RANGE_FULL_FILES | \
XFS_EXCH_RANGE_TO_EOF | \
XFS_EXCH_RANGE_FSYNC | \
XFS_EXCH_RANGE_DRY_RUN | \
XFS_EXCH_RANGE_FILE1_WRITTEN)
#define XFS_IOC_EXCHANGE_RANGE _IOWR('X', 129, struct xfs_exch_range)
#endif /* _LINUX_FIEXCHANGE_H */