#include #include #include #include struct gendisk *find_disk_by_name (char *); void dde_page_cache_add (struct page *); struct block_device *open_block_dev (char *name, int part, fmode_t mode) { struct gendisk *disk = find_disk_by_name (name); if (disk) { dev_t devid = MKDEV (disk->major, disk->first_minor + part); return open_by_devnum (devid, mode); } return ERR_PTR(-ENXIO); } /* read or write a piece of data to a block device. * DATA must be in one page. * SECTORNR: the writing location in sectors. */ int block_dev_rw (struct block_device *dev, int sectornr, char *data, int count, int rw, void (*done (int err))) { int err = 0; struct bio *bio; struct page *page; int i; void end_bio (struct bio *bio, int err) { done (err); } assert (count <= PAGE_SIZE); bio = bio_alloc (GFP_NOIO, 1); if (bio == NULL) { err = ENOMEM; goto out; } page = kmalloc (sizeof (*page), GFP_KERNEL); if (page == NULL) { err = ENOMEM; goto out; } bio->bi_sector = sectornr; bio->bi_bdev = dev; page->virtual = data; dde_page_cache_add (page); bio->bi_io_vec[0].bv_page = page; bio->bi_io_vec[0].bv_len = count; bio->bi_io_vec[0].bv_offset = (int) data & ~PAGE_MASK; bio->bi_vcnt = 1; bio->bi_idx = 0; bio->bi_size = count; bio->bi_end_io = end_bio; bio->bi_private = NULL; bio_get (bio); submit_bio (rw, bio); if (bio_flagged (bio, BIO_EOPNOTSUPP)) { err = -EOPNOTSUPP; goto out; } bio_put (bio); out: if (err) { if (bio) bio_put (bio); kfree (page); } return err; }