Как файловые системы ext2 / 3/4 работают с 64-битным time_t? - PullRequest
0 голосов
/ 17 февраля 2020

Я работаю над небольшим инструментом для работы с изображениями файловой системы ext2 (например, перечисление каталогов, добавление и извлечение файлов без необходимости их монтирования). Я только что столкнулся с проблемой с Unix полями меток времени. Все они 32-битные в файловых системах ext. Как мы знаем, 32-битные Unix временные метки не будут работать после 2038 года. Большинство программ может легко справиться с этой проблемой, просто изменив определение time_t на 64 бит. Но это не так просто для файловых систем. Они должны быть совместимы с существующими реализациями, но время от времени их нужно обновлять. Как именно файловые системы ext делают это? В частности, такие поля, как s_mtime, s_wtime, s_lastcheck, i_atime, i_ctime, i_mtime и i_dtime.

1 Ответ

2 голосов
/ 23 февраля 2020

Если вы посмотрите на структуру ext4 , вы увидите:

struct ext4_inode {
    ...
    __le32  i_ctime;    /* Inode Change time */
    ...
    __le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
    ...
};

Вы не найдете i_ctime_extra используемого (* вздох *). Вместо этого вы найдете :

#define EXT4_INODE_GET_XTIME(xtime, inode, raw_inode)               \
do {                                        \
    (inode)->xtime.tv_sec = (signed)le32_to_cpu((raw_inode)->xtime);    \
    if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) {    \
        ext4_decode_extra_time(&(inode)->xtime,             \
                       raw_inode->xtime ## _extra);     \
        }                               \
    else                                    \
        (inode)->xtime.tv_nsec = 0;                 \
} while (0)


#define EXT4_EINODE_GET_XTIME(xtime, einode, raw_inode)                \
do {                                           \
    if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime))              \
        (einode)->xtime.tv_sec =                       \
            (signed)le32_to_cpu((raw_inode)->xtime);           \
    else                                       \
        (einode)->xtime.tv_sec = 0;                    \
    if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra))        \
        ext4_decode_extra_time(&(einode)->xtime,               \
                       raw_inode->xtime ## _extra);        \
    else                                       \
        (einode)->xtime.tv_nsec = 0;                       \
} while (0)

И если вы посмотрите на использование, вы увидите, что в памяти используется 64-битное целое число, разделение существует только на диск.

...