libany(3)

НАЗВАНИЕ
libany - библиотека anyfs-tools.

СИНТАКСИС
#include <any.h>

#include <super.h>

#include <bitops.h>

#include <block_map.h>

#include <new_inode.h>

#include <release_fssys.h>

#include <progress.h>

#include <version.h>

ОПИСАНИЕ
Библиотека libany используется утилитами anyfs-tools.

СТРУКТУРЫ ТАБЛИЦЫ ИНФ.УЗЛОВ
Структуры для хранения таблицы инф.узлов в памяти объявлены в файле any.h

  ИНФОРМАЦИЯ СУПЕРБЛОКА
struct any_sb_info {
	char *si_itfilename;               /* имя файла таблицы инф.узлов */
	unsigned long si_blocksize;        /* размер блока */
	unsigned long si_inodes;           /* число инф.узлов */
	unsigned long *si_inode_bitmap;    /* карта инф.узлов */
	struct any_inode *si_inode_table;  /* массив инф.узлов */
};
Эта структура -- аналог суперблока в других файловых системах. Поле si_itfilename сохраняется при открытии таблицы инф.узлов и используется при сохранении, если не указано другого имени файла для записи таблицы инф.узлов. Поле si_inode_bitmap это карта битов обозначающих занят ли тот или иной инф.узел (т.е. 1 значит занят). Поле si_inode_table -- собственно таблица инф.узлов. Массив из si_inodes структур any_inode (будут описаны ниже).

  ИНФОРМАЦИОННЫЙ УЗЕЛ
struct any_inode {
    uint16_t  i_mode;         /* Режим доступа */
    uint16_t  i_uid;          /* Идентификатор пользователя */
    uint16_t  i_gid;          /* Идентификатор группы */
    uint64_t  i_size;         /* Размер в байтах */
    uint32_t  i_atime;        /* Время доступа */
    uint32_t  i_ctime;        /* Время создания */
    uint32_t  i_mtime;        /* Время модификации */
    uint16_t  i_links_count;  /* Число ссылок */
    union {
        struct any_file_frags   *file_frags; /* Фрагменты файла */
        struct any_dir          *dir;        /* Элементы директории */
        char   *symlink;                     /* Символическая ссылка */
        dev_t  device;                       /* Устройство */
    } i_info;
    size_t    i_it_file_offset; /* Смещение в файле таблицы инф.узлов */
}
Это структура является несколько модифицированной аналогичной структурой файловой системы ext2fs ext2_inode. Описание большинства элементов вы можете найти в stat(2). Объединение i_info содержит ссылку на часть информации об инф.узле зависимую от типа инф.узла. Для простого файла -- это описание расположения его фрагментов на диске. Для директорий -- список её элементов. Для символических ссылок -- строка ссылки. Для устройства -- тип устройства (см. описание элемента st_rdev в структуре stat(2)) Поле i_it_file_offset используется функцией сохранения таблицы инф.узлов.

  ДИРЕКТОРИЯ
Директорию описывает следующая структура:
struct any_dir {
        uint32_t              d_ndirents; /* число элементов */
        struct any_dirent*    d_dirent;   /* первый элемент директории */
        void*                 d_data;     /* ссылка на дополнительные данные
					  	(используется в графическом
					  	интерфейсе) */
};
Поле d_dirent является указателем на односвязный список элементов директории.

  ЭЛЕМЕНТ ДИРЕКТОРИИ
struct any_dirent {
        char*               d_name;  /* имя элемента */
        uint32_t            d_inode; /* номер инф.узла */
        struct any_dirent   *d_next; /* следующий элемент директории */
};

  ФРАГМЕНТЫ ФАЙЛА
Для простого файла хранится информация о расположении его на диске в следующей структуре:
struct any_file_frags {
        uint32_t                   fr_nfrags; /* число фрагментов */
        struct any_file_fragment   *fr_frags; /* фрагменты */
};
Поле fr_frags является массивом из fr_nfrags элементов, описывающих каждый фрагмент файла.

  ФРАГМЕНТ ФАЙЛА
struct any_file_fragment {
        uint32_t    fr_start;     /* номер начального блока фрагмента */
        uint32_t    fr_length;    /* длина фрагмента в блоках */
};
Размер блока, используемый в этой структуре в качестве единицы измерения, определён в структуре any_sb_info. Значение 0 элемента fr_start означает sparse-фрагмент (такой который не хранится на диске, но считается, что он заполнен нулями)

СОЗДАНИЕ/ЗАГРУЗКА/СОХРАНЕНИЕ ТАБЛИЦЫ ИНФ.УЗЛОВ
Следующие функции объявлены в файле super.h.

int alloc_it(struct any_sb_info **it, unsigned long blocksize,
            unsigned long inodes);
    Выделяет память для таблицы инф.узлов с размером блока blocksize и максимальным числом инф.узлов inodes, помещая указатель на структуру any_sb_info в *it. Новая таблица инф.узлов заполняется нулями. Возвращает 0 в случае успеха или -ENOMEM в случае не хватки памяти.

int realloc_it(struct any_sb_info *it, unsigned long inodes);
    Использует realloc чтобы изменить максимальное число элементов в таблице инф.узлов it на inodes. Имейте ввиду, что после этого вызова элементы si_inode_bitmap и si_inode_table структуры any_sb_info таблицы инф.узлов могут изменить своё значение (т.е. таблица и карта инф.узлов могут изменить своё расположение в памяти) и любые указатели на инф.узлы вычисленные перед этим вызовом выражением вроде (it->si_inode_table + ino) или &(it->si_inode_table[ino]). потребуют обновления. Возвращает 0 в случае успеха или выходит из программы со статусом ENOMEM.

int read_it(struct any_sb_info **it, char itfilename[]);
    Загружает таблицу инф.узлов из файла itfilename в память, помещая указатель на неё в *it. Возвращает 0 в случае успеха или -ENOMEM, -ENAMETOOLONG, -EINVAL в случае ошибки. В случае ошибки ввода/вывода переменная errno будет хранить более точный код ошибки.

int write_it(struct any_sb_info *it, char itfilename[]);
    Сохраняет таблицу инф.узлов it в файл itfilename. Если itfilename == NULL, то берёт имя файла из поля it->si_itfilename. Имейте ввиду, что этот вызов не освобождает память занимаемую таблицей инф.узлов (хотя вызов read_it выделяет память под загружаемую таблицу инф.узлов) Возвращает 0 в случае успеха или 1 в случае ошибки. В случае ошибки ввода/вывода переменная errno будет хранить более точный код ошибки.

void free_it(struct any_sb_info *info);
    Освобождает память, занимаемую таблицей инф.узлов.

РАБОТА С КАРТАМИ БИТОВ
Следующие функции объявлены в файле bitops.h

int test_and_set_bit(unsigned int nr, unsigned long* addr);
    Устанавливает бит nr в карте битов addr. Возвращает значение бита перед установкой.

set_bit(unsigned int nr, unsigned long* addr);
    Устанавливает бит nr в карте битов addr.

int test_and_clear_bit(unsigned int nr, unsigned long* addr);
    Очищает бит nr в карте битов addr. Возвращает значение бита перед очищением.

clear_bit(unsigned int nr, unsigned long* addr);
    Очищает бит nr в карте битов addr.

int test_bit(unsigned int nr, unsigned long* addr);
    Возвращает значение бита nr в карте бит addr.

int find_first_zero_bit(const unsigned long* addr, int size);
    Ищет первый нулевой бит в карте битов addr размером size. Возвращает номер найденного бита, или значение не меньшее size в случае неудачи.

int find_next_zero_bit(const unsigned long* addr, int size,
            int offset);
    Ищет первый, начиная с бита offset, нулевой бит в карте битов addr размером size. Возвращает номер найденного бита, или значение не меньшее size в случае неудачи.

СОЗДАНИЕ КАРТЫ БЛОКОВ
Следующие функции объявлены в файле block_map.h

int fill_block_bitmap(struct any_sb_info *info,
            unsigned long *block_bitmap,
            any_blk_t dev_size,
            int check_intersects);
    Заполняет карту блоков, помечая блоки занятые простыми файлами, в соответствии с информацией из таблицы инф.узлов info для устройства размером dev_size. Карта перед вызовом этой функции должна быть выделена в памяти и заполнена нулями. Кроме прочих блоков функция помечает нулевой блок как системный. Функция возвращает 0 в случае успеха или -1, если в таблице инф.узлов найдены файлы, разделяющие между собой информацию одних и тех же блоков (установка последнего параметра check_intersects позволяет отменить проверку на пересечение блоков, что используется в утилите anysurrect). Это значит, что в процессе своей работы функция не должна ни разу найти уже установленного бита в карте блоков (вероятно, помеченного ей же как используемый блок другим инф.узлом).

СОЗДАНИЕ ФАЙЛОВ В ANYFS
Следующие функции объявлены в файле new_inode.h

int any_new_inode(struct any_sb_info *info, int mode, void* data,
            uint32_t dirino, uint32_t *newino);
    Создаёт инф.узел в таблице инф.узлов info с режимом доступа (и типом) mode в директории инф.узла dirino. Номер нового инф.узла помещается в переменную *newino. В случае создания устройства (специального файла), указатель data должен указывать на переменную типа dev_t содержащей тип устройства. Возвращает ноль в случае успеха. Завершает работу программы при не хватке памяти.

int getpathino(char *path, uint32_t root, struct any_sb_info* info,
            uint32_t *ino);
    Ищет элемент (директорию) с именем (путём) path считая корневым инф.узел (директорию) root в таблице инф.узлов info. Помещает номер найденного инф.узла в переменную *ino. Возвращает 0 в случае успеха, 1 -- в случае отсутствия жлемента с таким именем, или -1, если инф.узел root не является директорией или является свободным инф.узлом.

int mkpathino(char *path, uint32_t root, struct any_sb_info* info,
            uint32_t *ino);
    Тоже что getpathino(), но создаёт все директории пути в случае их отсутствия. При этом в программе должна быть объявлена переменная mode_t dir_umask; содержащая маску сбрасываемых бит доступа для создаваемых директорий.

ОСВОБОЖДЕНИЕ СИСТЕМНЫХ БЛОКОВ
Следующие функции объявлены в файле release_fssys.h

typedef int any_rwblk_t(unsigned long from, unsigned long n,
            char *buffer);
    Тип функции чтения/записи блока. Функция этого типа должна считывать/записывать блоки начиная с from в количестве n штук в/из (заранее выделенного) буфера buffer. Функция должна возвращать 0 в случае успеха, или отрицательное значение в случае ошибки ввода/вывода.

extern any_rwblk_t *any_readblk;
    Указатель на функцию чтения блока с устройства. Присвойте этому указателю правильное значение перед вызовом any_release().

extern any_rwblk_t *any_writeblk;
    Указатель на функцию записи блока на устройство. Присвойте этому указателю правильное значение перед вызовом any_release().

typedef int any_testblk_t(unsigned long bitno);
    Тип функции проверки занятости блока номер bitno устройства. Функция этого типа должна возвращать 0, если проверяемый блок свободен.

extern any_testblk_t *any_testblk;
    Указатель на функцию проверки занятости блока устройства. Эта функция должна возвращать 1, только, если блок устройства будет занят системной информацией. Присвойте этому указателю правильное значение перед вызовом any_release().

typedef unsigned long any_getblkcount_t();
    Тип функции для получения размера устройства в блоках.

extern any_getblkcount_t *any_getblkcount;
    Указатель на функцию получения размера устройства. Присвойте этому указателю правильное значение перед вызовом any_release().

int any_release(struct any_sb_info *info, unsigned long *block_bitmap,
            unsigned long start, unsigned long length);
    Освобождает length (в будущем) системных блоков ФС, начиная с блока start, от пользовательской информации, основываясь на информации из таблицы инф.узлов info и карте блоков (пользовательской информации) block_bitmap. Функция будет использовать функции any_readblk и any_writeblk для чтения/записи с устройства, функцию any_getblkcount для получения размера устройства, а также функцию any_testblk для получения информации о расположении системных блоков на устройстве.

int any_release_sysinfo(struct any_sb_info *info,
            unsigned long *block_bitmap,
            any_rwblk_t *readblk,
            any_rwblk_t *writeblk,
            any_testblk_t *testblk,
            any_getblkcount_t *getblkcount);
    Освобождает все (в будущем) системные блоки от пользовательской информации, основываясь на информации из таблицы инф.узлов info и карте блоков (пользовательской информации) block_bitmap. Функция будет использовать функции readblk и writeblk для чтения/записи с устройства, функцию getblkcount для получения размера устройства, а также функцию testblk для получения информации о расположении системных блоков на устройстве.

int any_adddadd(struct any_sb_info *info);
    Функция добавляет во все директории таблицы инф.узлов info элементы "." и ".." Эта функция используется в утилитах построения файловых систем build_e2fs и build_xfs, после освобождения блоков от системной информации. Именно поэтому её объявление не было перенесено в другой файл.

СТРОКА ПРОГРЕССА
Следующие функции объявлены в файле progress.h Эти функции были взяты из e2fsprogs и немного модифицированы.

struct progress_struct;
    Структура для сохранения данных прогресса. Поля этой структуры используются функциями ниже, программисту использующему эти функции нет нужды исправлять их самостоятельно

void progress_init(struct progress_struct *progress,
            const char *label, uint32_t max);
    Инициализация строки прогресса progress с именем (пояснением действий программы для пользователя) label и максимальным значением max. Максимальное значение установленное в ноль будет означать что число обрабатываемых единиц (блоков, файлов и т.п.) не известно (возможно эта строка прогресса будет отображать подсчёт этих элементов), в этом случае строка прогресса будет выглядеть не как
    <пояснение>: <номер обрабатываемого элемента>/<всего элементов> а без указания максимального числа элементов:
    <пояснение>: <номер обрабатываемого элемента> Эта возможность используется в build_it для файловых систем которые не выдают правильное значение числа используемых инф.узлов (например, VFAT).

void progress_update(struct progress_struct *progress, uint32_t val);
    Обновление строки прогресса progress до значения val. Эта функция возвращает курсор и записывает новое значение прогресса.

int if_progress_update(struct progress_struct *progress, uint32_t val);
    Позволяет узнать будет ли обновлена строка прогресса progress при обновлении её до значения val. Функция используется в утилите anysurrect для принятия решения о возвращении курсора прогресса к его необходимому для обновления прогресса положению, которое изменяется при выводе индикатора типа распознаваемого файла.

int if_progress_updated(struct progress_struct *progress, uint32_t val);
    Позволяет узнать была ли обновлена строка прогресса progress при обновлении её до значения val. Функция используется в утилите anysurrect для принятия решения о печати нового значения индикатора типа распознаваемого файла после обновления строки прогресса.

void progress_close(struct progress_struct *progress);
    Закрытие строки прогресса progress.

ВЕРСИЯ ANYFS-TOOLS
Файл version.h имеет объявление двух макросов:

ANYFSTOOLS_VERSION
    Строка обозначающая версию пакета anyfs-tools.

ANYFSTOOLS_DATE
    Строка обозначающая дату релиза данной версии пакета anyfs-tools.

АВТОР
Николай Кривченков aka unDEFER <undefer@gmail.com>

СООБЩЕНИЯ ОБ ОШИБКАХ
Сообщения о любых проблемах с применением пакета anyfs-tools направляйте по адресу: undefer@gmail.com

ДОСТУПНОСТЬ
последнюю версию пакета вы можете получить на сайте проекта: http://anyfs-tools.sourceforge.net

СМ. ТАКЖЕ
anyfs-tools(8), build_it(8), anysurrect(8), stat(2)