Обсуждение: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, чем, если возвращаться будут их обнуленные аналоги.