首页 > 系统相关 >Linux内核有什么之块设备驱动有什么第六回 —— 邂逅的三个文件系统之二:实际文件系统(3)

Linux内核有什么之块设备驱动有什么第六回 —— 邂逅的三个文件系统之二:实际文件系统(3)

时间:2024-03-22 16:31:39浏览次数:28  
标签:函数 error 文件系统 dev 之块 Linux path bdev inode

接前一篇文章:Linux内核有什么之块设备驱动有什么第五回 —— 邂逅的三个文件系统之二:实际文件系统(2)

本文内容参考:

34 | 块设备(上):如何建立代理商销售模式?-趣谈Linux操作系统-极客时间

特此致谢!

上回书以F2FS文件系统为例,开始分析块设备邂逅的第二个文件系统:实际文件系统。本回继续沿着源码流程进行分析。

上一回的流程为:

struct file_system_type f2fs_fs_type --->

    f2fs_fs_type->mount ---> 

        f2fs_mount --->

            mount_bdev --->

                lookup_bdev

上一回就讲到这个lookup_bdev函数。其在block/bdev.c中,代码如下:

​
/**
 * lookup_bdev() - Look up a struct block_device by name.
 * @pathname: Name of the block device in the filesystem.
 * @dev: Pointer to the block device's dev_t, if found.
 *
 * Lookup the block device's dev_t at @pathname in the current
 * namespace if possible and return it in @dev.
 *
 * Context: May sleep.
 * Return: 0 if succeeded, negative errno otherwise.
 */
int lookup_bdev(const char *pathname, dev_t *dev)
{
	struct inode *inode;
	struct path path;
	int error;

	if (!pathname || !*pathname)
		return -EINVAL;

	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
	if (error)
		return error;

	inode = d_backing_inode(path.dentry);
	error = -ENOTBLK;
	if (!S_ISBLK(inode->i_mode))
		goto out_path_put;
	error = -EACCES;
	if (!may_open_dev(&path))
		goto out_path_put;

	*dev = inode->i_rdev;
	error = 0;
out_path_put:
	path_put(&path);
	return error;
}

根据函数注释,lookup_bdev函数的作用是按名称查找block_device结构。其实这个注释应该是对于老版本来说的,新版本代码中下边的把那一句描述更准确:在当前命名空间中,查找pathname所对应的块设备的dev_t,并在第二个参数dev中返回(如果能够找到)。其第一个参数const char *pathname是文件系统中块设备的名字,也就是设备的文件名(/dev/xxx);第二个参数dev_t *dev是找到时,指向块设备的dev_t的指针。注意,这个文件是在devtmpfs文件系统中的。

(1)lookup_bdev函数首先调用kern_path函数。kern_path函数可以在这个文件系统(devtmpfs)里面,一直找到设备的文件名对应的dentry。代码片段如下:

    error = kern_path(pathname, LOOKUP_FOLLOW, &path);
	if (error)
		return error;

kern_path函数在fs/namei.c中,代码如下:

int kern_path(const char *name, unsigned int flags, struct path *path)
{
	struct filename *filename = getname_kernel(name);
	int ret = filename_lookup(AT_FDCWD, filename, flags, path, NULL);

	putname(filename);
	return ret;

}
EXPORT_SYMBOL(kern_path);

(2)lookup_bdev函数接下来调用d_backing_inode函数。d_backing_inode函数会根据kern_path函数得到的path.dentry获得对应的inode。代码片段如下:

    inode = d_backing_inode(path.dentry);

d_backing_inode函数在include/linux/dcache.h中,代码如下:

/**
 * d_backing_inode - Get upper or lower inode we should be using
 * @upper: The upper layer
 *
 * This is the helper that should be used to get at the inode that will be used
 * if this dentry were to be opened as a file.  The inode may be on the upper
 * dentry or it may be on a lower dentry pinned by the upper.
 *
 * Normal filesystems should not use this to access their own inodes.
 */
static inline struct inode *d_backing_inode(const struct dentry *upper)
{
	struct inode *inode = upper->d_inode;

	return inode;
}

注意,这个path.dentry所对应的inode就是前文书讲到的init_special_inode函数中生成的那个特殊inode。当时笔者说埋一个伏笔,就在这出现(用到)了。

(3)得到根据pathname找到的对应块设备的dev_t,并赋给第二个参数dev返回(如果能够找到)。代码片段如下:

    *dev = inode->i_rdev;

这个inode->i_rdev正是上边在init_special_inode函数中赋值的。

    inode->i_rdev = rdev;

也就是说,lookup_bdev函数返回的指向块设备的dev_t的指针,指向的正是上边的这个rdev,即调用init_special_inode函数时传给第三个参数dev_t rdev所对应的实参。

至此,lookup_bdev函数就解析完了。欲知后事如何,且看下回分解。

标签:函数,error,文件系统,dev,之块,Linux,path,bdev,inode
From: https://blog.csdn.net/phmatthaus/article/details/136817904

相关文章

  • linux-sysrq
     sysrq        SysRq(systemrequest) 是Linux操作系统内核理解的一系列键,可以触发一组预定义的操作。当无法通过传统管理(执行虚拟机故障排除或恢复时,通常使用这些命令,例如,VM未)响应。         Sysrq被称为”魔术组合键”,是内建于Linux内核的调试工具......
  • Linux内核启动流程简介
    参考资料:https://www.bilibili.com/video/BV12E411h71h?p=38&vd_source=432ba293ecfc949a4174ab91ccc526d6 Linux内核链接脚本arch/arm/kernel/vmlinux.lds arch/arm/kernel/vmlinux.lds中OUTPUT_ARCH(arm)ENTRY(stext)//Linux内核入口,入口函数stextjiffies=......
  • linux查看指定进程打开的文件数
    1.背景正式环境多个用户登录频繁报网络错误2.排查及解决##查看error.log发现原因是Toomanyopenfiles##ulimit-a命令可以查看单个进程最大打开文件的数量限制;默认1024##统计指定进程打开的文件数,发现都在1024以内lsof-ppid|wc-l##尝试修改nginx.confwork......
  • linux 静态ip
    在Linux系统中设置固定IP地址,通常涉及以下步骤:确认网络接口。使用命令`ipaddr`和`ifconfig`来查看当前的网络接口和IP地址。例如,在`/etc/sysconfig/network-scripts/`目录下,通常会有一个名为`ifcfg-ens33`的文件,其中`ens33`是网络接口的名称。编辑网络配......
  • Linux-Java安装了多个版本
    近日在Deepin上发现安装了多个版本,但是我们仅仅指定的版本,这时就需要手工切换,切换方法如下:如果你发现有两个不同版本的OpenJDK,可能是因为系统默认安装了一个版本,而你可能也安装了另一个版本。要确定哪个版本正在被使用,你可以在终端中运行以下命令:java-version这将显示当前......
  • RK356x Linux解包update.img、打包update.img和win环境下烧写固件
    1.解包update.imgstep1将afptool、rkImageMaker、unpack.sh拷贝在~/work/test下topeet@ubuntu:~/work/test$lsafptooloutputrkImageMakerunpack.shupdate.imgstep2执行./unpack.sh,后会生成output文件夹topeet@ubuntu:~/work/test$./unpack.sh......
  • Linux mke2fs命令教程:创建和管理你的ext2/ext3/ext4文件系统(附案例详解和注意事项)
    Linuxmke2fs命令介绍mke2fs(makeext2filesystem)命令是用来创建ext2/ext3/ext4文件系统的。它通常在磁盘分区上创建文件系统,设备是对应设备的特殊文件(例如/dev/hdXX)。如果省略了块数,mke2fs会自动计算文件系统的大小。Linuxmke2fs命令适用的Linux版本mke2fs命令在所有......
  • Linux hdparm命令教程:优化硬盘性能和读写速度(附实例详解和注意事项)
    Linuxhdparm命令介绍hdparm是一个用于控制和配置硬盘驱动器的命令行工具。它允许您查看和修改硬盘的参数,包括缓存设置、高级电源管理、硬盘性能等。通过hdparm,您可以优化硬盘的读写速度和性能。Linuxhdparm命令适用的Linux版本hdparm在大多数Linux发行版中都可用,......
  • Linux-tar、tar.gz、tgz文件批量解压方法
    由于linux的tar命令不支持批量解压,所以很多网友编写了好多支持批量解压的shell命令,收集了一下,供大家分享:第一:使用for遍历压缩文件,使用tar命令逐个解压fortarin*.tar.gz; dotarxvf$tar;donefortarin*.tar.bz2;dotarxvf$tar;done或者for i in $(ls *.tar.g......
  • 在Linux中,有一堆日志文件,如何删除7天前的日志文件?
    在Linux中,如果你想要删除7天前的日志文件,你可以使用find命令配合-mtime选项来实现。下面是一个详细的步骤说明:1.确定日志文件所在的目录首先,你需要知道这些日志文件存放在哪个目录下。例如,假设你的日志文件都存放在/var/log/目录下。2.使用find命令查找并删除文件你可以使用......