]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/9p/client.c
Merge tag 'for-linus-3.11-merge-window-part-2' of git://git.kernel.org/pub/scm/linux...
[karo-tx-linux.git] / net / 9p / client.c
index addc116cecf0be16210498b6544fa40ad24cc615..8b93cae2d11d7d013d50c276bd08fc11a1187d08 100644 (file)
@@ -127,7 +127,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
        char *s;
        int ret = 0;
 
-       clnt->proto_version = p9_proto_2000u;
+       clnt->proto_version = p9_proto_2000L;
        clnt->msize = 8192;
 
        if (!opts)
@@ -204,6 +204,17 @@ free_and_return:
        return ret;
 }
 
+struct p9_fcall *p9_fcall_alloc(int alloc_msize)
+{
+       struct p9_fcall *fc;
+       fc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, GFP_NOFS);
+       if (!fc)
+               return NULL;
+       fc->capacity = alloc_msize;
+       fc->sdata = (char *) fc + sizeof(struct p9_fcall);
+       return fc;
+}
+
 /**
  * p9_tag_alloc - lookup/allocate a request by tag
  * @c: client session to lookup tag within
@@ -256,39 +267,36 @@ p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size)
        col = tag % P9_ROW_MAXTAG;
 
        req = &c->reqs[row][col];
-       if (!req->tc) {
+       if (!req->wq) {
                req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_NOFS);
-               if (!req->wq) {
-                       pr_err("Couldn't grow tag array\n");
-                       return ERR_PTR(-ENOMEM);
-               }
+               if (!req->wq)
+                       goto grow_failed;
                init_waitqueue_head(req->wq);
-               req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
-                                 GFP_NOFS);
-               req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
-                                 GFP_NOFS);
-               if ((!req->tc) || (!req->rc)) {
-                       pr_err("Couldn't grow tag array\n");
-                       kfree(req->tc);
-                       kfree(req->rc);
-                       kfree(req->wq);
-                       req->tc = req->rc = NULL;
-                       req->wq = NULL;
-                       return ERR_PTR(-ENOMEM);
-               }
-               req->tc->capacity = alloc_msize;
-               req->rc->capacity = alloc_msize;
-               req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
-               req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
        }
 
+       if (!req->tc)
+               req->tc = p9_fcall_alloc(alloc_msize);
+       if (!req->rc)
+               req->rc = p9_fcall_alloc(alloc_msize);
+       if (!req->tc || !req->rc)
+               goto grow_failed;
+
        p9pdu_reset(req->tc);
        p9pdu_reset(req->rc);
 
        req->tc->tag = tag-1;
        req->status = REQ_STATUS_ALLOC;
 
-       return &c->reqs[row][col];
+       return req;
+
+grow_failed:
+       pr_err("Couldn't grow tag array\n");
+       kfree(req->tc);
+       kfree(req->rc);
+       kfree(req->wq);
+       req->tc = req->rc = NULL;
+       req->wq = NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
 /**
@@ -648,12 +656,20 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
                return PTR_ERR(req);
 
 
-       /* if we haven't received a response for oldreq,
-          remove it from the list. */
+       /*
+        * if we haven't received a response for oldreq,
+        * 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;
@@ -995,6 +1011,9 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (err < 0)
                goto destroy_tagpool;
 
+       if (!clnt->trans_mod)
+               clnt->trans_mod = v9fs_get_trans_by_name("virtio");
+
        if (!clnt->trans_mod)
                clnt->trans_mod = v9fs_get_default_trans();