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

Reply via email to