今天的内容是关于简单的inode操作。
源码分析
今天的源码只涉及四个新函数,其中较关键的只有两个,分别是sfs_lookup
和sfs_mknod
。
#include <linux/module.h>
#include <linux/fs.h>
#include "samplefs.h"extern struct dentry_operations sfs_dentry_ops;
extern struct dentry_operations sfs_ci_dentry_ops;
extern struct inode *samplefs_get_inode(struct super_block *sb, int mode, dev_t dev);/** Lookup the data, if the dentry didn't already exist, it must be* negative. Set d_op to delete negative dentries to save memory* (and since it does not help performance for in memory filesystem).*/static struct dentry *sfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int len)
{struct samplefs_sb_info *sfs_sb = SFS_SB(dir->i_sb);if (dentry->d_name.len > NAME_MAX)return ERR_PTR(-ENAMETOOLONG);if (sfs_sb->flags & SFS_MNT_CASE)dentry->d_op = &sfs_ci_dentry_ops;elsedentry->d_op = &sfs_dentry_ops;d_add(dentry, NULL);return NULL;
}
在inode_operations中的lookup
函数主要作用是根据名称查找其inode实例,并将dentry->d_inode
指向inode实例。在实际实验中,d_op
一直为sfs_dentry_ops
。
sfs_mknod
这个函数主要是新建一个inode并将其连接到dentry上,而mknod命令被用来创建Linux中的字符设备文件和块设备文件。
static int
sfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
{struct inode *inode = samplefs_get_inode(dir->i_sb, mode, dev);struct timespec64 ts;int error = -ENOSPC;printk(KERN_INFO "samplefs: mknod\n");if (inode) {if (dir->i_mode & S_ISGID) {inode->i_gid = dir->i_gid;if (S_ISDIR(mode))inode->i_mode |= S_ISGID;}d_instantiate(dentry, inode);dget(dentry); /* Extra count - pin the dentry in core */error = 0;ktime_get_ts64(&ts);dir->i_mtime = dir->i_ctime = ts;/* real filesystems would normally use i_size_write function */dir->i_size += 0x20; /* bogus small size for each dir entry */}return error;
}static int sfs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
{int retval = 0;retval = sfs_mknod(dir, dentry, mode | S_IFDIR, 0);/* link count is two for dir, for dot and dot dot */if (!retval)dir->__i_nlink++;return retval;
}static int sfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,bool flag)
{return sfs_mknod(dir, dentry, mode | S_IFREG, 0);
}struct inode_operations sfs_dir_inode_ops = {.create = sfs_create,.lookup = sfs_lookup,.unlink = simple_unlink,.mkdir = sfs_mkdir,.rmdir = simple_rmdir,.mknod = sfs_mknod,.rename = simple_rename,
};
参考资料
Linux内核之设备驱动-sysfsmknod命令