Как реализована логика изменения ctime и mtime внутри директорий в Linux?

Не знаю насколько это справедливо для всех Linux-систем. Я проверял на Ubuntu и Centos. Пример такой:

  • у нас есть верхнеуровневая директория Programming (./Programming)
  • есть вложенная в нее test (/Programming/test/) Смотрим метки на директории:

stat Programming/

    Файл: Programming/

    Доступ:        2021-12-02 23:23:55.142840944 +0500

    Модифицирован: 2021-11-29 **18:07:30**.323736428 +0500

    Изменён:       2021-11-29 **18:07:30**.323736428 +0500

    Создан:        2021-11-02 23:16:06.040114949 +0500

stat test/

    Файл: test/

    Доступ:        2021-11-29 19:50:29.553706542 +0500

    Модифицирован: 2021-11-29 **19:50:29**.549706459 +0500

    Изменён:       2021-11-29 **19:50:29**.549706459 +0500

   Создан:        2021-11-29 18:07:30.323736428 +0500

Копируем файл в директорию cp test.txt ./Programming/test/ Смотрим снова метки:

stat ./Programming

  Файл: ./Programming

  Доступ:        2021-12-02 23:23:55.142840944 +0500

  Модифицирован: 2021-11-29 **18:07:30**.323736428 +0500

  Изменён:       2021-11-29 **18:07:30**.323736428 +0500

  Создан:        2021-11-02 23:16:06.040114949 +0500

stat ./Programming/test/

  Файл: ./Programming/test/

  Доступ:        2021-11-29 19:50:29.553706542 +0500

  Модифицирован: 2021-12-02 **23:29:34**.797360191 +0500

  Изменён:       2021-12-02 **23:29:34**.797360191 +0500

  Создан:        2021-11-29 18:07:30.323736428 +0500

Почему при копировании файла в вложенную директорию /test у нас у выщестоящей директории Programming не обновляется mtime и ctime? Возможно это как то связано, что доступ к директориям идет не линейно(верхняя/вложенная/), а сразу во вложенную директорию назначения. Или логика другая? Возможно я ошибаюсь, но по логике если обновляется вложенная, то должна обновиться и верхняя директория, ну хотя бы даже по atime.


Ответы (1 шт):

Автор решения: Pak Uula

В общем случае у файлового объекта может быть несколько родительских каталогов благодаря такой фиче Posix, как жесткие (hard) ссылки. Один и тот же файл (inode) может упоминаться в нескольких каталогах.

Соответственно, в Posix нет простых путей получить все родительские каталоги для существующего файла. Легко получить путь только к одному родительскому каталогу - тому, который фигурирует в пути к файлу. Если же в пути есть жесткие ссылки, то для поиска всех возможных родительских каталогов нужно в общем случае перелопачивать все каталоги на диске.

Однозначно можно указать родительский каталог только при создании файла. Как только файл создан, он может обзавестись кучей ссылок и, как следствие, кучей родительских каталогов.

По этой причине fopen и open атрибут st_mtime изменяют атрибут родительского каталога только при создании.

fopen:

If mode is w, wb, a, ab, w+, wb+, w+b, a+, ab+, or a+b, and the file did not previously exist, upon successful completion, fopen() shall mark for update ... the last file status change and last data modification timestamps of the parent directory.

open с флагом O_CREAT:

If O_CREAT is set and the file did not previously exist, upon successful completion, open() shall mark for update ... the last data modification and last file status change timestamps of the parent directory.

По ссылке описывается, что хранится в файле каталога в файловой системе ext4:

  • имя каталога
  • список файлов каталога: inode, тип файла, имя файла.

Атрибутов файлов в файле каталога нет, поэтому их измнение не меняет атрибуты каталога. Создание файла приводит к изменению содержимого файла каталога, поэтому успешное создание файла приводит к изменению атрибутов каталога.

→ Ссылка