2012-10-04 5 views
11

디스크 드라이브에서 섹터를 읽는 방법을 직접 작성하려면 어떻게해야합니까?리눅스 커널에서 바이오 요청을 사용하여 섹터를 읽는 방법

다음을 시도하지만 시스템이 정지합니다.

static void read_bio() 
{ 
    struct bio *b; 
    struct page *p; 

    b = bio_alloc(GFP_KERNEL, 1); 
    if (!b) { 
     printk(KERN_INFO "bio allocation failed\n"); 
    } 
    bio_init(b); 

    b->bi_sector = 10000; 
    b->bi_bdev = bd; /* "/dev/sda1" */ 
    b->bi_end_io = bio_end_clone; 

    p = alloc_page(GFP_KERNEL); 
    if (!p) { 
     printk(KERN_INFO "page allocation failed\n"); 
    } 
    bio_add_page(b, p, PAGE_SIZE, 0); 
    b->bi_private = p; 

    bio_get(b); 
    submit_bio(READ, b); 
    printk(KERN_DEBUG "submit read request\n"); 
} 
+0

나는 훨씬 더 잘 작동하는 sb_bread()를 사용해 보았습니다. 하지만 여전히 드라이버 사용자 정의 요청 기능 내에서 차단됩니다. (나는 자물쇠 때문에 그것을 추측하고있다). 내가 달성하고자하는 것은 블록에 쓰기가 일어나기 전에 블록을 읽고 싶다. 나는 블록 장치의 make_request_fn을 대체하여 이것을 처리하고있다. –

답변

6

그것은 오래된 질문이지만, 어쨌든 여기, 내가 누군가 도움이되기를 바랍니다 읽는 코드입니다 :

int readPage(struct block_device *device, sector_t sector, int size, 
    struct page *page) 
{ 
    int ret; 
    struct completion event; 
    struct bio *bio = bio_alloc(GFP_NOIO, 1); 
    bio->bi_bdev = device; 
    bio->bi_sector = sector; 
    bio_add_page(bio, page, size, 0); 
    init_completion(&event); 
    bio->bi_private = &event; 
    bio->bi_end_io = readComplete; 
    submit_bio(READ | REQ_SYNC, bio); 
    wait_for_completion(&event); 
    ret = test_bit(BIO_UPTODATE, &bio->bi_flags); 
    bio_put(bio); 
    return ret; 
} 

그리고 쓰기

가 :

void writePage(struct block_device *device, 
      sector_t sector, int size, struct page *page) 
{ 
    struct bio *bio = bio_alloc(GFP_NOIO, 1); 
    bio->bi_bdev = vnode->blkDevice; 
    bio->bi_sector = sector; 
    bio_add_page(bio, page, size, 0); 
    bio->bi_end_io = writeComplete; 
    submit_bio(WRITE_FLUSH_FUA, bio); 
} 

page 할당 할 수 있습니다 alloc_page (GFP_KERNEL)와 함께. page에서 데이터를 변경하려면 page_address(page)을 사용하십시오. void*을 반환하므로 포인터를 원하는대로 해석 할 수 있습니다.

관련 문제