aboutsummaryrefslogtreecommitdiffstats
path: root/block/bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/bsg.c')
-rw-r--r--block/bsg.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/block/bsg.c b/block/bsg.c
index 7c59ffaedfe0..0b3b282f0384 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -45,11 +45,12 @@ struct bsg_device {
45 char name[BUS_ID_SIZE]; 45 char name[BUS_ID_SIZE];
46 int max_queue; 46 int max_queue;
47 unsigned long flags; 47 unsigned long flags;
48 struct blk_scsi_cmd_filter *cmd_filter;
49 mode_t *f_mode;
48}; 50};
49 51
50enum { 52enum {
51 BSG_F_BLOCK = 1, 53 BSG_F_BLOCK = 1,
52 BSG_F_WRITE_PERM = 2,
53}; 54};
54 55
55#define BSG_DEFAULT_CMDS 64 56#define BSG_DEFAULT_CMDS 64
@@ -173,7 +174,7 @@ unlock:
173} 174}
174 175
175static 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,
176 struct sg_io_v4 *hdr, int has_write_perm) 177 struct sg_io_v4 *hdr, struct bsg_device *bd)
177{ 178{
178 if (hdr->request_len > BLK_MAX_CDB) { 179 if (hdr->request_len > BLK_MAX_CDB) {
179 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); 180 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
@@ -186,7 +187,8 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
186 return -EFAULT; 187 return -EFAULT;
187 188
188 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 189 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
189 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))
190 return -EPERM; 192 return -EPERM;
191 } else if (!capable(CAP_SYS_RAWIO)) 193 } else if (!capable(CAP_SYS_RAWIO))
192 return -EPERM; 194 return -EPERM;
@@ -264,8 +266,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr)
264 rq = blk_get_request(q, rw, GFP_KERNEL); 266 rq = blk_get_request(q, rw, GFP_KERNEL);
265 if (!rq) 267 if (!rq)
266 return ERR_PTR(-ENOMEM); 268 return ERR_PTR(-ENOMEM);
267 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);
268 &bd->flags));
269 if (ret) 270 if (ret)
270 goto out; 271 goto out;
271 272
@@ -567,12 +568,23 @@ static inline void bsg_set_block(struct bsg_device *bd, struct file *file)
567 set_bit(BSG_F_BLOCK, &bd->flags); 568 set_bit(BSG_F_BLOCK, &bd->flags);
568} 569}
569 570
570static 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)
571{ 573{
572 if (file->f_mode & FMODE_WRITE) 574 struct inode *inode;
573 set_bit(BSG_F_WRITE_PERM, &bd->flags); 575 struct gendisk *disk;
574 else 576
575 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;
576} 588}
577 589
578/* 590/*
@@ -596,6 +608,8 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
596 dprintk("%s: read %Zd bytes\n", bd->name, count); 608 dprintk("%s: read %Zd bytes\n", bd->name, count);
597 609
598 bsg_set_block(bd, file); 610 bsg_set_block(bd, file);
611 bsg_set_cmd_filter(bd, file);
612
599 bytes_read = 0; 613 bytes_read = 0;
600 ret = __bsg_read(buf, count, bd, NULL, &bytes_read); 614 ret = __bsg_read(buf, count, bd, NULL, &bytes_read);
601 *ppos = bytes_read; 615 *ppos = bytes_read;
@@ -669,7 +683,7 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
669 dprintk("%s: write %Zd bytes\n", bd->name, count); 683 dprintk("%s: write %Zd bytes\n", bd->name, count);
670 684
671 bsg_set_block(bd, file); 685 bsg_set_block(bd, file);
672 bsg_set_write_perm(bd, file); 686 bsg_set_cmd_filter(bd, file);
673 687
674 bytes_written = 0; 688 bytes_written = 0;
675 ret = __bsg_write(bd, buf, count, &bytes_written); 689 ret = __bsg_write(bd, buf, count, &bytes_written);
@@ -773,7 +787,9 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
773 } 787 }
774 788
775 bd->queue = rq; 789 bd->queue = rq;
790
776 bsg_set_block(bd, file); 791 bsg_set_block(bd, file);
792 bsg_set_cmd_filter(bd, file);
777 793
778 atomic_set(&bd->ref_count, 1); 794 atomic_set(&bd->ref_count, 1);
779 mutex_lock(&bsg_mutex); 795 mutex_lock(&bsg_mutex);