linux VFS 之三:索引节点inode
VFS 中的每个文件、目录等都用且只用一个VFS inode表示,存放关于具体文件或者目录的一般信息。每个索引节点对象都有一个索引节点号,这个号唯一地标识某个文件系统中的指定文件。文件名可以随时更改,但是索引节点对文件是唯一的,并且随文件的存在而存在。具体文件系统的索引节点是存放在磁盘上的,是一种静态结构,要使用它,必须调入内存,填写VFS的索引节点,因此,也称VFS索引节点是动态节点
一、进程与vfs对象之间的关系很重要:
1、VFS 中的每个文件、目录等都用且只用一个 索引节点inode表示,存放关于具体文件或者目录的一般信息。
2、每个索引节点对象都有一个索引节点号,这个号唯一地标识某个文件系统中的指定文件。
3、文件名可以随时更改,但是索引节点对文件是唯一的,并且随文件的存在而存在。每个文件又可以有多个文件名(ln建创链接)。即可以通过不同的文件名访问同一个文件。这里多个文件名对应一个文件的关系在数据结构中表示就是dentry和inode的关系。
4、具体文件系统的索引节点是存放在磁盘上的,是一种静态结构,要使用它,必须调入内存,填写VFS的索引节点,因此,也称VFS索引节点是动态节点。
Inode中不存储文件的名字,它只存储节点号;而dentry则保存有名字和与其对应的inode,所以就可以通过不同的dentry访问同一个inode。
进程每打开一个文件,就会有一个file结构与之对应。同一个进程可以多次打开同一个文件而得到多个不同的file结构,
多个进程也可以打开同一个文件得到多个不同的file结构。
file结构描述了被打开文件的属性,读写的偏移指针等等当前信息。
二、inode结构
每一个索引节点都由一个“struct inode”结构标识,下面认识一下inode的重要成员:struct inode {
umode_t i_mode; // 文件类型以及存取权限
const struct inode_operations *i_op; //索引节点操作的函数指针
struct super_block *i_sb; //超级块对象指针
struct address_space *i_mapping; //address_space对象指针??
struct address_spacei_data;
unsigned long i_ino; // 索引节点号
dev_t i_rdev; // 该文件系统的主设备号
blkcnt_t i_blocks; //块为单位的文件长度
loff_t i_size; //文件长度
unsigned long i_state; //索引节点状态标志
unsigned long dirtied_when; /* jiffies of first dirtying */
list_head i_dentry; //引用索引节点的目录项对象链表头
const struct file_operations*i_fop; //文件操作函数指针
struct list_headi_devices; //块设备指针
struct block_device *i_bdev; //块设备驱动程序指针
void *i_private; // 私有数据指针
};
三、inode操作方法
索引节点关联的方法叫索引节点操作,由一个“structinode_operations”结构标识:
struct inode_operations {
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); //查找目录项。
int (*create) (struct inode *,struct dentry *,umode_t,struct nameidata *); open(2) and creat(2)系统调用调用。
int (*link) (struct dentry *,struct inode *,struct dentry *); 创建硬链接
int (*unlink) (struct inode *,struct dentry *); unlink(2)系统调用调用。
int (*symlink) (struct inode *,struct dentry *,const char *); symlink(2)系统调用调用。
int (*mkdir) (struct inode *,struct dentry *,umode_t); 系统调用 mkdir(2)调用。
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); 系统调用rename(2)调用
void (*truncate) (struct inode *); 修改与索引节点相关的文件的文件大小。
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
.................
} ____cacheline_aligned;
四、inode初始化
static struct inode *sdcardfs_iget(struct super_block *sb,
struct inode *lower_inode)
{
struct sdcardfs_inode_info *info;
struct inode *inode; /* the new inode to return */
int err;
/* in order for FAT emulation */
//struct sdcardfs_sb_info *sb_info = sb->s_fs_info;
inode = iget5_locked(sb, /* our superblock */ //inode的查找、创建
/*
* hashval: we use inode number, but we can
* also use "(unsigned long)lower_inode"
* instead.
*/
lower_inode->i_ino, /* hashval */
sdcardfs_inode_test,/* inode comparison function */
sdcardfs_inode_set, /* inode init function */
lower_inode); /* data passed to test+set fxns */
if (!inode) {
err = -EACCES;
iput(lower_inode);
return ERR_PTR(err);
}
/* if found a cached inode, then just return it */
if (!(inode->i_state & I_NEW)) // cache的inode,已经初始化过,直接返回。
return inode;
inode->i_ino = lower_inode->i_ino; //初始化索引号
if (!igrab(lower_inode)) {
err = -ESTALE;
return ERR_PTR(err);
}
sdcardfs_set_lower_inode(inode, lower_inode); //记录低层文文件系统的inode,sdcardfs特有
inode->i_version++;
//*************初始化inode操作函数指针
/* use different set of inode ops for symlinks & directories */
if (S_ISDIR(lower_inode->i_mode))
inode->i_op = &sdcardfs_dir_iops;
else if (S_ISLNK(lower_inode->i_mode))
inode->i_op = &sdcardfs_symlink_iops;
else
inode->i_op = &sdcardfs_main_iops;
//*************初始化file操作函数指针***********//
/* use different set of file ops for directories */
if (S_ISDIR(lower_inode->i_mode))
inode->i_fop = &sdcardfs_dir_fops;
else
inode->i_fop = &sdcardfs_main_fops;
inode->i_mappng->a_ops = &sdcardfs_aops;
//初始化inode的访问时间
inode->i_atime.tv_sec = 0;
inode->i_atime.tv_nsec = 0;
inode->i_mtime.tv_sec = 0;
inode->i_mtime.tv_nsec = 0;
inode->i_ctime.tv_sec = 0;
inode->i_ctime.tv_nsec = 0;
//*************这边又初始化file操作函数指针,和上面有冲突?***********//
/* properly initialize special inodes */
if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) {
init_special_inode(inode, lower_inode->i_mode,
lower_inode->i_rdev);
//printk(KERN_INFO "sdcardfs: %s(%d)-> i_mode=%o \n", __FUNCTION__, __LINE__, inode->i_mode);
}
//从低层文件系统copy其它属性,用于初始化sdcardfs inode
/* all well, copy inode attributes */
fsstack_copy_attr_all(inode, lower_inode);
fsstack_copy_inode_size(inode, lower_inode);
fix_fat_permission(inode);
return inode;
}
更多推荐
所有评论(0)