- часть ОС, которая отвечает за возможность длительного хранения информации и доступа (чтение, создание, удаление, именование, переименование, запись, установка прав доступа и т.д.) к ней
- то есть:
- определяет формат сохраняемой информации и способ её физического хранения
- связывает физический носитель информации и системные вызовы (API) для доступа к файлу
- набор структур, при этом базовых структур 4 штуки:
1. **struct superblock** = хранит информацию о ФС (метаданные). Существует на диске (для надёжности в нескольких местах), а также в памяти ядра (туда она попадает в момент монтирования ФС).
Содержится указатель на:
* **struct super_operations** - описывает функции над суперблоком: read_inode, write_inode...
* **struct dentry_operations** -описывает функциии над dentry: d_init, d_delete, d_input, ....
2. **struct inode** (индексный узел) = дескриптор файла
3. **struct dentry** (элементы каталога) = любой dentry - компоненты пути какого-то файла
> Например: /mnt/cdrom/foo - компонентами dentry являются: /, mnt, cdrom, foo
Структура не хранится на диске (поэтому в ней нет флагов изменения объекта). Объекты dentry кэшируются ядром с помощью slab.
4. **struct file** (открытый файл)
- абстрактный интерфейс
- механизм управления памятью, обеспечивающей устранение фрагментации и её распределение
Удаление объектов не приводит к немедленному освобождению памяти.
Как говорят, открывается слот, который помещается в список свободных слотов.
И в результате следующего выделения памяти для объекта такого же размера вернет
указатель на слот памяти из этого списка.
GFP_KERNEL - (нормальное выделение памяти ядра) выделение памяти производится от имени процесса, запущенного в пространстве ядра. Если памяти не достаточно, процесс может перейти в состояние сна.
struct kmem_cache * kmem_cache_create(const char * name, size_t size, size_t offset, unsigned long flags, void (* ctor)(void *));
Создание нового кэш-slab
name - имя кэша
size - размер элементов
offset - смещение первого элемента от начала кэша
flags - параметры
ctor - конструктор, вызывается при размещении каждого элемента
Выделение объектов из кэша, после того, как кэш объектов создан
Уничтожение слаба
Регистрирование ФС
struct file_system_type - структура, **СОЗДАННАЯ РАЗРАБОТЧИКОМ ФС**
Дерегистрирование ФС
static struct file_system_type myfs_type = {
.owner = THIS_MODULE, // указатель на модуль реализации ФС, нужно для организации счетчика ссылок на модуль
.name = "myfs", // имя ФС, оно будет использоваться при монтировании
.mount = myfs_mount, // функция монтирования ФС
.kill_sb = kill_anon_super, // функция демонтирования ФС
};struct dentry * mount_nodev(struct file_system_type * fs_type, int flags, void * data, int (* fill_super)(struct superblock *, void *, int));
Если нет блочного устройства Функция монтирования
fs_type - структура, описывающая ФС
fill_super - функция инициализации суперблока
sb->s_blocksize = PAGE_SIZE; // Размер блока в байтах, PAGE_SIZE - 4 Кб
sb->s_blocksize_bits = PAGE_SHIFT; // Размер блока в битах
sb->s_magic = MYFS_MAGIC_NUMBER; // магическое число для доступа к суперблоку, по которому драйвер файловой системы может проверить, что на диске хранится именно та самая файловая система, а не что-то еще или прочие данные
sb->s_op = &myfs_super_ops; // Набор операций над суперблоком
sb->s_root = d_make_root(root); // Cоздание dentry по корневому inode (каталог, точка монтирования)static struct super_operations const myfs_super_ops =
{
.put_super = myfs_put_super, // вызывается при размонтировании ФС для освобождения структуры суперблока
.statfs = simple_statfs, // реализация системного вызова fstatfs/statfs - для получения статистики ФС, при этом статистика записывается в структуру statfs
// simple_statfs - заглушка из стандартной библиотеки
.drop_inode = generic_delete_inode, // вызывается, когда исчезает последняя ссылка на inode, удаляется inode
};S_IFDIR - если каталог
0755 - -rwxr-xr-x = обычный файл, всё можно user, только читать и исполнять - group/others
Размещение (создание) новго inode для заданного суперблока
1 параметр - новый inode
2 параметр - inode каталога
3 параметр - режим
ret->i_size = PAGE_SIZE;
ret->i_atime = ret->i_mtime = ret->i_ctime = current_time(ret); // последнее время доступа, модификации, изменения
ret->i_private = &myfs_inode; // Поле приватной информации
root->i_op = &simple_dir_inode_operations; // Операции с inode
root->i_fop = &simple_dir_operations; // Операции с файломСброс inode
// собираем наш загружаемый модуль (в данном случае его также называют драйвером ФС)
# make
// загрузка модуля
# sudo insmod ./main.ko
// создание образа диска image (по сути, данная команда создаст пустой текстовый файл image)
# touch image
// создание каталога dir, который станет точкой монтирования
# mkdir dir
// монтирование файловой системы
// -o loop - будет использован драйвер "диска", данные будут записываться в образ, не на физическое устройство
// -t myfs - имя используемой ФС = myfs. То есть будет использована ФС созданая в нашем модуле, имя "myfs" указывается в myfs_type.
// ./image - устройство расположения ФС
// ./dir - каталог монтирования ФС (корневой каталог ФС)
# sudo mount -o loop -t myfs ./image ./dir
// просматриваем логи ядра (должны увидеть сообщения о успешной загрузке модуля и успешном монтировании)
# dmesg | tail -10
//
// Вот в этот момент можно зайти в dir и попробовать разные станадртные комманды (ls, mkdir, ...).
// Так как в myfs_super_ops рабочий только деструктор суперблока, то тут нельзя ничего.
//
// размонтирование ФС
# sudo umount ./dir
// выгрузка модуля
# sudo rmmod ./vfs_md.ko
// и ещё раз просматриваем логи ядра
# dmesg | tail -10
ls -al
итого 312
drwxrwxr-x 3 ekaterina ekaterina 4096 мая 23 21:41 .
drwxrwxr-x 19 ekaterina ekaterina 4096 мая 20 12:24 ..
drwxr-xr-x 1 root root 4096 мая 23 21:43 dir
-rw-r--r-- 1 root root 0 мая 23 21:42 image
-rw-rw-r-- 1 ekaterina ekaterina 156160 мая 20 13:53 laboratornaya_VFS_2020.doc
-rw-rw-r-- 1 ekaterina ekaterina 4793 мая 23 21:22 main.c
-rw-rw-r-- 1 ekaterina ekaterina 11360 мая 23 21:41 main.ko
- права доступа к файлу,
- количество ссылок,
- имя владельца,
- группа владельцев,
- размер файла,
- время последней модификации и
- имя файла / каталога
sudo cat /proc/slabinfo | grep my
my_cache 170 170 24 170 1 : tunables 0 0 0 : slabdata 1 1 0- имя кэша
- число активных объектов
- общее число объектов (т. е., используемых и не используемых объектов)
- Размер объектов в этом кэше (slab), в байтах.
- Количество объектов, хранящихся в каждом кэше (slab).
- Количество страниц, выделенных для каждого кэша (slab).
- tunables = регулировки