vibecode the entire rgz ig
This commit is contained in:
+238
@@ -0,0 +1,238 @@
|
||||
# Отчет по дисциплине «Операционные системы»
|
||||
|
||||
## РГР «Разработка простой файловой системы»
|
||||
|
||||
**Выполнил:** ____________________
|
||||
**Группа:** ____________________
|
||||
**Проверил:** ____________________
|
||||
**Новосибирск, 2026**
|
||||
|
||||
## Оглавление
|
||||
|
||||
1. [Введение](#введение)
|
||||
2. [Постановка задачи](#постановка-задачи)
|
||||
3. [Выбранная архитектура файловой системы](#выбранная-архитектура-файловой-системы)
|
||||
4. [Структура носителя и основные данные](#структура-носителя-и-основные-данные)
|
||||
5. [Реализованные операции](#реализованные-операции)
|
||||
6. [Алгоритмы работы](#алгоритмы-работы)
|
||||
7. [Тестирование](#тестирование)
|
||||
8. [Ограничения реализации](#ограничения-реализации)
|
||||
9. [Вывод](#вывод)
|
||||
|
||||
## Введение
|
||||
|
||||
Цель работы — разработать учебную файловую систему на языке C, использующую обычный бинарный файл как виртуальный носитель произвольного доступа. Программа должна не только хранить файлы и каталоги, но и показывать основные принципы настоящих файловых систем: разметку носителя, учет свободного места, хранение метаданных, работу с путями и прикладные операции обслуживания.
|
||||
|
||||
В качестве ориентира использовался предоставленный пример реализации, однако приоритет был отдан требованиям задания. Поэтому итоговая программа сохраняет простую учебную архитектуру примера, но дополнительно реализует операции `open`, `close`, `seek`, `read`, `write`, `rename`, импорт и экспорт, дефрагментацию и сжатие.
|
||||
|
||||
## Постановка задачи
|
||||
|
||||
Согласно заданию необходимо разработать систему управления файлами, где разделом является бинарный файл произвольного доступа. Реализация должна включать:
|
||||
|
||||
- физический уровень хранения данных;
|
||||
- структуру учета свободных блоков;
|
||||
- базовый уровень с индексными метаданными;
|
||||
- размещение содержимого файлов;
|
||||
- систему каталогов и путей;
|
||||
- символьные операции над файлами и каталогами;
|
||||
- прикладную утилиту для форматирования, просмотра, импорта, экспорта, дефрагментации и сжатия.
|
||||
|
||||
## Выбранная архитектура файловой системы
|
||||
|
||||
Файловая система разделена на уровни. Такое деление полезно не только для описания в отчете: каждый уровень решает свою задачу и скрывает детали от следующего. Пользователь работает с командами и путями, а не с номерами кластеров; функции чтения работают с файлами, а не с отдельными битами карты свободного пространства.
|
||||
|
||||
| Уровень | Реализация | Назначение |
|
||||
| --- | --- | --- |
|
||||
| Физический уровень | Кластеры фиксированного размера по 1024 байта | Делит носитель на одинаковые адресуемые блоки; смещение кластера вычисляется как `номер * 1024` |
|
||||
| Учет свободного места | Битовая карта | Показывает, какие кластеры свободны, а какие уже принадлежат служебным областям или файлам |
|
||||
| Базовый уровень | Индексный файл с дескрипторами объектов | Хранит метаданные файлов и каталогов отдельно от пользовательских данных |
|
||||
| Размещение файлов | Список номеров кластеров в дескрипторе | Позволяет файлу занимать несколько несмежных кластеров и читать их в правильном порядке |
|
||||
| Логический уровень | Неупорядоченный список имен | Представляет каталоги через связь «объект — родительский каталог» и выполняет линейный поиск по именам |
|
||||
| Символьный уровень | Пути вида `/docs/file.txt`, буферизированные операции `open/close/seek/read/write` | Преобразует удобные человеку имена и позиции в обращения к дескрипторам и кластерам |
|
||||
| Прикладной уровень | Интерактивная консольная утилита | Дает команды для форматирования, просмотра, копирования, импорта, экспорта, сжатия и дефрагментации |
|
||||
|
||||
### Физический уровень
|
||||
|
||||
Носителем является обычный бинарный файл. Он рассматривается как последовательность кластеров одинакового размера. Фиксированный размер выбран ради простоты: адрес любого кластера находится прямым умножением, а алгоритм выделения не обязан искать переменные по длине участки памяти. Недостатком является внутреннее фрагментирование: даже файл в несколько байт занимает целый кластер.
|
||||
|
||||
### Уровень свободного пространства
|
||||
|
||||
Для каждого кластера хранится один бит. При форматировании служебные кластеры суперблока, битовой карты и индексного файла сразу помечаются занятыми. При записи файла функция выделения просматривает карту от начала области данных и выбирает первые свободные кластеры; при удалении файла соответствующие биты сбрасываются обратно в ноль.
|
||||
|
||||
### Базовый уровень
|
||||
|
||||
Индексный файл — это таблица дескрипторов `Entry`. Один дескриптор описывает один файл или каталог: имя, тип, родителя, размеры и список кластеров. Корневой каталог хранится в нулевой записи. Благодаря индексному файлу метаданные можно прочитать сразу после монтирования носителя, не просматривая всю область данных.
|
||||
|
||||
### Уровень размещения файлов
|
||||
|
||||
Каждый файл хранит массив номеров своих кластеров. Поэтому файл может лежать не непрерывно, а частями в разных местах виртуального диска. При чтении система идет по этому массиву и собирает содержимое в правильной последовательности. Дефрагментация перестраивает эти списки так, чтобы занятые кластеры снова располагались компактно.
|
||||
|
||||
### Логический и символьный уровни
|
||||
|
||||
Каталог реализован без отдельного файла содержимого: у каждого объекта есть поле `parent`, содержащее индекс родительского каталога. Путь разбивается по символу `/`, после чего система шаг за шагом ищет дочерний объект в текущем каталоге. Символьный уровень дает привычные операции над открытым файлом: `open`, `close`, `seek`, `read`, `write`; внутри программы они работают через буфер и скрывают детали физического размещения.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Команда пользователя] --> B[Путь /docs/a.txt]
|
||||
B --> C[Поиск дескриптора]
|
||||
C --> D[Список кластеров]
|
||||
D --> E[Битовая карта]
|
||||
D --> F[Байты в области данных]
|
||||
```
|
||||
|
||||
## Структура носителя и основные данные
|
||||
|
||||
В начале виртуального диска находится суперблок. Он хранит сигнатуру файловой системы, размер диска, размер кластера, смещения служебных областей и индекс корневого каталога.
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t disk_size;
|
||||
uint32_t cluster_size;
|
||||
uint32_t total_clusters;
|
||||
uint32_t bitmap_offset;
|
||||
uint32_t bitmap_size;
|
||||
uint32_t index_offset;
|
||||
uint32_t index_clusters;
|
||||
uint32_t data_start_cluster;
|
||||
uint32_t root_index;
|
||||
} SuperBlock;
|
||||
```
|
||||
|
||||
После суперблока располагается битовая карта. Каждый ее бит соответствует одному кластеру: `0` означает свободный кластер, `1` — занятый. Далее находится индексный файл, представленный массивом дескрипторов `Entry`.
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
char name[32];
|
||||
uint8_t type;
|
||||
uint8_t compressed;
|
||||
uint32_t parent;
|
||||
uint32_t size;
|
||||
uint32_t stored_size;
|
||||
uint32_t cluster_count;
|
||||
uint32_t clusters[128];
|
||||
} Entry;
|
||||
```
|
||||
|
||||
Поле `size` хранит логический размер файла, видимый пользователю, а `stored_size` — фактическое количество байт на носителе. Это различие необходимо для поддержки сжатых файлов.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
S[Суперблок] --> B[Битовая карта]
|
||||
B --> I[Индексный файл]
|
||||
I --> D[Область данных]
|
||||
I --> R[Корневой каталог /]
|
||||
R --> F[Дескрипторы файлов и каталогов]
|
||||
F --> D
|
||||
```
|
||||
|
||||
## Реализованные операции
|
||||
|
||||
Программа собирается из файла `simplefs.c` и запускается с именем файла-носителя:
|
||||
|
||||
```bash
|
||||
gcc -std=c11 -Wall -Wextra -pedantic simplefs.c -o simplefs
|
||||
./simplefs disk.img
|
||||
```
|
||||
|
||||
Интерактивная оболочка поддерживает историю команд: в обычном терминале стрелки **Up** и **Down** перемещаются по ранее введенным строкам. Основные команды названы в стиле Unix, чтобы работа с учебной файловой системой напоминала привычную командную строку.
|
||||
|
||||
### Справочник команд
|
||||
|
||||
| Команда | Синтаксис | Назначение |
|
||||
| --- | --- | --- |
|
||||
| Форматирование | `format <KiB>` | создает новый файл-носитель указанного размера |
|
||||
| Информация | `info` | показывает размер диска, размер кластера и число свободных кластеров |
|
||||
| Список | `ls [path]` | выводит содержимое текущего или указанного каталога |
|
||||
| Текущий каталог | `pwd` | печатает текущий абсолютный путь |
|
||||
| Переход | `cd <path>` | меняет текущий каталог |
|
||||
| Создание каталога | `mkdir <path>` | создает новый каталог |
|
||||
| Удаление каталога | `rmdir <path>` | удаляет только пустой каталог |
|
||||
| Создание файла | `touch <path>` | создает пустой файл |
|
||||
| Удаление файла | `rm <path>` | удаляет файл и освобождает его кластеры |
|
||||
| Копирование внутри ФС | `cp <from> <to>` | копирует файл в новый путь или в существующий каталог |
|
||||
| Перемещение/переименование | `mv <from> <to>` | переносит файл или каталог; если меняется только имя, работает как переименование |
|
||||
| Запись текста | `write <path> <text>` | перезаписывает файл текстовой строкой |
|
||||
| Просмотр файла | `cat <path>` | выводит логическое содержимое файла |
|
||||
| Просмотр хранения | `rawcat <path>` | выводит физически сохраненные байты и объясняет пары RLE |
|
||||
| Импорт файла | `import <host_file> <fs_path>` | копирует файл из основной ОС в учебную ФС |
|
||||
| Экспорт файла | `export <fs_path> <host_file>` | копирует файл из учебной ФС в основную ОС |
|
||||
| Импорт папки | `importdir <host_dir> <fs_path>` | рекурсивно импортирует каталог |
|
||||
| Экспорт папки | `exportdir <fs_path> <host_dir>` | рекурсивно экспортирует каталог |
|
||||
| Экспорт носителя | `savecarrier <host_file>` | сохраняет копию всего бинарного носителя |
|
||||
| Импорт носителя | `loadcarrier <host_file>` | заменяет текущий носитель ранее сохраненной копией |
|
||||
| Сжатие | `compress <path>` | применяет RLE-сжатие, если оно уменьшает файл |
|
||||
| Распаковка | `decomp <path>` | восстанавливает файл в несжатом виде |
|
||||
| Дефрагментация | `defrag` | заново записывает файлы подряд в область данных |
|
||||
| Справка и выход | `help`, `exit`, `quit` | показывает команды или завершает программу |
|
||||
|
||||
На уровне программного интерфейса реализованы функции `fs_open`, `fs_close`, `fs_seek`, `fs_read` и `fs_write`. Открытый файл использует буфер в памяти, поэтому чтение и запись записей произвольной длины выполняются без прямой работы пользователя с кластерами.
|
||||
|
||||
## Алгоритмы работы
|
||||
|
||||
### Форматирование
|
||||
|
||||
При выполнении `format` создается бинарный файл нужного размера, вычисляются размеры служебных областей, резервируются занятые кластеры и создается корневой каталог `/`.
|
||||
|
||||
### Выделение свободного кластера
|
||||
|
||||
Алгоритм линейно просматривает битовую карту, начиная с области данных. Первый свободный бит помечается как занятый, а номер соответствующего кластера возвращается вызывающей функции.
|
||||
|
||||
### Работа с каталогами
|
||||
|
||||
Каталог не хранит отдельный массив дочерних элементов. Вместо этого у каждого дескриптора есть поле `parent`, содержащее индекс родительского каталога. Для поиска элемента программа просматривает индексный файл и сравнивает имя и родителя.
|
||||
|
||||
### Сжатие
|
||||
|
||||
Команда `compress` использует простой алгоритм RLE: одинаковые подряд идущие байты заменяются парой «количество + значение». Если сжатый вариант не меньше исходного, файл не изменяется. При чтении сжатый файл автоматически восстанавливается в обычный вид. Для наблюдения за внутренним представлением предусмотрена команда `rawcat`: она показывает сохраненные байты в шестнадцатеричном виде и расшифровывает каждую RLE-пару. Команда `decomp` выполняет обратное преобразование и снова сохраняет файл без сжатия.
|
||||
|
||||
### Дефрагментация
|
||||
|
||||
Команда `defrag` временно считывает содержимое файлов, очищает карту размещения области данных и записывает файлы заново подряд. После операции используемые кластеры становятся компактно расположенными.
|
||||
|
||||
## Тестирование
|
||||
|
||||
Пример базового сценария:
|
||||
|
||||
```text
|
||||
format 512
|
||||
mkdir /docs
|
||||
touch /docs/a.txt
|
||||
write /docs/a.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
cat /docs/a.txt
|
||||
compress /docs/a.txt
|
||||
ls /docs
|
||||
rename /docs/a.txt b.txt
|
||||
export /docs/b.txt exported.txt
|
||||
defrag
|
||||
info
|
||||
```
|
||||
|
||||
Ожидаемые результаты:
|
||||
|
||||
| Проверка | Результат |
|
||||
| --- | --- |
|
||||
| Форматирование носителя | создается корректный виртуальный диск |
|
||||
| Создание каталога и файла | объекты появляются в `ls` |
|
||||
| Запись и чтение | `cat` выводит ранее записанный текст |
|
||||
| Сжатие повторяющихся данных | `stored_size` становится меньше `size` |
|
||||
| Переименование | файл доступен под новым именем |
|
||||
| Экспорт | создается внешний файл с тем же содержимым |
|
||||
| Дефрагментация | содержимое файлов сохраняется, кластеры уплотняются |
|
||||
|
||||
## Ограничения реализации
|
||||
|
||||
| Ограничение | Причина |
|
||||
| --- | --- |
|
||||
| Не более 128 объектов | фиксированный размер индексного файла |
|
||||
| Не более 128 кластеров на файл | фиксированный массив номеров кластеров |
|
||||
| Длина имени до 31 символа | размер поля `name[32]` |
|
||||
| Линейный поиск по каталогу | выбрана простая неупорядоченная структура |
|
||||
| RLE эффективно не для всех данных | алгоритм выбран ради понятности реализации |
|
||||
| Нет одновременного доступа нескольких процессов | учебная однопользовательская модель |
|
||||
|
||||
## Вывод
|
||||
|
||||
В ходе работы была реализована простая файловая система, работающая поверх бинарного файла как виртуального носителя. Реализация охватывает все основные уровни, указанные в задании: физическое размещение, учет свободных блоков, индексные метаданные, каталоги, операции над файлами и сервисные команды управления носителем.
|
||||
|
||||
Полученная программа остается достаточно простой для изучения начинающим разработчиком на C, но при этом показывает полный путь данных: от пользовательской команды до изменения битовой карты, индексного дескриптора и байтов в кластерах виртуального диска.
|
||||
Reference in New Issue
Block a user