LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 12-28-2017, 08:06 AM   #1
dr.SysMan
LQ Newbie
 
Registered: Dec 2017
Location: Sain-Petersburg
Distribution: Ubuntu
Posts: 13

Rep: Reputation: Disabled
How to get an access to data has been read in the custom bi_end_io routine ?


Hello!

I developing a small block layered driver for Linux ...

I use my own bi_end_io() routine to intercept a data has been read from other block/disk device. So, my routine looks like:

Code:
static	void	__iob_xxx	(
		struct bio *	iob
			)
{
struct bio_vec	bvec = {0};
struct	bvec_iter iter = {0};
sector_t	lbn, nlbn;

	bio_for_each_segment(bvec, iob, iter)
		{
		char *	iobuf;

		iobuf = __bio_kmap_atomic(iob, iter);

		$TRACE("#%02d: page=%p, off=%u, len=%u, iobuf=%p, lbn=%lu",
			iter.bi_idx, bvec.bv_page, bvec.bv_offset, bvec.bv_len, iobuf, iter.bi_sector);


		__bio_kunmap_atomic(iob);
		}
}


static	void	dua_bio_end_io	(
			struct bio *	iob
				)
{
IOB_ARGS * iob_args;

	iob_args = iob->bi_private;

	iob->bi_end_io = iob_args->bi_end_io;
	iob->bi_private = iob_args->bi_private;

	__ret_iob_args (iob_args);

	if ( bio_data_dir(iob) == READ )
		__iob_xxx (iob);

	if ( iob->bi_end_io )
		iob->bi_end_io (iob);

}
So the bio_for_each_segment don't do anything .
What I/m need to check additionaly ?
Do I'm need to set in the make_request_fn() routine for the bio additionaly


Thanks!

Last edited by dr.SysMan; 12-28-2017 at 08:10 AM. Reason: add question
 
Old 12-28-2017, 09:20 AM   #2
dr.SysMan
LQ Newbie
 
Registered: Dec 2017
Location: Sain-Petersburg
Distribution: Ubuntu
Posts: 13

Original Poster
Rep: Reputation: Disabled
Some additions, it looks like that bvecs has been cleared before calling my bi_end_io() routine.
I expects that my bi_end_io() routine is calling before original bi_end_io(), but seems that it's not so.

Code:
static blk_qc_t dua_make_request_fn	(
		struct request_queue *	ioq,
			struct bio *	iob
				)
{
int	status = 0;

	if ( bio_data_dir(iob) == WRITE )
		__iob_xxx(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;
		}

	/* 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;
}
Thanks for any ideas!

Last edited by dr.SysMan; 12-28-2017 at 09:28 AM.
 
Old 01-11-2018, 07:01 AM   #3
dr.SysMan
LQ Newbie
 
Registered: Dec 2017
Location: Sain-Petersburg
Distribution: Ubuntu
Posts: 13

Original Poster
Rep: Reputation: Disabled
Hi !

A solution is the replacing a dumb macro ( bio_for_each_segment(bvec, iob, iter) ) with old school "for", see follows:


Code:
...
	/* Do each segment independently. */
	for (i = 0, bvl = iob->bi_io_vec; i < iob->bi_vcnt; i++, bvl++)
		{
		void	 *kaddr = kmap_atomic(bvl->bv_page), *iobuf;

		iobuf	= kaddr + bvl->bv_offset;

		nlbn	= bvl->bv_len/DUDRV$K_SECTORSZ;


		for ( ;nlbn; nlbn--, lbn++ , iobuf += DUDRV$K_SECTORSZ)
			{
                         ...
			}

		kunmap_atomic(kaddr);
	}
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Failing to read the correct data on Beagle bone black using ioctl and file read on I2C bus 0 jwmueckl Linux - Newbie 1 04-05-2016 11:53 AM
the get data from serial port function read() blocks when data not available DEF. Programming 3 11-17-2014 07:11 AM
Read System Call is getting blocked when tried to read the data from CDC device sanju.lnt Linux - Embedded & Single-board computer 0 09-11-2011 11:48 PM
[SOLVED] Serial port : Read data problem, not reading complete data anujmehta Linux - Networking 5 09-06-2010 06:10 AM
GRASS GIS 6.2.2 BadAlloc Error Causes Crash on Previously Usable Data & Routine joek Linux - Software 0 09-22-2007 06:27 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 09:15 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration