[PATCH] xip: bdev: execute in place
This is the block device related part. The block device operation direct_access now has a struct block_device as first parameter. Signed-off-by: Carsten Otte <cotte@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
committed by
Linus Torvalds
parent
3d41088fa3
commit
420edbcc09
@@ -35,14 +35,17 @@
|
|||||||
static int dcssblk_open(struct inode *inode, struct file *filp);
|
static int dcssblk_open(struct inode *inode, struct file *filp);
|
||||||
static int dcssblk_release(struct inode *inode, struct file *filp);
|
static int dcssblk_release(struct inode *inode, struct file *filp);
|
||||||
static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
|
static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
|
||||||
|
static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
|
||||||
|
unsigned long *data);
|
||||||
|
|
||||||
static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
|
static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
|
||||||
|
|
||||||
static int dcssblk_major;
|
static int dcssblk_major;
|
||||||
static struct block_device_operations dcssblk_devops = {
|
static struct block_device_operations dcssblk_devops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = dcssblk_open,
|
.open = dcssblk_open,
|
||||||
.release = dcssblk_release,
|
.release = dcssblk_release,
|
||||||
|
.direct_access = dcssblk_direct_access,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
|
static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
|
||||||
@@ -641,6 +644,20 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
|
|||||||
/* Request beyond end of DCSS segment. */
|
/* Request beyond end of DCSS segment. */
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
/* verify data transfer direction */
|
||||||
|
if (dev_info->is_shared) {
|
||||||
|
switch (dev_info->segment_type) {
|
||||||
|
case SEG_TYPE_SR:
|
||||||
|
case SEG_TYPE_ER:
|
||||||
|
case SEG_TYPE_SC:
|
||||||
|
/* cannot write to these segments */
|
||||||
|
if (bio_data_dir(bio) == WRITE) {
|
||||||
|
PRINT_WARN("rejecting write to ro segment %s\n", dev_info->dev.bus_id);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
index = (bio->bi_sector >> 3);
|
index = (bio->bi_sector >> 3);
|
||||||
bio_for_each_segment(bvec, bio, i) {
|
bio_for_each_segment(bvec, bio, i) {
|
||||||
page_addr = (unsigned long)
|
page_addr = (unsigned long)
|
||||||
@@ -661,7 +678,26 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
|
|||||||
bio_endio(bio, bytes_done, 0);
|
bio_endio(bio, bytes_done, 0);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
bio_io_error(bio, bytes_done);
|
bio_io_error(bio, bio->bi_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
|
||||||
|
unsigned long *data)
|
||||||
|
{
|
||||||
|
struct dcssblk_dev_info *dev_info;
|
||||||
|
unsigned long pgoff;
|
||||||
|
|
||||||
|
dev_info = bdev->bd_disk->private_data;
|
||||||
|
if (!dev_info)
|
||||||
|
return -ENODEV;
|
||||||
|
if (secnum % (PAGE_SIZE/512))
|
||||||
|
return -EINVAL;
|
||||||
|
pgoff = secnum / (PAGE_SIZE / 512);
|
||||||
|
if ((pgoff+1)*PAGE_SIZE-1 > dev_info->end - dev_info->start)
|
||||||
|
return -ERANGE;
|
||||||
|
*data = (unsigned long) (dev_info->start+pgoff*PAGE_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -885,6 +885,7 @@ struct block_device_operations {
|
|||||||
int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
|
int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
|
||||||
long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
|
long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
|
||||||
long (*compat_ioctl) (struct file *, unsigned, unsigned long);
|
long (*compat_ioctl) (struct file *, unsigned, unsigned long);
|
||||||
|
int (*direct_access) (struct block_device *, sector_t, unsigned long *);
|
||||||
int (*media_changed) (struct gendisk *);
|
int (*media_changed) (struct gendisk *);
|
||||||
int (*revalidate_disk) (struct gendisk *);
|
int (*revalidate_disk) (struct gendisk *);
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
|
Reference in New Issue
Block a user