Linux内核源码分析-安装普通文件系统-mount系统调用

Linux内核源码分析-安装普通文件系统-mount系统调用

本文主要参考《深入理解Linux内核》,结合2.6.11.1版的内核代码,分析内核文件子系统中的安装普通文件系统函数。

注意:

1、不描述内核同步、错误处理、参数合法性验证相关的内容

2、源码摘自Linux内核2.6.11.1版

3、阅读本文请结合《深入理解Linux内核》第三版相关章节

4、本文会不定时更新

1、sys_mount

函数源码:

asmlinkage long sys_mount(char __user *dev_name, char __user * dir_name,

             char __user * type, unsigned long flags,

             void __user * data)

{

    intretval;

    unsignedlong data_page;

    unsignedlong type_page;

    unsignedlong dev_page;

    char*dir_page;

   //从用户空间复制文件系统类型字符串到type_page指向的内存地址

    retval= copy_mount_options (type, &type_page);

    if(retval < 0)

       returnretval;

   //从用户空间获取路径名

    dir_page= getname(dir_name);

    retval= PTR_ERR(dir_page);

    if(IS_ERR(dir_page))

       gotoout1;

   //从用户空间复制块设备文件名到内核空间

    retval= copy_mount_options (dev_name, &dev_page);

    if(retval < 0)

       gotoout2;

  //复制与文件系统相关的数据结构的地址

    retval= copy_mount_options (data, &data_page);

    if(retval < 0)

       gotoout3;

 

    lock_kernel();

   //分析见下文

    retval= do_mount((char*)dev_page, dir_page, (char*)type_page,

             flags, (void*)data_page);

    unlock_kernel();

    free_page(data_page);

 

out3:

    free_page(dev_page);

out2:

    putname(dir_page);

out1:

    free_page(type_page);

    returnretval;

}

函数处理流程:

从用户空间复制数据到内核空间(准备参数)、获取大内核锁、调用do_mount函数

2、copy_mount_options

函数源码:

int copy_mount_options(const void__user *data, unsigned long *where)

{

    inti;

    unsignedlong page;

    unsignedlong size;

   

    *where= 0;

    if(!data)

       return0;

 

    if(!(page = __get_free_page(GFP_KERNEL)))

       return-ENOMEM;

 

    /*We only care that *some* data at the address the user

     * gave us is valid.  Just in case, we'll zero

     * the remainder of the page.

     */

    /*copy_from_user cannot cross TASK_SIZE ! */

    size= TASK_SIZE - (unsigned long)data;

    if(size > PAGE_SIZE)

       size= PAGE_SIZE;

 

    i= size - exact_copy_from_user((void *)page, data, size);

    if(!i) {

       free_page(page);

       return-EFAULT;

    }

    if(i != PAGE_SIZE)

       memset((char*)page + i, 0, PAGE_SIZE - i);

    *where= page;

    return0;

}

函数处理流程:

1、调用函数__get_free_page分配一个空闲页框并返回页框的线性地址

2、调用函数exact_copy_from_user把用户空间的数据从data

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值