如果克隆了BIO,如何访问数据? [英] How to access to data if BIO has been cloned ?
本文介绍了如果克隆了BIO,如何访问数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
你好!
我写Linux设备驱动程序应该在existen设备驱动程序之上工作,所以我尝试使用bi_end_io()complition已从磁盘设备读取访问数据缓冲区的I / O例程,请参阅以下代码:
static void dua_bio_end_io(
struct bio * iob
)
{
IOB_ARGS * iob_args;
$ TRACE( 输入%s完成I / O,生物=%p。 ..,bio_data_dir(iob)== WRITE? WRITE: READ,iob);
$ SHOW_UNSIGNED(iob-> bi_flags);
$ SHOW_INT(iob-> bi_vcnt);
$ SHOW_BOOL(bio_has_data(iob));
iob_args = iob-> bi_private;
iob-> bi_end_io = iob_args-> bi_end_io;
iob-> bi_private = iob_args-> bi_private;
bio_put(iob);
__ret_iob_args(iob_args);
/ * 如果是READ请求 - 我们现在应该解密数据缓冲区* /
if (bio_data_dir(iob)== READ)
__iob_enc_dec(iob);
bio_endio(iob);
}
static blk_qc_t dua_make_request_fn(
struct request_queue * ioq,
struct bio * iob
)
{
int status = 0 ;
$ TRACE( 开始(%s),生物=%p,op =% d ...,bio_data_dir(iob)== WRITE? WRITE: READ,iob,bio_op(iob));
$ SHOW_UNSIGNED(iob-> bi_flags);
$ SHOW_INT(iob-> bi_vcnt);
$ SHOW_BOOL(bio_has_data(iob));
/ * 如果是WRITE请求 - 我们现在可以加密数据缓冲区* /
if (bio_data_dir(iob)== WRITE)
__iob_enc_dec(iob);
/ *
*处理READ请求需要'入队读取请求'& '等待读完成'范例,
*所以我们需要分配IOB_ARGS块来将数据传送到读完成I / O例程。
* /
else if (bio_data_dir(iob)= = READ)
{
IOB_ARGS * iob_args = NULL;
if (__ get_iob_args(& iob_args))
{
printk(KERN_ERR __MODULE__ :缓冲的I / O配额限制已用尽\ n);
iob-> bi_error = -EBUSY;
bio_endio(iob);
}
iob_args-> bi_end_io = iob-> bi_end_io;
iob_args-> bi_private = iob-> bi_private;
/ *
*替换完成I / O例程的地址'读'操作,
*保存原始地址。
* /
iob-> bi_private = iob_args;
iob-> bi_end_io = dua_bio_end_io;
bio_get(iob);
}
/ * 仅供健全检查...... * /
else {
printk(KERN_WARNING __MODULE__ :未处理的I / O请求%d \ n,bio_data_dir(iob));
}
/ * 调用原始make_reques_fn()执行主要工作...... * /
status = backend_make_request_fn(ioq,iob);
返回状态;
}
...
6463.418222] [DUDRIVER \\ \\ dua_make_request_fn:479]开始(READ),bio = ffff95c5f9552100,op = 0 ...
[6463.418222] [DUDRIVER\dua_make_request_fn:482]:iob-> bi_flags = 0x00000000
[6463.418223] [DUDRIVER\dua_make_request_fn:483]:iob-> bi_vcnt = 1
[6463.418223] [DUDRIVER\dua_make_request_fn:485]:bio_has_data(iob)= ENABLED(TRUE)
[ 6463.418266] [DUDRIVER\dua_bio_end_io:445]输入READ完成I / O,bio = ffff95c5f9552100 ...
[6463.418266] [DUDRIVER\dua_bio_end_io:447]:iob-> bi_flags = 0x00000102
[6463.418267] [DUDRIVER\dua_bio_end_io:448]:iob-> bi_vcnt = 1
[6463.418267] [DUDRIVER\dua_bio_end_io:450]:bio_has_data(iob)= DISABLED(FALSE)
那么,有没有办法在克隆的BIO中读取数据?
或者,也许我是需要使用其他一些策略来保持对原始biovecs的访问吗? />
我尝试了什么:
我读过LDD3,并检查了很多例子。
我使用Linux内核4.10.y
提前致谢!
解决方案
TRACE( 输入%s完成I / O,生物=%p ... ,bio_data_dir(iob)== WRITE? WRITE: READ,iob);
SHOW_UNSIGNED(iob-> bi_flags) ;
SHOW_INT(iob-> bi_vcnt);
Hello !
I writting the Linux Device Driver is supposed to work on top of existen device drivers, so I try to use bi_end_io() complition I/O routine to access a data buffers has been read from disk device, see piece of code follows:
static void dua_bio_end_io (
struct bio * iob
)
{
IOB_ARGS * iob_args;
$TRACE("Entering to %s completion I/O, bio=%p ...", bio_data_dir(iob) == WRITE ? "WRITE" : "READ", iob);
$SHOW_UNSIGNED(iob->bi_flags);
$SHOW_INT(iob->bi_vcnt);
$SHOW_BOOL(bio_has_data(iob));
iob_args = iob->bi_private;
iob->bi_end_io = iob_args->bi_end_io;
iob->bi_private = iob_args->bi_private;
bio_put(iob);
__ret_iob_args (iob_args);
/* In case of READ request - we should decrypt data buffer right now */
if ( bio_data_dir(iob) == READ )
__iob_enc_dec(iob);
bio_endio (iob);
}
static blk_qc_t dua_make_request_fn (
struct request_queue * ioq,
struct bio * iob
)
{
int status = 0;
$TRACE("Starting (%s), bio=%p, op=%d ...", bio_data_dir(iob) == WRITE ? "WRITE" : "READ", iob, bio_op(iob));
$SHOW_UNSIGNED(iob->bi_flags);
$SHOW_INT(iob->bi_vcnt);
$SHOW_BOOL(bio_has_data(iob));
/* In case of WRITE request - we can encrypt data buffer right now */
if ( bio_data_dir(iob) == WRITE )
__iob_enc_dec(iob);
/*
* A handling of the READ request is require 'enqueue read request' & 'wait for read completion' paradigm,
* so we need to allocate IOB_ARGS block to carry data to the "Read Completion I/O" routine.
*/
else if ( bio_data_dir(iob) == READ )
{
IOB_ARGS *iob_args = NULL;
if ( __get_iob_args (&iob_args) )
{
printk(KERN_ERR __MODULE__ ": Buffered I/O quota limit has been exhausted\n");
iob->bi_error = -EBUSY;
bio_endio(iob);
}
iob_args->bi_end_io = iob->bi_end_io;
iob_args->bi_private = iob->bi_private;
/*
* Replace an address of the Completion I/O routine for 'read' operation,
* save original address.
*/
iob->bi_private = iob_args;
iob->bi_end_io = dua_bio_end_io;
bio_get(iob);
}
/* Just for sanity check ... */
else {
printk(KERN_WARNING __MODULE__ ": Unhandled I/O request %d\n", bio_data_dir(iob) );
}
/* Call original make_reques_fn() to performs a main work ... */
status = backend_make_request_fn(ioq, iob);
return status;
}
...
6463.418222] [DUDRIVER\dua_make_request_fn:479] Starting (READ), bio=ffff95c5f9552100, op=0 ... [ 6463.418222] [DUDRIVER\dua_make_request_fn:482] : iob->bi_flags = 0x00000000 [ 6463.418223] [DUDRIVER\dua_make_request_fn:483] : iob->bi_vcnt = 1 [ 6463.418223] [DUDRIVER\dua_make_request_fn:485] : bio_has_data(iob) = ENABLED(TRUE) [ 6463.418266] [DUDRIVER\dua_bio_end_io:445] Entering to READ completion I/O, bio=ffff95c5f9552100 ... [ 6463.418266] [DUDRIVER\dua_bio_end_io:447] : iob->bi_flags = 0x00000102 [ 6463.418267] [DUDRIVER\dua_bio_end_io:448] : iob->bi_vcnt = 1 [ 6463.418267] [DUDRIVER\dua_bio_end_io:450] : bio_has_data(iob) = DISABLED(FALSE)
So, is there a way to access has been read data in the cloned BIO ?
Or, may be I'm need to use some other tactic to keep access to original biovecs ?
What I have tried:
I read LDD3, and check the a lot of examples. I working with the Linux kernel 4.10.y
Thanks in advance!
解决方案
TRACE("Entering to %s completion I/O, bio=%p ...", bio_data_dir(iob) == WRITE ? "WRITE" : "READ", iob);
SHOW_UNSIGNED(iob->bi_flags);
SHOW_INT(iob->bi_vcnt);
这篇关于如果克隆了BIO,如何访问数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文