Атомарный Файл Сохранить в Linux без потери метаданных

Я работаю над инструментом синхронизации файлов на основе Perl. Он загружает файлы во временный каталог (который гарантированно находится в той же файловой системе, что и реальный файл), а затем перемещает временные файлы на место поверх старых, сохраняя метаданные, такие как разрешения, права собственности и ACLs. Мне интересно, как достичь этого последнего шага в Linux.

на Mac OS X, по крайней мере, в C, я бы использовал . Это принимает два имени файлов в качестве аргументов и обменивает их содержимое, оставляя все метаданные (кроме mtime) нетронутыми. Это гарантирует, что операция является атомной-все читатели увидят либо старый файл, либо новый, никогда ничего между ними. К сожалению, я не думаю, что он доступен в Linux.

Я знаю, что rename движется автоматически, но не сохраняет метаданные. С другой стороны, я мог бы открыть файл и перезаписать данные содержимым нового, который сохранит все метаданные, но не будет атомарным операция. Есть предложения по решению этой проблемы?

2 ответов


единственный подход, который я вижу здесь, - это прочитать метаданные из файла, который вы заменяете, применить его к временному файлу, а затем переименовать временный файл поверх старого файла. (rename сохраняет атрибуты исходного файла, очевидно.)


специфичная для файловой системы, но...

на XFS_IOC_SWAPEXT ioctl меняет экстенты двух файловых дескрипторов на XFS.

#include <xfs/xfs.h>
#include <xfs/xfs_dfrag.h>

xfs_swapext_t sx = {
    ...,
    .sx_fdtarget = fd1,
    .sx_fdtmp    = fd2,
    ...
};
xfs_swapext(fd1, &sx);

см. источники к xfs_fsr использование.