sshfs utilise le protocole SSH File Transfer Protocol (SFTP). La solution de contournement que vous avez activée consiste à contourner la sémantique d'une opération rename () sur ce protocole lorsque le «nouveau» nom existe déjà.
Le comportement POSIX pour rename () dans ce cas consiste à supprimer le fichier existant et à terminer le changement de nom.
Dans le protocole SFTP, vous pouvez renommer un fichier avec l'opération SSH_FXP_RENAME; cependant, son comportement lorsque le nom cible existe déjà semble dépendre de la version du protocole que vous utilisez et des indicateurs que vous passez. La page wikipedia du protocole SFTP contient des liens vers divers projets de RFC pour différentes versions du protocole. Dans Draft 00, le comportement est répertorié comme suit:
C'est une erreur s'il existe déjà un fichier avec le nom spécifié par newpath.
Dans le projet 13 , le comportement est répertorié comme
Si les indicateurs n'incluent pas SSH_FXP_RENAME_OVERWRITE et qu'il existe déjà un fichier avec le nom spécifié par newpath, le serveur DOIT répondre avec SSH_FX_FILE_ALREADY_EXISTS.
Si les indicateurs incluent SSH_FXP_RENAME_ATOMIC et que le fichier de destination existe déjà, il est remplacé de manière atomique. C'est-à-dire qu'il n'y a aucun instant observable dans le temps où le nom ne fait référence ni à l'ancien ni au nouveau fichier. SSH_FXP_RENAME_ATOMIC implique SSH_FXP_RENAME_OVERWRITE.
Pour faire face à l'échec possible d'une opération rename () lorsque le nom cible existe, sshfs fournit la solution de contournement suivante (si elle est activée) :
if (err == -EPERM && sshfs.rename_workaround) {
size_t tolen = strlen(to);
if (tolen + RENAME_TEMP_CHARS < PATH_MAX) {
int tmperr;
char totmp[PATH_MAX];
strcpy(totmp, to);
random_string(totmp + tolen, RENAME_TEMP_CHARS);
tmperr = sshfs_do_rename(to, totmp);
if (!tmperr) {
err = sshfs_do_rename(from, to);
if (!err)
err = sshfs_unlink(totmp);
else
sshfs_do_rename(totmp, to);
}
}
}
Dans ce code, "from" est le nom existant du fichier que nous voulons renommer et "to" est le nouveau nom que nous voulons. En mettant de côté une certaine longueur de chemin et une comptabilité des erreurs, cela contourne
- Renomme "to" en "totmp"
- Renomme "de" en "à"
- Dissocie (supprime) "totmp"
Cela évite le conflit "le fichier existe déjà", mais modifie également la sémantique des opérations rename (), c'est pourquoi vous ne voudriez pas le faire par défaut.