On Mon, Jan 08 2007, Alan Stern wrote:
> On Wed, 6 Dec 2006, James Bottomley wrote:
>
> > On Wed, 2006-12-06 at 13:58 -0500, Alan Stern wrote:
> > > I'd love to do that -- but blkdev_ioctl() wants inode->i_bdev to be set,
> > > and blkdev_locked_ioctl() uses it as the argument to bdev_get_queue().
> > > So
> > > it won't work with sg, which uses character device nodes.
> >
> > Well, even sg has the queue ... and what we're looking for are the queue
> > parameters. In block/ioctl.c the bdev is just used for getting the
> > queue parameters (mainly via bdev->bd_disk->queue), so I could see if
> > Jens might be amenable to refactoring the queue ioctls so we can get at
> > them simply with a struct request_queue parameter.
> >
> > > How about adding BLKSECTGET to the list of commands accepted by
> > > sg_ioctl()?
> >
> > That's certainly a possible hack ... although I'd prefer to see the full
> > queue ioctls exposed.
>
> James:
>
> Back in December you wrote a patch to expose the queue ioctls, and sent it
> (off-list) to Jens Axboe and to me. Jens spproved it, but then it
> disappeared and was never applied. Unfortunately I have lost my copy of
> it.
>
> If you still have the patch, could you please apply it? If you don't, I
> could try to re-create it. Or maybe Jens still has it in his email
> records. Either way, please let me know.
This one?
diff --git a/block/ioctl.c b/block/ioctl.c
index 58aab63..8444d0c 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -135,6 +135,31 @@ static int put_u64(unsigned long arg, u6
return put_user(val, (u64 __user *)arg);
}
+static int blk_queue_locked_ioctl(struct request_queue *queue,
+ unsigned cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case BLKSSZGET: /* get block device hardware sector size */
+ return put_int(arg, queue_hardsect_size(queue));
+ case BLKSECTGET:
+ return put_ushort(arg, queue->max_sectors);
+ }
+ return -ENOIOCTLCMD;
+}
+
+int blk_queue_ioctl(struct request_queue *queue, unsigned cmd,
+ unsigned long arg)
+{
+ int ret;
+
+ lock_kernel();
+ ret = blk_queue_locked_ioctl(queue, cmd, arg);
+ unlock_kernel();
+
+ return ret;
+}
+EXPORT_SYMBOL(blk_queue_ioctl);
+
static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
unsigned cmd, unsigned long arg)
{
@@ -154,10 +179,6 @@ static int blkdev_locked_ioctl(struct fi
return put_int(arg, bdev_read_only(bdev) != 0);
case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
return put_int(arg, block_size(bdev));
- case BLKSSZGET: /* get block device hardware sector size */
- return put_int(arg, bdev_hardsect_size(bdev));
- case BLKSECTGET:
- return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
case BLKRASET:
case BLKFRASET:
if(!capable(CAP_SYS_ADMIN))
@@ -278,6 +299,8 @@ int blkdev_ioctl(struct inode *inode, st
lock_kernel();
ret = blkdev_locked_ioctl(file, bdev, cmd, arg);
+ if (ret == -ENOIOCTLCMD)
+ ret = blk_queue_locked_ioctl(bdev_get_queue(bdev), cmd, arg);
unlock_kernel();
if (ret != -ENOIOCTLCMD)
return ret;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 81e3bc7..d97244b 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -786,6 +786,11 @@ sg_ioctl(struct inode *inode, struct fil
sdp->disk->disk_name, (int) cmd_in));
read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
+ /* block ioctls first */
+ result = blk_queue_ioctl(sdp->device->request_queue, cmd_in, arg);
+ if (result != -ENOIOCTLCMD)
+ return result;
+
switch (cmd_in) {
case SG_IO:
{
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e1c7286..550b04a 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -754,6 +754,8 @@ extern void blk_queue_prep_rq(request_qu
extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *);
extern void blk_queue_dma_alignment(request_queue_t *, int);
extern void blk_queue_softirq_done(request_queue_t *, softirq_done_fn *);
+extern int blk_queue_ioctl(struct request_queue *queue, unsigned cmd,
+ unsigned long arg);
extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device
*bdev);
extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *);
extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *);
--
Jens Axboe
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html