Разработка файловой системы для AIX

В статье описывается организация и специфика файловой системы AIX®. Каждая операционная система имеет собственную структуру ядра, которую разработчики приложений должны понимать и использовать при создании приложений, использующих ядро этой ОС. Данная статья предоставляет информацию о структуре файловой системы ОС AIX. Понимание этой структуры необходимо, если нужно создать свою файловую систему или портировать существующую файловую систему на ОС AIX.

Шрикант Шринивазан, разработчик программного обеспечения, IBM

Шрикант Шринивазан (Srikanth Srinivasan) работает разработчиком программного обеспечения для IBM India Systems and Technology Labs. Область его интересов - это параллельные файловые системы и ядра ОС Linux. Как член команды разработчиков IBM General Parallel File systems (GPFS) он участвует в создании различных дополнений для GPFS. Шрикант получил степень бакалавра в проектировании электроники и коммуникаций в университете города Мадрас (University of Madras), Индия. Ему можно написать по адресу ssrikanth@in.ibm.com.



22.09.2008

Введение

AIX 5L™ - это отмеченная наградами операционная система, которая предлагает превосходную масштабируемость, надежность и управляемость. Эта операционная система является основной для всех UNIX-серверов IBM, в том числе и для самых мощных.

Файловую систему можно определить как часть программного обеспечения, которая помогает в хранении, организации и поиске данных на физических носителях, таких как жесткий диск, CD-ROM или других. Код для такой организации данных должен быть переносимым. Однако в реальном мире каждая операционная система предоставляет свои собственные интерфейсы для выполнения каких-либо операций файловой системы, поэтому ей необходимо, чтобы программное обеспечение нижнего уровня предоставляло результаты своей работы в формате, который она понимает. Эти интерфейсы различаются в разных операционных системах и должны экспортироваться файловой системой для их поддержки в разных определенных операционных системах.

В этой статье описана структура файловой системы ОС AIX®, а также принципы работы подсистемы ввода/вывода и важнейшие концепции файловой системы. Также в статье кратко затронуты интерфейсы и методы, необходимые при разработке новой файловой системы или при портировании уже существующей файловой системы на ОС AIX.

AIX, как и многие другие варианты UNIX, понимает файловую систему как расширение ядра. Для понимания этой статьи нужны базовые знания о программировании для UNIX и базовых концепциях устройства файловой системы, а также пригодятся навыки написания расширений для ядра ОС AIX.

Понимание логической файловой системы и виртуальной файловой системы

Уровень логической файловой системы является абстрактным уровнем, на котором пользователь может выполнять различные операции с файлами, такие как чтение, запись и так далее. Интерфейс логической файловой системы поддерживает семантику доступа к файлу как в UNIX-системах. Логическая файловая система ведет себя как расширенная виртуальная система, которая инкапсулирует в себе различные файловые системы, предоставляющие ядру дерево каталогов файловой системы. Логическая файловая система также ответственна за управление таблицей открытых файлов, принадлежащей ядру, и за файловые дескрипторы для каждого файла, открытого каким-либо процессом.

Виртуальная файловая система - абстракция основной физической файловой системы. Виртуальная файловая система предоставляет стандартный набор интерфейсов, поддержка которых нужна для того, чтобы файловая система поддерживалась ОС AIX. Виртуальная файловая система соединяет различные физические файловые системы и логическую файловую систему, делая их доступными для остальных компонентов ОС как корректное дерево каталогов.

Каждая отдельная смонтированная файловая система представляется структурой виртуальной файловой системы. Виртуальная файловая система может быть физической файловой системой, сетевой файловой системой или логической файловой системой (например, ramfs которая не имеет реального запоминающего физического устройства). Рисунок 1 показывает внутреннюю структуру файловой системы AIX.

Рисунок 1. Структура файловой системы AIX
Структура файловой системы AIX

Как показано в листинге 1, виртуальная файловая система хранится как связанный список структур struct vfs, связанных через поле vfs_next.

Листинг 1. Структура для описания виртуальной файловой системы
<sys/vfs.h>

struct vfs {
  struct vfs      *vfs_next;      
  struct gfs      *vfs_gfs;       
  struct vnode    *vfs_mntd;      
                                        
  struct vnode    *vfs_mntdover;  
                                        
  struct vnode    *vfs_vnodes;    
  int             vfs_count;      
  caddr_t         vfs_data;       
  unsigned int    vfs_number;     
  int             vfs_bsize;      
#ifdef  _SUN
  short           vfs_exflags;    
  unsigned short  vfs_exroot;     
#else
  short           vfs_rsvd1;      
  unsigned short  vfs_rsvd2;      
#endif  /* _SUN */
  struct vmount   *vfs_mdata;     
  Simple_lock     vfs_lock;       
};

Каждый элемент в списке представляет смонтированную файловою систему.

vfs_mntd
Поле vfs_mntd представляет точку монтирования vnode, куда была установлена эта файловая система. Для '/' корневой файловой системы эта точка монтирования будет называться также корневой точкой монтирования vnode.
vfs_vnodes
Поле vfs_vnodes содержит связанный список всех vnodes для конкретной смонтированной файловой системы.
vfs_lock
Поле vfs_lock используется для обеспечения последовательного доступа к vnode.
vfs_gfs
Поле vfs_gfs указывает на структуру struct gfs для соответствующей файловой системы.

Поле struct gfs содержит информацию относительно файловой системы, которая независима от уже установленных образцов файловых систем. Эта структура содержит все особенности файловой системы, как показано в листинге 2 ниже. Каждая файловая система, зарегистрированная операционной системой, имеет только одну struct gfs, в то время как для каждого смонтированного образца этой файловой системы полагается по одной структуре struct vfs. Важными членами структуры struct gfs являются gfs_ops и gn_ops, которые представляют действия виртуальной файловой системы и действия объекта vnode, возможные в файловой системе. Нужно реализовать поддержку операций виртуальной файловой системы и действий vnode для того, чтобы разрабатываемая файловая система поддерживалась в ОС AIX.

Листинг 2. Структура gfs
<sys/vfs.h>

struct gfs {
  struct vfsops   *gfs_ops;
  struct vnodeops *gn_ops;
  int             gfs_type;       
  char            gfs_name[16];   
  int             (*gfs_init)(struct gfs *);  
  int             gfs_flags;      
  caddr_t         gfs_data;       
  int             (*gfs_rinit)(void);
  int             gfs_hold;       
};

vnode, gnode и inode

Структура vnode представляет собой открытый объект в файловой системе. Каждая попытка создать или открыть файл приводит к созданию объекта vnode для файла. Если структура vnode уже существует, количество ссылок на файл увеличивается. Структура vnode существует в файловой системе до тех пор, пока не закроется последний процесс, использующий файл, для которого vnode была создана, таким образом число ссылок на этот файл становится равным нулю. Главная функция vnode состоит в преобразовании пути к реальному объекту в основной файловой системе. К объекту может существовать больше одного пути:

  • если файловая система была смонтирована больше чем один раз в разных точках монтирования;
  • при наличии жестких ссылок (указатель непосредственно на данные на физическом устройстве) или программных ссылок (soft link) на объект.

Однако попытки открытия синонимичных путей не приводят к созданию множества vnodes. На один объект gnode могут ссылаться много объектов vnodes, только когда смонтировано более одного экземпляра конкретной файловой системы. Для любого заданного экземпляра файловой системы существует по меньшей мере один vnode, ссылающийся на gnode. В листинге 3 показана структура vnode.

Листинг 3. Структура vnode
<sys/vnode.h>

struct vnode {
  ushort         v_flag;         
  ushort         v_flag2;        
  ulong32int64_t v_count; 
  int            v_vfsgen;       
  Simple_lock    v_lock;     
  struct vfs     *v_vfsp;     
  struct vfs     *v_mvfsp;    
                               
  struct gnode   *v_gnode;  
  struct vnode   *v_next;   
  struct vnode   *v_vfsnext; 
  struct vnode   *v_vfsprev; 
  union v_data {
    void         * _v_socket;      
    struct vnode * _v_pfsvnode;     
  } _v_data;
  char           *v_audit;        
};
v_vfsp
Поле v_vfsp представляют содержимое объекта vfs. Если vnode является точкой монтирования для какой-либо файловой системы, то поле v_mvfsp содержит struct vfs для этой файловой системы.
v_gnode
Поле v_gnode указывает на gnode структуры vnode. Каждый физический объект в файловой системе представлен уникальным gnode. В отличие от vnode, для одного объекта существует только один gnodeнезависимо от числа монтированных экземпляров файловой системы. Есть однозначное соответствие между gnode и файлом на физическом диске.

Открытый объект (файл) в каждом смонтированном экземпляре файловой системы имеет уникальный vnode. Таким образом, можно сказать, что vnode предназначен для хранения открытой, специфичной для каждой отдельной файловой системы информации, а gnode инкапсулирует собственно сам объект.

Листинг 4. Структура gnode
<sys/vnode.h>

struct gnode {
  enum vtype      gn_type;             
  short           gn_flags;              
  vmid_t          gn_seg;                 
  long32int64_t   gn_mwrcnt;      
  long32int64_t   gn_mrdcnt;     
  long32int64_t   gn_rdcnt;     
  long32int64_t   gn_wrcnt;     
  long32int64_t   gn_excnt;     
  long32int64_t   gn_rshcnt;    
  struct vnodeops *gn_ops;
  struct vnode    *gn_vnode; 
  dev_t           gn_rdev;       
  chan_t          gn_chan;       
  Simple_lock     gn_reclk_lock;  
  int             gn_reclk_event; 
  struct filock   *gn_filocks;     
  caddr_t         gn_data;       
};

Некоторые важные члены структуры gnode :

gn_vnode
Поле gn_vnode указывает на список vnodes для текущего gnode.
gn_ops
Поле gn_ops хранит стандартные vnode-операции, возможность реализации которых нужно включить в свою файловую систему.
gn_data
Поле gn_data указывает на зависящую от файловой системы информацию об объекте (обычно об inode).

Объект inode - структура данных в файловой системе, которая представляет информацию, связанную с файлом и действительную только для текущей, рассматриваемой файловой системы. Каждый gnode имеет связанный с ним inode в файловой системе. gnode хранит общие признаки для файла, а inode разработан для хранения информации о файле, характерной для конкретного экземпляра файловой системы. inode инкапсулирован внутри элемента gn_data объекта gnode.

AIX не содержит никаких интерфейсов для разработки inode, поэтому его создание и обработка ложатся на плечи разработчика. Обычно inode предоставляет информацию о владельце файла (пользователь или группа пользователей), информацию о правах доступа к файлу, времени создания или модификации файла, и т.п.

Операции виртуальной файловой системы

vnode и структура виртуальной файловой системы предоставляют определенные интерфейсы, более известные как операции виртуальной файловой системы и операции vnode. Операции виртуальной файловой системы используются для поддержки операций управления файловой системой, в том числе для монтирования и демонтирования файловой системы, синхронизация резервной копии файловой системы при ее демонтировании и запроса дополнительных возможностей, предоставляемых файловой системой. Листинг 5показывает операции монтирования и демонтирования.

Все операции виртуальной файловой системы возвращают 0 в случае своего успешного выполнения. В противном случае возвращается номер ошибки из файла /usr/include/sys/errno.h.

Листинг 5. Операции монтирования и демонтирования
int (*vfs_mount)(struct vfs *, struct ucred *);

int (*vfs_unmount)(struct vfs *, int, struct ucred *);
vfs_mount
Эта процедура вызывается уровнем логической файловой системы для запуска монтирования требуемой файловой системы. Ей передают инициализированный экземпляр структуры struct vfs, который процедура заполняет и возвращает. Метод vfs_mount возвращает 0 в случае успешного монтирования и номер ошибки в случае неудачного.
vfs_umount
Эта процедура вызывается для демонтирования файловой системы или явным вызовом команды umount или в ходе процесса выключения системы.

Процедура vfs_sync, показанная в листинге 6 ниже, вызывается для синхронизации данных файловой системы, находящихся в оперативной памяти, с ее резервной копией.

Листинг 6. Операции синхронизации
#if defined(__64BIT_KERNEL) || defined(__FULL_PROTO)
  int (*vfs_sync)(struct gfs *);
#else
  int (*vfs_sync)();
#endif

int (*vfs_syncvfs)(struct gfs *, struct vfs *, int, struct ucred *);
vfs_sync
Этой процедуре передают структуру struct gfs, которая описывает тип файловой системы, а не struct vfs, как в других операциях виртуальной файловой системы. Программа sync вызывается однократно для каждого типа файловой системы, а не для каждого экземпляра vfs.
vfs_syncfs
Процедура vfs_syncfs используется для синхронизации заданного экземпляра смонтированной файловой системы, тогда как vfs_sync вызывается только раз для всех смонтированных экземпляров какого-то одного типа файловой системы. vfs_syncfs может быть вызван с несколькими опциями для дополнительного контроля над процессом синхронизации.
Листинг 7. Управление списком предоставляемых квот и списком контроля доступа
int (*vfs_quotactl)(struct vfs *, int, uid_t, caddr_t, struct ucred *);

int (*vfs_aclxcntl)(struct vfs *, struct vnode *, int, struct uio *, size_t *, 
                    struct ucred *);
vfs_quotactl
Уровень логической файловой системы вызывает vfs_quotactl для выполнения связанных с квотой операций управления файловой системой.
vfs_aclxcntl
Процедура vfs_aclxcntl вызывается для выполнения различных списков контроля доступа (ACL) для определенных операций управления файловой системой. Если файловая система имеет квоты и поддержку ACL, тогда она должна придерживаться структуры, определенной для файловой системы AIX.

Методы возвращает 0 в случае успешной операции. Если операции не поддерживаются основной файловой системой, процедуры вернут EINVAL.

Листинг 8. Другие операции управления
int (*vfs_root)(struct vfs *, struct vnode **, struct ucred *);

int (*vfs_statfs)(struct vfs *, struct statfs *, struct ucred *);

int (*vfs_vget)(struct vfs *, struct vnode **, struct fileid *, struct ucred *);

int (*vfs_cntl)(struct vfs *, int, caddr_t, size_t, struct ucred *);
vfs_root
Метод vfs_root используется для получения корневого указателя vnode файловой системы. Метод возвращает экземпляр vnode в структуре struct vnode ** .
vfs_statfs
Метод vfs_statfs используется для получения характеристик файловой системы. В случае успешного выполнения структура struct statfs заполняется подходящими характеристиками файловой системы. Таблица 1 описывает различные характеристики файловой системы.
Таблица 1. Характеристики файловой системы
f_blocksОпределяет число блоков
f_filesОпределяет общее число экземпляров файловой системы
f_bsizeОпределяет размер блока файловой системы
f_bfreeОпределяет число свободных блоков
f_ffreeОпределяет число свободных объектов файловой системы
f_fnameОпределяет 32-байтную строку с именем файловой системы
f_fpackОпределяет 32-байтную строку с идентификатором блока
f_name_maxОпределяет максимальную длину имени объекта
vfs_vget
Метод vfs_vget используется для получения vnode для объекта, принадлежащего файловой системе, который идентифицируется виртуальной файловой системой и fileid. fileid создается при выполнении операции vn_fidvnode . Если vnode для соответствующего объекта существует на уровне виртуальной файловой системы, число ссылок увеличивается и возвращается vnode. Или создается новый vnode при помощи службы ядра vn_get, ссылающейся на объект, а затем, после своего создания, возвращается, причем число ссылок на этот объект становится равным 1. Параметр fileid используется для однозначной идентификации объекта в файловой системе.
vfs_cntl
Метод vfs_cntl используется для реализации различных определенных пользователем операций управления. Логическая файловая система запускает процедуру vfs_cntl с идентификатором операции управления и необходимыми аргументами. vfs_cntl запускается подпрограммой fscntl. Пользователь может определить максимум 32768 операций управления.

Операции vnode

Наряду с операцииями виртуальной файловой системы структура файловой системы AIX предлагает набор интерфейсов для выполнения различных операций с файловой системой, таких как чтение, запись и прочие. Эти интерфейсы называются операциямиvnode. Ядро AIX 5.3 определяет все 56 интерфейсов для различных операций с файловой системой. Необязательно реализовывать поддержку их всех - это зависит от того, какой цели служит драйвер разрабатываемой файловой системы. Некоторые из расширений предназначены только для предоставления обратной совместимости со старыми версиями ОС AIX, в то время как другие интерфейсы предназначены для помощи менеджеру виртуальной памяти в процессе листания. Остальная часть подпрограмм обеспечивают базовую поддержку различной семантики доступа к файлам в UNIX.

Листинг 9. Операции создания, переименования и удаления файлов
int (*vn_link)(struct vnode *dvp, struct vnode *vp, char *name, struct ucred *cred);

int (*vn_mkdir)(struct vnode *dvp, char *name, int32long64_t mode, struct ucred *cred);

int (*vn_mknod)(struct vnode *dvp, caddr_t name, int32long64_t mode, dev_t dev,
                struct ucred *cred);
                
int (*vn_remove)(struct vnode *vp, struct vnode *dvp, char *name, struct ucred *cred);

int (*vn_rename)(struct vnode *srcVp, struct vnode *srcDvp, caddr_t oldName,
                 struct vnode *destVp, struct vnode *destDvp, caddr_t newName,
                 struct ucred *cred);
                 
int (*vn_rmdir)(struct vnode *vp, struct vnode *dvp, char *name, struct ucred *cred);

Эти процедуры используются для создания, переименования и удаления объектов в основной файловой системе. Все процедуры принимают в качестве входного параметра по крайней мере один родительский каталог vnode, в котором выполняется операция над объектом. Уровень логической файловой системы будет гарантировать, что родительский каталог vnode не находится в файловой системе только для чтения. Ниже приводится описание этих процедур:

vn_link
Метод vn_link вызывается для создания жесткой ссылки (указатель непосредственно на данные на физическом устройстве) на уже существующий объект. Кроме того, программа создает жесткую ссылку на каталог dvp с именем name для vnodevp. Логическая файловая система гарантирует, что объекты, на которые ссылаются dvp и vp-параметры, находятся в той же виртуальной файловой системе.
vn_mkdir
Метод vn_mkdir используется для создания нового каталога с указанным именем в каталоге, заданном vnodedvp. Права для доступа к каталогу передаются с переменной int32long64_t и имя нового каталога задается параметром name.
vn_mknod
Метод vn_mknod используется для создания нового файла с именем name в каталоге dvp. Параметр mode задает тип файла (обычные, специальные файлы) и права на доступ к файлу как комбинацию битовых масок. В случае специальных файлов (например, файлы устройств), dev-параметр хранит номер устройства.
vn_remove
Метод vn_remove вызывается логическим уровнем файловой системы для подпрограммы unlink. Эта процедура используется для удаления объекта из каталога или ссылки, заданной vnodevp, которая находится в каталоге dvp. Необходимо чтобы пользователь вызвал функцию vn_rele для освобождения ссылки на vnode. Если это была последняя ссылка на объект, физические ресурсы диска, удерживаемые файлом, освободятся.
vn_rename
Метод vn_rename вызывается логической файловой системой для переименования файла или каталога. Исходный объект (srcName), находящийся в каталоге srcDvp, задается при помощи ссылки - vnodesrvVp. Новое имя задается при помощи параметра newName и новый конечный каталог задается параметром destDvp. В случае если объект с таким именем уже существует в указанном конечном каталоге, vnode этого объекта передается в destVp.
vn_rmdir
Метод vn_rmdir используется для удаления каталога, задающегося при помощи объекта vnodevp, находящегося в каталоге dvp. Логическая файловая система гарантирует, что vnode, который будет удален, будет каталогом, причем не текущим рабочим каталогом и не корневым каталогом. Требования для удаления каталога: он должен быть пустым и не должен содержать никаких объектов.
Листинг 10. Операции поиска и управления файлами
int (*vn_lookup)(struct vnode *dvp, struct vnode **vpp, char *name,
                 int32long64_t vflag, struct vattr *attr, struct ucred *cred);
                 
int (*vn_fid)(struct vnode *vp, struct fileid *fidp, struct ucred *cred);
vn_lookup
Логическая файловая система использует этот метод для поиска файла с именем name в каталоге dvp. Если таковой будет найден, в структуре vpp вернется vnode этого файла.

При каждом выполнении процедуры поиска файла число ссылок на него увеличивается. Поэтому вы должны позаботиться, чтобы в конце успешного поиска сокращать число ссылок на файл. Если поле attr не нулевое, программа должна также вернуть атрибуты файла в параметре attr.

vn_fid
Метод vn_fid вызывается для создания файлового идентификатора для vnodevp. Этот файловый идентификатор используется методом vfs_vget для получения vnode того объекта, на основе которого он был создан. Отсюда следует, что файловый идентификатор должен содержать достаточно информации для успешной идентификации правильного объекта.
Листинг 11. Операции для доступа к файлам
int (*vn_open)(struct vnode *vp, int32long64_t flag, ext_t dev, caddr_t * vinfo,
               struct ucred *cred);
               
int (*vn_create)(struct vnode *dvp, struct vnode **vpp, int32long64_t flags,
                 caddr_t name, int32long64_t mode, caddr_t *vinfo,
                 struct ucred *cred);
                 
int (*vn_hold)(struct vnode *vp);

int (*vn_rele)(struct vnode *vp);

int (*vn_close)(struct vnode *vp, int32long64_t flag, caddr_t vinfo,
                struct ucred *cred);
                
int (*vn_map)(struct vnode *vp, caddr_t addr, uint32long64_t length,
              uint32long64_t offset, uint32long64_t flags, struct ucred *cred);
              
int (*vn_unmap)(struct vnode *vp, int32long64_t flag, struct ucred *cred);
vn_open
Этот метод используется, чтобы открыть файл с параметрами, заданными в параметре flag. Объект vnode файла, который должен быть открыт, передается в параметре vp.

Обычно объект vnode создается во время поиска или создания файла (если команда на открытие запускалась с флагом O_CREAT). Сам разработчик решает, какие действия должны быть выполнены во время выполнения vn_open. Успешная процедура открытия приводит к увеличению числа ссылок на этот файл. В случае открытия файлов устройств параметр dev содержит информацию, специфическую для данного устройства.

vn_create
Этот метод вызывается для создания обычного файла с именем name в каталоге dvp. Права доступа для создаваемого файла передаются в параметре mode. Параметр flag сохраняет значение флага при успешном открытии файла. В случае успешного создания файла создается новый экземпляр vnode в виртуальной файловой системе и число ссылок на этот файл устанавливается в 1. Только что созданный объект vnode возвращается в параметре vpp.
vn_hold / vn_rele
Метод vn_hold используется для увеличения числа ссылок на объект vnode. Он гарантирует, что объект vnode не будет случайно удален в обход вызывающей программы без ее уведомления. После того как vn_hold отработает, необходимо сразу запустить vn_rele чтобы убедиться, что число ссылок уменьшилось.
vn_close
Метод vn_close вызывается подпрогаммой сlose для закрытия vnodevp. Эту процедуру вызывать можно только после того как была удалена последняя ссылка на vnode. После того как для объекта vnode был вызван метод vn_close, с ним больше нельзя выполнять никаких действий.
vn_map
Метод vn_map используется для проверки запросов на размещение файла в памяти, полученных из вызова mmap или из вызова shmat для файла, на который ссылается vnodevp. Параметр addr задает адрес в запрашиваемом адресном пространстве процесса, в котором находится объект. Параметры length, offset и flags задают длину списка запросов, смещение в пределах файла, с которого надо отображать файл, и битовую маску флагов, для определения типа размещения.

Предполагается, что основная файловая система хранит поле gn_seg структуры gnode для размещаемого файла. Уровень логической файловой системы создает объект в виртуальной памяти, если он еще не существует, и увеличивает число ссылок на него.

vn_unmap
Процедура vn_unmap используется для удаления файла из адресного пространства, куда до этого момента он был помещен. Параметр vnodevp задает файл, который должен быть удален из памяти. Параметр flag устанавливает битовую маску, задающую тип размещения.

Реализация файловой системы должна использовать для обеих процедур vn_map и vn_unmapтолько операции, определенные файловой системой. Уровень логической файловой системы несет ответственность за выполнение операций на уровне виртуальной памяти.

Листинг 12. Операции для обработки атрибутов
int (*vn_access)(struct vnode *vp, int32long64_t mode, int32long64_t who,
                 struct ucred *cred);
                 
int (*vn_getattr)(struct vnode *vp, struct vattr *attr, struct ucred *cred);

int (*vn_setattr)(struct vnode *vp, int32long64_t cmd, int32long64_t arg1,
                  int32long64_t arg2, int32long64_t arg3, struct ucred *cred);
vn_access
Метод vn_access используется логической файловой системой для проверки доступа к объекту vnodevp. Этот метод используется для реализации процедуры доступа и проверки прав доступа на чтение, запись, выполнение и т.д.

Параметр who определяет пользователя, для которого должна быть сделана проверка. Параметр mode задает тип проверки, которую надо выполнить.

vn_getattr
Метод vn_getattr используется для получения различных файловых атрибутов (определенных в структуре vattr ) для указанного объекта vnode. Эта процедура поддерживает подпрограммы stat, fstat, и lsta.
vn_setattr
Метод vn_setattr используется для установки различных файловых атрибутов (определенных в структуре vattr ) для указанного объекта vnodevp. Значения аргументов arg1, arg2, и arg3 зависят от параметра cmd.

В таблице 2 показаны значения этих параметров в зависимости от значения команды. Эта процедура поддерживает подпрограммы chmod, chownx и utime.

Таблица 2. Возможные значения команд для vn_setattr
КомандаV_OWNV_UTIMEV_MODE
arg 1int fag;int flag;int mode;
arg 2int uid;timestruct_t *atime;не используется
arg 3int gid;timestruct_t *mtime;не используется
Листинг 13. Операции модификации данных
int (*vn_fclear)(struct vnode *vp, int32long64_t flags, offset_t offset, offset_t len,
                 caddr_t vinfo, struct ucred *cred cred);
                 
int (*vn_fsync)(struct vnode *vp, int32long64_t flags, int32long64_t fd,
                struct ucred *cred);
                
int (*vn_ftrunc)(struct vnode *vp, int32long64_t flags, offset_t length, caddr_t vinfo,
                 struct ucred *cred);
                 
int (*vn_rdwr)(struct vnode *vp, enum uio_rw op, int32long64_t flag,
               struct uio *uiop, caddr_t dev, struct vattr *attr,
               struct ucred *cred);
               
int (*vn_lockctl)(struct vnode *vp, offset_t offset, struct eflock *lckdata,
                  int32long64_t cmd, int (*retry_fcn)(), ulong *retry_id,
                  struct ucred *cred);
vn_fclear
Процедура vn_fclear используется для очистки части файла и возвращении этого очищенного пространства основной файловой системе. Параметр offset задает позицию, с которой должна начаться очистка файла. Параметр len определяет количество байтов, которые надо очистить. Флаг, с которым был открыт файл, передается в параметре flag. Логическая файловая система обновляет размер файла с учетом количества очищенных байтов.
vn_fsync
Методvn_fsync вызывается для того, чтобы сделать запрос к файловой системе сохранить все измененные данные в резервное хранилище для выбранного vnode vp. Вызов этой процедуры необходимо производить синхронно, чтобы вызывающая программа могла быть уверена, что весь ввод/вывод осуществлен успешно. Параметр flag задает различные опциональные возможности синхронизации. Различные опциональные возможности синхронизации доступны в файле-заголовке fcntl.h.
vn_ftrunc
Метод vn_ftrunc вызывается для сокращения файла, определенного vnodevp. Параметр length определяет длину файла после его сокращения. Если новая длина меньше чем предыдущая длина, тогда выполняется уменьшение файла до требуемого размера. Если новая длина больше чем исходная, к файлу добавляются нули, чтобы увеличить его размер до требуемого.

Когда усечение завершено, удаленные из файла блоки возвращаются файловой системе и информация о файле обновляется. Операция не будет выполнена, если невозможно очистить выбранный диапазон.

vn_rdwr
Метод vn_rdwr - один из наиболее востребованных vnode методов. Метод vn_rdwr выполняет операции файлового ввода/вывода для файла, заданного по vnodevp. Параметр op определяет тип запроса - на операцию чтения (UIO_READ) или на операцию записи (UIO_WRITE). Параметр uio хранит пользовательскую структуру данных, определяющую буфер памяти, из которого будут записаны данные или в который будет произведено чтение. Параметр dev хранит специфическую информацию об устройстве, если ввод/вывод будет направлен в какое-либо устройство. Если параметр attr не равняется NULL, то атрибуты файла должны возвращаться в этом параметре.
vn_lockctl
Метод vn_lockctl используется для блокирования каких-либо записей в файле, заданном при помощи vnodevp. Параметр struct eflock (lckdata) передает информацию для выполнения блокировки требуемой записи. Параметр cmd определяет тип выполняемой операции блокировки.

Дополнительную функцию для повторения блокировки можно передать в параметре retry_fcn, чтобы повторить процедуру блокировки, если блокировка не была выполнена сразу по какой-либо причине. Параметр retry_id хранит значение, которое соотносит функцию для повторной блокировки с определенным набором блокировок. Реализация блокировки выполняется процедурой, предоставляемой операционной системой, common_reclock(), которая скрывает сложность операции блокировки от конечного пользователя.

Листинг 14. Операции расширения
int (*vn_ioctl)(struct vnode *vp, int32long64_t cmd, caddr_t arg, size_t flags,
                ext_t dev, struct ucred *cred);
                
int (*vn_readlink)(struct vnode *vp, struct uio *uio, struct ucred *cred);

int (*vn_select)(struct vnode *vp, int32long64_t corel_id, ushort req_event, 
                 ushort *ret_event, void (*notify)(), caddr_t vinfo,
                 struct ucred *cred);
                 
int (*vn_symlink)(struct vnode *dvp, char *link, char *target, struct ucred *cred);

int (*vn_readdir)(struct vnode *vp, struct uio *uio, struct ucred *cred);
vn_ioctl
Метод vn_ioctl используется логической файловой системой для выполнения различных определенных пользователем операций по управлению процессами ввода/вывода для специальных файлов. Если файловая система поддерживает специальные файлы, информация передается выбранному драйверу устройства, на который ссылается vnodevp.

Параметр cmd определяет, для какого IOCTL (IO Control) была вызвана эта процедура. Параметр arg хранит необходимые аргументы.

vn_readlink
Метод vn_readlink используется для чтения содержимого символьной ссылки для vnodevp. Логическая файловая система отвечает за нахождение vnode, соответствующего ссылке. Эта процедура просто считывает блоки данных по этой ссылке.
vn_select
Метод vn_select используется логической файловой системой для опроса vnodevp с целью определить, готов ли он к немедленной процедуре ввода/вывода. Этот метод используется для реализации подпрограмм выборки и опроса. Реализация файловой системы может поддерживать такие конструкции, как устройства и каналы, которые поддерживают семантику выбора.

Служба ядра fp_select предоставляет больше информации о запросах на выборку и опросах. Параметр req_event определяет события, которые надо обработать, и в параметре notify указывается метод, который вызывается при срабатывании события.

vn_symlink
Метод vn_symlink используется для создания символической ссылки на объект, абсолютный адрес которого задается параметром target. Создается новая ссылка с названием linkname в каталоге dvp.
vn_readdir
Метод vn_readdir используется для считывания содержимого каталога, на который указывает vnodevp. Записи в этом каталоге возвращаются как struct dirent в из структуры uio. Чтение начинается с первого элемента каталога, находящегося по адресу, указанному в uio_offset структуры struct uio.

Когда буфер uio заполняется, значение параметра uio_offset заменяется начальным адресом другого элемента каталога, который не попал в предыдущий буфер. В поле uiop->uio_resid записывается количество байтов, которые были переданы в структуру uio. Завершение операции чтения определяется передачей пустого значения в структуру uio .

Листинг 15. Операции с буфером
int (*vn_strategy)(struct vnode *vp, struct buf *buf, struct ucred *cred);
vn_startegy
Метод vn_startegy отвечает за чтение данных из блочного устройства. Этот метод предоставляет серверам интерфейс, ориентированный на чтение блоками, для обеспечения эффективных операций со страницами. Параметр vnodevp передает файловую информацию о блочном устройстве, с которого надо считать данные. Параметр buf содержит структуру struct buf, которая задает буфер для считывания данных.
Листинг 16. Операции, связанные с безопасностью
int (*vn_revoke)(struct vnode *vp, int32long64_t cmd, int32long64_t flags,
                 struct vattr *attr, struct ucred *cred);
                 
int (*vn_getacl)(struct vnode *vp, struct uio *uio, struct ucred *cred);

int (*vn_setacl)(struct vnode *vp, struct uio *uio, struct ucred *cred);

int (*vn_getpcl)(struct vnode *vp, struct uio *uio, struct ucred *cred);

int (*vn_setpcl)(struct vnode *vp, struct uio *uio, struct ucred *cred);

int (*vn_seek)(struct vnode *vp, offset_t *offset, struct ucred *cred);
vn_revoke
Метод vn_revoke используется для отмены всех прав доступа к файлу, определяемому параметром vnodevp. Параметр cmd определяет, был ли открыт данный файл вызываемым процессом, и может иметь следующие значения:
  • 0—Процесс не открывал этот файл.
  • 1—Процесс открыл этот файл.
  • 2—Процесс открыл этот файл, и число ссылок на него больше единицы.
vn_getacl / vn_setacl
Методы vn_getacl / vn_setacl, используемые логической файловой системой, чтобы получить список контроля доступа (ACL) для файла, необходимы при реализации подпрограммы getacl. Метод vn_setacl нужен, чтобы установить список контроля доступа (ACL) для файла. Эти методы являются основой подпрограмм chacl, chown, chmod, и statacl.
vn_getpcl / vn_setpcl
Методы vn_getpcl / vn_setpcl, используемые логической файловой системой, чтобы получить список контроля привилегий (privilege control list (PCL)) для файла, необходимы для реализации подпрограммы getpcl. Метод vn_setpcl используется для установки списка контроля привилегий для файла и обеспечивает функционирование подпрограммы setpcl.
vn_seek
Метод vn_seek используется для проверки смещения в операции seek. Объект vnode, для которого выполняется операция seek, передают в параметре vp, а величину смещения в файле передают в параметре offset. Обычно, если смещение больше нуля, но меньше чем максимальная длина файла, программа возвращает EOK; в противном случае она возвращает EINVAL.
Листинг 17. Вызов операции внешней разметки страниц
int (*pagerBackRange)(struct gnode *gnp, offset_t offset, caddr_t dest, 
                      size_t *nBytesOfRange, size_t *nBytesBacked, uint *flags);
                      
int64_t (*pagerGetFileSize)(struct gnode *gnp);

void (*pagerReadAhead)(struct gnode *gnp, vpn_t pFault, vpn_t * pFirst,
                       vpn_t *nPage, vpn_t *pTripWire, boolean_t tripWire);
                       
void (*pagerReadWriteBehind)(struct gnode *gnp, int64_t offset, int64_t length,
                             uint flags);
                             
void (*pagerEndCopy)(struct gnode *gnp, offset_t offset, size_t nBytesMoved,
                     size_t nBytesBacked, uint flags);

AIX обеспечивает поддержку программ внешней разметки страниц, которые запрашивает менеджер виртуальной памяти, когда подкачивает файлы в оперативную память и выгружает их из нее для текущей файловой системы.

pagerBackRange
Процедура обратного вызова, используется для того, чтобы запросить файловую систему перенести используемые страницы памяти в резервное хранилище данных. За вызовом pagerBackRange следует автоматический вызов pagerEndCopy .
pagerEndCopy
Метод pagerEndCopy выполняет дальнейшую обработку данных, скопированных в резервное хранилище.
pagerReadAhead, pagerReadWriteBehind
Процедура обратного вызова pagerReadWriteBehind помогает менеджеру виртуальной памяти взаимодействовать с файловой системой для организации упреждающего чтения и отложенной записи.

Все эти операции обратного вызова являются опциональными. Разработчик сам решает, какие операции ему необходимы, и реализует их.

Кроме этих методов vnodeops_t предоставляет набор интерфейсов, называемый 421 extensions, обеспечивающих обратную совместимость с AIX версии 4.2.1

Вспомогательные программы - file system helpers и mount helpers

Чтобы обеспечить поддержку множества файловых систем, многие из методов файловой системы этих систем не выполняют команды самостоятельно. Вместо этого они собирают аргументы, переданные в процедуру, и перенаправляют их в системные программы файловой системы, которые и выполняют обработку команды. Эти специальные программы также называются помощниками файловой системы(file system helpers) и помощниками монтирования (mount helpers); разработчик файловой системы обязательно должен обеспечить наличие этих программ.

Программы-помощники находятся в каталоге /sbin/helpers/<vfs_type>, гдеvfs_typeсоответствует типу файловой системы, для которой предназначена команда. Имя программы должно соответствовать имени выполняемой команды.

Команда mount является внешним интерфейсом для подпрограммы помощника монтирования, предоставляемой каждой файловой системой. Программы, которые на стороне сервера (внутренний интерфейс) предоставляют команды для установки и демонтирования файловых систем, и есть помощники монтирования. Программа монтирования на стороне клиента через внешний интерфейс собирает различные параметры, которые будут переданы во внутренний интерфейс. Потом она изучает файл /etc/filesystems, чтобы определить тип виртуальной файловой системы у целевой файловой системы. Она вызывает /sbin/helpers/<vfs_type>/mount с собранными параметрами для выполнения команды. Типичная запись в конфигурационном файле /etc/filesystems для файловой системы похожа на листинг 18.

Листинг 18. Запись о файловой системе в файле /etc/filesystems
/data:
    dev             = /dev/fslv00
    vfs             = jfs2
    log             = /dev/hd8
    mount           = true
    options         = rw

Атрибут vfs определяет тип виртуальной файловой системы для данной файловой системы (<vfs_type>). Атрибут mount определяет поведение по умолчанию при установке для этой файловой системы. Он может принимать следующие значения.

AutomaticФайловая система монтируется автоматически при запуске операционной системы
FalseФайловая система по умолчанию не монтируется
ReadonlyФайловая система монтируется только для чтения
TrueФайловая система монтируется командой mount all и демонтируется командой unmount all
NodenameЗначение Nodename используется командой mount для определения того, какой узел в сети содержит удаленную файловую систему. Если атрибут отсутствует, тогда монтируется локальная файловая система

Атрибут options определяет остальные дополнительные параметры, которые будут переданы процессору, осуществляющему монтирование. Команды mount и unmount имеют по шесть параметров; четыре первых параметра у них общие, два последних параметра у каждой команды свои.

Создание и конфигурация файловой системы

Файловая система в AIX создается как расширение ядра. Ядро поддерживает список зарегистрированных типов активных файловых систем. Чтобы операционная система AIX поддерживала разрабатываемую файловую систему, она должна быть зарегистрирована в ОС AIX. AIX предоставляет две службы ядра, gfsadd и gfsdel, для добавления и удаления файловой системы.

Каждая файловая система должна обладать процедурой конфигурации, которую можно было бы вызвать для конфигурации расширения ядра как файловой системы. Эта процедура должна заполнять информацией о файловой системе структуру struct gfs и вызывать gfsadd. Служба ядра gfsadd использует информацию в struct gfs для регистрации этой файловой системы в глобальной таблице файловых систем и вызова процедуры инициализации, определенной в gfs_init. Процедура инициализации делает остальную часть работы по инициализации файловой системы.

Для загрузки файловой системы со стороны пользователя необходимо:

  • Наличие пользовательской программы или сценария для вызова подпрограммы sysconfig для загрузки расширения ядра.
  • Задать процедуру конфигурации и осуществить повторный вызов подпрограммы sysconfig для конфигурации расширения ядра как виртуальной файловой системы.
  • Программа для конфигурации вызывает службу ядра gfsadd для регистрации расширения ядра как файловой системы для AIX.

Как только все шаги, перечисленные выше, сделаны, файловую систему можно считать функционирующей.

Заключение

Разработка файловой системы - один из наиболее трудоемких аспектов работы с ядром. Код для управления данными в файловой системе должен быть переносимым и платформо-независимым. Каждая операционная система имеет свои собственные механизмы ввода/вывода и интерфейсы, связывающие файловую систему с ядром. Разработчик должен хорошо понимать структуру своей операционной системы, чтобы создать файловую систему, которая будет корректно работать на ней.

Он также должен иметь базовые знания конструкции ядра и интерфейсов, которые оно предоставляет для поддержки различных операций, например, распределение памяти, процедуры копирования данных, и т.д. Нет единой библиотеки или стандарта, который определяет эти вспомогательные программы. Как правило, проектирование общих интерфейсов для таких распространенных вспомогательных программ и создание платформо-зависимых файлов, реализующих эти программы, намного упрощает жизнь разработчика. Хорошо спроектированная файловая система должна быть легко переносимой хотя бы в наиболее распространенные варианты UNIX.

Ресурсы

Научиться

Получить продукты и технологии

  • IBM trial software: ознакомительные версии программного обеспечения для разработчиков, которые загружаются прямо со страницы сообщества developerWorks.(EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=340295
ArticleTitle=Разработка файловой системы для AIX
publish-date=09222008