用户层read write io命令到NVMe SSD全流程

2024-04-14 07:12

本文主要是介绍用户层read write io命令到NVMe SSD全流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言

以EXT-4以及read io cmd为例,介绍从User Space -> File System -> NVMe Driver -> PCIe Controller -> NVMe Controller -> SSD Firmware(Flash Translate layer) 的基本流程

明确几个要点

  • inode number(inode号)是单纯一个整形数,一般存放在目录文件的data block里。
  • inode是struct inode对象,里面存放了跟文件相关的所有信息,结构体成员代码段1所示。
  • struct file是在打开文件时VFS分配的,fd(文件描述符)用指示struct file结构体对象,两者均属于进程。而inode不属于进程,一个文件对应一个inode。
代码段1
struct ext4_inode {  
__le16  i_mode;     /* File mode */  
__le16  i_uid;      /* Low 16 bits of Owner Uid */  
__le32  i_size_lo;  /* Size in bytes */  
__le32  i_atime;    /* Access time */  
__le32  i_ctime;    /* Inode Change time */  
__le32  i_mtime;    /* Modification time */  
__le32  i_dtime;    /* Deletion Time */  
__le16  i_gid;      /* Low 16 bits of Group Id */  
__le16  i_links_count;  /* Links count */  
__le32  i_blocks_lo;    /* Blocks count */  
__le32  i_flags;    /* File flags */  
union {  
struct {  
__le32  l_i_version;  
} linux1;  
struct {  
__u32  h_i_translator;  
} hurd1;  
struct {  
__u32  m_i_reserved1;  
} masix1;  
} osd1;             /* OS dependent 1 */  
__le32  i_block[EXT4_N_BLOCKS];/* Pointers to blocks */  
__le32  i_generation;   /* File version (for NFS) */  
__le32  i_file_acl_lo;  /* File ACL */  
__le32  i_size_high;  
__le32  i_obso_faddr;   /* Obsoleted fragment address */  
union {  
struct {  
__le16  l_i_blocks_high; /* were l_i_reserved1 */  
__le16  l_i_file_acl_high;  
__le16  l_i_uid_high;   /* these 2 fields */  
__le16  l_i_gid_high;   /* were reserved2[0] */  
__le16  l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */  
__le16  l_i_reserved;  
} linux2;  
struct {  
__le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */  
__u16   h_i_mode_high;  
__u16   h_i_uid_high;  
__u16   h_i_gid_high;  
__u32   h_i_author;  
} hurd2;  
struct {  
__le16  h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */  
__le16  m_i_file_acl_high;  
__u32   m_i_reserved2[2];  
} masix2;  
} osd2;             /* OS dependent 2 */  
__le16  i_extra_isize;  
__le16  i_checksum_hi;  /* crc32c(uuid+inum+inode) BE */  
__le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */  
__le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */  
__le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */  
__le32  i_crtime;       /* File Creation time */  
__le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */  
__le32  i_version_hi;   /* high 32 bits for 64-bit version */  
__le32  i_projid;   /* Project ID */  
}; 

整体流程

假设要对根目录下的1.txt文件进行读命令

  1. 首先是挂载文件系统。文件系统挂载时,会将一部分metadata存放在内存中,其中包括Super block, Group Block信息以及"/"根目录文件的inode number
  2. 根据"/“根目录文件的inode number以及metadata可以计算出”/"文件的inode,并且通过读取inode里面的i_block找到对应的逻辑块号以及文件的长度
  3. 根据逻辑块号向NVMe SSD发起read请求,得到数据块的真实内容,这里假设该数据块已经缓存在文件系统的page cache里,下文对1.txt进行读命令时再详细分析此过程。
  4. 在data block中根据文件名(1.txt)进行索引,找到1.txt对应的inode number
  5. 根据1.txt的inode number以及metadata可以计算出"1.txt"文件的inode,并且通过读取inode里面的i_block找到对应逻辑块号和长度
  6. 将此命令传到block io layer,并根据block io layer进行调度,最后再给到NVMe驱动层。
  7. 驱动层会根据NVMe控制器的特性,将此read请求进行分割,比如一次只读取64个block,然后同时发起多个read请求
  8. 将请求写入多个SQ队列
  9. 通过PCIe Write TLP向NVMe控制器的每个sq doorbell寄存器写入新增的请求数量,通知SSD来主机端的SQ队列拿请求
  10. SSD拿到请求后解析命令,并将逻辑地址(LBA)通过FTL转化成物理块地址(PPA)
  11. 通过Flash Controller读取对应的CHIP,DIE,Plane,Block中的page。
  12. 将完成状态写入主机端的CQ队列
  13. 通过中断告诉主机端命令已经完成
  14. 主机端通过读取CQ队列获取命令完成状态

这篇关于用户层read write io命令到NVMe SSD全流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/902402

相关文章

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

关于Maven生命周期相关命令演示

《关于Maven生命周期相关命令演示》Maven的生命周期分为Clean、Default和Site三个主要阶段,每个阶段包含多个关键步骤,如清理、编译、测试、打包等,通过执行相应的Maven命令,可以... 目录1. Maven 生命周期概述1.1 Clean Lifecycle1.2 Default Li

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Python实现NLP的完整流程介绍

《Python实现NLP的完整流程介绍》这篇文章主要为大家详细介绍了Python实现NLP的完整流程,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 编程安装和导入必要的库2. 文本数据准备3. 文本预处理3.1 小写化3.2 分词(Tokenizatio

Linux使用nohup命令在后台运行脚本

《Linux使用nohup命令在后台运行脚本》在Linux或类Unix系统中,后台运行脚本是一项非常实用的技能,尤其适用于需要长时间运行的任务或服务,本文我们来看看如何使用nohup命令在后台... 目录nohup 命令简介基本用法输出重定向& 符号的作用后台进程的特点注意事项实际应用场景长时间运行的任务服

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

如何使用 Bash 脚本中的time命令来统计命令执行时间(中英双语)

《如何使用Bash脚本中的time命令来统计命令执行时间(中英双语)》本文介绍了如何在Bash脚本中使用`time`命令来测量命令执行时间,包括`real`、`user`和`sys`三个时间指标,... 使用 Bash 脚本中的 time 命令来统计命令执行时间在日常的开发和运维过程中,性能监控和优化是不