aboutsummaryrefslogtreecommitdiffstats
path: root/block/cmd-filter.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-08-16 01:10:05 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-08-27 03:50:19 -0400
commitabf5439370491dd6fbb4fe1a7939680d2a9bc9d4 (patch)
treeaa3630557fe4a4bc6313617f5770af30eec68515 /block/cmd-filter.c
parent1941246dd98089dd637f44d3bd4f6cc1c61aa9e4 (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 'block/cmd-filter.c')
-rw-r--r--block/cmd-filter.c118
1 files changed, 6 insertions, 112 deletions
diff --git a/block/cmd-filter.c b/block/cmd-filter.c
index eec4404fd357..c705c33361a0 100644
--- a/block/cmd-filter.c
+++ b/block/cmd-filter.c
@@ -27,8 +27,8 @@
27#include <scsi/scsi.h> 27#include <scsi/scsi.h>
28#include <linux/cdrom.h> 28#include <linux/cdrom.h>
29 29
30int blk_cmd_filter_verify_command(struct blk_scsi_cmd_filter *filter, 30int blk_verify_command(struct blk_scsi_cmd_filter *filter,
31 unsigned char *cmd, mode_t *f_mode) 31 unsigned char *cmd, int has_write_perm)
32{ 32{
33 /* root can do any command. */ 33 /* root can do any command. */
34 if (capable(CAP_SYS_RAWIO)) 34 if (capable(CAP_SYS_RAWIO))
@@ -43,30 +43,11 @@ int blk_cmd_filter_verify_command(struct blk_scsi_cmd_filter *filter,
43 return 0; 43 return 0;
44 44
45 /* Write-safe commands require a writable open */ 45 /* Write-safe commands require a writable open */
46 if (test_bit(cmd[0], filter->write_ok) && (*f_mode & FMODE_WRITE)) 46 if (test_bit(cmd[0], filter->write_ok) && has_write_perm)
47 return 0; 47 return 0;
48 48
49 return -EPERM; 49 return -EPERM;
50} 50}
51EXPORT_SYMBOL(blk_cmd_filter_verify_command);
52
53int blk_verify_command(struct file *file, unsigned char *cmd)
54{
55 struct gendisk *disk;
56 struct inode *inode;
57
58 if (!file)
59 return -EINVAL;
60
61 inode = file->f_dentry->d_inode;
62 if (!inode)
63 return -EINVAL;
64
65 disk = inode->i_bdev->bd_disk;
66
67 return blk_cmd_filter_verify_command(&disk->cmd_filter,
68 cmd, &file->f_mode);
69}
70EXPORT_SYMBOL(blk_verify_command); 51EXPORT_SYMBOL(blk_verify_command);
71 52
72/* and now, the sysfs stuff */ 53/* and now, the sysfs stuff */
@@ -219,114 +200,27 @@ static struct kobj_type rcf_ktype = {
219 .default_attrs = default_attrs, 200 .default_attrs = default_attrs,
220}; 201};
221 202
222#ifndef MAINTENANCE_IN_CMD
223#define MAINTENANCE_IN_CMD 0xa3
224#endif
225
226static void rcf_set_defaults(struct blk_scsi_cmd_filter *filter)
227{
228 /* Basic read-only commands */
229 __set_bit(TEST_UNIT_READY, filter->read_ok);
230 __set_bit(REQUEST_SENSE, filter->read_ok);
231 __set_bit(READ_6, filter->read_ok);
232 __set_bit(READ_10, filter->read_ok);
233 __set_bit(READ_12, filter->read_ok);
234 __set_bit(READ_16, filter->read_ok);
235 __set_bit(READ_BUFFER, filter->read_ok);
236 __set_bit(READ_DEFECT_DATA, filter->read_ok);
237 __set_bit(READ_CAPACITY, filter->read_ok);
238 __set_bit(READ_LONG, filter->read_ok);
239 __set_bit(INQUIRY, filter->read_ok);
240 __set_bit(MODE_SENSE, filter->read_ok);
241 __set_bit(MODE_SENSE_10, filter->read_ok);
242 __set_bit(LOG_SENSE, filter->read_ok);
243 __set_bit(START_STOP, filter->read_ok);
244 __set_bit(GPCMD_VERIFY_10, filter->read_ok);
245 __set_bit(VERIFY_16, filter->read_ok);
246 __set_bit(REPORT_LUNS, filter->read_ok);
247 __set_bit(SERVICE_ACTION_IN, filter->read_ok);
248 __set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok);
249 __set_bit(MAINTENANCE_IN_CMD, filter->read_ok);
250 __set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok);
251
252 /* Audio CD commands */
253 __set_bit(GPCMD_PLAY_CD, filter->read_ok);
254 __set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok);
255 __set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok);
256 __set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok);
257 __set_bit(GPCMD_PAUSE_RESUME, filter->read_ok);
258
259 /* CD/DVD data reading */
260 __set_bit(GPCMD_READ_CD, filter->read_ok);
261 __set_bit(GPCMD_READ_CD_MSF, filter->read_ok);
262 __set_bit(GPCMD_READ_DISC_INFO, filter->read_ok);
263 __set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok);
264 __set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok);
265 __set_bit(GPCMD_READ_HEADER, filter->read_ok);
266 __set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok);
267 __set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok);
268 __set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok);
269 __set_bit(GPCMD_REPORT_KEY, filter->read_ok);
270 __set_bit(GPCMD_SCAN, filter->read_ok);
271 __set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok);
272 __set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok);
273 __set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok);
274 __set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok);
275 __set_bit(GPCMD_SEEK, filter->read_ok);
276 __set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok);
277
278 /* Basic writing commands */
279 __set_bit(WRITE_6, filter->write_ok);
280 __set_bit(WRITE_10, filter->write_ok);
281 __set_bit(WRITE_VERIFY, filter->write_ok);
282 __set_bit(WRITE_12, filter->write_ok);
283 __set_bit(WRITE_VERIFY_12, filter->write_ok);
284 __set_bit(WRITE_16, filter->write_ok);
285 __set_bit(WRITE_LONG, filter->write_ok);
286 __set_bit(WRITE_LONG_2, filter->write_ok);
287 __set_bit(ERASE, filter->write_ok);
288 __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok);
289 __set_bit(MODE_SELECT, filter->write_ok);
290 __set_bit(LOG_SELECT, filter->write_ok);
291 __set_bit(GPCMD_BLANK, filter->write_ok);
292 __set_bit(GPCMD_CLOSE_TRACK, filter->write_ok);
293 __set_bit(GPCMD_FLUSH_CACHE, filter->write_ok);
294 __set_bit(GPCMD_FORMAT_UNIT, filter->write_ok);
295 __set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok);
296 __set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok);
297 __set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok);
298 __set_bit(GPCMD_SEND_EVENT, filter->write_ok);
299 __set_bit(GPCMD_SEND_KEY, filter->write_ok);
300 __set_bit(GPCMD_SEND_OPC, filter->write_ok);
301 __set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok);
302 __set_bit(GPCMD_SET_SPEED, filter->write_ok);
303 __set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok);
304 __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok);
305 __set_bit(GPCMD_SET_STREAMING, filter->write_ok);
306}
307
308int blk_register_filter(struct gendisk *disk) 203int blk_register_filter(struct gendisk *disk)
309{ 204{
310 int ret; 205 int ret;
311 struct blk_scsi_cmd_filter *filter = &disk->cmd_filter; 206 struct blk_scsi_cmd_filter *filter = &disk->queue->cmd_filter;
312 struct kobject *parent = kobject_get(disk->holder_dir->parent); 207 struct kobject *parent = kobject_get(disk->holder_dir->parent);
313 208
314 if (!parent) 209 if (!parent)
315 return -ENODEV; 210 return -ENODEV;
316 211
317 ret = kobject_init_and_add(&filter->kobj, &rcf_ktype, parent, 212 ret = kobject_init_and_add(&filter->kobj, &rcf_ktype, parent,
318 "%s", "cmd_filter"); 213 "%s", "cmd_filter");
319 214
320 if (ret < 0) 215 if (ret < 0)
321 return ret; 216 return ret;
322 217
323 rcf_set_defaults(filter);
324 return 0; 218 return 0;
325} 219}
326 220
327void blk_unregister_filter(struct gendisk *disk) 221void blk_unregister_filter(struct gendisk *disk)
328{ 222{
329 struct blk_scsi_cmd_filter *filter = &disk->cmd_filter; 223 struct blk_scsi_cmd_filter *filter = &disk->queue->cmd_filter;
330 224
331 kobject_put(&filter->kobj); 225 kobject_put(&filter->kobj);
332 kobject_put(disk->holder_dir->parent); 226 kobject_put(disk->holder_dir->parent);