Как и для других объектов подсистемы VFS, таблица файловых операций является важной структурой. Операции, связанные со структурой struct file
, — это знакомые системные вызовы, составляющие основу системных вызовов ОС Unix.
Методы работы с файловым объектом хранятся в структуре file_operations
и определены в файле
следующим образом.
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(struct file *file,
char *buf, size_t count, loff_t* offset);
Эта функция считывает count
байт данных из указанного файла, начиная с позиции, заданной параметром offset
, в буфер памяти, на который указывает параметр buf
. После этого значение указателя текущей позиции в файле должно быть обновлено. Данная функция вызывается из системного вызова read()
.
• ssize_t aio_read(struct kiocb *iocb,
char *buf, size_t count, loff_t offset);
Эта функция запускает асинхронную операцию считывания count
байт данных из файла, который описывается параметром iocb
, в буфер памяти, описанный параметром buf
. Эта функция вызывается из системного вызова aio_read()
.
• ssize_t write(struct file *file,
const char *buf, size_t count, loff_t* offset);