예제 #1
0
static void virtblk_done(struct virtqueue *vq)
{
	struct virtio_blk *vblk = vq->vdev->priv;
	bool req_done = false;
	int qid = vq->index;
	struct virtblk_req *vbr;
	unsigned long flags;
	unsigned int len;

	spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
	do {
		virtqueue_disable_cb(vq);
		while ((vbr = virtqueue_get_buf(vblk->vqs[qid].vq, &len)) != NULL) {
			struct request *req = blk_mq_rq_from_pdu(vbr);

			blk_mq_complete_request(req, req->errors);
			req_done = true;
		}
		if (unlikely(virtqueue_is_broken(vq)))
			break;
	} while (!virtqueue_enable_cb(vq));

	/* In case queue is stopped waiting for more buffers. */
	if (req_done)
		blk_mq_start_stopped_hw_queues(vblk->disk->queue, true);
	spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
}
예제 #2
0
파일: bsg-lib.c 프로젝트: Anjali05/linux
/**
 * bsg_job_done - completion routine for bsg requests
 * @job: bsg_job that is complete
 * @result: job reply result
 * @reply_payload_rcv_len: length of payload recvd
 *
 * The LLD should call this when the bsg job has completed.
 */
void bsg_job_done(struct bsg_job *job, int result,
		  unsigned int reply_payload_rcv_len)
{
	job->result = result;
	job->reply_payload_rcv_len = reply_payload_rcv_len;
	blk_mq_complete_request(blk_mq_rq_from_pdu(job));
}
예제 #3
0
파일: nbd.c 프로젝트: kishore1006/linux
static void nbd_end_request(struct nbd_cmd *cmd)
{
	struct nbd_device *nbd = cmd->nbd;
	struct request *req = blk_mq_rq_from_pdu(cmd);
	int error = req->errors ? -EIO : 0;

	dev_dbg(nbd_to_dev(nbd), "request %p: %s\n", cmd,
		error ? "failed" : "done");

	blk_mq_complete_request(req, error);
}
예제 #4
0
파일: bsg-lib.c 프로젝트: Anjali05/linux
/**
 * bsg_teardown_job - routine to teardown a bsg job
 * @kref: kref inside bsg_job that is to be torn down
 */
static void bsg_teardown_job(struct kref *kref)
{
	struct bsg_job *job = container_of(kref, struct bsg_job, kref);
	struct request *rq = blk_mq_rq_from_pdu(job);

	put_device(job->dev);	/* release reference for the request */

	kfree(job->request_payload.sg_list);
	kfree(job->reply_payload.sg_list);

	blk_mq_end_request(rq, BLK_STS_OK);
}
예제 #5
0
파일: mtip32xx.c 프로젝트: vincentlao/linux
static void mtip_put_int_command(struct driver_data *dd, struct mtip_cmd *cmd)
{
	blk_put_request(blk_mq_rq_from_pdu(cmd));
}
예제 #6
0
파일: nbd.c 프로젝트: kishore1006/linux
/* always call with the tx_lock held */
static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
{
	struct request *req = blk_mq_rq_from_pdu(cmd);
	int result, flags;
	struct nbd_request request;
	unsigned long size = blk_rq_bytes(req);
	struct bio *bio;
	u32 type;
	u32 tag = blk_mq_unique_tag(req);

	if (req_op(req) == REQ_OP_DISCARD)
		type = NBD_CMD_TRIM;
	else if (req_op(req) == REQ_OP_FLUSH)
		type = NBD_CMD_FLUSH;
	else if (rq_data_dir(req) == WRITE)
		type = NBD_CMD_WRITE;
	else
		type = NBD_CMD_READ;

	memset(&request, 0, sizeof(request));
	request.magic = htonl(NBD_REQUEST_MAGIC);
	request.type = htonl(type);
	if (type != NBD_CMD_FLUSH) {
		request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
		request.len = htonl(size);
	}
	memcpy(request.handle, &tag, sizeof(tag));

	dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
		cmd, nbdcmd_to_ascii(type),
		(unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
	result = sock_xmit(nbd, index, 1, &request, sizeof(request),
			(type == NBD_CMD_WRITE) ? MSG_MORE : 0);
	if (result <= 0) {
		dev_err_ratelimited(disk_to_dev(nbd->disk),
			"Send control failed (result %d)\n", result);
		return -EIO;
	}

	if (type != NBD_CMD_WRITE)
		return 0;

	flags = 0;
	bio = req->bio;
	while (bio) {
		struct bio *next = bio->bi_next;
		struct bvec_iter iter;
		struct bio_vec bvec;

		bio_for_each_segment(bvec, bio, iter) {
			bool is_last = !next && bio_iter_last(bvec, iter);

			if (is_last)
				flags = MSG_MORE;
			dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes data\n",
				cmd, bvec.bv_len);
			result = sock_send_bvec(nbd, index, &bvec, flags);
			if (result <= 0) {
				dev_err(disk_to_dev(nbd->disk),
					"Send data failed (result %d)\n",
					result);
				return -EIO;
			}
			/*
			 * The completion might already have come in,
			 * so break for the last one instead of letting
			 * the iterator do it. This prevents use-after-free
			 * of the bio.
			 */
			if (is_last)
				break;
		}
		bio = next;
	}
예제 #7
0
파일: nbd.c 프로젝트: ivecera/linux-odroid
/* always call with the tx_lock held */
static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd)
{
    struct request *req = blk_mq_rq_from_pdu(cmd);
    int result, flags;
    struct nbd_request request;
    unsigned long size = blk_rq_bytes(req);
    u32 type;

    if (req->cmd_type == REQ_TYPE_DRV_PRIV)
        type = NBD_CMD_DISC;
    else if (req_op(req) == REQ_OP_DISCARD)
        type = NBD_CMD_TRIM;
    else if (req_op(req) == REQ_OP_FLUSH)
        type = NBD_CMD_FLUSH;
    else if (rq_data_dir(req) == WRITE)
        type = NBD_CMD_WRITE;
    else
        type = NBD_CMD_READ;

    memset(&request, 0, sizeof(request));
    request.magic = htonl(NBD_REQUEST_MAGIC);
    request.type = htonl(type);
    if (type != NBD_CMD_FLUSH && type != NBD_CMD_DISC) {
        request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
        request.len = htonl(size);
    }
    memcpy(request.handle, &req->tag, sizeof(req->tag));

    dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n",
            cmd, nbdcmd_to_ascii(type),
            (unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req));
    result = sock_xmit(nbd, 1, &request, sizeof(request),
                       (type == NBD_CMD_WRITE) ? MSG_MORE : 0);
    if (result <= 0) {
        dev_err(disk_to_dev(nbd->disk),
                "Send control failed (result %d)\n", result);
        return -EIO;
    }

    if (type == NBD_CMD_WRITE) {
        struct req_iterator iter;
        struct bio_vec bvec;
        /*
         * we are really probing at internals to determine
         * whether to set MSG_MORE or not...
         */
        rq_for_each_segment(bvec, req, iter) {
            flags = 0;
            if (!rq_iter_last(bvec, iter))
                flags = MSG_MORE;
            dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes data\n",
                    cmd, bvec.bv_len);
            result = sock_send_bvec(nbd, &bvec, flags);
            if (result <= 0) {
                dev_err(disk_to_dev(nbd->disk),
                        "Send data failed (result %d)\n",
                        result);
                return -EIO;
            }
        }
    }