NOM

copy_file_range - Copier une plage de données d'un fichier vers un autre

BIBLIOTHÈQUE

Bibliothèque C standard ( libc, -lc)

SYNOPSIS

#define _GNU_SOURCE
#include <unistd.h>
ssize_t copy_file_range(int fd_in, off64_t *_Nullable off_in,
                        int fd_out, off64_t *_Nullable off_out,
                        size_t len, unsigned int flags);

DESCRIPTION

L'appel système copy_file_range() effectue une copie interne au noyau entre deux descripteurs de fichier sans devoir en plus transférer des données du noyau à l'espace utilisateur puis revenir au noyau. Jusqu'à len octets de données sont transférés du descripteur de fichier fd_in au descripteur de fichier fd_out, écrasant toute donnée se trouvant dans la plage du fichier cible sollicité.
La sémantique suivante s'applique à off_in et des déclarations identiques s'appliquent à off_out :
Si off_in est NULL, les octets sont lus dans fd_in à partir de la position du fichier, laquelle est ajustée par le nombre d'octets copiés.
Si off_in n'est pas NULL, off_in doit pointer vers un tampon qui indique le point de départ à partir duquel les octets de fd_in seront lus. La position du fichier de fd_in n'est pas modifiée mais off_in est ajusté correctement.
fd_in et fd_out peuvent se rapporter au même fichier. Dans ce cas, les plages de la source et de la cible ne sont pas autorisées à se chevaucher.
L'argument flags est fourni pour de futures extensions et doit être positionné actuellement sur 0.

VALEUR RENVOYÉE

En cas de succès, copy_file_range() renverra le nombre d'octets copiés entre les fichiers. Il pourrait être inférieur à la taille demandée au départ. Si la position du fichier de fd_in est à la fin du fichier ou au-delà, aucun octet n'est copié et copy_file_range() renvoie zéro.
En cas d'erreur, copy_file_range() renvoie -1 et errno est configuré pour indiquer l'erreur.

ERREURS

EBADF
Un ou plusieurs descripteurs de fichier ne sont pas valables.
EBADF
fd_in n'est pas ouvert en lecture ou fd_out n'est pas ouvert en écriture.
EBADF
L'attribut O_APPEND est configuré pour une description d'un fichier ouvert (voir open(2)) auquel renvoie le descripteur de fichier fd_out.
EFBIG
Tentative d'écriture sur une position dépassant la position maximale du fichier gérée par le noyau.
EFBIG
Tentative d'écriture d'une plage dépassant la taille maximale d'un fichier permise. La taille maximale d'un fichier varie selon les implémentations de système de fichiers et peut être différente de la position du fichier maximale autorisée.
EFBIG
Tentative d'écriture au-delà de la limite de ressource de la taille du fichier du processus. Cela peut aussi avoir pour conséquence la réception, par le processus, d'un signal SIGXFSZ.
EINVAL
Le paramètre flags ne vaut pas 0.
EINVAL
fd_in et fd_out se rapportent au même fichier et les plages de la source et de la cible se chevauchent.
EINVAL
fd_in ou fd_out n'est pas un fichier normal.
EIO
Une erreur E/S de bas niveau s'est produite lors de la copie.
EISDIR
fd_in ou fd_out se rapporte à un répertoire.
ENOMEM
Plus assez de mémoire.
ENOSPC
Il n'y a pas assez d'espace sur le système de fichiers cible pour terminer la copie.
EOPNOTSUPP (depuis Linux 5.19)
Le système de fichiers ne prend pas en charge cette opération.
EOVERFLOW
La plage source ou de destination demandée est trop grande pour être représentée dans les types de données indiqués.
EPERM
fd_out se rapporte à un fichier immuable.
ETXTBSY
fd_in ou fd_out se rapporte à un fichier d'échange actif.
EXDEV (depuis Linux 5.3)
Les fichiers auxquels se rapportent fd_in et fd_out ne sont pas sur le même système de fichiers.
EXDEV (depuis Linux 5.19)
Les fichiers auxquels se rapportent fd_in et fd_out ne sont pas sur le même système de fichiers et les systèmes de fichiers source et cible ne sont pas du même type ou ne prennent pas en charge la copie entre systèmes de fichiers.

VERSIONS

L'appel système copy_file_range() est apparu pour la première fois dans Linux 4.5, mais la glibc 2.27 offre une émulation dans l'espace utilisateur s'il n'est pas disponible.
L'implémentation du noyau a été profondément retravaillée dans Linux 5.3. Les zones de l'API qui n'étaient pas clairement définies ont été clarifiées et les limites de l'API sont vérifiées beaucoup plus strictement que sur les noyaux précédents. Les applications devraient cibler le comportement et les exigences des noyaux 5.3.
Depuis Linux 5.19, les copies entre systèmes de fichiers peuvent se faire quand les deux systèmes de fichiers sont du même type et si le système de fichiers le prend en charge. Voir BOGUES pour le comportement avant la 5.19.
Les applications devraient cibler le comportement et les exigences de Linux 5.3 qui ont aussi été rétroportés dans les noyaux stable plus récents.

STANDARDS

L'appel système copy_file_range() est une extension GNU et un non standard de Linux.

NOTES

Si fd_in est un fichier éparpillé, il se peut que copy_file_range() agrandisse les trous existant dans la plage demandée. Les utilisateurs peuvent bénéficier d'un appel à copy_file_range() dans une boucle et utiliser les opérations SEEK_DATA et SEEK_HOLE de lseek(2) pour chercher des emplacements de segments de données.
copy_file_range() donne aux systèmes de fichiers la possibilité d'implémenter des techniques de « copie accélérée » telles que l'utilisation de reflink (c'est-à-dire deux ou plusieurs i-nœuds partageant des pointeurs avec les mêmes blocs de disque copy-on-write) ou server-side-copy (dans le cas de NFS).

BOGUES

De Linux 5.3 à Linux 5.18, les copies entre système de fichiers étaient implémentées par le noyau si l'opération n'était pas gérée par les systèmes de fichiers eux-mêmes. Cependant, sur certains systèmes de fichiers virtuels, le code n'arrivait pas à faire la copie mais la présentait comme réussie.

EXEMPLES

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char *argv[]) { int fd_in, fd_out; off64_t len, ret; struct stat stat;
if (argc != 3) { fprintf(stderr, "Utilisation : %s <source> <destination>\n", argv[0]); exit(EXIT_FAILURE); }
fd_in = open(argv[1], O_RDONLY); if (fd_in == -1) { perror("open (argv[1])"); exit(EXIT_FAILURE); }
if (fstat(fd_in, &stat) == -1) { perror("fstat"); exit(EXIT_FAILURE); }
len = stat.st_size;
fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd_out == -1) { perror("open (argv[2])"); exit(EXIT_FAILURE); }
do { ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0); if (ret == -1) { perror("copy_file_range"); exit(EXIT_FAILURE); }
len -= ret; } while (len > 0 && ret > 0);
close(fd_in); close(fd_out); exit(EXIT_SUCCESS); }

VOIR AUSSI

lseek(2), sendfile(2), splice(2)

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <[email protected]>, Thierry Vignaud <[email protected]>, François Micaux, Alain Portal <[email protected]>, Jean-Philippe Guérard <[email protected]>, Jean-Luc Coulon (f5ibh) <[email protected]>, Julien Cristau <[email protected]>, Thomas Huriaux <[email protected]>, Nicolas François <[email protected]>, Florentin Duneau <[email protected]>, Simon Paillard <[email protected]>, Denis Barbier <[email protected]>, David Prévot <[email protected]> et Jean-Philippe MENGUAL <[email protected]>
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à [email protected]

Recommended readings

Pages related to copy_file_range you should read also:

Questions & Answers

Helpful answers and articles about copy_file_range you may found on these sites:
Stack Overflow Server Fault Super User Unix & Linux Ask Ubuntu Network Engineering DevOps Raspberry Pi Webmasters Google Search