[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] xen_block:how to read mbr using blkfront driver



Hi all,
 
Now i am porting an OS to xen3.1.4(no-PAE).  I want to implement blkfront driver according to Linux. But when i using my driver to read mbr, i got the data which is different from the phisical disk. I want to read the segment 0 on disk to req->bufs[0].buffer,
The following is what i did:
 
 
ring_req->id = id;
ring_req->sector_number = 0;
ring_req->handle = info->handle;
ring_req->operation = BLKIF_OP_READ;
ring_req->nr_segments = 1 ;/*just one segment*/
 
buffer_mfn = virt_to_mfn(((unsigned int)req->bufs[0].buffer));/*macro in MiniOS, get the machine page of buffer*/
fsect = (((unsigned int)req->bufs[0].buffer) >> 9) %8;
lsect = fsect + (req->bufs[0].length >> 9) - 1;/*length of req->bufs[0].buffer*/
 
ref = gnttab_grant_access(info->xbdev->otherend_id, buffer_mfn, 0 );
info->shadow[id].frame[0] = mfn_to_pfn(buffer_mfn);
ring_req->seg[0] = (struct blkif_request_segment) {
.gref       = ref,
.first_sect = fsect,
.last_sect  = lsect 
};
 
 
Then i try to modify linux domU source code( linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c). I still got the same result.
The following is what i did:
 
volatile unsigned char * test_data = 0;
static int blkif_queue_request(struct request *req)
{
struct blkfront_info *info = req->rq_disk->private_data;
unsigned long buffer_mfn;
blkif_request_t *ring_req;
struct bio *bio;
struct bio_vec *bvec;
int idx;
unsigned long id;
unsigned int fsect, lsect;
int ref;
grant_ref_t gref_head;
int i=0;
if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
return 1;
if (gnttab_alloc_grant_references(
BLKIF_MAX_SEGMENTS_PER_REQUEST, &gref_head) < 0) {
gnttab_request_free_callback(
            &info->callback,
 blkif_restart_queue_callback,
            info,
            BLKIF_MAX_SEGMENTS_PER_REQUEST);
return 1;
}
ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
id = GET_ID_FROM_FREELIST(info);
info->shadow[id].request = (unsigned long)req;
ring_req->id = id;
ring_req->sector_number = (blkif_sector_t)0;
ring_req->handle = info->handle;
ring_req->operation = rq_data_dir(req) ?
BLKIF_OP_WRITE : BLKIF_OP_READ;
if (blk_barrier_rq(req))
ring_req->operation = BLKIF_OP_WRITE_BARRIER;
ring_req->nr_segments = 0;
rq_for_each_bio (bio, req) {
bio_for_each_segment (bvec, bio, idx) {
BUG_ON(ring_req->nr_segments
       == BLKIF_MAX_SEGMENTS_PER_REQUEST);
buffer_mfn = page_to_phys(bvec->bv_page) >> PAGE_SHIFT;
fsect = bvec->bv_offset >> 9;
lsect = fsect + (bvec->bv_len >> 9) - 1;
/* install a grant reference. */
ref = gnttab_claim_grant_reference(&gref_head);
BUG_ON(ref == -ENOSPC);
gnttab_grant_foreign_access_ref(
ref,
info->xbdev->otherend_id,
buffer_mfn,
rq_data_dir(req) );
info->shadow[id].frame[ring_req->nr_segments] =
mfn_to_pfn(buffer_mfn);
ring_req->seg[ring_req->nr_segments] =
(struct blkif_request_segment) {
.gref       = ref,
.first_sect = fsect,
.last_sect  = lsect };
ring_req->nr_segments++;
if(ring_req->nr_segments == 1)
goto end;
}
}
end:
if(!test_data){
test_data = ((char*)(bvec->bv_page)) + bvec->bv_offset;
printk("buffer_mfn = %d, buffer_mfn address = 0x%x\n", buffer_mfn, test_data);
for(i=0;i<256;i++){
printk("%02x ", *(test_data + i)); 
if(i%16 == 15)  
printk("\n");  
}
          }
    info->ring.req_prod_pvt++;
    /* Keep a private copy so we can reissue requests when recovering. */
    info->shadow[id].req = *ring_req;
gnttab_free_grant_references(gref_head);
return 0;
}
 
static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
struct request *req;
blkif_response_t *bret;
RING_IDX i, rp;
unsigned long flags;
struct blkfront_info *info = (struct blkfront_info *)dev_id;
int uptodate;
spin_lock_irqsave(&blkif_io_lock, flags);
if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
spin_unlock_irqrestore(&blkif_io_lock, flags);
return IRQ_HANDLED;
}
again:
rp = info->ring.sring->rsp_prod;
rmb(); /* Ensure we see queued responses up to 'rp'. */
for (i = info->ring.rsp_cons; i != rp; i++) {
unsigned long id;
int ret;
    bret = RING_GET_RESPONSE(&info->ring, i);
    id   = bret->id;
    req  = (struct request *)info->shadow[id].request;
    blkif_completion(&info->shadow[id]);
    ADD_ID_TO_FREELIST(info, id);
    uptodate = (bret->status == BLKIF_RSP_OKAY);
    switch (bret->operation) {
     case BLKIF_OP_WRITE_BARRIER:
     if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
            printk("blkfront: %s: write barrier op failed\n",
              info->gd->disk_name);
       uptodate = -EOPNOTSUPP;
  info->feature_barrier = 0;
            xlvbd_barrier(info);
     }
/* fall through */
    case BLKIF_OP_READ:
    case BLKIF_OP_WRITE:
    if (unlikely(bret->status != BLKIF_RSP_OKAY))
DPRINTK("Bad return from blkdev data "
"request: %x\n", bret->status);
    ret = end_that_request_first(req, uptodate,
    req->hard_nr_sectors);
    BUG_ON(ret);
    end_that_request_last(req, uptodate);
break;
default:
BUG();
    }
}
info->ring.rsp_cons = i;
if (i != info->ring.req_prod_pvt) {
int more_to_do;
RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
if (more_to_do)
goto again;
} else
info->ring.sring->rsp_event = i + 1;
kick_pending_request_queues(info);
spin_unlock_irqrestore(&blkif_io_lock, flags);
 
printk("blk int\n");
for(i=0;i<256;i++){
printk("%02x ", *(test_data + i)); 
if(i%16 == 15)  
printk("\n");  
}
while(1);
return IRQ_HANDLED;
}
 
Can anyone help me?
 
regards,
2009-11-09

arsene
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.