aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2009-06-26 10:27:10 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-07-01 04:56:26 -0400
commit018e0446890661504783f92388ecce7138c1566d (patch)
treed555758047dde4a26b2489d397a5a86be53723b9
parent7878cba9f0037f5599004b03a1260b32d9050360 (diff)
block: get rid of queue-private command filter
The initial patches to support this through sysfs export were broken and have been if 0'ed out in any release. So lets just kill the code and reclaim some space in struct request_queue, if anyone would later like to fixup the sysfs bits, the git history can easily restore the removed bits. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--block/Makefile2
-rw-r--r--block/blk-core.c2
-rw-r--r--block/bsg.c2
-rw-r--r--block/cmd-filter.c233
-rw-r--r--block/scsi_ioctl.c43
-rw-r--r--drivers/scsi/sg.c4
-rw-r--r--include/linux/blkdev.h15
7 files changed, 42 insertions, 259 deletions
diff --git a/block/Makefile b/block/Makefile
index e9fa4dd690f2..6c54ed0ff755 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -5,7 +5,7 @@
5obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ 5obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
6 blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ 6 blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \
7 blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \ 7 blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
8 ioctl.o genhd.o scsi_ioctl.o cmd-filter.o 8 ioctl.o genhd.o scsi_ioctl.o
9 9
10obj-$(CONFIG_BLK_DEV_BSG) += bsg.o 10obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
11obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o 11obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
diff --git a/block/blk-core.c b/block/blk-core.c
index 345d99da8d41..02b87134a167 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -595,8 +595,6 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
595 595
596 q->sg_reserved_size = INT_MAX; 596 q->sg_reserved_size = INT_MAX;
597 597
598 blk_set_cmd_filter_defaults(&q->cmd_filter);
599
600 /* 598 /*
601 * all done 599 * all done
602 */ 600 */
diff --git a/block/bsg.c b/block/bsg.c
index e7d475254248..5f184bb3ff9e 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -186,7 +186,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
186 return -EFAULT; 186 return -EFAULT;
187 187
188 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 188 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
189 if (blk_verify_command(&q->cmd_filter, rq->cmd, has_write_perm)) 189 if (blk_verify_command(rq->cmd, has_write_perm))
190 return -EPERM; 190 return -EPERM;
191 } else if (!capable(CAP_SYS_RAWIO)) 191 } else if (!capable(CAP_SYS_RAWIO))
192 return -EPERM; 192 return -EPERM;
diff --git a/block/cmd-filter.c b/block/cmd-filter.c
deleted file mode 100644
index 572bbc2f900d..000000000000
--- a/block/cmd-filter.c
+++ /dev/null
@@ -1,233 +0,0 @@
1/*
2 * Copyright 2004 Peter M. Jones <pjones@redhat.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public Licens
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
17 *
18 */
19
20#include <linux/list.h>
21#include <linux/genhd.h>
22#include <linux/spinlock.h>
23#include <linux/capability.h>
24#include <linux/bitops.h>
25#include <linux/blkdev.h>
26
27#include <scsi/scsi.h>
28#include <linux/cdrom.h>
29
30int blk_verify_command(struct blk_cmd_filter *filter,
31 unsigned char *cmd, fmode_t has_write_perm)
32{
33 /* root can do any command. */
34 if (capable(CAP_SYS_RAWIO))
35 return 0;
36
37 /* if there's no filter set, assume we're filtering everything out */
38 if (!filter)
39 return -EPERM;
40
41 /* Anybody who can open the device can do a read-safe command */
42 if (test_bit(cmd[0], filter->read_ok))
43 return 0;
44
45 /* Write-safe commands require a writable open */
46 if (test_bit(cmd[0], filter->write_ok) && has_write_perm)
47 return 0;
48
49 return -EPERM;
50}
51EXPORT_SYMBOL(blk_verify_command);
52
53#if 0
54/* and now, the sysfs stuff */
55static ssize_t rcf_cmds_show(struct blk_cmd_filter *filter, char *page,
56 int rw)
57{
58 char *npage = page;
59 unsigned long *okbits;
60 int i;
61
62 if (rw == READ)
63 okbits = filter->read_ok;
64 else
65 okbits = filter->write_ok;
66
67 for (i = 0; i < BLK_SCSI_MAX_CMDS; i++) {
68 if (test_bit(i, okbits)) {
69 npage += sprintf(npage, "0x%02x", i);
70 if (i < BLK_SCSI_MAX_CMDS - 1)
71 sprintf(npage++, " ");
72 }
73 }
74
75 if (npage != page)
76 npage += sprintf(npage, "\n");
77
78 return npage - page;
79}
80
81static ssize_t rcf_readcmds_show(struct blk_cmd_filter *filter, char *page)
82{
83 return rcf_cmds_show(filter, page, READ);
84}
85
86static ssize_t rcf_writecmds_show(struct blk_cmd_filter *filter,
87 char *page)
88{
89 return rcf_cmds_show(filter, page, WRITE);
90}
91
92static ssize_t rcf_cmds_store(struct blk_cmd_filter *filter,
93 const char *page, size_t count, int rw)
94{
95 unsigned long okbits[BLK_SCSI_CMD_PER_LONG], *target_okbits;
96 int cmd, set;
97 char *p, *status;
98
99 if (rw == READ) {
100 memcpy(&okbits, filter->read_ok, sizeof(okbits));
101 target_okbits = filter->read_ok;
102 } else {
103 memcpy(&okbits, filter->write_ok, sizeof(okbits));
104 target_okbits = filter->write_ok;
105 }
106
107 while ((p = strsep((char **)&page, " ")) != NULL) {
108 set = 1;
109
110 if (p[0] == '+') {
111 p++;
112 } else if (p[0] == '-') {
113 set = 0;
114 p++;
115 }
116
117 cmd = simple_strtol(p, &status, 16);
118
119 /* either of these cases means invalid input, so do nothing. */
120 if ((status == p) || cmd >= BLK_SCSI_MAX_CMDS)
121 return -EINVAL;
122
123 if (set)
124 __set_bit(cmd, okbits);
125 else
126 __clear_bit(cmd, okbits);
127 }
128
129 memcpy(target_okbits, okbits, sizeof(okbits));
130 return count;
131}
132
133static ssize_t rcf_readcmds_store(struct blk_cmd_filter *filter,
134 const char *page, size_t count)
135{
136 return rcf_cmds_store(filter, page, count, READ);
137}
138
139static ssize_t rcf_writecmds_store(struct blk_cmd_filter *filter,
140 const char *page, size_t count)
141{
142 return rcf_cmds_store(filter, page, count, WRITE);
143}
144
145struct rcf_sysfs_entry {
146 struct attribute attr;
147 ssize_t (*show)(struct blk_cmd_filter *, char *);
148 ssize_t (*store)(struct blk_cmd_filter *, const char *, size_t);
149};
150
151static struct rcf_sysfs_entry rcf_readcmds_entry = {
152 .attr = { .name = "read_table", .mode = S_IRUGO | S_IWUSR },
153 .show = rcf_readcmds_show,
154 .store = rcf_readcmds_store,
155};
156
157static struct rcf_sysfs_entry rcf_writecmds_entry = {
158 .attr = {.name = "write_table", .mode = S_IRUGO | S_IWUSR },
159 .show = rcf_writecmds_show,
160 .store = rcf_writecmds_store,
161};
162
163static struct attribute *default_attrs[] = {
164 &rcf_readcmds_entry.attr,
165 &rcf_writecmds_entry.attr,
166 NULL,
167};
168
169#define to_rcf(atr) container_of((atr), struct rcf_sysfs_entry, attr)
170
171static ssize_t
172rcf_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
173{
174 struct rcf_sysfs_entry *entry = to_rcf(attr);
175 struct blk_cmd_filter *filter;
176
177 filter = container_of(kobj, struct blk_cmd_filter, kobj);
178 if (entry->show)
179 return entry->show(filter, page);
180
181 return 0;
182}
183
184static ssize_t
185rcf_attr_store(struct kobject *kobj, struct attribute *attr,
186 const char *page, size_t length)
187{
188 struct rcf_sysfs_entry *entry = to_rcf(attr);
189 struct blk_cmd_filter *filter;
190
191 if (!capable(CAP_SYS_RAWIO))
192 return -EPERM;
193
194 if (!entry->store)
195 return -EINVAL;
196
197 filter = container_of(kobj, struct blk_cmd_filter, kobj);
198 return entry->store(filter, page, length);
199}
200
201static struct sysfs_ops rcf_sysfs_ops = {
202 .show = rcf_attr_show,
203 .store = rcf_attr_store,
204};
205
206static struct kobj_type rcf_ktype = {
207 .sysfs_ops = &rcf_sysfs_ops,
208 .default_attrs = default_attrs,
209};
210
211int blk_register_filter(struct gendisk *disk)
212{
213 int ret;
214 struct blk_cmd_filter *filter = &disk->queue->cmd_filter;
215
216 ret = kobject_init_and_add(&filter->kobj, &rcf_ktype,
217 &disk_to_dev(disk)->kobj,
218 "%s", "cmd_filter");
219 if (ret < 0)
220 return ret;
221
222 return 0;
223}
224EXPORT_SYMBOL(blk_register_filter);
225
226void blk_unregister_filter(struct gendisk *disk)
227{
228 struct blk_cmd_filter *filter = &disk->queue->cmd_filter;
229
230 kobject_put(&filter->kobj);
231}
232EXPORT_SYMBOL(blk_unregister_filter);
233#endif
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 5f8e798ede4e..f0e0ce0a607d 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -32,6 +32,11 @@
32#include <scsi/scsi_ioctl.h> 32#include <scsi/scsi_ioctl.h>
33#include <scsi/scsi_cmnd.h> 33#include <scsi/scsi_cmnd.h>
34 34
35struct blk_cmd_filter {
36 unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
37 unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
38} blk_default_cmd_filter;
39
35/* Command group 3 is reserved and should never be used. */ 40/* Command group 3 is reserved and should never be used. */
36const unsigned char scsi_command_size_tbl[8] = 41const unsigned char scsi_command_size_tbl[8] =
37{ 42{
@@ -105,7 +110,7 @@ static int sg_emulated_host(struct request_queue *q, int __user *p)
105 return put_user(1, p); 110 return put_user(1, p);
106} 111}
107 112
108void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) 113static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
109{ 114{
110 /* Basic read-only commands */ 115 /* Basic read-only commands */
111 __set_bit(TEST_UNIT_READY, filter->read_ok); 116 __set_bit(TEST_UNIT_READY, filter->read_ok);
@@ -187,14 +192,37 @@ void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
187 __set_bit(GPCMD_SET_STREAMING, filter->write_ok); 192 __set_bit(GPCMD_SET_STREAMING, filter->write_ok);
188 __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok); 193 __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok);
189} 194}
190EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults); 195
196int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm)
197{
198 struct blk_cmd_filter *filter = &blk_default_cmd_filter;
199
200 /* root can do any command. */
201 if (capable(CAP_SYS_RAWIO))
202 return 0;
203
204 /* if there's no filter set, assume we're filtering everything out */
205 if (!filter)
206 return -EPERM;
207
208 /* Anybody who can open the device can do a read-safe command */
209 if (test_bit(cmd[0], filter->read_ok))
210 return 0;
211
212 /* Write-safe commands require a writable open */
213 if (test_bit(cmd[0], filter->write_ok) && has_write_perm)
214 return 0;
215
216 return -EPERM;
217}
218EXPORT_SYMBOL(blk_verify_command);
191 219
192static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, 220static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
193 struct sg_io_hdr *hdr, fmode_t mode) 221 struct sg_io_hdr *hdr, fmode_t mode)
194{ 222{
195 if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) 223 if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
196 return -EFAULT; 224 return -EFAULT;
197 if (blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE)) 225 if (blk_verify_command(rq->cmd, mode & FMODE_WRITE))
198 return -EPERM; 226 return -EPERM;
199 227
200 /* 228 /*
@@ -427,7 +455,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
427 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) 455 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
428 goto error; 456 goto error;
429 457
430 err = blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE); 458 err = blk_verify_command(rq->cmd, mode & FMODE_WRITE);
431 if (err) 459 if (err)
432 goto error; 460 goto error;
433 461
@@ -645,5 +673,10 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
645 blk_put_queue(q); 673 blk_put_queue(q);
646 return err; 674 return err;
647} 675}
648
649EXPORT_SYMBOL(scsi_cmd_ioctl); 676EXPORT_SYMBOL(scsi_cmd_ioctl);
677
678int __init blk_scsi_ioctl_init(void)
679{
680 blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
681 return 0;
682}
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 8201387b4daa..ef142fd47a83 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -210,13 +210,11 @@ static void sg_put_dev(Sg_device *sdp);
210static int sg_allow_access(struct file *filp, unsigned char *cmd) 210static int sg_allow_access(struct file *filp, unsigned char *cmd)
211{ 211{
212 struct sg_fd *sfp = (struct sg_fd *)filp->private_data; 212 struct sg_fd *sfp = (struct sg_fd *)filp->private_data;
213 struct request_queue *q = sfp->parentdp->device->request_queue;
214 213
215 if (sfp->parentdp->device->type == TYPE_SCANNER) 214 if (sfp->parentdp->device->type == TYPE_SCANNER)
216 return 0; 215 return 0;
217 216
218 return blk_verify_command(&q->cmd_filter, 217 return blk_verify_command(cmd, filp->f_mode & FMODE_WRITE);
219 cmd, filp->f_mode & FMODE_WRITE);
220} 218}
221 219
222static int 220static int
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 8963d9149b5f..49ae07951d55 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -301,12 +301,6 @@ struct blk_queue_tag {
301#define BLK_SCSI_MAX_CMDS (256) 301#define BLK_SCSI_MAX_CMDS (256)
302#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) 302#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
303 303
304struct blk_cmd_filter {
305 unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
306 unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
307 struct kobject kobj;
308};
309
310struct queue_limits { 304struct queue_limits {
311 unsigned long bounce_pfn; 305 unsigned long bounce_pfn;
312 unsigned long seg_boundary_mask; 306 unsigned long seg_boundary_mask;
@@ -445,7 +439,6 @@ struct request_queue
445#if defined(CONFIG_BLK_DEV_BSG) 439#if defined(CONFIG_BLK_DEV_BSG)
446 struct bsg_class_device bsg_dev; 440 struct bsg_class_device bsg_dev;
447#endif 441#endif
448 struct blk_cmd_filter cmd_filter;
449}; 442};
450 443
451#define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ 444#define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */
@@ -998,13 +991,7 @@ static inline int sb_issue_discard(struct super_block *sb,
998 return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL); 991 return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL);
999} 992}
1000 993
1001/* 994extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm);
1002* command filter functions
1003*/
1004extern int blk_verify_command(struct blk_cmd_filter *filter,
1005 unsigned char *cmd, fmode_t has_write_perm);
1006extern void blk_unregister_filter(struct gendisk *disk);
1007extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter);
1008 995
1009#define MAX_PHYS_SEGMENTS 128 996#define MAX_PHYS_SEGMENTS 128
1010#define MAX_HW_SEGMENTS 128 997#define MAX_HW_SEGMENTS 128