diff options
Diffstat (limited to 'src/kernel/mq.c')
-rw-r--r-- | src/kernel/mq.c | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/src/kernel/mq.c b/src/kernel/mq.c deleted file mode 100644 index 98e6e14..0000000 --- a/src/kernel/mq.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * mq.c - * - * Created on: Jun 26, 2019 - * Author: fred - */ - -#include <net/sock.h> - -#include "mq.h" -#include "block.h" - -#define DNBD3_CMD_REQUEUED 1 - - -#define dnbd3_priv_to_cmd(req) ((req)->cmd_flags >> REQ_FLAG_BITS) - -static int dnbd3_send_cmd(struct dnbd3_device_t *dev, struct dnbd3_sock *sock, struct dnbd3_cmd *cmd, int index) -{ - struct request *req = blk_mq_rq_from_pdu(cmd); - dnbd3_request_t dnbd3_request; - dnbd3_reply_t dnbd3_reply; - struct msghdr msg; - struct kvec iov; - struct req_iterator iter; - struct bio_vec bvec_inst; - struct bio_vec *bvec = &bvec_inst; - sigset_t blocked, oldset; - void *kaddr; - int result; - sock->pending = req; - init_msghdr(msg); - - dnbd3_request.magic = dnbd3_packet_magic; - - switch (req_op(req)) { -// case REQ_OP_DISCARD: -// printk(KERN_DEBUG "dnbd3: request operation discard on device %d\n", dev->minor); -// break; -// case REQ_OP_FLUSH: -// printk(KERN_DEBUG "dnbd3: request operation flush on device %d\n", dev->minor); -// break; -// case REQ_OP_WRITE: -// printk(KERN_DEBUG "dnbd3: request operation write on device %d\n", dev->minor); -// break; - case REQ_OP_READ: - printk(KERN_DEBUG "dnbd3: request operation read on device %d\n", dev->minor); - dnbd3_request.cmd = CMD_GET_BLOCK; - dnbd3_request.offset = blk_rq_pos(req) << 9; // *512 - dnbd3_request.size = blk_rq_bytes(req); // bytes left to complete entire request - break; - case REQ_OP_DRV_IN: - printk(KERN_DEBUG "dnbd3: request operation driver in on device %d\n", dev->minor); - dnbd3_request.cmd = dnbd3_priv_to_cmd(req); - dnbd3_request.size = 0; - break; - - default: - return -EIO; - } - - dnbd3_request.handle = (uint64_t)(uintptr_t)req; // Double cast to prevent warning on 32bit - fixup_request(dnbd3_request); - iov.iov_base = &dnbd3_request; - iov.iov_len = sizeof(dnbd3_request); - if (kernel_sendmsg(sock->sock, &msg, &iov, 1, sizeof(dnbd3_request)) != sizeof(dnbd3_request)) { - printk(KERN_ERR "dnbd3: connection to server lost\n"); - result = -EIO; - goto error; - } - - // receive net reply - iov.iov_base = &dnbd3_reply; - iov.iov_len = sizeof(dnbd3_reply); - result = kernel_recvmsg(sock->sock, &msg, &iov, 1, sizeof(dnbd3_reply), msg.msg_flags); - if (!result) { - printk(KERN_ERR "dnbd3: connection to server lost\n"); - result = -EIO; - goto error; - - } - fixup_reply(dnbd3_reply); - - // check error - if (dnbd3_reply.magic != dnbd3_packet_magic) { - printk(KERN_ERR "dnbd3: wrong magic packet\n"); - result = -EIO; - goto error; - } - - if (dnbd3_reply.cmd != CMD_GET_BLOCK) { - printk(KERN_ERR "dnbd3: command was %d\n", dnbd3_reply.cmd); - result = -EIO; - goto error; - } - - - - rq_for_each_segment(bvec_inst, req, iter) { - siginitsetinv(&blocked, sigmask(SIGKILL)); - sigprocmask(SIG_SETMASK, &blocked, &oldset); - - kaddr = kmap(bvec->bv_page) + bvec->bv_offset; - iov.iov_base = kaddr; - iov.iov_len = bvec->bv_len; - if (kernel_recvmsg(sock->sock, &msg, &iov, 1, bvec->bv_len, msg.msg_flags) != bvec->bv_len) { - kunmap(bvec->bv_page); - sigprocmask(SIG_SETMASK, &oldset, NULL ); - printk(KERN_ERR "dnbd3: could not receive form net to block layer\n"); - goto error; - } - kunmap(bvec->bv_page); - - sigprocmask(SIG_SETMASK, &oldset, NULL ); - } - blk_mq_end_request(req, 0); - sock->pending = NULL; -error: - return result; -} - -static void dnbd3_requeue_cmd(struct dnbd3_cmd *cmd) -{ - struct request *req = blk_mq_rq_from_pdu(cmd); - - if (!test_and_set_bit(DNBD3_CMD_REQUEUED, &cmd->flags)) { - blk_mq_requeue_request(req, true); - } -} - -static int dnbd3_handle_cmd(struct dnbd3_cmd *cmd, int index) -{ - struct request *req = blk_mq_rq_from_pdu(cmd); - struct dnbd3_device_t *dev = cmd->dnbd3; - struct dnbd3_sock *sock; - int ret = -1; - - printk(KERN_DEBUG "dnbd3: handle request at position %lu and size %d, device %i\n", blk_rq_pos(req), blk_rq_bytes(req), dev->minor); - -// if (index >= 1) { // TODO use next server with good rtt for this request -// printk(KERN_INFO "dnbd3: index is %d", index); -// dev_err_ratelimited(disk_to_dev(dev->disk), "attempted send on invalid socket\n"); -// blk_mq_start_request(req); -// return -EINVAL; -// } - - sock = &dev->socks[index]; - if (!sock->sock) { - printk(KERN_INFO "dnbd3: index is %d but no socket was found\n", index); - dev_err_ratelimited(disk_to_dev(dev->disk), "attempted send on invalid socket\n"); - blk_mq_start_request(req); - return -EINVAL; - } - - - cmd->status = BLK_STS_OK; - -again: - - - mutex_lock(&sock->lock); - if (unlikely(!sock->sock)) { - mutex_unlock(&sock->lock); - printk(KERN_DEBUG "dnbd3: not connected\n"); - return -EIO; - } - - blk_mq_start_request(req); - if (unlikely(sock->pending && sock->pending != req)) { - dnbd3_requeue_cmd(cmd); - ret = 0; - goto out; - } - - ret = dnbd3_send_cmd(dev, sock, cmd, index); - if (ret == -EAGAIN) { - dev_err_ratelimited(disk_to_dev(dev->disk), "request send failed, requeueing\n"); - dnbd3_requeue_cmd(cmd); - ret = 0; - } -out: - mutex_unlock(&sock->lock); - return ret; -} - -static blk_status_t dnbd3_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) -{ - struct dnbd3_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); - int ret; - struct dnbd3_device_t *dev = cmd->dnbd3; - - printk(KERN_DEBUG "dnbd3: queue request device %i\n", dev->minor); - - - mutex_lock(&cmd->lock); - clear_bit(DNBD3_CMD_REQUEUED, &cmd->flags); - - - ret = dnbd3_handle_cmd(cmd, hctx->queue_num); - if (ret < 0) { - ret = BLK_STS_IOERR; - } else if (!ret) { - ret = BLK_STS_OK; - } - mutex_unlock(&cmd->lock); - - return ret; -} - -static void dnbd3_complete_rq(struct request *req) -{ - printk(KERN_DEBUG "dnbd3: dnbd3_complete_rq\n"); - -} - -static int dnbd3_init_request(struct blk_mq_tag_set *set, struct request *rq, unsigned int hctx_idx, unsigned int numa_node) -{ - struct dnbd3_cmd *cmd = blk_mq_rq_to_pdu(rq); - cmd->dnbd3 = set->driver_data; - cmd->flags = 0; - mutex_init(&cmd->lock); - return 0; -} -static enum blk_eh_timer_return dnbd3_xmit_timeout(struct request *req, bool reserved) -{ - printk(KERN_DEBUG "dnbd3: dnbd3_xmit_timeout\n"); - return BLK_EH_DONE; -} - - -struct blk_mq_ops dnbd3_mq_ops = { - .queue_rq = dnbd3_queue_rq, - .complete = dnbd3_complete_rq, - .init_request = dnbd3_init_request, - .timeout = dnbd3_xmit_timeout, -}; - |