WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: "xen-devel-list" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] xen_block:how to read mbr using blkfront driver
From: "arsene" <arsene@xxxxxxxxxxxxxxx>
Date: Mon, 9 Nov 2009 20:21:01 +0800
Delivery-date: Mon, 09 Nov 2009 04:21:38 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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
<Prev in Thread] Current Thread [Next in Thread>