diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 01:44:51 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 01:44:51 -0400 |
commit | 43d2548bb2ef7e6d753f91468a746784041e522d (patch) | |
tree | 77d13fcd48fd998393abb825ec36e2b732684a73 /block/bsg.c | |
parent | 585583d95c5660973bc0cf64add517b040acd8a4 (diff) | |
parent | 85082fd7cbe3173198aac0eb5e85ab1edcc6352c (diff) |
Merge commit '85082fd7cbe3173198aac0eb5e85ab1edcc6352c' into test-build
Manual fixup of:
arch/powerpc/Kconfig
Diffstat (limited to 'block/bsg.c')
-rw-r--r-- | block/bsg.c | 45 |
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 | ||
49 | enum { | 52 | enum { |
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 | ||
174 | static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, | 176 | static 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 | ||
569 | static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) | 571 | static 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 | ||
836 | static int bsg_open(struct inode *inode, struct file *file) | 853 | static 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); |