static void drv_chn_receive(struct msg_buffer* buffer) { struct ramdisk_message* rep = buffer->buffer; struct req_data* rdata; struct ramdisk_dev *dev; struct request *req; char* buff; unsigned long offset = rep->sector*KERNEL_SECTOR_SIZE; unsigned long nbytes = rep->nsect*KERNEL_SECTOR_SIZE; printk("response: %ld, sector: %ld, nsect: %ld, write:%d\n", rep->req_number, rep->sector, rep->nsect, rep->write); rdata = (struct req_data*)rep->req_number; dev = rdata->dev; req = rdata->req; buff = bio_data(req->bio); if (!rep->write) { printk("Writing from %p to %p, %ld nbytes\n", buffer->buffer, buff, nbytes); memcpy(buff, buffer->buffer + sizeof(struct ramdisk_message), nbytes); } if(blk_end_request_cur(req, 0)){ ramdisk_transfer(dev, req); } buffer->release(buffer); }
void block_request(struct request_queue *q) { struct request *req; unsigned long offset, nbytes; req = blk_fetch_request(q); while (req != NULL) { // Stop looping once we've exhausted the queue. // The kernel will call this function whenever // there is at least one element in the queue. // Check if we support handling this request. if (req == NULL || req->cmd_type != REQ_TYPE_FS) { // Declare our intention to handle no buffers // from this request. We'll use an IO error // to signal that we don't accept requests that // aren't related to reading/writing to the // filesystem. blk_end_request_all(req, -EIO); continue; } // Handle the request. // offset = blk_rq_pos(req) * LOGICAL_BLOCK_SIZE; // nbytes = blk_rq_cur_sectors(req) * LOGICAL_BLOCK_SIZE; if (rq_data_dir(req)) { // Check that the write won't exceed the size of the block device. if ((offset + nbytes) <= size) { // Do write. memcpy(data + offset, req->buffer, nbytes); } } else { // Do read. memcpy(req->buffer, data + offset, nbytes); } // Declare our intention to end the request. // if buffers still need to be handled, blk_end_request_cur // will return true, and we'll continue handling this req. if (!blk_end_request_cur(req, 0)) { // If not, pop a new request off the queue req = blk_fetch_request(q); } } }