Thanks, that was it! Therefore, it means that, i suppose, blk_rq_cur_sectors() is meaningless and bio's are needed to be used exclusively. Andras On Sat, 4 Mar 2017, Pranay Srivastava wrote: > On Friday, March 3, 2017, Andras Pal <apal@xxxxxxxxx> wrote: >> Dear All, >> >> with some experience in low-level C programming, I started to develop a >> kernel module which allows I2C slave EEPROM-alike devices (EEPROMs, FRAMs, >> BBRAMs, etc) to be accessed as block devices. Since the i/o transactions > are >> relatively slow (say, 40k/sec), i'm using kernel threads. However, it > seems >> that while the read (rq_data_dir(req)) == 0) operations are fine, write >> operations (rq_data_dir != 0) seems to be lost. For instance, if I do `dd >> bs=512 count=32 of=/dev/i2cblk0`, only the first 8 sectors are fetched by >> blk_fetch_request(). I copy the critical/relevant/interesting parts after > this >> message. The code is based on drivers/block/nbd.c. >> >> In addition - according to printk()-based debugging - after each write > request, >> the kernel starts to access sectors in the order of 0, 24, 8, 56, 120, > 64, 32 >> (with 8 sectors == 1 page per request). Maybe it seeks for some > filesystems...? >> Can this feature be turned off (like setting >> disk->queue->backing_dev_info.ra_pages to zero in order to turn off >> readaheaad)? >> >> thanks in advance, cheers, Andras >> >> > /*****************************************************************************/ >> >> static int i2cblk_process_io_request(struct i2cblk_device *device,struct > request *req) >> { >> int ret; >> >> /* i2cblk_transfer(): this function calls i2c_master_send/recv(), etc. > */ >> >> ret=i2cblk_transfer(device, blk_rq_pos(req), blk_rq_cur_sectors(req), > > Shouldn't you be going over all bio(s) > in this req? > >> bio_data(req->bio), >> rq_data_dir(req)); >> >> return(ret); >> } >> >> static void i2cblk_request(struct request_queue *q) >> { >> struct request *req; >> >> while ( (req=blk_fetch_request(q)) != NULL ) >> { struct i2cblk_device *device; >> >> if ( req->cmd_type != REQ_TYPE_FS ) >> { __blk_end_request_all(req, -EIO); >> continue; >> } >> >> /* spin_unlock_irq(q->queue_lock); */ >> >> device=req->rq_disk->private_data; >> >> spin_lock_irq(&device->active_lock); >> list_add_tail(&req->queuelist,&device->active_queue); >> spin_unlock_irq(&device->active_lock); >> >> wake_up(&device->active_wq); >> >> /* spin_lock_irq(q->queue_lock); */ >> }; >> >> } >> >> static void i2cblk_end_request(struct request *req) >> { >> int error; >> struct request_queue *q = req->q; >> unsigned long flags; >> >> error=(req->errors ? -EIO : 0); >> >> spin_lock_irqsave(q->queue_lock, flags); >> __blk_end_request_all(req, error); >> spin_unlock_irqrestore(q->queue_lock, flags); >> } >> >> static void i2cblk_handle_request(struct i2cblk_device *device,struct > request *req) >> { >> if ( i2cblk_process_io_request(device,req) ) >> req->errors++; >> >> i2cblk_end_request(req); >> >> return; >> } >> >> static int i2cblk_thread(void *data) >> { >> struct i2cblk_device *device = data; >> struct request *req; >> >> while ( ! kthread_should_stop() ) >> { >> wait_event_interruptible(device->active_wq,kthread_should_stop() > || (!list_empty(&device->active_queue))); >> >> if ( list_empty(&device->active_queue) ) >> continue; >> >> spin_lock_irq(&device->active_lock); >> req = list_entry(device->active_queue.next,struct > request,queuelist); >> list_del_init(&req->queuelist); >> spin_unlock_irq(&device->active_lock); >> >> i2cblk_handle_request(device,req); >> }; >> >> return(0); >> } >> >> >> _______________________________________________ >> Kernelnewbies mailing list >> Kernelnewbies@xxxxxxxxxxxxxxxxx >> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies >> > > -- > ---P.K.S > _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies