Обсуждение:Linux/ZeroInode

Материал из Etersoft wiki
Перейти к: навигация, поиск

Из письма в devel@lists.altlinux.org от 23.10.2013

Начну с того, что у нас в компании используются как 32-битные, так и 64-битные системы. При этом они взаимодействуют между собой, а ещё и работают с файлами.

За последний год выявилось следующее:
1. Файловая система glusterfs, разработчики которой заявляют, что она не работает на 32-битных системах, на самом деле работает.
2. Файловая система XFS при достижении определённого объёма начинает создавать файлы с inode >2^32 (поскольку inode там зависит от позиции данных на диске)
3. Функция stat (32-битная функция stat — для структуры с 32-битным st_ino) возвращает ошибку, если inode у файла слишком велик
4. Многие программы (особенно такие важные, как apt и rpm) собраны без поддержки _FILE_OFFSET_BITS=64 (AC_SYS_LARGEFILE в configure.am)
и не способны работать с файлами (работа с файлами почти всегда включает в себя вызов функции stat).

Не дождавшись исправления сборки rpm (rpmReadSignature failed при inode, выходящем за 32 бита https://bugzilla.altlinux.org/show_bug.cgi?id=29117)
я подумал, что большинству программ, вызывающих stat(), значение inode не очень-то интересно.

Собственно, я рассматриваю 3 варианта:
1. Обнулять st_ino, если значение туда не влезает. Возражающие программы следует пересобрать со stat64()
2. Заполнять st_ino максимальным значением (все единицы). Возражающие программы следует пересобрать со stat64()
3. Сжимать значение inode в 32-битное (squash). Это существующая практика, применяемая в cifs, nfs и fuse. Но возникает вопрос с последствиями коллизий.

При использовании glibc исправление касается только glibc, при использовании других библиотек, предполагаю, нужно изменить и соответствующую функцию в ядре.

Предлагаемая формулировка проблемы и обоснования выбора решения:

Обнуление 64-битных inode.
Проблема: при использовании  32-битных систем совместно с файловыми системами, позволяющими создавать файлы и каталоги с inode >2^32, 
программы зачастую не могут оперировать с файлами, так как при обращении к последним функцией stat, весто ожидаемого 32-битного inode,
 может вернуться значение >2^32 и вызвать ошибку.
Цель: обеспечить  оперирование файлами с inode >2^32 на 32-битных системах.

Описание проблемы.
Зачастую на предприятиях, где замена оборудования крайне затратна, используются 32-битные совместно с системами, позволяющими создавать 
файлы с inode >2^32. На последних величина inode файла может достигать 2^64, в то время как на 32-битных только 2^32. Для правильного 
функционирования на 32-битных системах необходимо использовать функции наподобие stat64(), readdir64() или компилировать программы с опцией
_FILE_OFFSET_BITS=64. Однако, многие программы собраны без поддержки этой опции и пересборка их либо затруднительна, либо не представляется
возможной, поэтому при попытке их использования на 32-битных системах с файлами имеющими inode > 2^32, функция stat возвращает ошибку
переполнения(EOVERFLOW).

Способы решения.
Для обхода этой проблемы, исходя из того, что большинству программ значение inode не интересно, предлагается три возможных решения:
1. Обнулять st_ino, если значение inode не влезает.
2. Заполнять st_ino максимальным значением, т е. единицами. 
3. Сжимать значение inode в 32-битное (squash).

Обнуление inode.
Основная проблема во всех перечисленных выше методах — коллизии при оперировании с inode файлов. С этой точки зрения наиболее выгодным кажется 
метод обнуления inode. Этот метод по своему подходу идентичен заполнению поля st_ino единицами, но в отличие от него менее опасен в плане 
коллизий — если пользователь захочет сохранить значение inode, то вероятность ошибки оперирования с граничным значением гораздо выше, чем аналогичная 
при оперировании с обнуленным. Если же сравнивать метод обнуления с методом сжатия, то кажется очевидным, что пользователю будет гораздо труднее 
найти ошибку в своей программе, если возвращаться будут на вид правильные, но обрезанные значения inode, чем, если возвращаться будут их обнуленные 
аналоги.