Linux内核源码分析--打开块设备文件--open_bdev_excl函数

本文主要参考《深入理解Linux内核》,结合2.6.11.1版的内核代码,分析内核文件子系统中的打开设备文件函数,梳理了关于内核块设备文件打开的处理流程。

注意:

1、不描述内核同步、错误处理相关的内容

2、参考信息除具体说明外,包含在《深入理解Linux内核》第三版中

3、源码摘自Linux内核2.6.11.1版

1、open_bdev_excl

函数功能:

打开设备名为path的块设备,返回块设备描述符的地址

函数参数:

Path:块设备文件的路径名(如:/dev/sda1);

Flags:mount系统调用的的flag参数

Holder: 指向类型为file_system_type的文件系统类型对象的指针

函数源码及处理流程:

struct block_device*open_bdev_excl(const char *path, int flags, void *holder)

{

    structblock_device *bdev;

    mode_tmode = FMODE_READ;

    interror = 0;

 

    bdev= lookup_bdev(path);

    if(IS_ERR(bdev))

       returnbdev;

 

    if(!(flags & MS_RDONLY))

       mode|= FMODE_WRITE;

    error= blkdev_get(bdev, mode, 0);

    if(error)

       returnERR_PTR(error);

    error= -EACCES;

    if(!(flags & MS_RDONLY) && bdev_read_only(bdev))

       gotoblkdev_put;

    error= bd_claim(bdev, holder);

    if(error)

       gotoblkdev_put;

 

    returnbdev;

   

blkdev_put:

    blkdev_put(bdev);

    returnERR_PTR(error);

}

函数处理流程:

1、调用lookup_bdev函数,根据设备文件名path,查找或分配一个block_device对象,地址存入局部变量bdev中

2、根据flags参数设置文件系统权限为只读(FMODE_READ)或读写(FMODE_READ| FMODE_WRITE)

3、调用blkdev_get函数,初始化bdev中和分区、磁盘相关的数据,参见后面分析

4、调用bd_claim函数,更新bdev对象和其包含对象的持有者信息

 

2、lookup_bdev

函数功能:

打开或查找设备名为path的块设备。

函数参数:

函数源码:

/**

 * lookup_bdev - lookup a struct block_device by name

 *

 * @path:  specialfile representing the block device

 *

 * Get a reference to the blockdevice at @pathin the current

 * namespace if possible and return it.  Return ERR_PTR(error)

 * otherwise.

 */

struct block_device *lookup_bdev(constchar *path)

{

    structblock_device *bdev;

    structinode *inode;

    structnameidata nd;

    interror;

 

    if(!path || !*path)

       returnERR_PTR(-EINVAL);

 

    error= path_lookup(path, LOOKUP_FOLLOW, &nd);

    if(error)

       returnERR_PTR(error);

 

    inode= nd.dentry->d_inode;

    error= -ENOTBLK;

    if(!S_ISBLK(inode->i_mode))

       gotofail;

    error= -EACCES;

    if(nd.mnt->mnt_flags & MNT_NODEV)

       gotofail;

    error= -ENOMEM;

    bdev= bd_acquire(inode);

    if(!bdev)

       gotofail;

out:

    path_release(&nd);

    returnbdev;

fail:

    bdev= ERR_PTR(error);

    gotoout;

}

函数处理流程:

1、调用path_lookup函数(参见p495“路径名查找”),查找块设备文件名对应的nameidata对象并存入nd局部变量中,设备文件对应的节点对象地址存入inode类型的inode局部变量中

2、调用bd_acquire函数,打开或查找设备文件名为path的块设备,返回块设备描述符

3、blkdev_get

函数功能:

初始化块设备描述符中和分区、磁盘相关的字段

函数参数:

函数源码:

int blkdev_get(struct block_device*bdev, mode_t mode, unsigned flags)

{

    /*

     * This crockload is due to bad choice of->open() type.

     * It will go away.

     * For now, block device ->open() routinemust _not_

     * examine anything in 'inode' argument except->i_rdev.

     */

    structfile fake_file = {};

    structdentry fake_dentry = {};

    fake_file.f_mode= mode;

    fake_file.f_flags= flags;

    fake_file.f_dentry= &fake_dentry;

    fake_dentry.d_inode= bdev->bd_inode;

 

    returndo_open(bdev, &fake_file);

}

 

static int do

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值