Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Файловая система

  • часть ОС, которая отвечает за возможность длительного хранения информации и доступа (чтение, создание, удаление, именование, переименование, запись, установка прав доступа и т.д.) к ней
  • то есть:
    • определяет формат сохраняемой информации и способ её физического хранения
    • связывает физический носитель информации и системные вызовы (API) для доступа к файлу

VFS

  • набор структур, при этом базовых структур 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** (открытый файл)

  • абстрактный интерфейс

Распределение slab

  • механизм управления памятью, обеспечивающей устранение фрагментации и её распределение
Удаление объектов не приводит к немедленному освобождению памяти.  
Как говорят, открывается слот, который помещается в список свободных слотов.  
И в результате следующего выделения памяти для объекта такого же размера вернет 
указатель на слот памяти из этого списка.

Лабораторная работа

void * kmalloc(size_t size, gfp_t flags);

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 - конструктор, вызывается при размещении каждого элемента

void * kmem_cache_alloc(kmem_cache_t *cache, int kmflag);

Выделение объектов из кэша, после того, как кэш объектов создан

int kmem_cache_destroy(kmem_cache_t *cache);

Уничтожение слаба

int register_filesystem(struct file_system_type * fs);

Регистрирование ФС

struct file_system_type - структура, **СОЗДАННАЯ РАЗРАБОТЧИКОМ ФС**

int unregister_filesystem(struct file_system_type * fs);

Дерегистрирование ФС

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 - функция инициализации суперблока

Заполнение struct superblock

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 (каталог, точка монтирования)

struct super_operations

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

S_IFDIR - если каталог
0755 - -rwxr-xr-x = обычный файл, всё можно user, только читать и исполнять - group/others

struct inode * new_inode(struct super_block * sb);

Размещение (создание) новго inode для заданного суперблока

void inode_init_owner(struct inode *inode, const struct inode *dir, umode_t mode);

1 параметр - новый inode
2 параметр - inode каталога
3 параметр - режим

struct inode_operations

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;                           // Операции с файлом

iput(root);

Сброс 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 = регулировки