unsigned long nrpages; /* общее количество страниц */
pgoff_t writeback_index; /* смещения начала
обратной записи */
struct address_space_operations *a_ops; /* таблица операций */
unsigned long flags; /* маска gfp_mask
и флаги ошибок */
struct backing_dev_info *backing_dev_info; /* информация
упреждающего чтения */
spinlock_t private_lock; /* блокировка
для частных отображений */
struct list_head private_list; /* список
частных отображений */
struct address_spacs *assoc_mapping; /* соответствующие
буферы */
};
Поле i_mmap
— это дерево поиска по приоритетам для всех совместно используемых и частных отображений. Дерево поиска по приоритетам— это хитрая смесь базисных и частично упорядоченных бинарных деревьев[86].
Всего в адресном пространстве nrpages страниц памяти.
Объект address_space
связан с некоторым другим объектом ядра, обычно с файловым индексом. Если это так, то поле host
указывает на соответствующий файловый индекс. Если значение поля host
равно NULL
, то соответствующий объект не является файловым индексом; например, объект address_space
может быть связан с процессом подкачки страниц (swapper).
Поле a_ops
указывает на таблицу операций с адресным пространством так же, как и в случае объектов подсистемы VFS. Таблица операций представлена с помощью структуры struct address_space_operations
, которая определена в файле
следующим образом.
struct address_space_operations {
int (*writepage)(struct page*, struct writeback_control*);
int (*readpage)(struct file*, struct page*);
int (*sync_page)(struct page*);
int (*writepages)(struct address_space*,
struct writeback_control*);
int (*set_page_dirty)(struct page*);
int (*readpages)(struct file*, struct address_space*,
struct list_head*, unsigned);
int (*prepare_write)(struct file*, struct page*,
unsigned, unsigned);
int (*commit_write)(struct file*, struct page*,
unsigned, unsigned);
sector_t (*bmap)(struct address_space*, sector_t);
int (*invalidatepage)(struct page*, unsigned long);
int (*releasepage)(struct page*, int);
int (*direct_IO)(int, struct kiocb*, const struct iovec*,
loff_t, unsigned long);
};
Методы read_page
и write_page
являются наиболее важными. Рассмотрим шаги, которые выполняются при страничной операции чтения.
Методу чтения в качестве параметров передается пара значений: объект address_space
и смещение. Эти значения используются следующим образом для поиска необходимых данных в страничном кэше.
page = find_get_page(mapping, index);
где параметр mapping
— это заданное адресное пространство, a index
— заданная позиция в файле.
Если в кэше нет необходимой страницы памяти, то новая страница памяти выделяется и добавляется в кэш следующим образом.
struct page *cached_page;
int error;
cached_page = page_cache_alloc_cold(mapping);
if (!cached_page)
/* ошибка выделения памяти */
error =
add_to_page_cache_lru(cached_page, mapping, index, GFP_KERNEL);
if (error)
/* ошибка добавления страницы памяти в страничный кэш */
Наконец, необходимые данные могут быть считаны с диска, добавлены в страничный кэш и возвращены пользователю. Это делается следующим образом.
error = mapping->a_ops->readpage(file, page);