1. kern_mount:
-
#define kern_mount(type) kern_mount_data(type, NULL)
kern_mount相当于直接调用了kern_mount_data函数。
2.kern_mount_data
-
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
-
{
-
struct vfsmount *mnt;
-
mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); /**/
-
if (!IS_ERR(mnt)) {
-
/*
-
* it is a longterm mount, don't release mnt until
-
* we unmount before file sys is unregistered
-
*/
-
real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL; /* 将包含vfsmount的mount对象的mnt_ns(struct mnt_namespace)赋值ERR_PTR(-EINVAL) */
-
}
-
return mnt;
-
}
3. vfs_kern_mount
-
struct vfsmount *
-
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
-
{
-
struct mount *mnt;
-
struct dentry *root;
-
-
if (!type)
-
return ERR_PTR(-ENODEV);
-
-
mnt = alloc_vfsmnt(name); /*分配一个mnt对象,并对其进行部分初始化*/
-
if (!mnt)
-
return ERR_PTR(-ENOMEM);
-
-
if (flags & MS_KERNMOUNT)
-
mnt->mnt.mnt_flags = MNT_INTERNAL;
-
-
root = mount_fs(type, flags, name, data); /* 获取该文件系统的根目录的dentry,同时也获取super_block */
-
if (IS_ERR(root)) {
-
free_vfsmnt(mnt);
-
return ERR_CAST(root);
-
}
-
-
/* differentiate nand and emmc*/
-
if(root->d_sb->s_mtd){
-
g_rsrvd_size = NAND_DATA_RESERVED_SIZE;
-
}
-
/* 对mnt对象与root进行绑定 */
-
mnt->mnt.mnt_root = root;
-
mnt->mnt.mnt_sb = root->d_sb;
-
mnt->mnt_mountpoint = mnt->mnt.mnt_root;
-
mnt->mnt_parent = mnt;
-
br_write_lock(&vfsmount_lock);
-
list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts); /* 将mnt添加到root->d_sb->s_mounts链表中 */
-
br_write_unlock(&vfsmount_lock);
-
return &mnt->mnt;
-
}
4. mount_fs
-
struct dentry *
-
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
-
{
-
struct dentry *root;
-
struct super_block *sb;
-
char *secdata = NULL;
-
int error = -ENOMEM;
-
-
if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { /* 在kern_mount调用中data为NULL,所以该if判断为假 */
-
secdata = alloc_secdata();
-
if (!secdata)
-
goto out;
-
-
error = security_sb_copy_data(data, secdata);
-
if (error)
-
goto out_free_secdata;
-
}
-
-
root = type->mount(type, flags, name, data); /* 调用file_system_type中的 mount方法,通过该方法获取该文件系统的根目录dentry,同时也获取super_block. file_system_type的mount方法kernel提供以实现的函数:mount_single,mount_pseudo等 */
-
if (IS_ERR(root)) {
-
error = PTR_ERR(root);
-
goto out_free_secdata;
-
}
-
sb = root->d_sb;
-
BUG_ON(!sb);
-
WARN_ON(!sb->s_bdi);
-
WARN_ON(sb->s_bdi == &default_backing_dev_info);
-
sb->s_flags |= MS_BORN;
-
-
error = security_sb_kern_mount(sb, flags, secdata);
-
if (error)
-
goto out_sb;
-
-
/*
-
* filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE
-
* but s_maxbytes was an unsigned long long for many releases. Throw
-
* this warning for a little while to try and catch filesystems that
-
* violate this rule.
-
*/
-
WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
-
"negative value (%lld)\n", type->name, sb->s_maxbytes);
-
-
up_write(&sb->s_umount);
-
free_secdata(secdata);
-
return root;
-
out_sb:
-
dput(root);
-
deactivate_locked_super(sb);
-
out_free_secdata:
-
free_secdata(secdata);
-
out:
-
return ERR_PTR(error);
-
}
总结:kern_count函数主要用于那些没有实体介质的文件系统,该函数主要是获取文件系统的super_block对象与根目录的inode与dentry对象,并将这些对象加入到系统链表。
阅读(2721) | 评论(0) | 转发(0) |