Я хочу атомарно изменить некоторые атрибуты файла. (Справочная информация: это для реализации NFS в пользовательском пространстве, в которой вызов SETATTR устанавливает несколько атрибутов для файла).
Проблема, которую мне не удалось решить, заключается в том, чтобы выполнить обновление атомом c. То есть другой процесс, в котором stat()
s или rename()
s файл не должен видеть частично обновленные атрибуты.
Различные упрощенные (то есть без проверки ошибок и обработки символических ссылок) подходы с их недостатками:
с использованием традиционных функций:
int setattr(char *path, attributes attrs)
{
lchown(path, attr.owner, attr.group);
chmod(path, attr.mode)
utime(path, ...)
return 0
}
Это не атомы c (и не работает должным образом с символическими ссылками).
с использованием fchown()
и др.
int setattr(char *path, attributes attrs)
{
int fd = open(path, O_WRONLY);
fchown(fd, attr.owner, attr.group);
fchmod(fd, attr.mode);
futimens(fd, ...);
return 0;
}
Это несколько атомов c, но происходит сбой, если режим файла не позволяет открыть или файл является символической ссылкой (в этом случае символическая ссылка атрибуты должны быть изменены вместо цели). Добавление O_PATH
к вызову open()
также не поможет, так как fchown()
и fchmod()
затем не удаются.
с использованием fchownat()
и др.
int setattr(char *path, attributes attrs)
{
int fd = open(dirname(path), O_WRONLY | O_PATH);
fchownat(fd, basename(path), attr.owner, attr.group, AT_SYMLINK_NOFOLLOW);
fchmodat(fd, basename(path), attr.mode, 0);
utimensat(fd, basename(path), ..., AT_SYMLINK_NOFOLLOW);
return 0;
}
Это выглядит наиболее многообещающе, но опять-таки это не атомы c.
Я что-то упускаю или нет подхода, который делает то, что я хочу