Skip to content

Commit

Permalink
block: fold cmd_type into the REQ_OP_ space
Browse files Browse the repository at this point in the history
Instead of keeping two levels of indirection for requests types, fold it
all into the operations.  The little caveat here is that previously
cmd_type only applied to struct request, while the request and bio op
fields were set to plain REQ_OP_READ/WRITE even for passthrough
operations.

Instead this patch adds new REQ_OP_* for SCSI passthrough and driver
private requests, althought it has to add two for each so that we
can communicate the data in/out nature of the request.

Signed-off-by: Christoph Hellwig <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Christoph Hellwig authored and axboe committed Jan 31, 2017
1 parent 2f5a8e8 commit aebf526
Show file tree
Hide file tree
Showing 53 changed files with 338 additions and 326 deletions.
10 changes: 0 additions & 10 deletions block/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1227,9 +1227,6 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
if (!bio)
goto out_bmd;

if (iter->type & WRITE)
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);

ret = 0;

if (map_data) {
Expand Down Expand Up @@ -1394,12 +1391,6 @@ struct bio *bio_map_user_iov(struct request_queue *q,

kfree(pages);

/*
* set data direction, and check if mapped pages need bouncing
*/
if (iter->type & WRITE)
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);

bio_set_flag(bio, BIO_USER_MAPPED);

/*
Expand Down Expand Up @@ -1590,7 +1581,6 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
bio->bi_private = data;
} else {
bio->bi_end_io = bio_copy_kern_endio;
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
}

return bio;
Expand Down
6 changes: 2 additions & 4 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ static void req_bio_endio(struct request *rq, struct bio *bio,

void blk_dump_rq_flags(struct request *rq, char *msg)
{
printk(KERN_INFO "%s: dev %s: type=%x, flags=%llx\n", msg,
rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type,
printk(KERN_INFO "%s: dev %s: flags=%llx\n", msg,
rq->rq_disk ? rq->rq_disk->disk_name : "?",
(unsigned long long) rq->cmd_flags);

printk(KERN_INFO " sector %llu, nr/cnr %u/%u\n",
Expand Down Expand Up @@ -1593,7 +1593,6 @@ unsigned int blk_plug_queued_count(struct request_queue *q)

void init_request_from_bio(struct request *req, struct bio *bio)
{
req->cmd_type = REQ_TYPE_FS;
if (bio->bi_opf & REQ_RAHEAD)
req->cmd_flags |= REQ_FAILFAST_MASK;

Expand Down Expand Up @@ -2983,7 +2982,6 @@ EXPORT_SYMBOL_GPL(blk_rq_unprep_clone);
static void __blk_rq_prep_clone(struct request *dst, struct request *src)
{
dst->cpu = src->cpu;
dst->cmd_type = src->cmd_type;
dst->__sector = blk_rq_pos(src);
dst->__data_len = blk_rq_bytes(src);
dst->nr_phys_segments = src->nr_phys_segments;
Expand Down
1 change: 0 additions & 1 deletion block/blk-flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq)
blk_mq_tag_set_rq(hctx, first_rq->tag, flush_rq);
}

flush_rq->cmd_type = REQ_TYPE_FS;
flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
flush_rq->rq_flags |= RQF_FLUSH_SEQ;
flush_rq->rq_disk = first_rq->rq_disk;
Expand Down
13 changes: 7 additions & 6 deletions block/blk-map.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
int blk_rq_append_bio(struct request *rq, struct bio *bio)
{
if (!rq->bio) {
rq->cmd_flags &= REQ_OP_MASK;
rq->cmd_flags |= (bio->bi_opf & REQ_OP_MASK);
blk_rq_bio_prep(rq->q, rq, bio);
} else {
if (!ll_back_merge_fn(rq->q, rq, bio))
Expand Down Expand Up @@ -62,6 +60,9 @@ static int __blk_rq_map_user_iov(struct request *rq,
if (IS_ERR(bio))
return PTR_ERR(bio);

bio->bi_opf &= ~REQ_OP_MASK;
bio->bi_opf |= req_op(rq);

if (map_data && map_data->null_mapped)
bio_set_flag(bio, BIO_NULL_MAPPED);

Expand Down Expand Up @@ -90,7 +91,7 @@ static int __blk_rq_map_user_iov(struct request *rq,
}

/**
* blk_rq_map_user_iov - map user data to a request, for REQ_TYPE_BLOCK_PC usage
* blk_rq_map_user_iov - map user data to a request, for passthrough requests
* @q: request queue where request should be inserted
* @rq: request to map data to
* @map_data: pointer to the rq_map_data holding pages (if necessary)
Expand Down Expand Up @@ -199,7 +200,7 @@ int blk_rq_unmap_user(struct bio *bio)
EXPORT_SYMBOL(blk_rq_unmap_user);

/**
* blk_rq_map_kern - map kernel data to a request, for REQ_TYPE_BLOCK_PC usage
* blk_rq_map_kern - map kernel data to a request, for passthrough requests
* @q: request queue where request should be inserted
* @rq: request to fill
* @kbuf: the kernel buffer
Expand Down Expand Up @@ -234,8 +235,8 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
if (IS_ERR(bio))
return PTR_ERR(bio);

if (!reading)
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
bio->bi_opf &= ~REQ_OP_MASK;
bio->bi_opf |= req_op(rq);

if (do_copy)
rq->rq_flags |= RQF_COPY_USER;
Expand Down
4 changes: 2 additions & 2 deletions block/blk-mq-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ static int blk_mq_debugfs_rq_show(struct seq_file *m, void *v)
{
struct request *rq = list_entry_rq(v);

seq_printf(m, "%p {.cmd_type=%u, .cmd_flags=0x%x, .rq_flags=0x%x, .tag=%d, .internal_tag=%d}\n",
rq, rq->cmd_type, rq->cmd_flags, (unsigned int)rq->rq_flags,
seq_printf(m, "%p {.cmd_flags=0x%x, .rq_flags=0x%x, .tag=%d, .internal_tag=%d}\n",
rq, rq->cmd_flags, (unsigned int)rq->rq_flags,
rq->tag, rq->internal_tag);
return 0;
}
Expand Down
17 changes: 8 additions & 9 deletions block/bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
* Check if sg_io_v4 from user is allowed and valid
*/
static int
bsg_validate_sgv4_hdr(struct sg_io_v4 *hdr, int *rw)
bsg_validate_sgv4_hdr(struct sg_io_v4 *hdr, int *op)
{
int ret = 0;

Expand All @@ -198,7 +198,7 @@ bsg_validate_sgv4_hdr(struct sg_io_v4 *hdr, int *rw)
ret = -EINVAL;
}

*rw = hdr->dout_xfer_len ? WRITE : READ;
*op = hdr->dout_xfer_len ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN;
return ret;
}

Expand All @@ -210,8 +210,8 @@ 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;
int ret, rw;
unsigned int dxfer_len;
int ret;
unsigned int op, dxfer_len;
void __user *dxferp = NULL;
struct bsg_class_device *bcd = &q->bsg_dev;

Expand All @@ -226,14 +226,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp,
hdr->din_xfer_len);

ret = bsg_validate_sgv4_hdr(hdr, &rw);
ret = bsg_validate_sgv4_hdr(hdr, &op);
if (ret)
return ERR_PTR(ret);

/*
* map scatter-gather elements separately and string them to request
*/
rq = blk_get_request(q, rw, GFP_KERNEL);
rq = blk_get_request(q, op, GFP_KERNEL);
if (IS_ERR(rq))
return rq;
scsi_req_init(rq);
Expand All @@ -242,20 +242,19 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
if (ret)
goto out;

if (rw == WRITE && hdr->din_xfer_len) {
if (op == REQ_OP_SCSI_OUT && hdr->din_xfer_len) {
if (!test_bit(QUEUE_FLAG_BIDI, &q->queue_flags)) {
ret = -EOPNOTSUPP;
goto out;
}

next_rq = blk_get_request(q, READ, GFP_KERNEL);
next_rq = blk_get_request(q, REQ_OP_SCSI_IN, GFP_KERNEL);
if (IS_ERR(next_rq)) {
ret = PTR_ERR(next_rq);
next_rq = NULL;
goto out;
}
rq->next_rq = next_rq;
next_rq->cmd_type = rq->cmd_type;

dxferp = (void __user *)(unsigned long)hdr->din_xferp;
ret = blk_rq_map_user(q, next_rq, NULL, dxferp,
Expand Down
9 changes: 5 additions & 4 deletions block/scsi_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
at_head = 1;

ret = -ENOMEM;
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
rq = blk_get_request(q, writing ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
GFP_KERNEL);
if (IS_ERR(rq))
return PTR_ERR(rq);
req = scsi_req(rq);
Expand Down Expand Up @@ -448,7 +449,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,

}

rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_RECLAIM);
rq = blk_get_request(q, in_len ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
__GFP_RECLAIM);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto error_free_buffer;
Expand Down Expand Up @@ -537,7 +539,7 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
struct request *rq;
int err;

rq = blk_get_request(q, WRITE, __GFP_RECLAIM);
rq = blk_get_request(q, REQ_OP_SCSI_OUT, __GFP_RECLAIM);
if (IS_ERR(rq))
return PTR_ERR(rq);
scsi_req_init(rq);
Expand Down Expand Up @@ -745,7 +747,6 @@ void scsi_req_init(struct request *rq)
{
struct scsi_request *req = scsi_req(rq);

rq->cmd_type = REQ_TYPE_BLOCK_PC;
memset(req->__cmd, 0, sizeof(req->__cmd));
req->cmd = req->__cmd;
req->cmd_len = BLK_MAX_CDB;
Expand Down
13 changes: 9 additions & 4 deletions drivers/block/cciss.c
Original file line number Diff line number Diff line change
Expand Up @@ -3394,7 +3394,9 @@ static void do_cciss_request(struct request_queue *q)
c->Header.SGList = h->max_cmd_sgentries;
set_performant_mode(h, c);

if (likely(creq->cmd_type == REQ_TYPE_FS)) {
switch (req_op(creq)) {
case REQ_OP_READ:
case REQ_OP_WRITE:
if(h->cciss_read == CCISS_READ_10) {
c->Request.CDB[1] = 0;
c->Request.CDB[2] = (start_blk >> 24) & 0xff; /* MSB */
Expand Down Expand Up @@ -3424,13 +3426,16 @@ static void do_cciss_request(struct request_queue *q)
c->Request.CDB[13]= blk_rq_sectors(creq) & 0xff;
c->Request.CDB[14] = c->Request.CDB[15] = 0;
}
} else if (creq->cmd_type == REQ_TYPE_BLOCK_PC) {
break;
case REQ_OP_SCSI_IN:
case REQ_OP_SCSI_OUT:
c->Request.CDBLen = scsi_req(creq)->cmd_len;
memcpy(c->Request.CDB, scsi_req(creq)->cmd, BLK_MAX_CDB);
scsi_req(creq)->sense = c->err_info->SenseInfo;
} else {
break;
default:
dev_warn(&h->pdev->dev, "bad request type %d\n",
creq->cmd_type);
creq->cmd_flags);
BUG();
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/block/floppy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2900,8 +2900,8 @@ static void do_fd_request(struct request_queue *q)
return;

if (WARN(atomic_read(&usage_count) == 0,
"warning: usage count=0, current_req=%p sect=%ld type=%x flags=%llx\n",
current_req, (long)blk_rq_pos(current_req), current_req->cmd_type,
"warning: usage count=0, current_req=%p sect=%ld flags=%llx\n",
current_req, (long)blk_rq_pos(current_req),
(unsigned long long) current_req->cmd_flags))
return;

Expand Down
45 changes: 22 additions & 23 deletions drivers/block/hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,30 +626,29 @@ static void hd_request(void)
req_data_dir(req) == READ ? "read" : "writ",
cyl, head, sec, nsect, bio_data(req->bio));
#endif
if (req->cmd_type == REQ_TYPE_FS) {
switch (rq_data_dir(req)) {
case READ:
hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_READ,
&read_intr);
if (reset)
goto repeat;
break;
case WRITE:
hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_WRITE,
&write_intr);
if (reset)
goto repeat;
if (wait_DRQ()) {
bad_rw_intr();
goto repeat;
}
outsw(HD_DATA, bio_data(req->bio), 256);
break;
default:
printk("unknown hd-command\n");
hd_end_request_cur(-EIO);
break;

switch (req_op(req)) {
case REQ_OP_READ:
hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_READ,
&read_intr);
if (reset)
goto repeat;
break;
case REQ_OP_WRITE:
hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_WRITE,
&write_intr);
if (reset)
goto repeat;
if (wait_DRQ()) {
bad_rw_intr();
goto repeat;
}
outsw(HD_DATA, bio_data(req->bio), 256);
break;
default:
printk("unknown hd-command\n");
hd_end_request_cur(-EIO);
break;
}
}

Expand Down
31 changes: 17 additions & 14 deletions drivers/block/mg_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,15 +670,17 @@ static void mg_request_poll(struct request_queue *q)
break;
}

if (unlikely(host->req->cmd_type != REQ_TYPE_FS)) {
mg_end_request_cur(host, -EIO);
continue;
}

if (rq_data_dir(host->req) == READ)
switch (req_op(host->req)) {
case REQ_OP_READ:
mg_read(host->req);
else
break;
case REQ_OP_WRITE:
mg_write(host->req);
break;
default:
mg_end_request_cur(host, -EIO);
break;
}
}
}

Expand All @@ -687,13 +689,15 @@ static unsigned int mg_issue_req(struct request *req,
unsigned int sect_num,
unsigned int sect_cnt)
{
if (rq_data_dir(req) == READ) {
switch (req_op(host->req)) {
case REQ_OP_READ:
if (mg_out(host, sect_num, sect_cnt, MG_CMD_RD, &mg_read_intr)
!= MG_ERR_NONE) {
mg_bad_rw_intr(host);
return host->error;
}
} else {
break;
case REQ_OP_WRITE:
/* TODO : handler */
outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr)
Expand All @@ -712,6 +716,10 @@ static unsigned int mg_issue_req(struct request *req,
mod_timer(&host->timer, jiffies + 3 * HZ);
outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
MG_REG_COMMAND);
break;
default:
mg_end_request_cur(host, -EIO);
break;
}
return MG_ERR_NONE;
}
Expand Down Expand Up @@ -753,11 +761,6 @@ static void mg_request(struct request_queue *q)
continue;
}

if (unlikely(req->cmd_type != REQ_TYPE_FS)) {
mg_end_request_cur(host, -EIO);
continue;
}

if (!mg_issue_req(req, host, sect_num, sect_cnt))
return;
}
Expand Down
Loading

0 comments on commit aebf526

Please sign in to comment.