add X_CLOSE in xsegbd removal
authorGiannakos Filippos <philipgian@cslab.ece.ntua.gr>
Mon, 1 Oct 2012 11:20:09 +0000 (14:20 +0300)
committerGiannakos Filippos <philipgian@cslab.ece.ntua.gr>
Mon, 1 Oct 2012 11:20:09 +0000 (14:20 +0300)
xseg/peers/kernel/xsegbd.c
xseg/peers/user/mt-mapperd.c
xseg/peers/user/mt-vlmcd.c
xseg/xseg/protocol.h

index 1342e72..0dbd322 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <sys/kernel/segdev.h>
 #include "xsegbd.h"
+#include <xseg/protocol.h>
 
 #define XSEGBD_MINORS 1
 /* define max request size to be used in xsegbd */
@@ -185,6 +186,7 @@ static const struct block_device_operations xsegbd_ops = {
 
 static void xseg_request_fn(struct request_queue *rq);
 static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev);
+static int xsegbd_mapclose(struct xsegbd_device *xsegbd_dev);
 
 static int xsegbd_dev_init(struct xsegbd_device *xsegbd_dev)
 {
@@ -274,6 +276,7 @@ static void xsegbd_dev_release(struct device *dev)
 
                blk_cleanup_queue(xsegbd_dev->blk_queue);
                put_disk(xsegbd_dev->gd);
+               xsegbd_mapclose(xsegbd_dev);
        }
 
 //     if (xseg_free_requests(xsegbd_dev->xseg, 
@@ -485,11 +488,10 @@ static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev)
        xreq = xseg_get_request(xsegbd_dev->xseg, xsegbd_dev->src_portno,
                        xsegbd_dev->dst_portno, X_ALLOC);
        if (!xreq)
-               goto out;
+               return ret;
 
-       datalen = sizeof(uint64_t);
-       BUG_ON(xseg_prep_request(xsegbd_dev->xseg, xreq, xsegbd_dev->targetlen, datalen));
-       BUG_ON(xreq->bufferlen - xsegbd_dev->targetlen < datalen);
+       BUG_ON(xseg_prep_request(xsegbd_dev->xseg, xreq, xsegbd_dev->targetlen, 
+                               sizeof(struct xseg_reply_info)));
 
        init_completion(&comp);
        blkreq_idx = xq_pop_head(&xsegbd_dev->blk_queue_pending, 1);
@@ -506,7 +508,7 @@ static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev)
 
        target = xseg_get_target(xsegbd_dev->xseg, xreq);
        strncpy(target, xsegbd_dev->target, xsegbd_dev->targetlen);
-       xreq->size = datalen;
+       xreq->size = xreq->datalen;
        xreq->offset = 0;
        xreq->op = X_INFO;
 
@@ -525,12 +527,75 @@ static int xsegbd_get_size(struct xsegbd_device *xsegbd_dev)
        ret = update_dev_sectors_from_request(xsegbd_dev, xreq);
        //XSEGLOG("get_size: sectors = %ld\n", (long)xsegbd_dev->sectors);
 out:
+       BUG_ON(xseg_put_request(xsegbd_dev->xseg, xreq, xsegbd_dev->src_portno) == -1);
+       return ret;
+
+out_queue:
        pending->dev = NULL;
        pending->comp = NULL;
+       xq_append_head(&xsegbd_dev->blk_queue_pending, blkreq_idx, 1);
+       
+       goto out;
+}
+
+static int xsegbd_mapclose(struct xsegbd_device *xsegbd_dev)
+{
+       struct xseg_request *xreq;
+       char *target;
+       uint64_t datalen;
+       xqindex blkreq_idx;
+       struct xsegbd_pending *pending;
+       struct completion comp;
+       xport p;
+       void *data;
+       int ret = -EBUSY, r;
+       xreq = xseg_get_request(xsegbd_dev->xseg, xsegbd_dev->src_portno,
+                       xsegbd_dev->dst_portno, X_ALLOC);
+       if (!xreq)
+               return ret;;
+
+       BUG_ON(xseg_prep_request(xsegbd_dev->xseg, xreq, xsegbd_dev->targetlen, 0));
+       BUG_ON(xreq->bufferlen - xsegbd_dev->targetlen < datalen);
+
+       init_completion(&comp);
+       blkreq_idx = xq_pop_head(&xsegbd_dev->blk_queue_pending, 1);
+       if (blkreq_idx == Noneidx)
+               goto out;
+       
+       pending = &xsegbd_dev->blk_req_pending[blkreq_idx];
+       pending->dev = xsegbd_dev;
+       pending->request = NULL;
+       pending->comp = &comp;
+
+       
+       xreq->priv = (uint64_t) blkreq_idx;
+
+       target = xseg_get_target(xsegbd_dev->xseg, xreq);
+       strncpy(target, xsegbd_dev->target, xsegbd_dev->targetlen);
+       xreq->size = xreq->datalen;
+       xreq->offset = 0;
+       xreq->op = X_CLOSE;
+
+       xseg_prepare_wait(xsegbd_dev->xseg, xsegbd_dev->src_portno);
+       p = xseg_submit(xsegbd_dev->xseg, xreq, 
+                               xsegbd_dev->src_portno, X_ALLOC);
+       if ( p == NoPort) {
+               XSEGLOG("couldn't submit request");
+               BUG_ON(1);
+               goto out_queue;
+       }
+       WARN_ON(xseg_signal(xsegbd_dev->xseg, p) < 0);
+       wait_for_completion_interruptible(&comp);
+       ret = 0;
+       if (xreq->state & XS_FAILED)
+               XSEGLOG("Couldn't close disk on mapper");
+out:
        BUG_ON(xseg_put_request(xsegbd_dev->xseg, xreq, xsegbd_dev->src_portno) == -1);
        return ret;
 
 out_queue:
+       pending->dev = NULL;
+       pending->comp = NULL;
        xq_append_head(&xsegbd_dev->blk_queue_pending, blkreq_idx, 1);
        
        goto out;
index 999455f..3f2d91f 100644 (file)
@@ -199,14 +199,14 @@ out:
 }
 
 /* async map load */
-static int load_map(struct peerd *peer, struct peer_req *pr, char *target, uint32_t targetlen)
+static int load_map(struct peerd *peer, struct peer_req *pr, char *target, 
+                       uint32_t targetlen)
 {
        int r;
        xport p;
        struct xseg_request *req;
        struct mapperd *mapper = __get_mapperd(peer);
        void *dummy;
-       //printf("Loading map\n");
 
        struct map *m = find_map(mapper, target, targetlen);
        if (!m) {
@@ -241,7 +241,6 @@ static int load_map(struct peerd *peer, struct peer_req *pr, char *target, uint3
        if (r < 0)  
                goto out_hash;
        
-       //printf("Loading map: preparing req\n");
 
        req = xseg_get_request(peer->xseg, peer->portno, mapper->mbportno, X_ALLOC);
        if (!req){
index 1b16760..4fec96d 100644 (file)
@@ -97,6 +97,7 @@ static int handle_accepted(struct peerd *peer, struct peer_req *pr,
                case X_READ: vio->mreq->op = X_MAPR; break;
                case X_WRITE: vio->mreq->op = X_MAPW; break;
                case X_INFO: vio->mreq->op = X_INFO; break;
+               case X_CLOSE: vio->mreq->op = X_CLOSE; break;
                default: goto out_put;
        }
        xseg_set_req_data(peer->xseg, vio->mreq, pr);
@@ -155,6 +156,12 @@ static int handle_mapping(struct peerd *peer, struct peer_req *pr,
                vio->mreq = NULL;
                __set_vio_state(vio, CONCLUDED);
                complete(peer, pr);
+       } else if (vio->mreq->op == X_CLOSE) {
+               struct xseg_reply_info *xinfo = (struct xseg_reply_info *) xseg_get_data(peer->xseg, vio->mreq);
+               xseg_put_request(peer->xseg, vio->mreq, peer->portno);
+               vio->mreq = NULL;
+               __set_vio_state(vio, CONCLUDED);
+               complete(peer, pr);
        } else {
                struct xseg_reply_map *mreply = (struct xseg_reply_map *) xseg_get_data(peer->xseg, vio->mreq);
                if (!mreply->cnt){
index a333726..f65f506 100644 (file)
@@ -1,7 +1,11 @@
 #ifndef _PROTOCOL_H
 #define _PROTOCOL_H
 
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
 #include <stdint.h>
+#endif
 
 /*
  * Reply structures.