2012-10-04 17 views
11

Bir diski diskten okumak için kendi bio isteğimi nasıl oluşturabilirim?Linux çekirdeğinde bir bio isteği kullanarak bir sektör nasıl okunmalı

Aşağıdakileri deniyorum ama sistemi donduruyor.

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

Çok daha iyi çalışan sb_bread() kullanmayı denedim. Ama yine de sürücü özel istek fonksiyonu içinde engeller. (Bazı kilit nedeniyle tahmin ediyorum). Benim elde etmeye çalıştığım şey, bloğa bir blok yazılmadan önce bloğu okumak istiyorum, bunu blok cihazının make_request_fn'sini değiştirerek ele alıyorum. –

cevap

6

Eski bir soru ama yine de burada, ben birisi yardımcı olacağını umuyoruz okuma için kodudur:

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; 
} 

Ve yazma için

:

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 tahsis edilebilir alloc_page (GFP_KERNEL) ile. Ayrıca page'daki verileri değiştirmek için page_address(page)'u kullanın. void* değerini döndürür, böylece bu göstericiyi istediğiniz gibi yorumlayabilirsiniz.

İlgili konular