|
Packit |
7cfc04 |
.\" Copyright (c) 2016, Oracle. All rights reserved.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
|
|
Packit |
7cfc04 |
.\" This is free documentation; you can redistribute it and/or
|
|
Packit |
7cfc04 |
.\" modify it under the terms of the GNU General Public License as
|
|
Packit |
7cfc04 |
.\" published by the Free Software Foundation; either version 2 of
|
|
Packit |
7cfc04 |
.\" the License, or (at your option) any later version.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" The GNU General Public License's references to "object code"
|
|
Packit |
7cfc04 |
.\" and "executables" are to be interpreted as the output of any
|
|
Packit |
7cfc04 |
.\" document formatting or typesetting system, including
|
|
Packit |
7cfc04 |
.\" intermediate and printed output.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" This manual is distributed in the hope that it will be useful,
|
|
Packit |
7cfc04 |
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
7cfc04 |
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
7cfc04 |
.\" GNU General Public License for more details.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" You should have received a copy of the GNU General Public
|
|
Packit |
7cfc04 |
.\" License along with this manual; if not, see
|
|
Packit |
7cfc04 |
.\" <http://www.gnu.org/licenses/>.
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_END
|
|
Packit |
7cfc04 |
.TH IOCTL-FIDEDUPERANGE 2 2017-09-15 "Linux" "Linux Programmer's Manual"
|
|
Packit |
7cfc04 |
.SH NAME
|
|
Packit |
7cfc04 |
ioctl_fideduperange \- share some the data of one file with another file
|
|
Packit |
7cfc04 |
.SH SYNOPSIS
|
|
Packit |
7cfc04 |
.br
|
|
Packit |
7cfc04 |
.B #include <sys/ioctl.h>
|
|
Packit |
7cfc04 |
.br
|
|
Packit |
7cfc04 |
.B #include <linux/fs.h>
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BI "int ioctl(int " src_fd ", FIDEDUPERANGE, struct file_dedupe_range *" arg );
|
|
Packit |
7cfc04 |
.SH DESCRIPTION
|
|
Packit |
7cfc04 |
If a filesystem supports files sharing physical storage between multiple
|
|
Packit |
7cfc04 |
files, this
|
|
Packit |
7cfc04 |
.BR ioctl (2)
|
|
Packit |
7cfc04 |
operation can be used to make some of the data in the
|
|
Packit |
7cfc04 |
.B src_fd
|
|
Packit |
7cfc04 |
file appear in the
|
|
Packit |
7cfc04 |
.B dest_fd
|
|
Packit |
7cfc04 |
file by sharing the underlying storage if the file data is identical
|
|
Packit |
7cfc04 |
("deduplication").
|
|
Packit |
7cfc04 |
Both files must reside within the same filesystem.
|
|
Packit |
7cfc04 |
This reduces storage consumption by allowing the filesystem
|
|
Packit |
7cfc04 |
to store one shared copy of the data.
|
|
Packit |
7cfc04 |
If a file write should occur to a shared
|
|
Packit |
7cfc04 |
region, the filesystem must ensure that the changes remain private to the file
|
|
Packit |
7cfc04 |
being written.
|
|
Packit |
7cfc04 |
This behavior is commonly referred to as "copy on write".
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
This ioctl performs the "compare and share if identical" operation on up to
|
|
Packit |
7cfc04 |
.IR src_length
|
|
Packit |
7cfc04 |
bytes from file descriptor
|
|
Packit |
7cfc04 |
.IR src_fd
|
|
Packit |
7cfc04 |
at offset
|
|
Packit |
7cfc04 |
.IR src_offset ".
|
|
Packit |
7cfc04 |
This information is conveyed in a structure of the following form:
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
struct file_dedupe_range {
|
|
Packit |
7cfc04 |
__u64 src_offset;
|
|
Packit |
7cfc04 |
__u64 src_length;
|
|
Packit |
7cfc04 |
__u16 dest_count;
|
|
Packit |
7cfc04 |
__u16 reserved1;
|
|
Packit |
7cfc04 |
__u32 reserved2;
|
|
Packit |
7cfc04 |
struct file_dedupe_range_info info[0];
|
|
Packit |
7cfc04 |
};
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Deduplication is atomic with regards to concurrent writes, so no locks need to
|
|
Packit |
7cfc04 |
be taken to obtain a consistent deduplicated copy.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The fields
|
|
Packit |
7cfc04 |
.IR reserved1 " and " reserved2
|
|
Packit |
7cfc04 |
must be zero.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Destinations for the deduplication operation are conveyed in the array at the
|
|
Packit |
7cfc04 |
end of the structure.
|
|
Packit |
7cfc04 |
The number of destinations is given in
|
|
Packit |
7cfc04 |
.IR dest_count ",
|
|
Packit |
7cfc04 |
and the destination information is conveyed in the following form:
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
struct file_dedupe_range_info {
|
|
Packit |
7cfc04 |
__s64 dest_fd;
|
|
Packit |
7cfc04 |
__u64 dest_offset;
|
|
Packit |
7cfc04 |
__u64 bytes_deduped;
|
|
Packit |
7cfc04 |
__s32 status;
|
|
Packit |
7cfc04 |
__u32 reserved;
|
|
Packit |
7cfc04 |
};
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Each deduplication operation targets
|
|
Packit |
7cfc04 |
.IR src_length
|
|
Packit |
7cfc04 |
bytes in file descriptor
|
|
Packit |
7cfc04 |
.IR dest_fd
|
|
Packit |
7cfc04 |
at offset
|
|
Packit |
7cfc04 |
.IR dest_offset ".
|
|
Packit |
7cfc04 |
The field
|
|
Packit |
7cfc04 |
.IR reserved
|
|
Packit |
7cfc04 |
must be zero.
|
|
Packit |
7cfc04 |
During the call,
|
|
Packit |
7cfc04 |
.IR src_fd
|
|
Packit |
7cfc04 |
must be open for reading and
|
|
Packit |
7cfc04 |
.IR dest_fd
|
|
Packit |
7cfc04 |
must be open for writing.
|
|
Packit |
7cfc04 |
The combined size of the struct
|
|
Packit |
7cfc04 |
.IR file_dedupe_range
|
|
Packit |
7cfc04 |
and the struct
|
|
Packit |
7cfc04 |
.IR file_dedupe_range_info
|
|
Packit |
7cfc04 |
array must not exceed the system page size.
|
|
Packit |
7cfc04 |
The maximum size of
|
|
Packit |
7cfc04 |
.IR src_length
|
|
Packit |
7cfc04 |
is filesystem dependent and is typically 16\ MiB.
|
|
Packit |
7cfc04 |
This limit will be enforced silently by the filesystem.
|
|
Packit |
7cfc04 |
By convention, the storage used by
|
|
Packit |
7cfc04 |
.IR src_fd
|
|
Packit |
7cfc04 |
is mapped into
|
|
Packit |
7cfc04 |
.IR dest_fd
|
|
Packit |
7cfc04 |
and the previous contents in
|
|
Packit |
7cfc04 |
.IR dest_fd
|
|
Packit |
7cfc04 |
are freed.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Upon successful completion of this ioctl, the number of bytes successfully
|
|
Packit |
7cfc04 |
deduplicated is returned in
|
|
Packit |
7cfc04 |
.IR bytes_deduped
|
|
Packit |
7cfc04 |
and a status code for the deduplication operation is returned in
|
|
Packit |
7cfc04 |
.IR status ".
|
|
Packit |
7cfc04 |
If even a single byte in the range does not match, the deduplication
|
|
Packit |
7cfc04 |
request will be ignored and
|
|
Packit |
7cfc04 |
.IR status
|
|
Packit |
7cfc04 |
set to
|
|
Packit |
7cfc04 |
.BR FILE_DEDUPE_RANGE_DIFFERS .
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.IR status
|
|
Packit |
7cfc04 |
code is set to
|
|
Packit |
7cfc04 |
.B FILE_DEDUPE_RANGE_SAME
|
|
Packit |
7cfc04 |
for success, a negative error code in case of error, or
|
|
Packit |
7cfc04 |
.B FILE_DEDUPE_RANGE_DIFFERS
|
|
Packit |
7cfc04 |
if the data did not match.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.SH RETURN VALUE
|
|
Packit |
7cfc04 |
On error, \-1 is returned, and
|
|
Packit |
7cfc04 |
.I errno
|
|
Packit |
7cfc04 |
is set to indicate the error.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.SH ERRORS
|
|
Packit |
7cfc04 |
Error codes can be one of, but are not limited to, the following:
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B ENOMEM
|
|
Packit |
7cfc04 |
The kernel was unable to allocate sufficient memory to perform the
|
|
Packit |
7cfc04 |
operation or
|
|
Packit |
7cfc04 |
.IR dest_count
|
|
Packit |
7cfc04 |
is so large that the input argument description spans more than a single
|
|
Packit |
7cfc04 |
page of memory.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EBADF
|
|
Packit |
7cfc04 |
.IR src_fd
|
|
Packit |
7cfc04 |
is not open for reading;
|
|
Packit |
7cfc04 |
.IR dest_fd
|
|
Packit |
7cfc04 |
is not open for writing or is open for append-only writes; or the filesystem
|
|
Packit |
7cfc04 |
which
|
|
Packit |
7cfc04 |
.IR src_fd
|
|
Packit |
7cfc04 |
resides on does not support deduplication.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EINVAL
|
|
Packit |
7cfc04 |
The filesystem does not support deduplicating the ranges of the given files.
|
|
Packit |
7cfc04 |
This error can also appear if either file descriptor represents
|
|
Packit |
7cfc04 |
a device, FIFO, or socket.
|
|
Packit |
7cfc04 |
Disk filesystems generally require the offset and length arguments
|
|
Packit |
7cfc04 |
to be aligned to the fundamental block size.
|
|
Packit |
7cfc04 |
Neither Btrfs nor XFS support
|
|
Packit |
7cfc04 |
overlapping deduplication ranges in the same file.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EISDIR
|
|
Packit |
7cfc04 |
One of the files is a directory and the filesystem does not support shared
|
|
Packit |
7cfc04 |
regions in directories.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EOPNOTSUPP
|
|
Packit |
7cfc04 |
This can appear if the filesystem does not support deduplicating either file
|
|
Packit |
7cfc04 |
descriptor, or if either file descriptor refers to special inodes.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EPERM
|
|
Packit |
7cfc04 |
.IR dest_fd
|
|
Packit |
7cfc04 |
is immutable.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B ETXTBSY
|
|
Packit |
7cfc04 |
One of the files is a swap file.
|
|
Packit |
7cfc04 |
Swap files cannot share storage.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.B EXDEV
|
|
Packit |
7cfc04 |
.IR dest_fd " and " src_fd
|
|
Packit |
7cfc04 |
are not on the same mounted filesystem.
|
|
Packit |
7cfc04 |
.SH VERSIONS
|
|
Packit |
7cfc04 |
This ioctl operation first appeared in Linux 4.5.
|
|
Packit |
7cfc04 |
It was previously known as
|
|
Packit |
7cfc04 |
.B BTRFS_IOC_FILE_EXTENT_SAME
|
|
Packit |
7cfc04 |
and was private to Btrfs.
|
|
Packit |
7cfc04 |
.SH CONFORMING TO
|
|
Packit |
7cfc04 |
This API is Linux-specific.
|
|
Packit |
7cfc04 |
.SH NOTES
|
|
Packit |
7cfc04 |
Because a copy-on-write operation requires the allocation of new storage, the
|
|
Packit |
7cfc04 |
.BR fallocate (2)
|
|
Packit |
7cfc04 |
operation may unshare shared blocks to guarantee that subsequent writes will
|
|
Packit |
7cfc04 |
not fail because of lack of disk space.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Some filesystems may limit the amount of data that can be deduplicated in a
|
|
Packit |
7cfc04 |
single call.
|
|
Packit |
7cfc04 |
.SH SEE ALSO
|
|
Packit |
7cfc04 |
.BR ioctl (2)
|
|
Packit |
7cfc04 |
.SH COLOPHON
|
|
Packit |
7cfc04 |
This page is part of release 4.15 of the Linux
|
|
Packit |
7cfc04 |
.I man-pages
|
|
Packit |
7cfc04 |
project.
|
|
Packit |
7cfc04 |
A description of the project,
|
|
Packit |
7cfc04 |
information about reporting bugs,
|
|
Packit |
7cfc04 |
and the latest version of this page,
|
|
Packit |
7cfc04 |
can be found at
|
|
Packit |
7cfc04 |
\%https://www.kernel.org/doc/man\-pages/.
|