当前位置:编程学习 > C/C++ >>

dm_io_async_bvec()函数分析

[cpp]  
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);  
}  
The user must set up an io_region structure to describe the desired location of the I/O. Each io_region indicates a block-device along with the starting sector and size of the region.
但是不同的内核版本io_region 结构体的表示不同。
2.6.26以后的版本用dm_io_region表示如下:
[cpp] 
struct dm_io_region {  
    struct block_device *bdev;  
    sector_t sector;  
    sector_t count;     /* If this is zero the region is ignored. */  
};  
 
2.6.26之前的版本用io_region表示如下:
[cpp] 
struct io_region {                                                                                                                                  
     struct block_device *bdev;  
     sector_t sector;  
     sector_t count;                                                                                                                           
 };  
 
虽然形式不同,但是里面的内容是一样的,都含有一个指向block_device的指针,以及区域的起始扇区和区域的大小。
 
bio_vec结构体如下:
[cpp]  
struct bio_vec {  
    struct page *bv_page;<span style="white-space:pre"> </span>//指向段的页框中页描述符的指针  
    unsigned int    bv_len;<span style="white-space:pre">       </span>//段的字节长度  
    unsigned int    bv_offset;<span style="white-space:pre">    </span>//页框中段数据的偏移量  
};  
 
io_notify_fn是一个回调函数指针的类型,其定义如下:
[cpp] 
typedef void (*io_notify_fn)(unsigned long error, void *context);  
The "error" parameter in this callback,, is a bitset (instead of a 易做图 error value). In the case of an write-I/O to multiple regions, this bitset allows dm-io to indicate success or failure on each individual region.
 
dm_io_request结构体如下:(通过dm_io_request结构来封装请求的类型,如果设置了dm_io_notify.fn则是异步IO,否则是同步IO。)
[cpp] 
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_async_bvec通过io_notify_fn fn来确定是同步操作还是异步操作,通过bio_vec *bvec确定dm_io的服务类型,dm_io有3种服务类型:
[cpp]  
//The first I/O service type takes a list of memory pages as the data buffer for the I/O, along with an offset into the first page.  
  
   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);  
[cpp]  
//The second I/O service type takes an array of bio vectors as the data buffer for the I/O. This service can be handy if the caller has a pre-assembled bio, but wants to direct different portions of the bio to different devices.  
  
   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);  
 
[cpp] 
//The third I/O service type takes a pointer to a vmalloc'd memory buffer as the data buffer for the I/O. This service can be handy if the caller needs to do I/O to a large region but doesn't want to allocate a large number of individual memory pages.  
     
   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);  
 
dm_io_async_bvec通过dm_io_request封装请求之后,确定了请求的各种类型,然后由dm_io()函数来完成操作。dm_io函数如下:
[cpp]  
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) &nbs
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,