aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2008-11-05 18:12:34 -0500
committerJames Morris <jmorris@namei.org>2008-11-05 18:12:34 -0500
commite21e696edb498c7f7eed42ba3096f6bbe13927b6 (patch)
tree73b0bc28e45b0268f05c4b384a17bfb2140a73bc /block
parent2f99db28af90957271a6448479c3e492ccf7c697 (diff)
parent75fa67706cce5272bcfc51ed646f2da21f3bdb6e (diff)
Merge branch 'master' into next
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c37
-rw-r--r--block/blk-merge.c20
-rw-r--r--block/blk-settings.c2
-rw-r--r--block/blk.h1
-rw-r--r--block/bsg.c12
-rw-r--r--block/cmd-filter.c2
-rw-r--r--block/compat_ioctl.c177
-rw-r--r--block/elevator.c16
-rw-r--r--block/genhd.c40
-rw-r--r--block/ioctl.c173
-rw-r--r--block/scsi_ioctl.c33
11 files changed, 270 insertions, 243 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 2d053b584410..c3df30cfb3fc 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -257,7 +257,6 @@ void __generic_unplug_device(struct request_queue *q)
257 257
258 q->request_fn(q); 258 q->request_fn(q);
259} 259}
260EXPORT_SYMBOL(__generic_unplug_device);
261 260
262/** 261/**
263 * generic_unplug_device - fire a request queue 262 * generic_unplug_device - fire a request queue
@@ -325,6 +324,9 @@ EXPORT_SYMBOL(blk_unplug);
325 324
326static void blk_invoke_request_fn(struct request_queue *q) 325static void blk_invoke_request_fn(struct request_queue *q)
327{ 326{
327 if (unlikely(blk_queue_stopped(q)))
328 return;
329
328 /* 330 /*
329 * one level of recursion is ok and is much faster than kicking 331 * one level of recursion is ok and is much faster than kicking
330 * the unplug handling 332 * the unplug handling
@@ -399,8 +401,13 @@ void blk_sync_queue(struct request_queue *q)
399EXPORT_SYMBOL(blk_sync_queue); 401EXPORT_SYMBOL(blk_sync_queue);
400 402
401/** 403/**
402 * blk_run_queue - run a single device queue 404 * __blk_run_queue - run a single device queue
403 * @q: The queue to run 405 * @q: The queue to run
406 *
407 * Description:
408 * See @blk_run_queue. This variant must be called with the queue lock
409 * held and interrupts disabled.
410 *
404 */ 411 */
405void __blk_run_queue(struct request_queue *q) 412void __blk_run_queue(struct request_queue *q)
406{ 413{
@@ -418,6 +425,12 @@ EXPORT_SYMBOL(__blk_run_queue);
418/** 425/**
419 * blk_run_queue - run a single device queue 426 * blk_run_queue - run a single device queue
420 * @q: The queue to run 427 * @q: The queue to run
428 *
429 * Description:
430 * Invoke request handling on this queue, if it has pending work to do.
431 * May be used to restart queueing when a request has completed. Also
432 * See @blk_start_queueing.
433 *
421 */ 434 */
422void blk_run_queue(struct request_queue *q) 435void blk_run_queue(struct request_queue *q)
423{ 436{
@@ -501,6 +514,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
501 init_timer(&q->unplug_timer); 514 init_timer(&q->unplug_timer);
502 setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q); 515 setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
503 INIT_LIST_HEAD(&q->timeout_list); 516 INIT_LIST_HEAD(&q->timeout_list);
517 INIT_WORK(&q->unplug_work, blk_unplug_work);
504 518
505 kobject_init(&q->kobj, &blk_queue_ktype); 519 kobject_init(&q->kobj, &blk_queue_ktype);
506 520
@@ -884,7 +898,8 @@ EXPORT_SYMBOL(blk_get_request);
884 * 898 *
885 * This is basically a helper to remove the need to know whether a queue 899 * This is basically a helper to remove the need to know whether a queue
886 * is plugged or not if someone just wants to initiate dispatch of requests 900 * is plugged or not if someone just wants to initiate dispatch of requests
887 * for this queue. 901 * for this queue. Should be used to start queueing on a device outside
902 * of ->request_fn() context. Also see @blk_run_queue.
888 * 903 *
889 * The queue lock must be held with interrupts disabled. 904 * The queue lock must be held with interrupts disabled.
890 */ 905 */
@@ -1003,8 +1018,9 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
1003} 1018}
1004 1019
1005/** 1020/**
1006 * part_round_stats() - Round off the performance stats on a struct 1021 * part_round_stats() - Round off the performance stats on a struct disk_stats.
1007 * disk_stats. 1022 * @cpu: cpu number for stats access
1023 * @part: target partition
1008 * 1024 *
1009 * The average IO queue length and utilisation statistics are maintained 1025 * The average IO queue length and utilisation statistics are maintained
1010 * by observing the current state of the queue length and the amount of 1026 * by observing the current state of the queue length and the amount of
@@ -1075,8 +1091,15 @@ void init_request_from_bio(struct request *req, struct bio *bio)
1075 /* 1091 /*
1076 * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST) 1092 * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
1077 */ 1093 */
1078 if (bio_rw_ahead(bio) || bio_failfast(bio)) 1094 if (bio_rw_ahead(bio))
1079 req->cmd_flags |= REQ_FAILFAST; 1095 req->cmd_flags |= (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
1096 REQ_FAILFAST_DRIVER);
1097 if (bio_failfast_dev(bio))
1098 req->cmd_flags |= REQ_FAILFAST_DEV;
1099 if (bio_failfast_transport(bio))
1100 req->cmd_flags |= REQ_FAILFAST_TRANSPORT;
1101 if (bio_failfast_driver(bio))
1102 req->cmd_flags |= REQ_FAILFAST_DRIVER;
1080 1103
1081 /* 1104 /*
1082 * REQ_BARRIER implies no merging, but lets make it explicit 1105 * REQ_BARRIER implies no merging, but lets make it explicit
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 908d3e11ac52..8681cd6f9911 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -77,12 +77,20 @@ void blk_recalc_rq_segments(struct request *rq)
77 continue; 77 continue;
78 } 78 }
79new_segment: 79new_segment:
80 if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
81 rq->bio->bi_seg_front_size = seg_size;
82
80 nr_phys_segs++; 83 nr_phys_segs++;
81 bvprv = bv; 84 bvprv = bv;
82 seg_size = bv->bv_len; 85 seg_size = bv->bv_len;
83 highprv = high; 86 highprv = high;
84 } 87 }
85 88
89 if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
90 rq->bio->bi_seg_front_size = seg_size;
91 if (seg_size > rq->biotail->bi_seg_back_size)
92 rq->biotail->bi_seg_back_size = seg_size;
93
86 rq->nr_phys_segments = nr_phys_segs; 94 rq->nr_phys_segments = nr_phys_segs;
87} 95}
88 96
@@ -106,7 +114,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
106 if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) 114 if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
107 return 0; 115 return 0;
108 116
109 if (bio->bi_size + nxt->bi_size > q->max_segment_size) 117 if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
118 q->max_segment_size)
110 return 0; 119 return 0;
111 120
112 if (!bio_has_data(bio)) 121 if (!bio_has_data(bio))
@@ -309,6 +318,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
309 struct request *next) 318 struct request *next)
310{ 319{
311 int total_phys_segments; 320 int total_phys_segments;
321 unsigned int seg_size =
322 req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
312 323
313 /* 324 /*
314 * First check if the either of the requests are re-queued 325 * First check if the either of the requests are re-queued
@@ -324,8 +335,13 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
324 return 0; 335 return 0;
325 336
326 total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; 337 total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
327 if (blk_phys_contig_segment(q, req->biotail, next->bio)) 338 if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
339 if (req->nr_phys_segments == 1)
340 req->bio->bi_seg_front_size = seg_size;
341 if (next->nr_phys_segments == 1)
342 next->biotail->bi_seg_back_size = seg_size;
328 total_phys_segments--; 343 total_phys_segments--;
344 }
329 345
330 if (total_phys_segments > q->max_phys_segments) 346 if (total_phys_segments > q->max_phys_segments)
331 return 0; 347 return 0;
diff --git a/block/blk-settings.c b/block/blk-settings.c
index b21dcdb64151..41392fbe19ff 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -141,8 +141,6 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
141 if (q->unplug_delay == 0) 141 if (q->unplug_delay == 0)
142 q->unplug_delay = 1; 142 q->unplug_delay = 1;
143 143
144 INIT_WORK(&q->unplug_work, blk_unplug_work);
145
146 q->unplug_timer.function = blk_unplug_timeout; 144 q->unplug_timer.function = blk_unplug_timeout;
147 q->unplug_timer.data = (unsigned long)q; 145 q->unplug_timer.data = (unsigned long)q;
148 146
diff --git a/block/blk.h b/block/blk.h
index e5c579769963..d2e49af90db5 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -20,6 +20,7 @@ void blk_unplug_timeout(unsigned long data);
20void blk_rq_timed_out_timer(unsigned long data); 20void blk_rq_timed_out_timer(unsigned long data);
21void blk_delete_timer(struct request *); 21void blk_delete_timer(struct request *);
22void blk_add_timer(struct request *); 22void blk_add_timer(struct request *);
23void __generic_unplug_device(struct request_queue *);
23 24
24/* 25/*
25 * Internal atomic flags for request handling 26 * Internal atomic flags for request handling
diff --git a/block/bsg.c b/block/bsg.c
index 56cb343c76d8..e8bd2475682a 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -173,7 +173,7 @@ unlock:
173 173
174static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, 174static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
175 struct sg_io_v4 *hdr, struct bsg_device *bd, 175 struct sg_io_v4 *hdr, struct bsg_device *bd,
176 int has_write_perm) 176 fmode_t has_write_perm)
177{ 177{
178 if (hdr->request_len > BLK_MAX_CDB) { 178 if (hdr->request_len > BLK_MAX_CDB) {
179 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); 179 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
@@ -242,7 +242,7 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
242 * map sg_io_v4 to a request. 242 * map sg_io_v4 to a request.
243 */ 243 */
244static struct request * 244static struct request *
245bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, int has_write_perm) 245bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
246{ 246{
247 struct request_queue *q = bd->queue; 247 struct request_queue *q = bd->queue;
248 struct request *rq, *next_rq = NULL; 248 struct request *rq, *next_rq = NULL;
@@ -601,7 +601,8 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
601} 601}
602 602
603static int __bsg_write(struct bsg_device *bd, const char __user *buf, 603static int __bsg_write(struct bsg_device *bd, const char __user *buf,
604 size_t count, ssize_t *bytes_written, int has_write_perm) 604 size_t count, ssize_t *bytes_written,
605 fmode_t has_write_perm)
605{ 606{
606 struct bsg_command *bc; 607 struct bsg_command *bc;
607 struct request *rq; 608 struct request *rq;
@@ -913,7 +914,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
913 case SG_EMULATED_HOST: 914 case SG_EMULATED_HOST:
914 case SCSI_IOCTL_SEND_COMMAND: { 915 case SCSI_IOCTL_SEND_COMMAND: {
915 void __user *uarg = (void __user *) arg; 916 void __user *uarg = (void __user *) arg;
916 return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg); 917 return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg);
917 } 918 }
918 case SG_IO: { 919 case SG_IO: {
919 struct request *rq; 920 struct request *rq;
@@ -1024,8 +1025,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
1024 bcd->release = release; 1025 bcd->release = release;
1025 kref_init(&bcd->ref); 1026 kref_init(&bcd->ref);
1026 dev = MKDEV(bsg_major, bcd->minor); 1027 dev = MKDEV(bsg_major, bcd->minor);
1027 class_dev = device_create_drvdata(bsg_class, parent, dev, NULL, 1028 class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname);
1028 "%s", devname);
1029 if (IS_ERR(class_dev)) { 1029 if (IS_ERR(class_dev)) {
1030 ret = PTR_ERR(class_dev); 1030 ret = PTR_ERR(class_dev);
1031 goto put_dev; 1031 goto put_dev;
diff --git a/block/cmd-filter.c b/block/cmd-filter.c
index e669aed4c6bc..504b275e1b90 100644
--- a/block/cmd-filter.c
+++ b/block/cmd-filter.c
@@ -27,7 +27,7 @@
27#include <linux/cdrom.h> 27#include <linux/cdrom.h>
28 28
29int blk_verify_command(struct blk_cmd_filter *filter, 29int blk_verify_command(struct blk_cmd_filter *filter,
30 unsigned char *cmd, int has_write_perm) 30 unsigned char *cmd, fmode_t has_write_perm)
31{ 31{
32 /* root can do any command. */ 32 /* root can do any command. */
33 if (capable(CAP_SYS_RAWIO)) 33 if (capable(CAP_SYS_RAWIO))
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 1e559fba7bdf..3d3e7a46f38c 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -71,8 +71,8 @@ static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
71 return ret; 71 return ret;
72} 72}
73 73
74static int compat_hdio_ioctl(struct inode *inode, struct file *file, 74static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode,
75 struct gendisk *disk, unsigned int cmd, unsigned long arg) 75 unsigned int cmd, unsigned long arg)
76{ 76{
77 mm_segment_t old_fs = get_fs(); 77 mm_segment_t old_fs = get_fs();
78 unsigned long kval; 78 unsigned long kval;
@@ -80,7 +80,7 @@ static int compat_hdio_ioctl(struct inode *inode, struct file *file,
80 int error; 80 int error;
81 81
82 set_fs(KERNEL_DS); 82 set_fs(KERNEL_DS);
83 error = blkdev_driver_ioctl(inode, file, disk, 83 error = __blkdev_driver_ioctl(bdev, mode,
84 cmd, (unsigned long)(&kval)); 84 cmd, (unsigned long)(&kval));
85 set_fs(old_fs); 85 set_fs(old_fs);
86 86
@@ -111,8 +111,8 @@ struct compat_cdrom_generic_command {
111 compat_caddr_t reserved[1]; 111 compat_caddr_t reserved[1];
112}; 112};
113 113
114static int compat_cdrom_read_audio(struct inode *inode, struct file *file, 114static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode,
115 struct gendisk *disk, unsigned int cmd, unsigned long arg) 115 unsigned int cmd, unsigned long arg)
116{ 116{
117 struct cdrom_read_audio __user *cdread_audio; 117 struct cdrom_read_audio __user *cdread_audio;
118 struct compat_cdrom_read_audio __user *cdread_audio32; 118 struct compat_cdrom_read_audio __user *cdread_audio32;
@@ -134,12 +134,12 @@ static int compat_cdrom_read_audio(struct inode *inode, struct file *file,
134 if (put_user(datap, &cdread_audio->buf)) 134 if (put_user(datap, &cdread_audio->buf))
135 return -EFAULT; 135 return -EFAULT;
136 136
137 return blkdev_driver_ioctl(inode, file, disk, cmd, 137 return __blkdev_driver_ioctl(bdev, mode, cmd,
138 (unsigned long)cdread_audio); 138 (unsigned long)cdread_audio);
139} 139}
140 140
141static int compat_cdrom_generic_command(struct inode *inode, struct file *file, 141static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t mode,
142 struct gendisk *disk, unsigned int cmd, unsigned long arg) 142 unsigned int cmd, unsigned long arg)
143{ 143{
144 struct cdrom_generic_command __user *cgc; 144 struct cdrom_generic_command __user *cgc;
145 struct compat_cdrom_generic_command __user *cgc32; 145 struct compat_cdrom_generic_command __user *cgc32;
@@ -167,7 +167,7 @@ static int compat_cdrom_generic_command(struct inode *inode, struct file *file,
167 put_user(compat_ptr(data), &cgc->reserved[0])) 167 put_user(compat_ptr(data), &cgc->reserved[0]))
168 return -EFAULT; 168 return -EFAULT;
169 169
170 return blkdev_driver_ioctl(inode, file, disk, cmd, (unsigned long)cgc); 170 return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc);
171} 171}
172 172
173struct compat_blkpg_ioctl_arg { 173struct compat_blkpg_ioctl_arg {
@@ -177,7 +177,7 @@ struct compat_blkpg_ioctl_arg {
177 compat_caddr_t data; 177 compat_caddr_t data;
178}; 178};
179 179
180static int compat_blkpg_ioctl(struct inode *inode, struct file *file, 180static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
181 unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32) 181 unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
182{ 182{
183 struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a)); 183 struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
@@ -196,7 +196,7 @@ static int compat_blkpg_ioctl(struct inode *inode, struct file *file,
196 if (err) 196 if (err)
197 return err; 197 return err;
198 198
199 return blkdev_ioctl(inode, file, cmd, (unsigned long)a); 199 return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
200} 200}
201 201
202#define BLKBSZGET_32 _IOR(0x12, 112, int) 202#define BLKBSZGET_32 _IOR(0x12, 112, int)
@@ -308,8 +308,8 @@ static struct {
308 308
309#define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table) 309#define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table)
310 310
311static int compat_fd_ioctl(struct inode *inode, struct file *file, 311static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode,
312 struct gendisk *disk, unsigned int cmd, unsigned long arg) 312 unsigned int cmd, unsigned long arg)
313{ 313{
314 mm_segment_t old_fs = get_fs(); 314 mm_segment_t old_fs = get_fs();
315 void *karg = NULL; 315 void *karg = NULL;
@@ -413,7 +413,7 @@ static int compat_fd_ioctl(struct inode *inode, struct file *file,
413 return -EINVAL; 413 return -EINVAL;
414 } 414 }
415 set_fs(KERNEL_DS); 415 set_fs(KERNEL_DS);
416 err = blkdev_driver_ioctl(inode, file, disk, kcmd, (unsigned long)karg); 416 err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg);
417 set_fs(old_fs); 417 set_fs(old_fs);
418 if (err) 418 if (err)
419 goto out; 419 goto out;
@@ -579,11 +579,9 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
579 return 0; 579 return 0;
580} 580}
581 581
582static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, 582static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
583 struct gendisk *disk, unsigned cmd, unsigned long arg) 583 unsigned cmd, unsigned long arg)
584{ 584{
585 int ret;
586
587 switch (cmd) { 585 switch (cmd) {
588 case HDIO_GET_UNMASKINTR: 586 case HDIO_GET_UNMASKINTR:
589 case HDIO_GET_MULTCOUNT: 587 case HDIO_GET_MULTCOUNT:
@@ -596,7 +594,7 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
596 case HDIO_GET_ACOUSTIC: 594 case HDIO_GET_ACOUSTIC:
597 case HDIO_GET_ADDRESS: 595 case HDIO_GET_ADDRESS:
598 case HDIO_GET_BUSSTATE: 596 case HDIO_GET_BUSSTATE:
599 return compat_hdio_ioctl(inode, file, disk, cmd, arg); 597 return compat_hdio_ioctl(bdev, mode, cmd, arg);
600 case FDSETPRM32: 598 case FDSETPRM32:
601 case FDDEFPRM32: 599 case FDDEFPRM32:
602 case FDGETPRM32: 600 case FDGETPRM32:
@@ -606,11 +604,11 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
606 case FDPOLLDRVSTAT32: 604 case FDPOLLDRVSTAT32:
607 case FDGETFDCSTAT32: 605 case FDGETFDCSTAT32:
608 case FDWERRORGET32: 606 case FDWERRORGET32:
609 return compat_fd_ioctl(inode, file, disk, cmd, arg); 607 return compat_fd_ioctl(bdev, mode, cmd, arg);
610 case CDROMREADAUDIO: 608 case CDROMREADAUDIO:
611 return compat_cdrom_read_audio(inode, file, disk, cmd, arg); 609 return compat_cdrom_read_audio(bdev, mode, cmd, arg);
612 case CDROM_SEND_PACKET: 610 case CDROM_SEND_PACKET:
613 return compat_cdrom_generic_command(inode, file, disk, cmd, arg); 611 return compat_cdrom_generic_command(bdev, mode, cmd, arg);
614 612
615 /* 613 /*
616 * No handler required for the ones below, we just need to 614 * No handler required for the ones below, we just need to
@@ -679,55 +677,49 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
679 case DVD_WRITE_STRUCT: 677 case DVD_WRITE_STRUCT:
680 case DVD_AUTH: 678 case DVD_AUTH:
681 arg = (unsigned long)compat_ptr(arg); 679 arg = (unsigned long)compat_ptr(arg);
682 /* These intepret arg as an unsigned long, not as a pointer,
683 * so we must not do compat_ptr() conversion. */
684 case HDIO_SET_MULTCOUNT:
685 case HDIO_SET_UNMASKINTR:
686 case HDIO_SET_KEEPSETTINGS:
687 case HDIO_SET_32BIT:
688 case HDIO_SET_NOWERR:
689 case HDIO_SET_DMA:
690 case HDIO_SET_PIO_MODE:
691 case HDIO_SET_NICE:
692 case HDIO_SET_WCACHE:
693 case HDIO_SET_ACOUSTIC:
694 case HDIO_SET_BUSSTATE:
695 case HDIO_SET_ADDRESS:
696 case CDROMEJECT_SW:
697 case CDROM_SET_OPTIONS:
698 case CDROM_CLEAR_OPTIONS:
699 case CDROM_SELECT_SPEED:
700 case CDROM_SELECT_DISC:
701 case CDROM_MEDIA_CHANGED:
702 case CDROM_DRIVE_STATUS:
703 case CDROM_LOCKDOOR:
704 case CDROM_DEBUG:
705 break; 680 break;
706 default: 681 default:
707 /* unknown ioctl number */ 682 /* unknown ioctl number */
708 return -ENOIOCTLCMD; 683 return -ENOIOCTLCMD;
709 } 684 }
710 685
711 if (disk->fops->unlocked_ioctl) 686 return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
712 return disk->fops->unlocked_ioctl(file, cmd, arg);
713
714 if (disk->fops->ioctl) {
715 lock_kernel();
716 ret = disk->fops->ioctl(inode, file, cmd, arg);
717 unlock_kernel();
718 return ret;
719 }
720
721 return -ENOTTY;
722} 687}
723 688
724static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, 689/* Most of the generic ioctls are handled in the normal fallback path.
725 struct block_device *bdev, 690 This assumes the blkdev's low level compat_ioctl always returns
726 unsigned cmd, unsigned long arg) 691 ENOIOCTLCMD for unknown ioctls. */
692long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
727{ 693{
694 int ret = -ENOIOCTLCMD;
695 struct inode *inode = file->f_mapping->host;
696 struct block_device *bdev = inode->i_bdev;
697 struct gendisk *disk = bdev->bd_disk;
698 fmode_t mode = file->f_mode;
728 struct backing_dev_info *bdi; 699 struct backing_dev_info *bdi;
700 loff_t size;
701
702 if (file->f_flags & O_NDELAY)
703 mode |= FMODE_NDELAY_NOW;
729 704
730 switch (cmd) { 705 switch (cmd) {
706 case HDIO_GETGEO:
707 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
708 case BLKFLSBUF:
709 case BLKROSET:
710 case BLKDISCARD:
711 /*
712 * the ones below are implemented in blkdev_locked_ioctl,
713 * but we call blkdev_ioctl, which gets the lock for us
714 */
715 case BLKRRPART:
716 return blkdev_ioctl(bdev, mode, cmd,
717 (unsigned long)compat_ptr(arg));
718 case BLKBSZSET_32:
719 return blkdev_ioctl(bdev, mode, BLKBSZSET,
720 (unsigned long)compat_ptr(arg));
721 case BLKPG:
722 return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg));
731 case BLKRAGET: 723 case BLKRAGET:
732 case BLKFRAGET: 724 case BLKFRAGET:
733 if (!arg) 725 if (!arg)
@@ -753,65 +745,36 @@ static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file,
753 bdi = blk_get_backing_dev_info(bdev); 745 bdi = blk_get_backing_dev_info(bdev);
754 if (bdi == NULL) 746 if (bdi == NULL)
755 return -ENOTTY; 747 return -ENOTTY;
748 lock_kernel();
756 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; 749 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
750 unlock_kernel();
757 return 0; 751 return 0;
758 case BLKGETSIZE: 752 case BLKGETSIZE:
759 if ((bdev->bd_inode->i_size >> 9) > ~0UL) 753 size = bdev->bd_inode->i_size;
754 if ((size >> 9) > ~0UL)
760 return -EFBIG; 755 return -EFBIG;
761 return compat_put_ulong(arg, bdev->bd_inode->i_size >> 9); 756 return compat_put_ulong(arg, size >> 9);
762 757
763 case BLKGETSIZE64_32: 758 case BLKGETSIZE64_32:
764 return compat_put_u64(arg, bdev->bd_inode->i_size); 759 return compat_put_u64(arg, bdev->bd_inode->i_size);
765 760
766 case BLKTRACESETUP32: 761 case BLKTRACESETUP32:
767 return compat_blk_trace_setup(bdev, compat_ptr(arg)); 762 lock_kernel();
763 ret = compat_blk_trace_setup(bdev, compat_ptr(arg));
764 unlock_kernel();
765 return ret;
768 case BLKTRACESTART: /* compatible */ 766 case BLKTRACESTART: /* compatible */
769 case BLKTRACESTOP: /* compatible */ 767 case BLKTRACESTOP: /* compatible */
770 case BLKTRACETEARDOWN: /* compatible */ 768 case BLKTRACETEARDOWN: /* compatible */
771 return blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); 769 lock_kernel();
772 } 770 ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
773 return -ENOIOCTLCMD; 771 unlock_kernel();
774}
775
776/* Most of the generic ioctls are handled in the normal fallback path.
777 This assumes the blkdev's low level compat_ioctl always returns
778 ENOIOCTLCMD for unknown ioctls. */
779long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
780{
781 int ret = -ENOIOCTLCMD;
782 struct inode *inode = file->f_mapping->host;
783 struct block_device *bdev = inode->i_bdev;
784 struct gendisk *disk = bdev->bd_disk;
785
786 switch (cmd) {
787 case HDIO_GETGEO:
788 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
789 case BLKFLSBUF:
790 case BLKROSET:
791 case BLKDISCARD:
792 /*
793 * the ones below are implemented in blkdev_locked_ioctl,
794 * but we call blkdev_ioctl, which gets the lock for us
795 */
796 case BLKRRPART:
797 return blkdev_ioctl(inode, file, cmd,
798 (unsigned long)compat_ptr(arg));
799 case BLKBSZSET_32:
800 return blkdev_ioctl(inode, file, BLKBSZSET,
801 (unsigned long)compat_ptr(arg));
802 case BLKPG:
803 return compat_blkpg_ioctl(inode, file, cmd, compat_ptr(arg));
804 }
805
806 lock_kernel();
807 ret = compat_blkdev_locked_ioctl(inode, file, bdev, cmd, arg);
808 /* FIXME: why do we assume -> compat_ioctl needs the BKL? */
809 if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
810 ret = disk->fops->compat_ioctl(file, cmd, arg);
811 unlock_kernel();
812
813 if (ret != -ENOIOCTLCMD)
814 return ret; 772 return ret;
815 773 default:
816 return compat_blkdev_driver_ioctl(inode, file, disk, cmd, arg); 774 if (disk->fops->compat_ioctl)
775 ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
776 if (ret == -ENOIOCTLCMD)
777 ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg);
778 return ret;
779 }
817} 780}
diff --git a/block/elevator.c b/block/elevator.c
index 04518921db31..59173a69ebdf 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -612,7 +612,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
612 * processing. 612 * processing.
613 */ 613 */
614 blk_remove_plug(q); 614 blk_remove_plug(q);
615 q->request_fn(q); 615 blk_start_queueing(q);
616 break; 616 break;
617 617
618 case ELEVATOR_INSERT_SORT: 618 case ELEVATOR_INSERT_SORT:
@@ -950,7 +950,7 @@ void elv_completed_request(struct request_queue *q, struct request *rq)
950 blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN && 950 blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN &&
951 blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) { 951 blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) {
952 blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0); 952 blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0);
953 q->request_fn(q); 953 blk_start_queueing(q);
954 } 954 }
955 } 955 }
956} 956}
@@ -1109,8 +1109,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
1109 elv_drain_elevator(q); 1109 elv_drain_elevator(q);
1110 1110
1111 while (q->rq.elvpriv) { 1111 while (q->rq.elvpriv) {
1112 blk_remove_plug(q); 1112 blk_start_queueing(q);
1113 q->request_fn(q);
1114 spin_unlock_irq(q->queue_lock); 1113 spin_unlock_irq(q->queue_lock);
1115 msleep(10); 1114 msleep(10);
1116 spin_lock_irq(q->queue_lock); 1115 spin_lock_irq(q->queue_lock);
@@ -1166,15 +1165,10 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
1166 size_t count) 1165 size_t count)
1167{ 1166{
1168 char elevator_name[ELV_NAME_MAX]; 1167 char elevator_name[ELV_NAME_MAX];
1169 size_t len;
1170 struct elevator_type *e; 1168 struct elevator_type *e;
1171 1169
1172 elevator_name[sizeof(elevator_name) - 1] = '\0'; 1170 strlcpy(elevator_name, name, sizeof(elevator_name));
1173 strncpy(elevator_name, name, sizeof(elevator_name) - 1); 1171 strstrip(elevator_name);
1174 len = strlen(elevator_name);
1175
1176 if (len && elevator_name[len - 1] == '\n')
1177 elevator_name[len - 1] = '\0';
1178 1172
1179 e = elevator_get(elevator_name); 1173 e = elevator_get(elevator_name);
1180 if (!e) { 1174 if (!e) {
diff --git a/block/genhd.c b/block/genhd.c
index 4cd3433c99ac..4e5e7493f676 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -10,6 +10,7 @@
10#include <linux/blkdev.h> 10#include <linux/blkdev.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/proc_fs.h>
13#include <linux/seq_file.h> 14#include <linux/seq_file.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15#include <linux/kmod.h> 16#include <linux/kmod.h>
@@ -358,7 +359,6 @@ static int blk_mangle_minor(int minor)
358/** 359/**
359 * blk_alloc_devt - allocate a dev_t for a partition 360 * blk_alloc_devt - allocate a dev_t for a partition
360 * @part: partition to allocate dev_t for 361 * @part: partition to allocate dev_t for
361 * @gfp_mask: memory allocation flag
362 * @devt: out parameter for resulting dev_t 362 * @devt: out parameter for resulting dev_t
363 * 363 *
364 * Allocate a dev_t for block device. 364 * Allocate a dev_t for block device.
@@ -535,7 +535,7 @@ void unlink_gendisk(struct gendisk *disk)
535/** 535/**
536 * get_gendisk - get partitioning information for a given device 536 * get_gendisk - get partitioning information for a given device
537 * @devt: device to get partitioning information for 537 * @devt: device to get partitioning information for
538 * @part: returned partition index 538 * @partno: returned partition index
539 * 539 *
540 * This function gets the structure containing partitioning 540 * This function gets the structure containing partitioning
541 * information for the given device @devt. 541 * information for the given device @devt.
@@ -728,12 +728,24 @@ static int show_partition(struct seq_file *seqf, void *v)
728 return 0; 728 return 0;
729} 729}
730 730
731const struct seq_operations partitions_op = { 731static const struct seq_operations partitions_op = {
732 .start = show_partition_start, 732 .start = show_partition_start,
733 .next = disk_seqf_next, 733 .next = disk_seqf_next,
734 .stop = disk_seqf_stop, 734 .stop = disk_seqf_stop,
735 .show = show_partition 735 .show = show_partition
736}; 736};
737
738static int partitions_open(struct inode *inode, struct file *file)
739{
740 return seq_open(file, &partitions_op);
741}
742
743static const struct file_operations proc_partitions_operations = {
744 .open = partitions_open,
745 .read = seq_read,
746 .llseek = seq_lseek,
747 .release = seq_release,
748};
737#endif 749#endif
738 750
739 751
@@ -993,12 +1005,32 @@ static int diskstats_show(struct seq_file *seqf, void *v)
993 return 0; 1005 return 0;
994} 1006}
995 1007
996const struct seq_operations diskstats_op = { 1008static const struct seq_operations diskstats_op = {
997 .start = disk_seqf_start, 1009 .start = disk_seqf_start,
998 .next = disk_seqf_next, 1010 .next = disk_seqf_next,
999 .stop = disk_seqf_stop, 1011 .stop = disk_seqf_stop,
1000 .show = diskstats_show 1012 .show = diskstats_show
1001}; 1013};
1014
1015static int diskstats_open(struct inode *inode, struct file *file)
1016{
1017 return seq_open(file, &diskstats_op);
1018}
1019
1020static const struct file_operations proc_diskstats_operations = {
1021 .open = diskstats_open,
1022 .read = seq_read,
1023 .llseek = seq_lseek,
1024 .release = seq_release,
1025};
1026
1027static int __init proc_genhd_init(void)
1028{
1029 proc_create("diskstats", 0, NULL, &proc_diskstats_operations);
1030 proc_create("partitions", 0, NULL, &proc_partitions_operations);
1031 return 0;
1032}
1033module_init(proc_genhd_init);
1002#endif /* CONFIG_PROC_FS */ 1034#endif /* CONFIG_PROC_FS */
1003 1035
1004static void media_change_notify_thread(struct work_struct *work) 1036static void media_change_notify_thread(struct work_struct *work)
diff --git a/block/ioctl.c b/block/ioctl.c
index 38bee321e1fa..c832d639b6e2 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -201,97 +201,41 @@ static int put_u64(unsigned long arg, u64 val)
201 return put_user(val, (u64 __user *)arg); 201 return put_user(val, (u64 __user *)arg);
202} 202}
203 203
204static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, 204int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
205 unsigned cmd, unsigned long arg) 205 unsigned cmd, unsigned long arg)
206{
207 struct backing_dev_info *bdi;
208 int ret, n;
209
210 switch (cmd) {
211 case BLKRAGET:
212 case BLKFRAGET:
213 if (!arg)
214 return -EINVAL;
215 bdi = blk_get_backing_dev_info(bdev);
216 if (bdi == NULL)
217 return -ENOTTY;
218 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
219 case BLKROGET:
220 return put_int(arg, bdev_read_only(bdev) != 0);
221 case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
222 return put_int(arg, block_size(bdev));
223 case BLKSSZGET: /* get block device hardware sector size */
224 return put_int(arg, bdev_hardsect_size(bdev));
225 case BLKSECTGET:
226 return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
227 case BLKRASET:
228 case BLKFRASET:
229 if(!capable(CAP_SYS_ADMIN))
230 return -EACCES;
231 bdi = blk_get_backing_dev_info(bdev);
232 if (bdi == NULL)
233 return -ENOTTY;
234 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
235 return 0;
236 case BLKBSZSET:
237 /* set the logical block size */
238 if (!capable(CAP_SYS_ADMIN))
239 return -EACCES;
240 if (!arg)
241 return -EINVAL;
242 if (get_user(n, (int __user *) arg))
243 return -EFAULT;
244 if (bd_claim(bdev, file) < 0)
245 return -EBUSY;
246 ret = set_blocksize(bdev, n);
247 bd_release(bdev);
248 return ret;
249 case BLKPG:
250 return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
251 case BLKRRPART:
252 return blkdev_reread_part(bdev);
253 case BLKGETSIZE:
254 if ((bdev->bd_inode->i_size >> 9) > ~0UL)
255 return -EFBIG;
256 return put_ulong(arg, bdev->bd_inode->i_size >> 9);
257 case BLKGETSIZE64:
258 return put_u64(arg, bdev->bd_inode->i_size);
259 case BLKTRACESTART:
260 case BLKTRACESTOP:
261 case BLKTRACESETUP:
262 case BLKTRACETEARDOWN:
263 return blk_trace_ioctl(bdev, cmd, (char __user *) arg);
264 }
265 return -ENOIOCTLCMD;
266}
267
268int blkdev_driver_ioctl(struct inode *inode, struct file *file,
269 struct gendisk *disk, unsigned cmd, unsigned long arg)
270{ 206{
207 struct gendisk *disk = bdev->bd_disk;
271 int ret; 208 int ret;
272 if (disk->fops->unlocked_ioctl)
273 return disk->fops->unlocked_ioctl(file, cmd, arg);
274 209
275 if (disk->fops->ioctl) { 210 if (disk->fops->ioctl)
211 return disk->fops->ioctl(bdev, mode, cmd, arg);
212
213 if (disk->fops->locked_ioctl) {
276 lock_kernel(); 214 lock_kernel();
277 ret = disk->fops->ioctl(inode, file, cmd, arg); 215 ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg);
278 unlock_kernel(); 216 unlock_kernel();
279 return ret; 217 return ret;
280 } 218 }
281 219
282 return -ENOTTY; 220 return -ENOTTY;
283} 221}
284EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); 222/*
223 * For the record: _GPL here is only because somebody decided to slap it
224 * on the previous export. Sheer idiocy, since it wasn't copyrightable
225 * at all and could be open-coded without any exports by anybody who cares.
226 */
227EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
285 228
286/* 229/*
287 * always keep this in sync with compat_blkdev_ioctl() and 230 * always keep this in sync with compat_blkdev_ioctl() and
288 * compat_blkdev_locked_ioctl() 231 * compat_blkdev_locked_ioctl()
289 */ 232 */
290int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, 233int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
291 unsigned long arg) 234 unsigned long arg)
292{ 235{
293 struct block_device *bdev = inode->i_bdev;
294 struct gendisk *disk = bdev->bd_disk; 236 struct gendisk *disk = bdev->bd_disk;
237 struct backing_dev_info *bdi;
238 loff_t size;
295 int ret, n; 239 int ret, n;
296 240
297 switch(cmd) { 241 switch(cmd) {
@@ -299,7 +243,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
299 if (!capable(CAP_SYS_ADMIN)) 243 if (!capable(CAP_SYS_ADMIN))
300 return -EACCES; 244 return -EACCES;
301 245
302 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); 246 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
303 /* -EINVAL to handle old uncorrected drivers */ 247 /* -EINVAL to handle old uncorrected drivers */
304 if (ret != -EINVAL && ret != -ENOTTY) 248 if (ret != -EINVAL && ret != -ENOTTY)
305 return ret; 249 return ret;
@@ -311,7 +255,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
311 return 0; 255 return 0;
312 256
313 case BLKROSET: 257 case BLKROSET:
314 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); 258 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
315 /* -EINVAL to handle old uncorrected drivers */ 259 /* -EINVAL to handle old uncorrected drivers */
316 if (ret != -EINVAL && ret != -ENOTTY) 260 if (ret != -EINVAL && ret != -ENOTTY)
317 return ret; 261 return ret;
@@ -327,7 +271,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
327 case BLKDISCARD: { 271 case BLKDISCARD: {
328 uint64_t range[2]; 272 uint64_t range[2];
329 273
330 if (!(file->f_mode & FMODE_WRITE)) 274 if (!(mode & FMODE_WRITE))
331 return -EBADF; 275 return -EBADF;
332 276
333 if (copy_from_user(range, (void __user *)arg, sizeof(range))) 277 if (copy_from_user(range, (void __user *)arg, sizeof(range)))
@@ -357,14 +301,75 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
357 return -EFAULT; 301 return -EFAULT;
358 return 0; 302 return 0;
359 } 303 }
360 } 304 case BLKRAGET:
361 305 case BLKFRAGET:
362 lock_kernel(); 306 if (!arg)
363 ret = blkdev_locked_ioctl(file, bdev, cmd, arg); 307 return -EINVAL;
364 unlock_kernel(); 308 bdi = blk_get_backing_dev_info(bdev);
365 if (ret != -ENOIOCTLCMD) 309 if (bdi == NULL)
310 return -ENOTTY;
311 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
312 case BLKROGET:
313 return put_int(arg, bdev_read_only(bdev) != 0);
314 case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
315 return put_int(arg, block_size(bdev));
316 case BLKSSZGET: /* get block device hardware sector size */
317 return put_int(arg, bdev_hardsect_size(bdev));
318 case BLKSECTGET:
319 return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
320 case BLKRASET:
321 case BLKFRASET:
322 if(!capable(CAP_SYS_ADMIN))
323 return -EACCES;
324 bdi = blk_get_backing_dev_info(bdev);
325 if (bdi == NULL)
326 return -ENOTTY;
327 lock_kernel();
328 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
329 unlock_kernel();
330 return 0;
331 case BLKBSZSET:
332 /* set the logical block size */
333 if (!capable(CAP_SYS_ADMIN))
334 return -EACCES;
335 if (!arg)
336 return -EINVAL;
337 if (get_user(n, (int __user *) arg))
338 return -EFAULT;
339 if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0)
340 return -EBUSY;
341 ret = set_blocksize(bdev, n);
342 if (!(mode & FMODE_EXCL))
343 bd_release(bdev);
366 return ret; 344 return ret;
367 345 case BLKPG:
368 return blkdev_driver_ioctl(inode, file, disk, cmd, arg); 346 lock_kernel();
347 ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
348 unlock_kernel();
349 break;
350 case BLKRRPART:
351 lock_kernel();
352 ret = blkdev_reread_part(bdev);
353 unlock_kernel();
354 break;
355 case BLKGETSIZE:
356 size = bdev->bd_inode->i_size;
357 if ((size >> 9) > ~0UL)
358 return -EFBIG;
359 return put_ulong(arg, size >> 9);
360 case BLKGETSIZE64:
361 return put_u64(arg, bdev->bd_inode->i_size);
362 case BLKTRACESTART:
363 case BLKTRACESTOP:
364 case BLKTRACESETUP:
365 case BLKTRACETEARDOWN:
366 lock_kernel();
367 ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg);
368 unlock_kernel();
369 break;
370 default:
371 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
372 }
373 return ret;
369} 374}
370EXPORT_SYMBOL_GPL(blkdev_ioctl); 375EXPORT_SYMBOL_GPL(blkdev_ioctl);
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index c34272a348fe..5963cf91a3a0 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -190,12 +190,11 @@ void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
190EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults); 190EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults);
191 191
192static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, 192static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
193 struct sg_io_hdr *hdr, struct file *file) 193 struct sg_io_hdr *hdr, fmode_t mode)
194{ 194{
195 if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) 195 if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
196 return -EFAULT; 196 return -EFAULT;
197 if (blk_verify_command(&q->cmd_filter, rq->cmd, 197 if (blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE))
198 file->f_mode & FMODE_WRITE))
199 return -EPERM; 198 return -EPERM;
200 199
201 /* 200 /*
@@ -260,8 +259,8 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
260 return r; 259 return r;
261} 260}
262 261
263static int sg_io(struct file *file, struct request_queue *q, 262static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
264 struct gendisk *bd_disk, struct sg_io_hdr *hdr) 263 struct sg_io_hdr *hdr, fmode_t mode)
265{ 264{
266 unsigned long start_time; 265 unsigned long start_time;
267 int writing = 0, ret = 0; 266 int writing = 0, ret = 0;
@@ -293,7 +292,7 @@ static int sg_io(struct file *file, struct request_queue *q,
293 if (!rq) 292 if (!rq)
294 return -ENOMEM; 293 return -ENOMEM;
295 294
296 if (blk_fill_sghdr_rq(q, rq, hdr, file)) { 295 if (blk_fill_sghdr_rq(q, rq, hdr, mode)) {
297 blk_put_request(rq); 296 blk_put_request(rq);
298 return -EFAULT; 297 return -EFAULT;
299 } 298 }
@@ -380,11 +379,11 @@ out:
380 * bytes in one int) where the lowest byte is the SCSI status. 379 * bytes in one int) where the lowest byte is the SCSI status.
381 */ 380 */
382#define OMAX_SB_LEN 16 /* For backward compatibility */ 381#define OMAX_SB_LEN 16 /* For backward compatibility */
383int sg_scsi_ioctl(struct file *file, struct request_queue *q, 382int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
384 struct gendisk *disk, struct scsi_ioctl_command __user *sic) 383 struct scsi_ioctl_command __user *sic)
385{ 384{
386 struct request *rq; 385 struct request *rq;
387 int err, write_perm = 0; 386 int err;
388 unsigned int in_len, out_len, bytes, opcode, cmdlen; 387 unsigned int in_len, out_len, bytes, opcode, cmdlen;
389 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; 388 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
390 389
@@ -426,11 +425,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q,
426 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) 425 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
427 goto error; 426 goto error;
428 427
429 /* scsi_ioctl passes NULL */ 428 err = blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE);
430 if (file && (file->f_mode & FMODE_WRITE))
431 write_perm = 1;
432
433 err = blk_verify_command(&q->cmd_filter, rq->cmd, write_perm);
434 if (err) 429 if (err)
435 goto error; 430 goto error;
436 431
@@ -522,8 +517,8 @@ static inline int blk_send_start_stop(struct request_queue *q,
522 return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); 517 return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
523} 518}
524 519
525int scsi_cmd_ioctl(struct file *file, struct request_queue *q, 520int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode,
526 struct gendisk *bd_disk, unsigned int cmd, void __user *arg) 521 unsigned int cmd, void __user *arg)
527{ 522{
528 int err; 523 int err;
529 524
@@ -564,7 +559,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
564 err = -EFAULT; 559 err = -EFAULT;
565 if (copy_from_user(&hdr, arg, sizeof(hdr))) 560 if (copy_from_user(&hdr, arg, sizeof(hdr)))
566 break; 561 break;
567 err = sg_io(file, q, bd_disk, &hdr); 562 err = sg_io(q, bd_disk, &hdr, mode);
568 if (err == -EFAULT) 563 if (err == -EFAULT)
569 break; 564 break;
570 565
@@ -612,7 +607,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
612 hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd; 607 hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
613 hdr.cmd_len = sizeof(cgc.cmd); 608 hdr.cmd_len = sizeof(cgc.cmd);
614 609
615 err = sg_io(file, q, bd_disk, &hdr); 610 err = sg_io(q, bd_disk, &hdr, mode);
616 if (err == -EFAULT) 611 if (err == -EFAULT)
617 break; 612 break;
618 613
@@ -636,7 +631,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
636 if (!arg) 631 if (!arg)
637 break; 632 break;
638 633
639 err = sg_scsi_ioctl(file, q, bd_disk, arg); 634 err = sg_scsi_ioctl(q, bd_disk, mode, arg);
640 break; 635 break;
641 case CDROMCLOSETRAY: 636 case CDROMCLOSETRAY:
642 err = blk_send_start_stop(q, bd_disk, 0x03); 637 err = blk_send_start_stop(q, bd_disk, 0x03);