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);
}
예제 #2
0
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);
    }
  }
}