libpmem主要通过pmem_map_file封装来进行mmap的映射,首先通过util_file_get_type获取文件类型,主要区分文件是否存在,DAX设备文件。比赛用的fsdax,这个主要通过mmap来实现的寻址操作,挂载路径为/dev/pmem/。还有devdax,这个好像是给虚拟机分配的时候用这个模式,挂载路径为/dev/dax/。还有sector和raw模式。

文件支持的flag有(PMEM_FILE_CREATE|PMEM_FILE_EXCL|PMEM_FILE_SPARSE|PMEM_FILE_TMPFILE),dax设备支持的flag有(PMEM_FILE_CREATE|PMEM_FILE_SPARSE).

然后判断是dax后,判断len必须是0或者文件大小。open_flags默认有O_RDWR,如果flag有PMEM_FILE_CREATE则open_flags添加O_CREAT。后边判断传了len必须有PMEM_FILE_CREATE,len为0必须没有PMEM_FILE_CREATE.PMEM_FILE_TMPFILE必须有PMEM_FILE_CREATE.之后os_open(path, open_flags, mode)打开文件。如果flag带有PMEM_FILE_CREATE,则os_ftruncate文件,没有PMEM_FILE_SPARSE,则os_posix_fallocate(fd, 0, (os_off_t)len))文件。这里看不太懂,看手册这俩函数基本是等价的。如果没有PMEM_FILE_CREATE,则获取真是文件大小,重新复制len。

然后pmem_map_register,在pmem_posix.c里,调用util_map,传了MAP_SHARED。在common/mmap.c里
肯定有PROT_READ|PROT_WRITE,然后调用util_map_hint,这个主要就是确定mmap地址的,调试有参数可以固定虚地址的,这个看书看过。基本用不上。好像是通过mmap MAP_PRIVATE找一个mmap对齐的地址。 req_align为零,align = GIGABYTE。#define GIGABYTE ((uintptr_t)1 << 30)。这里脑袋有点浆糊了,不具体看就是找个一个对齐地址,然后后边用来mmap pmem文件使用,先这样吧。然后util_map_sync,地址是刚返回的地址,在这里mmap了。

然后复制len和is_pmemp。关闭fd,就结束了。pmem_is_pmem里边东西还挺多,有调试相关,乱七八糟一堆,主要是在初始化指定默认判断函数,然后在这里如果有env或者其他情况进行函数转换,然后掉函数看结果,不细看了,因为比赛肯定为pmem。

其实总结一下流程很简单,先打开文件,设置文件大小。然后mmap寻找一个对齐地址,最后真正mmap,返回。

上一篇:
下一篇:

相关文章:

Categories: 博客记录

0 Responses so far.

Leave a Reply