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 f0b7cd343216..439940c3a1ff 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -44,11 +44,12 @@ struct bsg_device {
44 char name[BUS_ID_SIZE]; 44 char name[BUS_ID_SIZE];
45 int max_queue; 45 int max_queue;
46 unsigned long flags; 46 unsigned long flags;
47 struct blk_scsi_cmd_filter *cmd_filter;
48 mode_t *f_mode;
47}; 49};
48 50
49enum { 51enum {
50 BSG_F_BLOCK = 1, 52 BSG_F_BLOCK = 1,
51 BSG_F_WRITE_PERM = 2,
52}; 53};
53 54
54#define BSG_DEFAULT_CMDS 64 55#define BSG_DEFAULT_CMDS 64
@@ -172,7 +173,7 @@ unlock:
172} 173}
173 174
174static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, 175static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
175 struct sg_io_v4 *hdr, int has_write_perm) 176 struct sg_io_v4 *hdr, struct bsg_device *bd)
176{ 177{
177 if (hdr->request_len > BLK_MAX_CDB) { 178 if (hdr->request_len > BLK_MAX_CDB) {
178 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); 179 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
@@ -185,7 +186,8 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
185 return -EFAULT; 186 return -EFAULT;
186 187
187 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { 188 if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
188 if (blk_verify_command(rq->cmd, has_write_perm)) 189 if (blk_cmd_filter_verify_command(bd->cmd_filter, rq->cmd,
190 bd->f_mode))
189 return -EPERM; 191 return -EPERM;
190 } else if (!capable(CAP_SYS_RAWIO)) 192 } else if (!capable(CAP_SYS_RAWIO))
191 return -EPERM; 193 return -EPERM;
@@ -263,8 +265,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr)
263 rq = blk_get_request(q, rw, GFP_KERNEL); 265 rq = blk_get_request(q, rw, GFP_KERNEL);
264 if (!rq) 266 if (!rq)
265 return ERR_PTR(-ENOMEM); 267 return ERR_PTR(-ENOMEM);
266 ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM, 268 ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd);
267 &bd->flags));
268 if (ret) 269 if (ret)
269 goto out; 270 goto out;
270 271
@@ -566,12 +567,23 @@ static inline void bsg_set_block(struct bsg_device *bd, struct file *file)
566 set_bit(BSG_F_BLOCK, &bd->flags); 567 set_bit(BSG_F_BLOCK, &bd->flags);
567} 568}
568 569
569static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file) 570static void bsg_set_cmd_filter(struct bsg_device *bd,
571 struct file *file)
570{ 572{
571 if (file->f_mode & FMODE_WRITE) 573 struct inode *inode;
572 set_bit(BSG_F_WRITE_PERM, &bd->flags); 574 struct gendisk *disk;
573 else 575
574 clear_bit(BSG_F_WRITE_PERM, &bd->flags); 576 if (!file)
577 return;
578
579 inode = file->f_dentry->d_inode;
580 if (!inode)
581 return;
582
583 disk = inode->i_bdev->bd_disk;
584
585 bd->cmd_filter = &disk->cmd_filter;
586 bd->f_mode = &file->f_mode;
575} 587}
576 588
577/* 589/*
@@ -595,6 +607,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); 607 dprintk("%s: read %Zd bytes\n", bd->name, count);
596 608
597 bsg_set_block(bd, file); 609 bsg_set_block(bd, file);
610 bsg_set_cmd_filter(bd, file);
611
598 bytes_read = 0; 612 bytes_read = 0;
599 ret = __bsg_read(buf, count, bd, NULL, &bytes_read); 613 ret = __bsg_read(buf, count, bd, NULL, &bytes_read);
600 *ppos = bytes_read; 614 *ppos = bytes_read;
@@ -668,7 +682,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); 682 dprintk("%s: write %Zd bytes\n", bd->name, count);
669 683
670 bsg_set_block(bd, file); 684 bsg_set_block(bd, file);
671 bsg_set_write_perm(bd, file); 685 bsg_set_cmd_filter(bd, file);
672 686
673 bytes_written = 0; 687 bytes_written = 0;
674 ret = __bsg_write(bd, buf, count, &bytes_written); 688 ret = __bsg_write(bd, buf, count, &bytes_written);
@@ -771,7 +785,9 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
771 } 785 }
772 786
773 bd->queue = rq; 787 bd->queue = rq;
788
774 bsg_set_block(bd, file); 789 bsg_set_block(bd, file);
790 bsg_set_cmd_filter(bd, file);
775 791
776 atomic_set(&bd->ref_count, 1); 792 atomic_set(&bd->ref_count, 1);
777 mutex_lock(&bsg_mutex); 793 mutex_lock(&bsg_mutex);