9P: Add cancelled() to the transport functions.
authorSimon Derr <simon.derr@bull.net>
Fri, 21 Jun 2013 13:32:43 +0000 (15:32 +0200)
committerEric Van Hensbergen <ericvh@gmail.com>
Mon, 8 Jul 2013 03:18:18 +0000 (22:18 -0500)
RDMA needs to post a buffer for each incoming reply.
Hence it needs to keep count of these and needs to be
aware of whether a flushed request has received a reply
or not.

This patch adds the cancelled() callback to the transport modules.
It is called when RFLUSH has been received and that the corresponding
request will never receive a reply.

Signed-off-by: Simon Derr <simon.derr@bull.net>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
include/net/9p/transport.h
net/9p/client.c
net/9p/trans_rdma.c

index 9a36d929711482da1f4090fb9e51c4ab9a261ffd..d9fa68f26c41c34c33db5f743a4142faf7886792 100644 (file)
@@ -40,6 +40,8 @@
  * @close: member function to discard a connection on this transport
  * @request: member function to issue a request to the transport
  * @cancel: member function to cancel a request (if it hasn't been sent)
+ * @cancelled: member function to notify that a cancelled request will not
+ *             not receive a reply
  *
  * This is the basic API for a transport module which is registered by the
  * transport module with the 9P core network module and used by the client
@@ -58,6 +60,7 @@ struct p9_trans_module {
        void (*close) (struct p9_client *);
        int (*request) (struct p9_client *, struct p9_req_t *req);
        int (*cancel) (struct p9_client *, struct p9_req_t *req);
+       int (*cancelled)(struct p9_client *, struct p9_req_t *req);
        int (*zc_request)(struct p9_client *, struct p9_req_t *,
                          char *, char *, int , int, int, int);
 };
index d18a0b22f62cd7383651259f5a49cbd589f00c3f..8b93cae2d11d7d013d50c276bd08fc11a1187d08 100644 (file)
@@ -658,12 +658,18 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
 
        /*
         * if we haven't received a response for oldreq,
-        * remove it from the list.
+        * remove it from the list, and notify the transport
+        * layer that the reply will never arrive.
         */
        spin_lock(&c->lock);
-       if (oldreq->status == REQ_STATUS_FLSH)
+       if (oldreq->status == REQ_STATUS_FLSH) {
                list_del(&oldreq->req_list);
-       spin_unlock(&c->lock);
+               spin_unlock(&c->lock);
+               if (c->trans_mod->cancelled)
+                       c->trans_mod->cancelled(c, req);
+       } else {
+               spin_unlock(&c->lock);
+       }
 
        p9_free_req(c, req);
        return 0;
index 8f68df5d29731cf23b6de1bbee5284c904006c93..928f2bb9bf8d5d4d43d6324c3ea989a9daf12728 100644 (file)
@@ -588,6 +588,17 @@ static int rdma_cancel(struct p9_client *client, struct p9_req_t *req)
        return 1;
 }
 
+/* A request has been fully flushed without a reply.
+ * That means we have posted one buffer in excess.
+ */
+static int rdma_cancelled(struct p9_client *client, struct p9_req_t *req)
+{
+       struct p9_trans_rdma *rdma = client->trans;
+
+       atomic_inc(&rdma->excess_rc);
+       return 0;
+}
+
 /**
  * trans_create_rdma - Transport method for creating atransport instance
  * @client: client instance