上篇定位到 vfs_get_tree
在更改error code的地方打log
根据log中打出来的行 定位到 error = fc->ops->get_tree(fc); 这里返回了-6
所以下一步找get_tree具体指向哪个接口
显然 get_tree 来自 fc的ops
fc的ops赋值的地方比较绕
先从log中的报错信息 /dev/root: Can’t open blockdev入手
定位到 setup_bdev_super
fc的结构 struct fs_context
struct fs_context 看名字应该是文件系统上下文
fs_context结构体
struct fs_context {
const struct fs_context_operations *ops;
struct mutex uapi_mutex; /* Userspace access mutex */
struct file_system_type *fs_type;
void *fs_private; /* The filesystem's context */
void *sget_key;
struct dentry *root; /* The root and superblock */
struct user_namespace *user_ns; /* The user namespace for this mount */
struct net *net_ns; /* The network namespace for this mount */
const struct cred *cred; /* The mounter's credentials */
struct p_log log; /* Logging buffer */
const char *source; /* The source name (eg. dev path) */
void *security; /* LSM options */
void *s_fs_info; /* Proposed s_fs_info */
unsigned int sb_flags; /* Proposed superblock flags (SB_*) */
unsigned int sb_flags_mask; /* Superblock flags that were changed */
unsigned int s_iflags; /* OR'd with sb->s_iflags */
enum fs_context_purpose purpose:8;
enum fs_context_phase phase:8; /* The phase the context is in */
bool need_free:1; /* Need to call ops->free() */
bool global:1; /* Goes into &init_user_ns */
bool oldapi:1; /* Coming from mount(2) */
bool exclusive:1; /* create new superblock, reject existing one */
};
注意 修饰 ops 的类型是 const struct * 即不可通过该指针修改指向的内容
回顾之前的调用链 这个文件系统上下文的结构体是通过 fs_context_for_mount 函数得到的
struct fs_context *fs_context_for_mount(struct file_system_type *fs_type,
unsigned int sb_flags)
参数相对简单 一个文件系统类型 一个flag
然后添加一个目的参数(FS_CONTEXT_FOR_MOUNT) 调用alloc_fs_context
在 alloc_fs_context 里主要做一些申请和初始化操作 没有对后续调用需要的 ops 字段赋值
ops字段结构体
struct fs_context_operations {
void (*free)(struct fs_context *fc);
int (*dup)(struct fs_context *fc, struct fs_context *src_fc);
int (*parse_param)(struct fs_context *fc, struct fs_parameter *param);
int (*parse_monolithic)(struct fs_context *fc, void *data);
int (*get_tree)(struct fs_context *fc);
int (*reconfigure)(struct fs_context *fc);
};