struct file_operations
======================
结构file_operations包含了VFS对一个已打开文件的操作。
在内核2.1.99中,此结构的定义如下:
(注:在2.2的内核中,此结构已经有了少许改变)
struct file_operations {
/*在VFS需要移动文件位置指针时被调用 */
loff_t (*llseek) (struct file *, loff_t, int);
/* 被read系统调用所使用 */
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
/* 被write系统调用所使用 */
ssize_t (*write) (struct file *, 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 (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *);
int (*fasync) (struct file *, int);
int (*check_media_change) (kdev_t dev);
int (*revalidate) (kdev_t dev);
int (*lock) (struct file *, int, struct file_lock *);
};
llseek:当VFS需要移动文件指针的位置时调用。
read:被read(2)所调用。
write:被write(2)所调用。
readdir:当VFS需要读取目录中的内容时被调用。
poll: called by the VFS when a process wants to check if there is
activity on this file and (optionally) go to sleep until there
is activity.
(注:这里我怎么想都翻不好,所以就把原文放在这里了,poll就是相当于select的东西)
ioctl:被ioctl(2)所调用。
mmap:被mmap(2)所调用。
open:当VFS要打开一个i节点时调用它。当VFS打开一个文件时,它建立一个新的struct fil
e
结构,并用i节点中的"default_file_ops"来初始化其中的f_op域,然后对新分配的文件结构
调用open方法。你可以认为open方法实际上属于struct inode_operations。I think it's
done the way it is because it makes filesystems simpler to implement.open方法是一
个很好的初始化文件结构中的"private_data"域的的地方。
release:当没有对被打开文件的引用时调用此方法。
fsync:被fsync(2)所调用。
fasync:当用fcntl(2)激活一个文件的异步模式时此方法被调用。
这些文件操作是由i节点所在的特定文件系统所实现的。当打开一个设备节点时(字符或块设
备
特殊文件),大多数文件系统会调用VFS中的特定支持例程,由此来找到所需要的设备驱动信息
;
这些支持例程用设备驱动程序的方法来代替文件系统的文件操作,然后继续对文件调用新的
open方法。这就是为什么当你打开文件系统上的一个设备特殊文件时,最后被调用的却是设
备
驱动程序的open方法。另外,devfs(Device Filesystem)有一个从设备节点到设备驱动程序
的
更直接的方式(这是非官方的内核补丁)
struct dentry_operations
========================
This describes how a filesystem can overload the standard dentry
operations.Dentries和dcache是属于VFS和单个文件系统实现的,设备驱动与此无关。
在内核2.1.99中,此结构的定义如下:
(注:在2.2的内核中,此结构没有改变)
struct dentry_operations {
int (*d_revalidate)(struct dentry *);
int (*d_hash) (struct dentry *, struct qstr *);
int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
void (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
};
d_revalidate:当VFS要使一个dentry重新生效时被调用。
d_hash:当VFS向哈希表中加入一个dentry时被调用。
d_compare:当指向一个dentry的最后的引用被去除时此方法被调用,因为这意味这没有人在
使用此dentry;当然,此dentry仍然有效,并且仍然在dcache中。
d_release: 当一个dentry被清除时调用此方法。
d_iput:当一个dentry释放它的i节点时(在dentry被清除之前)此方法被调用。The default
when this is NULL is that the VFS calls iput(). If you define this method, you
must call iput() yourself.
每个dentry都有一个指向其父目录dentry的指针,一个子dentry的哈希列表。子dentry基本
上就是目录中的文件。
dget:为一个已经存在的dentry打开一个新的句柄(这仅仅增加引用计数)
dput:关闭一个dentry的句柄(减少引用计数).如果引用计数减少为0,d_delete方法将会被调
用;并且,如果此dentry仍然在其父目录的哈希列表中的话,此dentry将被放置于一个未被
使用的列表中。将dentry放置于未使用表中意味着当系统需要更多的RAM时,将会遍历未使用
的dentry的列表,并回收其内存空间。假如当detry的引用计数为0时,它已经没有在父目录
的哈希表中的话,在d_delete方法被调用之后系统就会回收起内存空间。
d_drop: 此方法将一个dentry从其父目录的哈希列表中去掉。如果被去掉的dentry的引用计
数降为0的话,系统会马上调用d_put来去掉此dentry.
d_delete:删除一个dentry.如果没有别的对此dentry的打开引用的话,此dentry会变成一个
negative dentry(d_iput方法会被调用);如果有别的对此dentry的引用的话,将会调用d_drop.
d_add:向父目录的哈希列表中加入一个dentry,然后调用d_instantiate().
d_instantiate:把一个dentry加入别名哈希列表中,并更新其d_inode域为所给的i节点。i节点中的i_count域加一。假如i节点的指针为NULL,此dentry就被称为"negative dentry".此函数通常在为一个已存在的negative dentry建立i节点时被调用。
阅读(1927) | 评论(0) | 转发(0) |