1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#include <linux/fs.h>
#include <linux/genhd.h>
#include <linux/bio.h>
#include <ddekit/assert.h>
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;
}
|