aboutsummaryrefslogtreecommitdiffstats
path: root/block/bsg.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-15 01:44:51 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-15 01:44:51 -0400
commit43d2548bb2ef7e6d753f91468a746784041e522d (patch)
tree77d13fcd48fd998393abb825ec36e2b732684a73 /block/bsg.c
parent585583d95c5660973bc0cf64add517b040acd8a4 (diff)
parent85082fd7cbe3173198aac0eb5e85ab1edcc6352c (diff)
Merge commit '85082fd7cbe3173198aac0eb5e85ab1edcc6352c' into test-build
Manual fixup of: arch/powerpc/Kconfig
Diffstat (limited to 'block/bsg.c')
-rw-r--r--block/bsg.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/block/bsg.c b/block/bsg.c
index 54d617f7df3e..0b3b282f0384 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -19,6 +19,7 @@
19#include <linux/uio.h> 19#include <linux/uio.h>
20#include <linux/idr.h> 20#include <linux/idr.h>
21#include <linux/bsg.h> 21#include <linux/bsg.h>
22#include <linux/smp_lock.h>
22 23
23#include <scsi/scsi.h> 24#include <scsi/scsi.h>
24#include <scsi/scsi_ioctl.h> 25#include <scsi/scsi_ioctl.h>
@@ -44,11 +45,12 @@ struct bsg_device {
44 char name[BUS_ID_SIZE]; 45 char name[BUS_ID_SIZE];
45 int max_queue; 46 int max_queue;
46 unsigned long flags; 47 unsigned long flags;
48 struct blk_scsi_cmd_filter *cmd_filter;
49 mode_t *f_mode;
47}; 50};
48 51
49enum { 52enum {
50 BSG_F_BLOCK = 1, 53 BSG_F_BLOCK = 1,
51 BSG_F_WRITE_PERM = 2,
52}; 54};
53 55
54#define BSG_DEFAULT_CMDS 64 56#define BSG_DEFAULT_CMDS 64
@@ -172,7 +174,7 @@ unlock:
172} 174}
173 175
174static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, 176static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
175 struct sg_io_v4 *hdr, int has_write_perm) 177 struct sg_io_v4 *hdr, struct bsg_device *bd)
176{ 178{
177 if (hdr->request_len > BLK_MAX_CDB) { 179 if (hdr->request_len > BLK_MAX_CDB) {
178 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); 180 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
@@ -185,7 +187,8 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
185 return -EFAULT; 187 return -EFAULT;
186 188
187 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 189 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
188 if (blk_verify_command(rq->cmd, has_write_perm)) 190 if (blk_cmd_filter_verify_command(bd->cmd_filter, rq->cmd,
191 bd->f_mode))
189 return -EPERM; 192 return -EPERM;
190 } else if (!capable(CAP_SYS_RAWIO)) 193 } else if (!capable(CAP_SYS_RAWIO))
191 return -EPERM; 194 return -EPERM;
@@ -263,8 +266,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr)
263 rq = blk_get_request(q, rw, GFP_KERNEL); 266 rq = blk_get_request(q, rw, GFP_KERNEL);
264 if (!rq) 267 if (!rq)
265 return ERR_PTR(-ENOMEM); 268 return ERR_PTR(-ENOMEM);
266 ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM, 269 ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd);
267 &bd->flags));
268 if (ret) 270 if (ret)
269 goto out; 271 goto out;
270 272
@@ -566,12 +568,23 @@ static inline void bsg_set_block(struct bsg_device *bd, struct file *file)
566 set_bit(BSG_F_BLOCK, &bd->flags); 568 set_bit(BSG_F_BLOCK, &bd->flags);
567} 569}
568 570
569static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) 571static void bsg_set_cmd_filter(struct bsg_device *bd,
572 struct file *file)
570{ 573{
571 if (file->f_mode & FMODE_WRITE) 574 struct inode *inode;
572 set_bit(BSG_F_WRITE_PERM, &bd->flags); 575 struct gendisk *disk;
573 else 576
574 clear_bit(BSG_F_WRITE_PERM, &bd->flags); 577 if (!file)
578 return;
579
580 inode = file->f_dentry->d_inode;
581 if (!inode)
582 return;
583
584 disk = inode->i_bdev->bd_disk;
585
586 bd->cmd_filter = &disk->cmd_filter;
587 bd->f_mode = &file->f_mode;
575} 588}
576 589
577/* 590/*
@@ -595,6 +608,8 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
595 dprintk("%s: read %Zd bytes\n", bd->name, count); 608 dprintk("%s: read %Zd bytes\n", bd->name, count);
596 609
597 bsg_set_block(bd, file); 610 bsg_set_block(bd, file);
611 bsg_set_cmd_filter(bd, file);
612
598 bytes_read = 0; 613 bytes_read = 0;
599 ret = __bsg_read(buf, count, bd, NULL, &bytes_read); 614 ret = __bsg_read(buf, count, bd, NULL, &bytes_read);
600 *ppos = bytes_read; 615 *ppos = bytes_read;
@@ -668,7 +683,7 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
668 dprintk("%s: write %Zd bytes\n", bd->name, count); 683 dprintk("%s: write %Zd bytes\n", bd->name, count);
669 684
670 bsg_set_block(bd, file); 685 bsg_set_block(bd, file);
671 bsg_set_write_perm(bd, file); 686 bsg_set_cmd_filter(bd, file);
672 687
673 bytes_written = 0; 688 bytes_written = 0;
674 ret = __bsg_write(bd, buf, count, &bytes_written); 689 ret = __bsg_write(bd, buf, count, &bytes_written);
@@ -772,7 +787,9 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
772 } 787 }
773 788
774 bd->queue = rq; 789 bd->queue = rq;
790
775 bsg_set_block(bd, file); 791 bsg_set_block(bd, file);
792 bsg_set_cmd_filter(bd, file);
776 793
777 atomic_set(&bd->ref_count, 1); 794 atomic_set(&bd->ref_count, 1);
778 mutex_lock(&bsg_mutex); 795 mutex_lock(&bsg_mutex);
@@ -835,7 +852,11 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
835 852
836static int bsg_open(struct inode *inode, struct file *file) 853static int bsg_open(struct inode *inode, struct file *file)
837{ 854{
838 struct bsg_device *bd = bsg_get_device(inode, file); 855 struct bsg_device *bd;
856
857 lock_kernel();
858 bd = bsg_get_device(inode, file);
859 unlock_kernel();
839 860
840 if (IS_ERR(bd)) 861 if (IS_ERR(bd))
841 return PTR_ERR(bd); 862 return PTR_ERR(bd);