- PVSM.RU - https://www.pvsm.ru -
Объяснять что такое Reiser4 и с чем его едят я не буду, т. к. на этот счет достаточно информации [1 [1], 2 [2]] и повторять её я не вижу смысла. Поэтому начну пожалуй с того, что Reiser4 я решил опробовать в 2010 году, но из-за проблем с использования прозрачной компрессии совместно с упаковкой хвостов (как оказалось были проблемы в flush процедуре, которые на данный момент решены[3 [3]]) перешел обратно на ReiserFS. В 2013 году я узнал о том, что эта проблема решена [4 [4]] и я снова вернулся на Reiser4 (LZO1 на стационарной системе, на ноутбуке без сжатия). Через какое-то время я вспомнил про новости о «Чрезвычайно быстром алгоритме сжатия» LZ4, а так-же о том, что комьюнити Illumos добавило поддержку оного в ZFS. Тут меня посетила мысль: «А было-бы здорово будь в Reiser4 поддержка LZ4»! Вот я и начал «приделывать» его к Reiser4.
Сначала я просмотрел код плагина ccreg40 (как известно Reiser4 имеет плагиновую структуру). Все начинается с файла fs/reiser4/plugin/compress/compress.h в котором есть перечисление reiser4_compression_id:
typedef enum {
LZO1_COMPRESSION_ID,
GZIP1_COMPRESSION_ID,
LAST_COMPRESSION_ID,
} reiser4_compression_id;
В нем обозначаются идентификационные номера того или иного алгоритма сжатия (по умолчанию доступны LZO1 и GZIP1). Последним в списке идет LAST_COMPRESSION_ID, который нужен для определения размеров различных таблиц содержащих информацию о алгоритмах и сопутствующих им функций.
Продолжаем мы в файле fs/reiser4/plugin/compress/compress.c, в котором мы уже непосредственно описываем функции. Всего 7-мь основных функций:
Подробнее остановлюсь на функциях alloc()/free(). Один из аргументов которые они принимают, значится аргумент act типа tfm_action. tfm_action является перечислением описанным в заголовочном файле fs/reiser4/plugin/compress/compress.h (имеет такую-же структуру как и reiser4_compression_id), в котором два элемента TFMA_READ и TFMA_WRITE.
typedef enum {
TFMA_READ, /* decrypt, decompress */
TFMA_WRITE, /* encrypt, compress */
TFMA_LAST
} tfm_action;
Таким образом можно определить момент, вызывания функции, при чтении или при записи. Некоторые алгоритмы требуют дополнительную память для декомпрессии, и таким образом мы правильно выделим нужное количество памяти. К примеру алгоритм GZIP1 требует дополнительной памяти и мы выделяем для него оную, а алгоритмы LZO1/LZ4 не требуют и мы не выделяем её.
Заканчивается все в том-же файле compress.c, описанием массива compression_plugins, в котором мы указываем тип плагина, его идентификационный номер, заголовок, функции и т. д.
[LZ4_COMPRESSION_ID] = {
.h = {
.type_id = REISER4_COMPRESSION_PLUGIN_TYPE,
.id = LZ4_COMPRESSION_ID,
.pops = &compression_plugin_ops,
.label = "lz4",
.desc = "lz4 compression transform",
.linkage = {NULL, NULL}
},
.init = lz4_init,
.overrun = lz4_overrun,
.alloc = lz4_alloc,
.free = lz4_free,
.min_size_deflate = lz4_min_size_deflate,
.checksum = reiser4_adler32,
.compress = lz4_compress,
.decompress = lz4_decompress
}
Теперь о том, что я изменил в коде LZ4. Для начала я убрал весь код связанный с Microsoft Visual Studio (может когда-нибудь и соберут ядро Linux посредством компилятора MS VS, но явно это будет не в ближайшем будущем) и C++ (один extern “C”). Затем убрал код, связанный с оптимизацией для BigEndian систем, которая делала выходную информацию несовместимой с LittleEndian системами и код, позволяющий использовать стековую память вместо обычной (получится быстрее, но мы в ядре, нам такие вольности не пройдут даром). Напоследок убрал из кода функции malloc()/free(), добавив в список аргументов функций указатель на участок памяти, выделенной для нужд LZ4 (вспомните alloc()).
Ну а теперь самое главное, как все это работало… откровенно говоря, плохо. Плагин LZ4 работал медленнее и сжимал хуже плагина LZO1. Замеры проводились на живой системе, в однопользовательском режиме. В замер входила операция размонтирования раздела (чтоб сработали sync/flush процедуры и файлы полностью записались на диск). Производилось три теста: линейное запись/чтение на диск файла забитого нулями (из /dev/zero), линейное чтение/запись несжимаемого файла (предварительно взятого с /dev/urandom и записанного в память на tmpfs) и распаковка/сжатие исходных кодов ядра Linux версии 3.9.5. Из всех тестов, плагин с LZ4 показал преимущество только при записи/чтении файла с нулями. Во всех остальных тестах, LZO1 обошел LZ4 и по скорости сжатия/декомпрессии, и по конечному объему файлов.
В ходе дальнейших исследований (fullbench из состава LZ4 и lz4c vs lzop), было выяснено, что LZ4 теряет все свои свойства при блоках маленького размера, а проявляет заявленные свойства [5 [5]] только на больших блоках, к примеру в fullbench по умолчанию 4MiB, в lz4c 8MiB. Как выразился Эдуард Шишкин: «4MiB — это как-то многовато. LZO1 сжимает куски и много мельче..» [6 [6]]
Таким образом я выяснил, что для Reiser4 LZO1 является более предпочтительным вариантом, ежели LZ4. Кстати говоря, что-то мне подсказывает, что поддержка LZ4, которая была добавлена сообществом, в ZFS будет проявлять себя далеко не всегда (хотя по сравнению с LZJB всегда), и безуспешные попытки протолкнуть LZ4 в Linux [7 [7]] (в качестве возможности использования для сжатия ядра или initram) тому подтверждение. Что до LZ4 в btrfs… Эдуард Шишкин наглядно рассказал о том, что из себя представляет btrfs [8 [8]] и как ведется его разработка.
Автор: BratSinot
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/36473
Ссылки в тексте:
[1] 1: http://habrahabr.ru/post/45873/
[2] 2: http://theoks.net/~onekopaka/Reiser4Site/v4.html
[3] 3: http://marc.info/?l=reiserfs-devel&m=135146138331012&w=2
[4] 4: https://sourceforge.net/p/reiser4/discussion/general/thread/2bca4f8e/
[5] 5: http://code.google.com/p/lz4/
[6] 6: https://sourceforge.net/p/reiser4/discussion/general/thread/780facb4/
[7] 7: http://lwn.net/Articles/534168/
[8] 8: http://habrahabr.ru/post/108629/
[9] Патч Reiser4 для Linux 3.9: http://sourceforge.net/projects/reiser4/files/reiser4-for-linux-3.x/reiser4-for-3.9.2.patch.gz
[10] Патч LZ4 для Reiser4: http://sourceforge.net/p/reiser4/discussion/general/thread/780facb4/8dff/attachment/reiser4-lz4-4.patch
[11] Источник: http://habrahabr.ru/post/183230/
Нажмите здесь для печати.