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

0

Последним  из основных объектов подсистемы VFS рассмотрим объект файла. Объект File используется для представления файлов, которые открыты процессом. Когда мы думаем о  подсистеме VFS с  точки зрения пространства пользователя, то объект файла — это то, что первое приходит в  голову. Процессы непосредственно работают с файлами, а не с суперблоками, индексами или элементами каталогов. Не удивительно, что информация,  которая содержится в объекте file, наиболее привычна (такие данные, как режим доступа или текущее смещение), а файловые операции очень похожи на знакомые системные вызовы, такие как rea d ()  и writ e ().

Объект файла — это представление открытого файла,  которое хранится в  оперативной памяти. Объект (а не сам файл) создается в  ответ на системный вызов open ()  и уничтожается в  результате системного вызова clos e () . Все вызовы, связанные с файлом, на самом деле являются методами, которые определены в таблице операций с файлом. Так как несколько процессов могут одновременно открыть и использовать один и тот  же  файл, то  для одного файла может существовать несколько объектов file. Файловый объект просто представляет открытый файл с  точки зрения процесса. Этот объект содержит указатель на соответствующий элемент каталога (который, в свою очередь, указывает на файловый индекс), представляющий открытый файл. Соответствующие объекты inode и dentry, конечно, являются уникальными.

Файловый  объект представляется с  помощью  структуры  struc t   file , которая определена в  файле <linux/fs.h> . Рассмотрим поля этой структуры с  комментариями, которые описывают назначение каждого поля.

struct file {

struct list_head     f_list;     /* список объектов file*/ struct dentry        *f_dentry;  /* связанный объект dentry */ struct vfsmount      *f_vfsmnt;  /* связанная смонтированная

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

struct file_operations  *f_op;     /* таблица файловых операций */ atomic_t             f_count;   /* счетчик ссылок на этот объект */ unsigned int        f_flags;   /*флаги, указанные при вызове функции open*/ mode_t              f_mode;    /* режим доступа к файлу */

loff_t             f_pos;     /*смещение в файле (file pointer, offset) */

struct fown_struct   f_owner;   /* информация о владельце для обработки сигналов */

unsigned int         f_uid;    /*идентификатор пользователя владельца, UID*/

unsigned int         f_gid;  /*  идентификатор группы владельца, GID */

int                 f_error;   /* код ошибки */

struct file_ra_state  f_ra;     /* состояние предварительного считывания*/

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

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

void                *private_data; /* привязка для драйвера терминала */ struct list_head    f_ep_links; /*список ссылок eventpoll (опрос событий) */ spinlock_t           f_ep_lock;  /* блокировка eventpoll */

struct address_space  *f_mapping; /* отображение в страничном кэше */

};

По  аналогии с объектом элемента каталога объект  файла  на самом  деле не соответствует  никакой структуре, которая хранится на жестком диске.  Поэтому в этой структуре  нет никакого флага, который бы указывал, что объект  изменен (dirty)  и требует  обратной записи на диск.  Объект  file указывает на связанный с ним  объект dentry  с помощью указателя f_dentry. Объект  dentry  в свою  очередь  содержит указатель  на связанный с ним  индекс файла, который содержит информацию о том, изменен ли файл.

Файловые операции

Как  и для других объектоп подсистемы VFS, таблица файловых операций является важной структурой. Операции, связанные со структурой struc t  file , — это знакомые системные вызовы, составляющие основу системных вызовов ОС Unix.

Методы работы  с файловым объектом хранятся в структуре  file_operation s и определены в файле  <linux/fs.h > следующим образом.

struct file_operations {

struct module *owner;

loff_t (*llseek) (struct file *, loff_t, int);

ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*aio_read)  (struct kiocb *, char *, size_t, loff_t); ssize_t (*write) (struct file *, const char *, size_t, loff_t *) ; ssize_t (*aio_write) (struct kiocb *, const char *, size_t, loff_t); int (*readdir) (struct file *, void *, filldir_t);

unsigned int (*poll) (struct file *, struct poll_table_struct *) ;

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

int (*mmap) (struct file *, struct vm_area_struct *) ;

int (*open) (struct inode *, struct file *) ;

int (*flush) (struct file *) ;

int (*release) (struct inode *, struct file *) ;

int (*fsync) (struct file *, struct dentry *, int);

int (*aio_fsync) (struct kiocb *, int);

int (*fasync) (int, struct file *, int);

int (*lock) (struct file *, int, struct file_lock *) ; ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *) ;

ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *) ;

ssize_t (*sendfile) (struct file *, loff_t *, size_t,

read_actor_t,void*) ;

ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

unsigned long (*get_unmapped_area) (struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

int (*check_flags) (int flags);

int (*dir_notify)  (struct file *filp, unsigned long arg);

int (*flock) (struct file *filp, int cmd, struct file_lock *fl);

};

Файловые  системы  могут реализовать  уникальную  функцию  для  каждой  из  этих операций  или  использовать  общий  существующий  метод.  Общие  методы  нормально работают  для  обычных  Unix-подобных   файловых  систем.  Разработчики   файловых систем  не  обязаны  реализовать  все  эти  функции,   хотя  основные  методы  должны быть реализованы.   Если  какой-либо метод не представляет  интереса,  то его можно установить в значение  NULL.

Рассмотрим  каждую операцию  подробнее.

• loff_t llseek(struct file *file, loff_t offset, int origin)

Эта  функция устанавливает значения указателя текущей позиции в файле (file pointer) в заданное значение параметра offset .  Функция вызывается из  системного вызова lseek() .

• ssize_ t  read(struc t  fil e   *file ,

char  *buf,  size_ t  count, loff_t   *offset)

Эта  функция считывает count байт данных из  указанного файла, начиная с позиции, заданной параметром offset , в буфер памяти, на который указывает параметр buf.  После этого значение указателя текущей позиции в файле должно быть обновлено. Данная функция вызывается из  системного вызова read() .

• ssize_ t  aio_read(struc t   kiocb  *iocb, char  *buf,   size_ t  count, loff_t   offset)

Эта  функция запускает асинхронную операцию считывания count байт данных из файла, который описывается параметром iocb, в буфер памяти, описанный параметром buf.  Эта  функция вызывается из  системного вызова aio_read ().

• ssize_ t write(struc t  fil e   *file ,

const  char  *buf,   size_ t  count, loff_t    *offset)

Эта  функция записывает count байт данных в указанный файл, начиная с позиции offset. Данная функция вызывается из  системного вызова writ e ().

• ssize_ t   aio_write(struc t  kiocb   *iocb, const  char  *buf,

size_ t  count,   loff_t offset)

Эта функция запускает асинхронную операцию записи count байт данных в файл, описываемый параметром iocb, из буфера памяти, на который указывает параметр buf. Данная функция вызывается из системного вызова aio_write.

• in t  readdir(struc t  fil e   *file ,  void *dirent ,  filldir_ t  filldir ) Эта функция возвращает следующий элемент из  списка содержимого каталога. Данная функция вызывается из  системного вызова readdi r ().

• unsigned  in t  poll(struc t  fil e   *file ,

struc t   poll_table_struc t   *poll_table )

Эта  функция переводит вызывающий процесс в состояние ожидания для ожидания действий, которые производятся с указанным файлом. Она вызывается из  системного вызова poll() .

• int ioctl(struct inode *inode, struct file *file, unsigned int cmd, signed long arg)

Эта функция используется для того, чтобы отправлять устройствам пары значений команда/аргумент. Функция используется, когда открытый файл— это специальный файл устройства. Данная функция вызывается из системного вызова ioctl() .

• in t  mmap(struct fil e  *file ,  struc t  vra_area_struct *vma)

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

• in t  open(struc t  inode  *inode,  struc t  fil e  *file )

Эта функция создает новый файловый объект и связывает его с указанным файловым индексом. Она вызывается из системного вызова open ().

• in t flush(struc t fil e  *file)

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

• in t release(struc t  inode *inode,  struc t  fil e  *file )

Эта функция вызывается подсистемой VFS, когда исчезает последняя ссылка на файл, например, когда последний процесс, который использовал соответствующий файловый дескриптор, вызывает функцию clos e ()  или завершается. Назначение этой функции также зависит от файловой системы.

• in t  fsync(struc t  fil e  *file , struc t  dentr y    *dentry , in t  datasync)

Эта функция вызывается из системного вызова fsync( )  для записи на диск всех закэшированных данных файла.

• in t  aio_fsync(struc t  kiocb  *iocb ,  in t  datasync)

Эта функция вызывается из системного вызова aio f sync ()  для записи на диск всех закэшированных данных файла, связанного с параметром iocb.

• in t  fasyn (fin t  fd,  struc t  fil e  *file ,  in t  on)

Эта функция разрешает или запрещает отправку сигнала для уведомлении о событиях при асинхронном вводе-выводе.

• in t  lock(struc t  fil e  *file ,   in t  cmd,   struc t  file_loc k    *lock) Эта функция управляет файловыми блокировками для данного файла.

• ssize_ t  readv(struc t  fil e   *file , const struc t  iovec    *vector , unsigned long   count,

loff_ t   *offset )

Эта функция вызывается из системного вызова readv ()  для считывания данных из указанного файла в count буферов, которые описываются параметром vector . После этого указатель текущей позиции файла должен быть соответственным образом увеличен.

• ssize_t writev(struct file *file, const struct iovec *vector, unsigned long count,

loff_t *offset)

Эта функция вызывается из системного вызова write v () для записи в указанный файл буферов, описанных параметром vector ; количество буферов равно count. После этого должно быть соответственным образом увеличено значение текущей позиции в файле.

• ssize_ t   sendfile(struc t  fil e   *file , loff_t *offset, size_t size, read_actor_t actor, void *target)

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

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

• ssize_ t   sendpage(struc t  fil e   *file , struc t  page    *page,

in t  offset ,  size_ t  size , loff_ t  *pos,  in t  more)

Эта функция используется для отправки данных из одного файла в другой.

•  unsigned  long    get_unmapped_area(struct   file*file , unsigned  long  addr,

unsigned  long  len , unsigned  long  offset , unsigned  long  flags)

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

• in t check_flags(in t flags)

Эта функция используется для проверки корректности флагов, которые передаются в системный вызов fcnt l (), при использовании команды SETFL. Как и в случае многих операций подсистемы VFS, для файловой системы нет необходимости реализовать функцию check_flags (). Сейчас это сделано только для файловой системы NFS. Эта функция позволяет файловой системе ограничить некорректные значения флагов команды SETFL в обобщенном системном вызове fcntl() . Для файловой системы NFS не разрешается  использовать комбинацию флагов O_APPEND  и  O_DIRECT.

• in t  flock(struc t  fil e  *filp ,  in t cmd,  struc t  file_lock *fl)

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

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

По теме:

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