Главная » Ядро Linux » Объект inode

0

Объект  inode  содержит  всю информацию, которая  необходима ядру для манипуляций  с файлами и каталогами. В файловых системах  в стиле  Unix  вся информация просто  считывается из дисковых  индексов и помещается в объект  inode  подсистемы VFS. Если  файловые системы  не имеют  индексов, то эту информацию необходимо получить из других дисковых структур4.

Объект  индекса  файла  представляется с помощью структуры  struc t    inode,  которая  определена в файле  <linux/ f s.h>.  Эта  структура  с комментариями, описывающими  назначение каждого  поля,  имеет  следующий вид.

struct inode {

struct hlist_node     i_hash; struct list_head     i_list; struct list_head      i_dentry; unsigned long        i_ino; atomic_t             i_count; umode_t             i_mode; unsigned int         i_nlink; uid_t                i_uid; gid_t                i_gid; kdev_t               i_rdev; loff_t              i_size; struct timespec      i_atime; struct timespec      i_mtime; struct timespec      i_ctime;

unsigned int        i_blkbits;

/* хешированный список */

/* связанный список индексов */

/* связанный список объектов dentry */

/* номер индекса */

/* счетчик ссылок */

/* права доступа */

/* количество жестких ссылок */

/* идентификатор пользователя-владельца */

/* идентификатор группы-владельца */

/* связанное устройство */

/* размер файла в байтах */

/* время последнего доступа к файлу */

/* время последнего изменения файла */

/* время изменения индекса */

/* размер блока в битах */

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

unsigned long       i_blksize;   /* размер блока в байтах */

unsigned long       i_version;   /* номер версии */

unsigned long        i_blocks;    /* размер файла в блоках */

unsigned short       i_bytes;     /* количество использованных байтов*/ spinlock_t           i_lock;       /* блокировка для защиты полей */ struct rw_semaphore i_alloc_sem /* вложенные блокировки при

захваченной i_sem */

struct semaphore     i_sem;       /* семафор индекса */

struct inode_operations *i_op;       /* таблица операций с индексом */

struct file_operations *i_fop;      /* файловые операции */ struct super_block    *i_sb;       /* связанный суперблок */ struct file_lock     *i_flock;    /* список блокировок файлов */ struct address_space *i_mapping;  /* соответствующее адресное

пространство */

struct address_space i_data;      /* адресное пространство устройства*/ struct dquot        *i_dquot[MAXQUOTAS]; /* дисковые квоты для индекса*/ struct list_head     i_devices;   /* список блочных устройств */

struct pipe_inode_info *i_pipe;     /* информация конвейера */

struct block_device   *i_bdev;     /* драйвер блочного устройства */

unsigned long       i_dnotify_mask; /* события каталога */

struct dnotify_struct *i_dnotify;   /* информация о событиях каталога */

unsigned long        i_state;     /* флаги состояния */

unsigned long       dirtied_when /* время первого изменения */ unsigned int         i_flags;     /* флаги файловой системы */ unsigned char        i_sock;      /* сокет или нет? */

atomic_t             i_writecount; /* счетчик использования для записи*/

void                 *i_security;  /* модуль безопасности */

  u32                i_generation; /* номер версии индекса */

union {

void             *generic_ip;  /* специфическая информация

файловой системы */

} u;

};

Для  каждого  файла  в системе существует  представляющий его индекс (хотя  объект файлового индекса создается в памяти только  тогда, когда к файлу осуществляется доступ).  Это справедливо и для специальных файлов, таких  как файлы устройств или  конвейеры. Следовательно, некоторые из полей  структуры struc t  inode  относятся  к этим  специальным файлам. Например, поле  i_pip e указывает на структуру данных именованного конвейера. Если индекс не относится к именованному конвейеру, то это поле просто  содержит значение NULL. Другие  поля, связанные со специальными файлами, — это  i_devices , i_bdev, i_cdev.

Может  оказаться, что та или иная  файловая система не поддерживает тех свойств, которые присутствуют в объекте  inode . Например, некоторые файловые системы не поддерживают такого  атрибута, как время  создания файла. В этом  случае файловая  система может  реализовать это свойство как угодно.  Например, поле  i_ctim e можно сделать  нулевым или  равным значению поля  i_mtime.

Операции с файловыми индексами

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

i->i_op->truncate(i)

где  переменная  i  содержит  указатель   на  определенный  объект  файлового   индекса. В  данном   случае  для  индекса   I  выполняется  операция   trancat e () ,  которая   определена  для  файловой  системы,   в  которой   находится   указанный  файловый  индекс   i. Структура   inode_operation s  определена   в  файле     <linux/fs.h> ,    как  показано ниже.

struct inode_operations {

int (*create) (struct inode *, struct dentry *,int);

struct dentry * (*lookup) (struct inode *, struct dentry *) ;

int (*link) (struct dentry *, struct inode *, struct dentry *) ;

int (*unlink) (struct inode *, struct dentry *) ;

int (*symlink) (struct inode *, struct dentry *, const char *) ;

int (*mkdir) (struct inode *, struct dentry *, int);

int (*rmdir) (struct inode *, struct dentry *);

int (*mknod) (struct inode *, struct dentry *, int, dev_t);

int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *) ;

int (*readlink) (struct dentry *, char *, int);

int (*follow_link) (struct dentry *, struct nameidata *) ; int (*put_link) (struct dentry *, struct nameidata *) ; void (*truncate) (struct inode *) ;

int (*permission) (struct inode *, int);

int (*setattr) (struct dentry *, struct iattr *) ;

int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *) ;

int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);

ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);

ssize_t (*listxattr) (struct dentry *, char *, size_t);

int (*removexattr) (struct dentry *, const char *) ;

};

Рассмотрим указанные операции более подробно.

• in t  create(struc t  inode  *dir ,  struc t  dentry *dentry ,  in t mode)

Эта функция вызывается подсистемой VFS из системных вызовов crea t () и open () для создания нового файлового индекса, который имеет указанный режим доступа (mode) и связан с указанным элементом каталога (dentry).

• struc t  dentry *   lookup(struc t  inode  *dir ,  struc t  dentry *dentry) Эта функция производит поиск файлового индекса в указанном каталоге. Файловый индекс должен соответствовать имени файла, хранящемуся в указанном объекте элемента каталога.

• in t  link(struc t  ctentry   *old_dentry ,  struc t   inode  *dir , struc t  dentr y   *dentry)

Эта функция вызывается из системного вызова lin k ()  для создания жесткой ссылки (hard link) на файл, соответствующий элементу каталога old_dentr y в каталоге dir . Новая ссылка должна иметь имя, которое хранится в указанном элементе каталога dentry .

• in t  unlink(struc t  inode   *dir ,  struc t  dentr y   *dentry)

Эта функция вызывается из системного вызова unlin k () для удаления файлового индекса,  соответствующего элементу каталога dentr y  в каталоге dir .

• int  symlink(struct inode  *dir,  struct dentry *dentry,  const char  *symname) Эта функция вызывается из системного вызова symlink() для  создания символьной ссылки с именем symnarne на файл, которому соответствует элемент каталога dentr y  в каталоге dir .

• in t mkdir(struc t  inode  *dir ,  struc t  dentr y   *dentry ,  in t mode)

Эта функция вызывается из системного вызова mkdir () для создания нового каталога с указанным режимом доступа (mode).

• in t  rmdir(struc t  inode  *dir ,  struc t  dentr y   *dentry)

Эта функция вызывается из системного вызова rmdir () для удаления каталога на который указывает элемент каталога dentr y  из каталога dir .

• int mknod (struct inode  *dir, struct dentry *dentry,  int mode,  dev_t rdev) Эта функция вызывается из системного вызова mknod () для создания специального файла (файла устройства, именованного конвейера или сокета), информация о котором хранится в параметре rdev. Файл должен быть создан в каталоге di r с именем, указанным в параметре dentry, и режимом доступа mode.

• in t  rename(struc t  inode  *old_dir ,  struc t  dentr y   *old_dentry , struc t  inode  *new_dir,  struc t  dentr y   *new_dentry)

Эта функция вызывается подсистемой VFS для перемещения указанного элемента каталога old_dentr y  из каталога old_di r в каталог new_dir с новым именем, указанным в параметре new_dentry.

• in t  readlink(struc t  dentr y   *dentry ,   char *buffer,    in t  buflen)

Эта функция вызывается из системного вызова readlin k () для копирования не более bufle n байт полного пути, связанного с символьной ссылкой, соответствующей указанному элементу каталога, в указанный буфер.

• in t  follow_link(struc t  dentr y   *dentry ,  struc t  nameidata *nd)

Эта функция вызывается подсистемой VFS для трансляции символьной ссылки в индекс файла, на который эта ссылка указывает. На ссылку указывает указатель dentry , а результат сохраняется в структуру nameidata, на которую указывает параметр nd.

• in t  put_link(struc t  dentr y   *dentry ,  struc t  nameidata* nd)

Эта функция вызывается подсистемой VFS после вызова функции followlink ().

• void  truncat e (struc t  inode  *inode). Эта функция вызывается  подсистемой VFS для изменения размера заданного файла. Перед вызовом  поле  i_siz e указанного индекса файла должно быть установлено в желаемое значение размера.

• in t permission(struc t  inode  *inode,  in t mask)

Эта функция проверяет, разрешен ли указанный режим доступа к файлу, на который ссылается объект inode. Функция должна возвращать нулевое  значение, если доступ разрешен, и отрицательное значение кода ошибки в противном случае. Для большинства файловых систем данное поле  устанавливается в значение NULL,  и при этом используется общий метод VFS,  который просто сравнивает биты поля режима доступа файлового индекса с указанной маской. Более сложные файловые системы, которые  поддерживают списки контроля доступа (ACL), реализуют свой метод  permission ().

• in t  setattr(struc t  dentry  *dentry,   struc t  iatt r  *attr )

Эта функция  вызывается функцией  notify_change ()  для уведомления о том, что произошло "событие изменения" ("change event") после модификации  индекса.

• in t  getattr(struc t  vfsmount   *mnt,    struc t   dentry  *dentry, struc t  ksta t  *stat )

Эта функция вызывается подсистемой VFS при уведомлении, что индекс  должен быть обновлен с диска.

• in t  setxattr(struc t  dentry  *dentry,   const   char  *name, const  void  *value,    size_ t  size ,    in t  flags)

Эта функция вызывается подсистемой VFS для установки одного из  расширенных атрибутов (extended attributes)5   с именем name  в значение value для файла, соответствующего элементу каталога dentry.

• in t getxatt r (struc t dentry *dentry,    const   char  *name, void  *value,  size_ t  size )

Эта функция вызывается подсистемой VFS для копирования значения одного из расширенных атрибутов (extended attributes) с именем name в область памяти с указателем value.

•  ssize_t  listxattr(struc t  dentry  *dentry,  char  *list ,   size_t size)

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

• in t  removexattr(struc t  dentr y   *dentry ,  const char   *name) Эта функция удаляет указанный атрибут для указанного  файла.

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии