diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2008-08-16 01:10:05 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-08-27 03:50:19 -0400 |
commit | abf5439370491dd6fbb4fe1a7939680d2a9bc9d4 (patch) | |
tree | aa3630557fe4a4bc6313617f5770af30eec68515 /include | |
parent | 1941246dd98089dd637f44d3bd4f6cc1c61aa9e4 (diff) |
block: move cmdfilter from gendisk to request_queue
cmd_filter works only for the block layer SG_IO with SCSI block
devices. It breaks scsi/sg.c, bsg, and the block layer SG_IO with SCSI
character devices (such as st). We hit a kernel crash with them.
The problem is that cmd_filter code accesses to gendisk (having struct
blk_scsi_cmd_filter) via inode->i_bdev->bd_disk. It works for only
SCSI block device files. With character device files, inode->i_bdev
leads you to struct cdev. inode->i_bdev->bd_disk->blk_scsi_cmd_filter
isn't safe.
SCSI ULDs don't expose gendisk; they keep it private. bsg needs to be
independent on any protocols. We shouldn't change ULDs to expose their
gendisk.
This patch moves struct blk_scsi_cmd_filter from gendisk to
request_queue, a common object, which eveyone can access to.
The user interface doesn't change; users can change the filters via
/sys/block/. gendisk has a pointer to request_queue so the cmd_filter
code accesses to struct blk_scsi_cmd_filter.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/blkdev.h | 16 | ||||
-rw-r--r-- | include/linux/genhd.h | 10 |
2 files changed, 13 insertions, 13 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e61f22be4d0e..d2d34e2774b2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -280,6 +280,15 @@ struct blk_queue_tag { | |||
280 | atomic_t refcnt; /* map can be shared */ | 280 | atomic_t refcnt; /* map can be shared */ |
281 | }; | 281 | }; |
282 | 282 | ||
283 | #define BLK_SCSI_MAX_CMDS (256) | ||
284 | #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) | ||
285 | |||
286 | struct blk_scsi_cmd_filter { | ||
287 | unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; | ||
288 | unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; | ||
289 | struct kobject kobj; | ||
290 | }; | ||
291 | |||
283 | struct request_queue | 292 | struct request_queue |
284 | { | 293 | { |
285 | /* | 294 | /* |
@@ -398,6 +407,7 @@ struct request_queue | |||
398 | #if defined(CONFIG_BLK_DEV_BSG) | 407 | #if defined(CONFIG_BLK_DEV_BSG) |
399 | struct bsg_class_device bsg_dev; | 408 | struct bsg_class_device bsg_dev; |
400 | #endif | 409 | #endif |
410 | struct blk_scsi_cmd_filter cmd_filter; | ||
401 | }; | 411 | }; |
402 | 412 | ||
403 | #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ | 413 | #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ |
@@ -833,11 +843,11 @@ extern int blkdev_issue_flush(struct block_device *, sector_t *); | |||
833 | /* | 843 | /* |
834 | * command filter functions | 844 | * command filter functions |
835 | */ | 845 | */ |
836 | extern int blk_verify_command(struct file *file, unsigned char *cmd); | 846 | extern int blk_verify_command(struct blk_scsi_cmd_filter *filter, |
837 | extern int blk_cmd_filter_verify_command(struct blk_scsi_cmd_filter *filter, | 847 | unsigned char *cmd, int has_write_perm); |
838 | unsigned char *cmd, mode_t *f_mode); | ||
839 | extern int blk_register_filter(struct gendisk *disk); | 848 | extern int blk_register_filter(struct gendisk *disk); |
840 | extern void blk_unregister_filter(struct gendisk *disk); | 849 | extern void blk_unregister_filter(struct gendisk *disk); |
850 | extern void blk_set_cmd_filter_defaults(struct blk_scsi_cmd_filter *filter); | ||
841 | 851 | ||
842 | #define MAX_PHYS_SEGMENTS 128 | 852 | #define MAX_PHYS_SEGMENTS 128 |
843 | #define MAX_HW_SEGMENTS 128 | 853 | #define MAX_HW_SEGMENTS 128 |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 118216f1bd3c..be4f5e5bfe06 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -110,15 +110,6 @@ struct hd_struct { | |||
110 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 | 110 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 |
111 | #define GENHD_FL_FAIL 64 | 111 | #define GENHD_FL_FAIL 64 |
112 | 112 | ||
113 | #define BLK_SCSI_MAX_CMDS (256) | ||
114 | #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) | ||
115 | |||
116 | struct blk_scsi_cmd_filter { | ||
117 | unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; | ||
118 | unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; | ||
119 | struct kobject kobj; | ||
120 | }; | ||
121 | |||
122 | struct gendisk { | 113 | struct gendisk { |
123 | int major; /* major number of driver */ | 114 | int major; /* major number of driver */ |
124 | int first_minor; | 115 | int first_minor; |
@@ -128,7 +119,6 @@ struct gendisk { | |||
128 | struct hd_struct **part; /* [indexed by minor] */ | 119 | struct hd_struct **part; /* [indexed by minor] */ |
129 | struct block_device_operations *fops; | 120 | struct block_device_operations *fops; |
130 | struct request_queue *queue; | 121 | struct request_queue *queue; |
131 | struct blk_scsi_cmd_filter cmd_filter; | ||
132 | void *private_data; | 122 | void *private_data; |
133 | sector_t capacity; | 123 | sector_t capacity; |
134 | 124 | ||