mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
block: split scsi_request out of struct request
And require all drivers that want to support BLOCK_PC to allocate it as the first thing of their private data. To support this the legacy IDE and BSG code is switched to set cmd_size on their queues to let the block layer allocate the additional space. Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
This commit is contained in:
parent
8ae94eb65b
commit
82ed4db499
49 changed files with 458 additions and 410 deletions
47
block/bsg.c
47
block/bsg.c
|
|
@ -85,7 +85,6 @@ struct bsg_command {
|
|||
struct bio *bidi_bio;
|
||||
int err;
|
||||
struct sg_io_v4 hdr;
|
||||
char sense[SCSI_SENSE_BUFFERSIZE];
|
||||
};
|
||||
|
||||
static void bsg_free_command(struct bsg_command *bc)
|
||||
|
|
@ -140,18 +139,20 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
|
|||
struct sg_io_v4 *hdr, struct bsg_device *bd,
|
||||
fmode_t has_write_perm)
|
||||
{
|
||||
struct scsi_request *req = scsi_req(rq);
|
||||
|
||||
if (hdr->request_len > BLK_MAX_CDB) {
|
||||
rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
|
||||
if (!rq->cmd)
|
||||
req->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
|
||||
if (!req->cmd)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (copy_from_user(rq->cmd, (void __user *)(unsigned long)hdr->request,
|
||||
if (copy_from_user(req->cmd, (void __user *)(unsigned long)hdr->request,
|
||||
hdr->request_len))
|
||||
return -EFAULT;
|
||||
|
||||
if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
|
||||
if (blk_verify_command(rq->cmd, has_write_perm))
|
||||
if (blk_verify_command(req->cmd, has_write_perm))
|
||||
return -EPERM;
|
||||
} else if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
|
|
@ -159,7 +160,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
|
|||
/*
|
||||
* fill in request structure
|
||||
*/
|
||||
rq->cmd_len = hdr->request_len;
|
||||
req->cmd_len = hdr->request_len;
|
||||
|
||||
rq->timeout = msecs_to_jiffies(hdr->timeout);
|
||||
if (!rq->timeout)
|
||||
|
|
@ -205,8 +206,7 @@ bsg_validate_sgv4_hdr(struct sg_io_v4 *hdr, int *rw)
|
|||
* map sg_io_v4 to a request.
|
||||
*/
|
||||
static struct request *
|
||||
bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
|
||||
u8 *sense)
|
||||
bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
|
||||
{
|
||||
struct request_queue *q = bd->queue;
|
||||
struct request *rq, *next_rq = NULL;
|
||||
|
|
@ -236,7 +236,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
|
|||
rq = blk_get_request(q, rw, GFP_KERNEL);
|
||||
if (IS_ERR(rq))
|
||||
return rq;
|
||||
blk_rq_set_block_pc(rq);
|
||||
scsi_req_init(rq);
|
||||
|
||||
ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
|
||||
if (ret)
|
||||
|
|
@ -280,13 +280,9 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
|
|||
goto out;
|
||||
}
|
||||
|
||||
rq->sense = sense;
|
||||
rq->sense_len = 0;
|
||||
|
||||
return rq;
|
||||
out:
|
||||
if (rq->cmd != rq->__cmd)
|
||||
kfree(rq->cmd);
|
||||
scsi_req_free_cmd(scsi_req(rq));
|
||||
blk_put_request(rq);
|
||||
if (next_rq) {
|
||||
blk_rq_unmap_user(next_rq->bio);
|
||||
|
|
@ -393,6 +389,7 @@ static struct bsg_command *bsg_get_done_cmd(struct bsg_device *bd)
|
|||
static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
||||
struct bio *bio, struct bio *bidi_bio)
|
||||
{
|
||||
struct scsi_request *req = scsi_req(rq);
|
||||
int ret = 0;
|
||||
|
||||
dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors);
|
||||
|
|
@ -407,12 +404,12 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
|||
hdr->info |= SG_INFO_CHECK;
|
||||
hdr->response_len = 0;
|
||||
|
||||
if (rq->sense_len && hdr->response) {
|
||||
if (req->sense_len && hdr->response) {
|
||||
int len = min_t(unsigned int, hdr->max_response_len,
|
||||
rq->sense_len);
|
||||
req->sense_len);
|
||||
|
||||
ret = copy_to_user((void __user *)(unsigned long)hdr->response,
|
||||
rq->sense, len);
|
||||
req->sense, len);
|
||||
if (!ret)
|
||||
hdr->response_len = len;
|
||||
else
|
||||
|
|
@ -420,14 +417,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
|||
}
|
||||
|
||||
if (rq->next_rq) {
|
||||
hdr->dout_resid = rq->resid_len;
|
||||
hdr->din_resid = rq->next_rq->resid_len;
|
||||
hdr->dout_resid = req->resid_len;
|
||||
hdr->din_resid = scsi_req(rq->next_rq)->resid_len;
|
||||
blk_rq_unmap_user(bidi_bio);
|
||||
blk_put_request(rq->next_rq);
|
||||
} else if (rq_data_dir(rq) == READ)
|
||||
hdr->din_resid = rq->resid_len;
|
||||
hdr->din_resid = req->resid_len;
|
||||
else
|
||||
hdr->dout_resid = rq->resid_len;
|
||||
hdr->dout_resid = req->resid_len;
|
||||
|
||||
/*
|
||||
* If the request generated a negative error number, return it
|
||||
|
|
@ -439,8 +436,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
|
|||
ret = rq->errors;
|
||||
|
||||
blk_rq_unmap_user(bio);
|
||||
if (rq->cmd != rq->__cmd)
|
||||
kfree(rq->cmd);
|
||||
scsi_req_free_cmd(req);
|
||||
blk_put_request(rq);
|
||||
|
||||
return ret;
|
||||
|
|
@ -625,7 +621,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf,
|
|||
/*
|
||||
* get a request, fill in the blanks, and add to request queue
|
||||
*/
|
||||
rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense);
|
||||
rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm);
|
||||
if (IS_ERR(rq)) {
|
||||
ret = PTR_ERR(rq);
|
||||
rq = NULL;
|
||||
|
|
@ -911,12 +907,11 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
struct bio *bio, *bidi_bio = NULL;
|
||||
struct sg_io_v4 hdr;
|
||||
int at_head;
|
||||
u8 sense[SCSI_SENSE_BUFFERSIZE];
|
||||
|
||||
if (copy_from_user(&hdr, uarg, sizeof(hdr)))
|
||||
return -EFAULT;
|
||||
|
||||
rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense);
|
||||
rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE);
|
||||
if (IS_ERR(rq))
|
||||
return PTR_ERR(rq);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue