Merge tag 'dmaengine-4.9-rc1' of git://git.infradead.org/users/vkoul/slave-dma
[cascardo/linux.git] / fs / afs / cmservice.c
index 85737e9..2037e7a 100644 (file)
 #include "internal.h"
 #include "afs_cm.h"
 
-#if 0
-struct workqueue_struct *afs_cm_workqueue;
-#endif  /*  0  */
-
-static int afs_deliver_cb_init_call_back_state(struct afs_call *,
-                                              struct sk_buff *, bool);
-static int afs_deliver_cb_init_call_back_state3(struct afs_call *,
-                                               struct sk_buff *, bool);
-static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool);
-static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool);
-static int afs_deliver_cb_probe_uuid(struct afs_call *, struct sk_buff *, bool);
-static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *,
-                                                struct sk_buff *, bool);
+static int afs_deliver_cb_init_call_back_state(struct afs_call *);
+static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
+static int afs_deliver_cb_probe(struct afs_call *);
+static int afs_deliver_cb_callback(struct afs_call *);
+static int afs_deliver_cb_probe_uuid(struct afs_call *);
+static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
 static void afs_cm_destructor(struct afs_call *);
 
 /*
@@ -134,7 +127,7 @@ static void afs_cm_destructor(struct afs_call *call)
         * received.  The step number here must match the final number in
         * afs_deliver_cb_callback().
         */
-       if (call->unmarshall == 6) {
+       if (call->unmarshall == 5) {
                ASSERT(call->server && call->count && call->request);
                afs_break_callbacks(call->server, call->count, call->request);
        }
@@ -168,27 +161,27 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
 /*
  * deliver request data to a CB.CallBack call
  */
-static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
-                                  bool last)
+static int afs_deliver_cb_callback(struct afs_call *call)
 {
+       struct sockaddr_rxrpc srx;
        struct afs_callback *cb;
        struct afs_server *server;
-       struct in_addr addr;
        __be32 *bp;
        u32 tmp;
        int ret, loop;
 
-       _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
+       _enter("{%u}", call->unmarshall);
 
        switch (call->unmarshall) {
        case 0:
+               rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
                call->offset = 0;
                call->unmarshall++;
 
                /* extract the FID array and its count in two steps */
        case 1:
                _debug("extract FID count");
-               ret = afs_extract_data(call, skb, last, &call->tmp, 4);
+               ret = afs_extract_data(call, &call->tmp, 4, true);
                if (ret < 0)
                        return ret;
 
@@ -205,8 +198,8 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
 
        case 2:
                _debug("extract FID array");
-               ret = afs_extract_data(call, skb, last, call->buffer,
-                                      call->count * 3 * 4);
+               ret = afs_extract_data(call, call->buffer,
+                                      call->count * 3 * 4, true);
                if (ret < 0)
                        return ret;
 
@@ -232,7 +225,7 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
                /* extract the callback array and its count in two steps */
        case 3:
                _debug("extract CB count");
-               ret = afs_extract_data(call, skb, last, &call->tmp, 4);
+               ret = afs_extract_data(call, &call->tmp, 4, true);
                if (ret < 0)
                        return ret;
 
@@ -242,13 +235,11 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
                        return -EBADMSG;
                call->offset = 0;
                call->unmarshall++;
-               if (tmp == 0)
-                       goto empty_cb_array;
 
        case 4:
                _debug("extract CB array");
-               ret = afs_extract_data(call, skb, last, call->request,
-                                      call->count * 3 * 4);
+               ret = afs_extract_data(call, call->buffer,
+                                      call->count * 3 * 4, false);
                if (ret < 0)
                        return ret;
 
@@ -261,15 +252,9 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
                        cb->type        = ntohl(*bp++);
                }
 
-       empty_cb_array:
                call->offset = 0;
                call->unmarshall++;
 
-       case 5:
-               ret = afs_data_complete(call, skb, last);
-               if (ret < 0)
-                       return ret;
-
                /* Record that the message was unmarshalled successfully so
                 * that the call destructor can know do the callback breaking
                 * work, even if the final ACK isn't received.
@@ -278,17 +263,15 @@ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
                 * updated also.
                 */
                call->unmarshall++;
-       case 6:
+       case 5:
                break;
        }
 
-
        call->state = AFS_CALL_REPLYING;
 
        /* we'll need the file server record as that tells us which set of
         * vnodes to operate upon */
-       memcpy(&addr, &ip_hdr(skb)->saddr, 4);
-       server = afs_find_server(&addr);
+       server = afs_find_server(&srx);
        if (!server)
                return -ENOTCONN;
        call->server = server;
@@ -315,17 +298,17 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
 /*
  * deliver request data to a CB.InitCallBackState call
  */
-static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
-                                              struct sk_buff *skb,
-                                              bool last)
+static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
 {
+       struct sockaddr_rxrpc srx;
        struct afs_server *server;
-       struct in_addr addr;
        int ret;
 
-       _enter(",{%u},%d", skb->len, last);
+       _enter("");
+
+       rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
 
-       ret = afs_data_complete(call, skb, last);
+       ret = afs_extract_data(call, NULL, 0, false);
        if (ret < 0)
                return ret;
 
@@ -334,8 +317,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
 
        /* we'll need the file server record as that tells us which set of
         * vnodes to operate upon */
-       memcpy(&addr, &ip_hdr(skb)->saddr, 4);
-       server = afs_find_server(&addr);
+       server = afs_find_server(&srx);
        if (!server)
                return -ENOTCONN;
        call->server = server;
@@ -348,27 +330,68 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
 /*
  * deliver request data to a CB.InitCallBackState3 call
  */
-static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
-                                               struct sk_buff *skb,
-                                               bool last)
+static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
 {
+       struct sockaddr_rxrpc srx;
        struct afs_server *server;
-       struct in_addr addr;
+       struct afs_uuid *r;
+       unsigned loop;
+       __be32 *b;
+       int ret;
+
+       _enter("");
+
+       rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);
+
+       _enter("{%u}", call->unmarshall);
 
-       _enter(",{%u},%d", skb->len, last);
+       switch (call->unmarshall) {
+       case 0:
+               call->offset = 0;
+               call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
+               if (!call->buffer)
+                       return -ENOMEM;
+               call->unmarshall++;
 
-       /* There are some arguments that we ignore */
-       afs_data_consumed(call, skb);
-       if (!last)
-               return -EAGAIN;
+       case 1:
+               _debug("extract UUID");
+               ret = afs_extract_data(call, call->buffer,
+                                      11 * sizeof(__be32), false);
+               switch (ret) {
+               case 0:         break;
+               case -EAGAIN:   return 0;
+               default:        return ret;
+               }
+
+               _debug("unmarshall UUID");
+               call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
+               if (!call->request)
+                       return -ENOMEM;
+
+               b = call->buffer;
+               r = call->request;
+               r->time_low                     = ntohl(b[0]);
+               r->time_mid                     = ntohl(b[1]);
+               r->time_hi_and_version          = ntohl(b[2]);
+               r->clock_seq_hi_and_reserved    = ntohl(b[3]);
+               r->clock_seq_low                = ntohl(b[4]);
+
+               for (loop = 0; loop < 6; loop++)
+                       r->node[loop] = ntohl(b[loop + 5]);
+
+               call->offset = 0;
+               call->unmarshall++;
+
+       case 2:
+               break;
+       }
 
        /* no unmarshalling required */
        call->state = AFS_CALL_REPLYING;
 
        /* we'll need the file server record as that tells us which set of
         * vnodes to operate upon */
-       memcpy(&addr, &ip_hdr(skb)->saddr, 4);
-       server = afs_find_server(&addr);
+       server = afs_find_server(&srx);
        if (!server)
                return -ENOTCONN;
        call->server = server;
@@ -393,14 +416,13 @@ static void SRXAFSCB_Probe(struct work_struct *work)
 /*
  * deliver request data to a CB.Probe call
  */
-static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
-                               bool last)
+static int afs_deliver_cb_probe(struct afs_call *call)
 {
        int ret;
 
-       _enter(",{%u},%d", skb->len, last);
+       _enter("");
 
-       ret = afs_data_complete(call, skb, last);
+       ret = afs_extract_data(call, NULL, 0, false);
        if (ret < 0)
                return ret;
 
@@ -426,7 +448,6 @@ static void SRXAFSCB_ProbeUuid(struct work_struct *work)
 
        _enter("");
 
-
        if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
                reply.match = htonl(0);
        else
@@ -439,19 +460,14 @@ static void SRXAFSCB_ProbeUuid(struct work_struct *work)
 /*
  * deliver request data to a CB.ProbeUuid call
  */
-static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
-                                    bool last)
+static int afs_deliver_cb_probe_uuid(struct afs_call *call)
 {
        struct afs_uuid *r;
        unsigned loop;
        __be32 *b;
        int ret;
 
-       _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
-
-       ret = afs_data_complete(call, skb, last);
-       if (ret < 0)
-               return ret;
+       _enter("{%u}", call->unmarshall);
 
        switch (call->unmarshall) {
        case 0:
@@ -463,8 +479,8 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
 
        case 1:
                _debug("extract UUID");
-               ret = afs_extract_data(call, skb, last, call->buffer,
-                                      11 * sizeof(__be32));
+               ret = afs_extract_data(call, call->buffer,
+                                      11 * sizeof(__be32), false);
                switch (ret) {
                case 0:         break;
                case -EAGAIN:   return 0;
@@ -491,16 +507,9 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
                call->unmarshall++;
 
        case 2:
-               _debug("trailer");
-               if (skb->len != 0)
-                       return -EBADMSG;
                break;
        }
 
-       ret = afs_data_complete(call, skb, last);
-       if (ret < 0)
-               return ret;
-
        call->state = AFS_CALL_REPLYING;
 
        INIT_WORK(&call->work, SRXAFSCB_ProbeUuid);
@@ -574,14 +583,13 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
 /*
  * deliver request data to a CB.TellMeAboutYourself call
  */
-static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call,
-                                                struct sk_buff *skb, bool last)
+static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
 {
        int ret;
 
-       _enter(",{%u},%d", skb->len, last);
+       _enter("");
 
-       ret = afs_data_complete(call, skb, last);
+       ret = afs_extract_data(call, NULL, 0, false);
        if (ret < 0)
                return ret;