flashcache中内存与磁盘,磁盘与磁盘的io
int dm_io_async_bvec(unsigned int num_regions,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
struct dm_io_region *where,
#else
struct io_region *where,
#endif
int rw,
struct bio_vec *bvec, io_notify_fn fn,
void *context)
{
struct dm_io_request iorq; iorq.bi_rw = rw;
iorq.mem.type = DM_IO_BVEC;
iorq.mem.ptr.bvec = bvec;
iorq.notify.fn = fn;
iorq.notify.context = context;
iorq.client = flashcache_io_client;
return dm_io(&iorq, num_regions, where, NULL);
}
#endif
int
flashcache_dm_io_async_vm(struct cache_c *dmc, unsigned int num_regions,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
struct io_region *where,
#else
struct dm_io_region *where,
#endif
int rw,
void *data, io_notify_fn fn, void *context)
{
unsigned long error_bits = ;
int error;
struct dm_io_request io_req = {
.bi_rw = rw,
.mem.type = DM_IO_VMA,
.mem.ptr.vma = data,
.mem.offset = ,
.notify.fn = fn,
.notify.context = context,
.client = flashcache_io_client,
}; error = dm_io(&io_req, , where, &error_bits);
if (error)
return error;
if (error_bits)
return error_bits;
return ;
}
#endif
上面两个函数都使用struct dm_io_request 来包装了请求,其中的只有两种请求的类型是不一样的,第一个函数对应的是DM_IO_BVEC,第二个函数是DM_IO_VMA。
其实我开始一直不明白,为什么要使用这两个函数让硬盘与内存打交道,不过后来看了dm_io发现其中的io服务类型有多种不同类型,这两个函数的调用分别对应不同的io类型。下面先看一下dm_io相关的数据结构。
dm_io
dm-io为device mapper提供同步或者异步的io服务。
使用dm-io必须设置dm_io_region结构(2.6.26版本以前叫io_region),该结构定义了io操作的区域,读一般针对一个dm_io_region区,而写可以针对一组dm_io_region区。
struct dm_io_region {
struct block_device *bdev;
sector_t sector;
sector_t count; /* If this is zero the region is ignored. */
};
struct io_region {
struct block_device *bdev;
sector_t sector;
sector_t count;
};
dm-io一共有四种dm_io_mem_type类型(老一点的内核版本只有前面三种,Flashcache主要使用DM_IO_BVEC):
enum dm_io_mem_type {
DM_IO_PAGE_LIST,/* Page list */
DM_IO_BVEC, /* Bio vector */
DM_IO_VMA, /* Virtual memory area */
DM_IO_KMEM, /* Kernel memory */
}; struct dm_io_memory {
enum dm_io_mem_type type;
union {
struct page_list *pl;
struct bio_vec *bvec;
void *vma;
void *addr;
} ptr; unsigned offset;
};
struct page_list {
struct page_list *next;
struct page *page;
};
int dm_io_sync(unsigned int num_regions, struct io_region *where, int rw,
struct page_list *pl, unsigned int offset,
unsigned long *error_bits);
int dm_io_async(unsigned int num_regions, struct io_region *where, int rw,
struct page_list *pl, unsigned int offset,
io_notify_fn fn, void *context);
int dm_io_sync_bvec(unsigned int num_regions, struct io_region *where,
int rw, struct bio_vec *bvec,
unsigned long *error_bits);
int dm_io_async_bvec(unsigned int num_regions, struct io_region *where,
int rw, struct bio_vec *bvec,
io_notify_fn fn, void *context);
int dm_io_sync_vm(unsigned int num_regions, struct io_region *where, int rw,
void *data, unsigned long *error_bits);
int dm_io_async_vm(unsigned int num_regions, struct io_region *where, int rw,
void *data, io_notify_fn fn, void *context);
当用户完成了使用I/O服务,他们将调用dm_io_put(),并指定和给dm_io_get()的相同数量的页面。
dm-io通过dm_io_request结构来封装请求的类型,如果设置了dm_io_notify.fn则是异步IO,否则是同步IO。
struct dm_io_request {
int bi_rw; /* READ|WRITE - not READA */
struct dm_io_memory mem; /* Memory to use for io */
struct dm_io_notify notify; /* Synchronous if notify.fn is NULL */
struct dm_io_client *client; /* Client memory handler */
};
使用dm_io服务前前需要通过dm_io_client_create函数(在2.6.22版本前是dm_io_get)先创建dm_io_client结构,为dm-io的执行过程中分配内存池。使用dm-io服务完毕后,则需要调用dm_io_client_destroy函数(在2.6.22版本前是dm_io_put)释放内存池。
struct dm_io_client {
mempool_t *pool;
struct bio_set *bios;
};
dm-io函数执行具体的io请求。
int dm_io(struct dm_io_request *io_req, unsigned num_regions,
struct dm_io_region *where, unsigned long *sync_error_bits)
{
int r;
struct dpages dp; r = dp_init(io_req, &dp);
if (r)
return r; if (!io_req->notify.fn)
return sync_io(io_req->client, num_regions, where,
io_req->bi_rw, &dp, sync_error_bits); return async_io(io_req->client, num_regions, where, io_req->bi_rw,
&dp, io_req->notify.fn, io_req->notify.context);
}
对于第二种情况,磁盘跟磁盘之前的交互。这种情况只用于将ssd中脏块写入disk中。
int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from,
unsigned int num_dests, struct dm_io_region *dests,
unsigned int flags, dm_kcopyd_notify_fn fn, void *context)
第一个参数dm_kcopyd_client,在使用kcopyd异步拷贝服务时,必须先创建一个对应的client,首先要分配“kcopyd客户端”结构,调用函数如下:
kcopyd_client_create(FLASHCACHE_COPY_PAGES, &flashcache_kcp_client);
创建dm_kcopyd_client结构。
struct block_device *bdev;
sector_t sector;
sector_t count; /* If this is zero the region is ignored. */
};
flashcache中内存与磁盘,磁盘与磁盘的io的更多相关文章
- CentOS查看CPU、内存、网络流量和磁盘 I/O
安装 yum install -y sysstat sar -d 1 1 rrqm/s: 每秒进行 merge 的读操作数目.即 delta(rmerge)/swrqm/s: 每秒进行 merge 的 ...
- CentOS查看CPU、内存、网络流量和磁盘 I/O【详细】
安装 yum install -y sysstat sar -d 1 1 rrqm/s: 每秒进行 merge 的读操作数目.即 delta(rmerge)/swrqm/s: 每秒进行 merge 的 ...
- linux硬件资源问题排查:cpu负载、内存使用情况、磁盘空间、磁盘IO
在使用过程中之前正常的功能,突然无法使用,性能变慢,通常都是资源消耗问题,资源消耗可以从以下几个方面去排查.对于已经安装硬件资源监控软件(zabbix)的环境,直接使用硬件资源监控软件(zabbix) ...
- 请确认 <Import> 声明中的路径正确,且磁盘上存在该文件。
在网上下了个源码打开报错. 请确认 <Import> 声明中的路径正确,且磁盘上存在该文件. 一查,原来是路径错误. 解决办法:将项目文件(.csproj)用记事本打开,然后找到<I ...
- 升级CUDA版本导致VS2010错误:未找到导入的项目XXX,请确认<Import>声明中的路径正确,且磁盘上存在该文件
转自:http://www.cnblogs.com/yeahgis/p/3853420.html VS2010错误:未找到导入的项目XXX,请确认<Import>声明中的路径正确,且磁盘上 ...
- Linux学习(十四)磁盘格式化、磁盘挂载、手动增加swap空间
一.磁盘格式化 分好去的磁盘需要格式化之后才可以使用.磁盘分区一般用mke2fs命令或者mkfs.filesystemtype.这个filesystemtype分为ext4,ext3,xfs等等.xf ...
- Linux学习之CentOS(十二)------磁盘管理之 磁盘的分区、格式化、挂载(转)
磁盘分区.格式化.挂载磁盘分区 新增分区 查询分区 删除分区磁盘格式化 mkfs mke2fs磁盘挂载与卸载 mount umount 磁盘的分区.格式化.挂 ...
- (转)GPT磁盘与MBR磁盘区别
摘要: Windows 2008磁盘管理器中,在磁盘标签处右击鼠标,随磁盘属性的不同会出现“转换到动态磁盘”,“转换到基本磁盘”“转换成GPT磁盘”,“转换成MBR磁盘”等选项,在此做简单介绍.部 ...
- Linux磁盘系统——管理磁盘的命令
Linux磁盘系统——管理磁盘的命令 摘要:本文主要学习了Linux系统中管理磁盘的命令,包括查看磁盘使用情况.磁盘挂载相关.磁盘分区相关.磁盘格式化等操作. df命令 df命令用于显示Linux系统 ...
随机推荐
- C#3.0匿名类和Lanmda表达式
1.初始化器:className variableName = new className(property1=value1…); 2.var可以声明一个没有类型的变量,根据赋值的不同改变数据类型 3 ...
- 转:centos7.2安装jdk1.6和/etc/profile不生效问题
转:centos7.2安装jdk1.6和/etc/profile不生效问题 转自:http://blog.csdn.net/cuker919/article/details/54178611 一.查看 ...
- LintCode2016年8月22日算法比赛----平面列表
平面列表 题目描述 给定一个列表,该列表中的每个要素要么是个列表,要么是整数.将其变成一个只包含整数的简单列表. 注意事项 如果给定的列表中的要素本身也是一个列表,那么它也可以包含列表. 样例 给定 ...
- How to fix Mysql table crashes
Whenever you enconter this: Please use mysql_upgrade to fix this error. or using mysql_upgrade -u r ...
- VC学习笔记---ATL MFC CLR三个库的区别
MFC.ATL和CLR是VC2005内置的三大库,涵盖了Windows的各种开发方法和开发应用.当然关于C++开发的库不止这三个,不过这三个是微软推荐. 从编程所处层次而言,WIN32为最底层,其次是 ...
- winform基础控件-例子学习
1.如图实现整数计算器 ComboBox控件: Items属性:添加集合中的项. this.comoper.Items.AddRange(new object[] { "+", & ...
- Unity IOC/DI使用
一.IOC介绍 IOC(Inversion of Control),中文译为控制反转,又称为“依赖注入”(DI =Dependence Injection) IOC的基本概念是:不创建对象,但是描述创 ...
- iOS设计模式 - 装饰
iOS设计模式 - 装饰 原理图 说明 1. cocoa框架本身实现了装饰模式(category的方式实现了装饰模式) 2. 装饰模式指的是动态的给一个对象添加一些额外的职责,相对于继承子类来说,装饰 ...
- Win10笔记本显卡驱动更新升级
对于游戏玩家来说,对显卡的关注度要高于电脑其它硬件,一般来说,显卡越好,游戏性能往往越强.不过要持续发挥显卡的最佳游戏性能,经常更新显卡驱动也是很有必要的.那么笔记本显卡驱动怎么更新?下面小编以自己的 ...
- Microsoft Visual Studio 遇到了问题需要关闭
新年刚来Microsoft Visual Studio就找麻烦,debug的时候如果不打断点可以正常跑过,一打断点就崩溃,重启.报的问题是:Microsoft Visual Studio 遇到了问题需 ...