~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/afs/cmservice.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/afs/cmservice.c (Version linux-6.11.5) and /fs/afs/cmservice.c (Version linux-4.4.302)


  1 // SPDX-License-Identifier: GPL-2.0-or-later   << 
  2 /* AFS Cache Manager Service                        1 /* AFS Cache Manager Service
  3  *                                                  2  *
  4  * Copyright (C) 2002 Red Hat, Inc. All Rights      3  * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
  5  * Written by David Howells (dhowells@redhat.c      4  * Written by David Howells (dhowells@redhat.com)
                                                   >>   5  *
                                                   >>   6  * This program is free software; you can redistribute it and/or
                                                   >>   7  * modify it under the terms of the GNU General Public License
                                                   >>   8  * as published by the Free Software Foundation; either version
                                                   >>   9  * 2 of the License, or (at your option) any later version.
  6  */                                                10  */
  7                                                    11 
  8 #include <linux/module.h>                          12 #include <linux/module.h>
  9 #include <linux/init.h>                            13 #include <linux/init.h>
 10 #include <linux/slab.h>                            14 #include <linux/slab.h>
 11 #include <linux/sched.h>                           15 #include <linux/sched.h>
 12 #include <linux/ip.h>                              16 #include <linux/ip.h>
 13 #include "internal.h"                              17 #include "internal.h"
 14 #include "afs_cm.h"                                18 #include "afs_cm.h"
 15 #include "protocol_yfs.h"                      << 
 16 #define RXRPC_TRACE_ONLY_DEFINE_ENUMS          << 
 17 #include <trace/events/rxrpc.h>                << 
 18                                                << 
 19 static int afs_deliver_cb_init_call_back_state << 
 20 static int afs_deliver_cb_init_call_back_state << 
 21 static int afs_deliver_cb_probe(struct afs_cal << 
 22 static int afs_deliver_cb_callback(struct afs_ << 
 23 static int afs_deliver_cb_probe_uuid(struct af << 
 24 static int afs_deliver_cb_tell_me_about_yourse << 
 25 static void afs_cm_destructor(struct afs_call  << 
 26 static void SRXAFSCB_CallBack(struct work_stru << 
 27 static void SRXAFSCB_InitCallBackState(struct  << 
 28 static void SRXAFSCB_Probe(struct work_struct  << 
 29 static void SRXAFSCB_ProbeUuid(struct work_str << 
 30 static void SRXAFSCB_TellMeAboutYourself(struc << 
 31                                                    19 
 32 static int afs_deliver_yfs_cb_callback(struct  !!  20 #if 0
                                                   >>  21 struct workqueue_struct *afs_cm_workqueue;
                                                   >>  22 #endif  /*  0  */
                                                   >>  23 
                                                   >>  24 static int afs_deliver_cb_init_call_back_state(struct afs_call *,
                                                   >>  25                                                struct sk_buff *, bool);
                                                   >>  26 static int afs_deliver_cb_init_call_back_state3(struct afs_call *,
                                                   >>  27                                                 struct sk_buff *, bool);
                                                   >>  28 static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool);
                                                   >>  29 static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool);
                                                   >>  30 static int afs_deliver_cb_probe_uuid(struct afs_call *, struct sk_buff *, bool);
                                                   >>  31 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *,
                                                   >>  32                                                  struct sk_buff *, bool);
                                                   >>  33 static void afs_cm_destructor(struct afs_call *);
 33                                                    34 
 34 /*                                                 35 /*
 35  * CB.CallBack operation type                      36  * CB.CallBack operation type
 36  */                                                37  */
 37 static const struct afs_call_type afs_SRXCBCal     38 static const struct afs_call_type afs_SRXCBCallBack = {
 38         .name           = "CB.CallBack",           39         .name           = "CB.CallBack",
 39         .deliver        = afs_deliver_cb_callb     40         .deliver        = afs_deliver_cb_callback,
                                                   >>  41         .abort_to_error = afs_abort_to_error,
 40         .destructor     = afs_cm_destructor,       42         .destructor     = afs_cm_destructor,
 41         .work           = SRXAFSCB_CallBack,   << 
 42 };                                                 43 };
 43                                                    44 
 44 /*                                                 45 /*
 45  * CB.InitCallBackState operation type             46  * CB.InitCallBackState operation type
 46  */                                                47  */
 47 static const struct afs_call_type afs_SRXCBIni     48 static const struct afs_call_type afs_SRXCBInitCallBackState = {
 48         .name           = "CB.InitCallBackStat     49         .name           = "CB.InitCallBackState",
 49         .deliver        = afs_deliver_cb_init_     50         .deliver        = afs_deliver_cb_init_call_back_state,
                                                   >>  51         .abort_to_error = afs_abort_to_error,
 50         .destructor     = afs_cm_destructor,       52         .destructor     = afs_cm_destructor,
 51         .work           = SRXAFSCB_InitCallBac << 
 52 };                                                 53 };
 53                                                    54 
 54 /*                                                 55 /*
 55  * CB.InitCallBackState3 operation type            56  * CB.InitCallBackState3 operation type
 56  */                                                57  */
 57 static const struct afs_call_type afs_SRXCBIni     58 static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
 58         .name           = "CB.InitCallBackStat     59         .name           = "CB.InitCallBackState3",
 59         .deliver        = afs_deliver_cb_init_     60         .deliver        = afs_deliver_cb_init_call_back_state3,
                                                   >>  61         .abort_to_error = afs_abort_to_error,
 60         .destructor     = afs_cm_destructor,       62         .destructor     = afs_cm_destructor,
 61         .work           = SRXAFSCB_InitCallBac << 
 62 };                                                 63 };
 63                                                    64 
 64 /*                                                 65 /*
 65  * CB.Probe operation type                         66  * CB.Probe operation type
 66  */                                                67  */
 67 static const struct afs_call_type afs_SRXCBPro     68 static const struct afs_call_type afs_SRXCBProbe = {
 68         .name           = "CB.Probe",              69         .name           = "CB.Probe",
 69         .deliver        = afs_deliver_cb_probe     70         .deliver        = afs_deliver_cb_probe,
                                                   >>  71         .abort_to_error = afs_abort_to_error,
 70         .destructor     = afs_cm_destructor,       72         .destructor     = afs_cm_destructor,
 71         .work           = SRXAFSCB_Probe,      << 
 72 };                                                 73 };
 73                                                    74 
 74 /*                                                 75 /*
 75  * CB.ProbeUuid operation type                     76  * CB.ProbeUuid operation type
 76  */                                                77  */
 77 static const struct afs_call_type afs_SRXCBPro     78 static const struct afs_call_type afs_SRXCBProbeUuid = {
 78         .name           = "CB.ProbeUuid",          79         .name           = "CB.ProbeUuid",
 79         .deliver        = afs_deliver_cb_probe     80         .deliver        = afs_deliver_cb_probe_uuid,
                                                   >>  81         .abort_to_error = afs_abort_to_error,
 80         .destructor     = afs_cm_destructor,       82         .destructor     = afs_cm_destructor,
 81         .work           = SRXAFSCB_ProbeUuid,  << 
 82 };                                                 83 };
 83                                                    84 
 84 /*                                                 85 /*
 85  * CB.TellMeAboutYourself operation type           86  * CB.TellMeAboutYourself operation type
 86  */                                                87  */
 87 static const struct afs_call_type afs_SRXCBTel     88 static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
 88         .name           = "CB.TellMeAboutYours     89         .name           = "CB.TellMeAboutYourself",
 89         .deliver        = afs_deliver_cb_tell_     90         .deliver        = afs_deliver_cb_tell_me_about_yourself,
                                                   >>  91         .abort_to_error = afs_abort_to_error,
 90         .destructor     = afs_cm_destructor,       92         .destructor     = afs_cm_destructor,
 91         .work           = SRXAFSCB_TellMeAbout << 
 92 };                                             << 
 93                                                << 
 94 /*                                             << 
 95  * YFS CB.CallBack operation type              << 
 96  */                                            << 
 97 static const struct afs_call_type afs_SRXYFSCB << 
 98         .name           = "YFSCB.CallBack",    << 
 99         .deliver        = afs_deliver_yfs_cb_c << 
100         .destructor     = afs_cm_destructor,   << 
101         .work           = SRXAFSCB_CallBack,   << 
102 };                                                 93 };
103                                                    94 
104 /*                                                 95 /*
105  * route an incoming cache manager call            96  * route an incoming cache manager call
106  * - return T if supported, F if not               97  * - return T if supported, F if not
107  */                                                98  */
108 bool afs_cm_incoming_call(struct afs_call *cal     99 bool afs_cm_incoming_call(struct afs_call *call)
109 {                                                 100 {
110         _enter("{%u, CB.OP %u}", call->service !! 101         u32 operation_id = ntohl(call->operation_ID);
                                                   >> 102 
                                                   >> 103         _enter("{CB.OP %u}", operation_id);
111                                                   104 
112         switch (call->operation_ID) {          !! 105         switch (operation_id) {
113         case CBCallBack:                          106         case CBCallBack:
114                 call->type = &afs_SRXCBCallBac    107                 call->type = &afs_SRXCBCallBack;
115                 return true;                      108                 return true;
116         case CBInitCallBackState:                 109         case CBInitCallBackState:
117                 call->type = &afs_SRXCBInitCal    110                 call->type = &afs_SRXCBInitCallBackState;
118                 return true;                      111                 return true;
119         case CBInitCallBackState3:                112         case CBInitCallBackState3:
120                 call->type = &afs_SRXCBInitCal    113                 call->type = &afs_SRXCBInitCallBackState3;
121                 return true;                      114                 return true;
122         case CBProbe:                             115         case CBProbe:
123                 call->type = &afs_SRXCBProbe;     116                 call->type = &afs_SRXCBProbe;
124                 return true;                      117                 return true;
125         case CBProbeUuid:                         118         case CBProbeUuid:
126                 call->type = &afs_SRXCBProbeUu    119                 call->type = &afs_SRXCBProbeUuid;
127                 return true;                      120                 return true;
128         case CBTellMeAboutYourself:               121         case CBTellMeAboutYourself:
129                 call->type = &afs_SRXCBTellMeA    122                 call->type = &afs_SRXCBTellMeAboutYourself;
130                 return true;                      123                 return true;
131         case YFSCBCallBack:                    << 
132                 if (call->service_id != YFS_CM << 
133                         return false;          << 
134                 call->type = &afs_SRXYFSCB_Cal << 
135                 return true;                   << 
136         default:                                  124         default:
137                 return false;                     125                 return false;
138         }                                         126         }
139 }                                                 127 }
140                                                   128 
141 /*                                                129 /*
142  * Find the server record by peer address and  !! 130  * clean up a cache manager call
143  * manager from a server.                      << 
144  */                                            << 
145 static int afs_find_cm_server_by_peer(struct a << 
146 {                                              << 
147         struct sockaddr_rxrpc srx;             << 
148         struct afs_server *server;             << 
149         struct rxrpc_peer *peer;               << 
150                                                << 
151         peer = rxrpc_kernel_get_call_peer(call << 
152                                                << 
153         server = afs_find_server(call->net, pe << 
154         if (!server) {                         << 
155                 trace_afs_cm_no_server(call, & << 
156                 return 0;                      << 
157         }                                      << 
158                                                << 
159         call->server = server;                 << 
160         return 0;                              << 
161 }                                              << 
162                                                << 
163 /*                                             << 
164  * Find the server record by server UUID and r << 
165  * manager from a server.                      << 
166  */                                               131  */
167 static int afs_find_cm_server_by_uuid(struct a !! 132 static void afs_cm_destructor(struct afs_call *call)
168                                       struct a << 
169 {                                                 133 {
170         struct afs_server *server;             !! 134         _enter("");
171                                                   135 
172         rcu_read_lock();                       !! 136         /* Break the callbacks here so that we do it after the final ACK is
173         server = afs_find_server_by_uuid(call- !! 137          * received.  The step number here must match the final number in
174         rcu_read_unlock();                     !! 138          * afs_deliver_cb_callback().
175         if (!server) {                         !! 139          */
176                 trace_afs_cm_no_server_u(call, !! 140         if (call->unmarshall == 6) {
177                 return 0;                      !! 141                 ASSERT(call->server && call->count && call->request);
                                                   >> 142                 afs_break_callbacks(call->server, call->count, call->request);
178         }                                         143         }
179                                                   144 
180         call->server = server;                 !! 145         afs_put_server(call->server);
181         return 0;                              !! 146         call->server = NULL;
182 }                                              << 
183                                                << 
184 /*                                             << 
185  * Clean up a cache manager call.              << 
186  */                                            << 
187 static void afs_cm_destructor(struct afs_call  << 
188 {                                              << 
189         kfree(call->buffer);                      147         kfree(call->buffer);
190         call->buffer = NULL;                      148         call->buffer = NULL;
191 }                                                 149 }
192                                                   150 
193 /*                                                151 /*
194  * Abort a service call from within an action  !! 152  * allow the fileserver to see if the cache manager is still alive
195  */                                            << 
196 static void afs_abort_service_call(struct afs_ << 
197                                    enum rxrpc_ << 
198 {                                              << 
199         rxrpc_kernel_abort_call(call->net->soc << 
200                                 abort_code, er << 
201         afs_set_call_complete(call, error, 0); << 
202 }                                              << 
203                                                << 
204 /*                                             << 
205  * The server supplied a list of callbacks tha << 
206  */                                               153  */
207 static void SRXAFSCB_CallBack(struct work_stru    154 static void SRXAFSCB_CallBack(struct work_struct *work)
208 {                                                 155 {
209         struct afs_call *call = container_of(w    156         struct afs_call *call = container_of(work, struct afs_call, work);
210                                                   157 
211         _enter("");                               158         _enter("");
212                                                   159 
213         /* We need to break the callbacks befo !! 160         /* be sure to send the reply *before* attempting to spam the AFS server
214          * server holds up change visibility t !! 161          * with FSFetchStatus requests on the vnodes with broken callbacks lest
215          * to maintain cache coherency.        !! 162          * the AFS server get into a vicious cycle of trying to break further
216          */                                    !! 163          * callbacks because it hadn't received completion of the CBCallBack op
217         if (call->server) {                    !! 164          * yet */
218                 trace_afs_server(call->server- << 
219                                  refcount_read << 
220                                  atomic_read(& << 
221                                  afs_server_tr << 
222                 afs_break_callbacks(call->serv << 
223         }                                      << 
224                                                << 
225         afs_send_empty_reply(call);               165         afs_send_empty_reply(call);
226         afs_put_call(call);                    !! 166 
                                                   >> 167         afs_break_callbacks(call->server, call->count, call->request);
227         _leave("");                               168         _leave("");
228 }                                                 169 }
229                                                   170 
230 /*                                                171 /*
231  * deliver request data to a CB.CallBack call     172  * deliver request data to a CB.CallBack call
232  */                                               173  */
233 static int afs_deliver_cb_callback(struct afs_ !! 174 static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb,
                                                   >> 175                                    bool last)
234 {                                                 176 {
235         struct afs_callback_break *cb;         !! 177         struct afs_callback *cb;
                                                   >> 178         struct afs_server *server;
                                                   >> 179         struct in_addr addr;
236         __be32 *bp;                               180         __be32 *bp;
                                                   >> 181         u32 tmp;
237         int ret, loop;                            182         int ret, loop;
238                                                   183 
239         _enter("{%u}", call->unmarshall);      !! 184         _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
240                                                   185 
241         switch (call->unmarshall) {               186         switch (call->unmarshall) {
242         case 0:                                   187         case 0:
243                 afs_extract_to_tmp(call);      !! 188                 call->offset = 0;
244                 call->unmarshall++;               189                 call->unmarshall++;
245                                                   190 
246                 /* extract the FID array and i    191                 /* extract the FID array and its count in two steps */
247                 fallthrough;                   << 
248         case 1:                                   192         case 1:
249                 _debug("extract FID count");      193                 _debug("extract FID count");
250                 ret = afs_extract_data(call, t !! 194                 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
251                 if (ret < 0)                   !! 195                 switch (ret) {
252                         return ret;            !! 196                 case 0:         break;
                                                   >> 197                 case -EAGAIN:   return 0;
                                                   >> 198                 default:        return ret;
                                                   >> 199                 }
253                                                   200 
254                 call->count = ntohl(call->tmp)    201                 call->count = ntohl(call->tmp);
255                 _debug("FID count: %u", call->    202                 _debug("FID count: %u", call->count);
256                 if (call->count > AFSCBMAX)       203                 if (call->count > AFSCBMAX)
257                         return afs_protocol_er !! 204                         return -EBADMSG;
258                                                   205 
259                 call->buffer = kmalloc(array3_ !! 206                 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
260                                        GFP_KER << 
261                 if (!call->buffer)                207                 if (!call->buffer)
262                         return -ENOMEM;           208                         return -ENOMEM;
263                 afs_extract_to_buf(call, call- !! 209                 call->offset = 0;
264                 call->unmarshall++;               210                 call->unmarshall++;
265                                                   211 
266                 fallthrough;                   << 
267         case 2:                                   212         case 2:
268                 _debug("extract FID array");      213                 _debug("extract FID array");
269                 ret = afs_extract_data(call, t !! 214                 ret = afs_extract_data(call, skb, last, call->buffer,
270                 if (ret < 0)                   !! 215                                        call->count * 3 * 4);
271                         return ret;            !! 216                 switch (ret) {
                                                   >> 217                 case 0:         break;
                                                   >> 218                 case -EAGAIN:   return 0;
                                                   >> 219                 default:        return ret;
                                                   >> 220                 }
272                                                   221 
273                 _debug("unmarshall FID array")    222                 _debug("unmarshall FID array");
274                 call->request = kcalloc(call->    223                 call->request = kcalloc(call->count,
275                                         sizeof !! 224                                         sizeof(struct afs_callback),
276                                         GFP_KE    225                                         GFP_KERNEL);
277                 if (!call->request)               226                 if (!call->request)
278                         return -ENOMEM;           227                         return -ENOMEM;
279                                                   228 
280                 cb = call->request;               229                 cb = call->request;
281                 bp = call->buffer;                230                 bp = call->buffer;
282                 for (loop = call->count; loop     231                 for (loop = call->count; loop > 0; loop--, cb++) {
283                         cb->fid.vid     = ntoh    232                         cb->fid.vid     = ntohl(*bp++);
284                         cb->fid.vnode   = ntoh    233                         cb->fid.vnode   = ntohl(*bp++);
285                         cb->fid.unique  = ntoh    234                         cb->fid.unique  = ntohl(*bp++);
                                                   >> 235                         cb->type        = AFSCM_CB_UNTYPED;
286                 }                                 236                 }
287                                                   237 
288                 afs_extract_to_tmp(call);      !! 238                 call->offset = 0;
289                 call->unmarshall++;               239                 call->unmarshall++;
290                                                   240 
291                 /* extract the callback array     241                 /* extract the callback array and its count in two steps */
292                 fallthrough;                   << 
293         case 3:                                   242         case 3:
294                 _debug("extract CB count");       243                 _debug("extract CB count");
295                 ret = afs_extract_data(call, t !! 244                 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
296                 if (ret < 0)                   !! 245                 switch (ret) {
297                         return ret;            !! 246                 case 0:         break;
298                                                !! 247                 case -EAGAIN:   return 0;
299                 call->count2 = ntohl(call->tmp !! 248                 default:        return ret;
300                 _debug("CB count: %u", call->c !! 249                 }
301                 if (call->count2 != call->coun !! 250 
302                         return afs_protocol_er !! 251                 tmp = ntohl(call->tmp);
303                 call->iter = &call->def_iter;  !! 252                 _debug("CB count: %u", tmp);
304                 iov_iter_discard(&call->def_it !! 253                 if (tmp != call->count && tmp != 0)
                                                   >> 254                         return -EBADMSG;
                                                   >> 255                 call->offset = 0;
305                 call->unmarshall++;               256                 call->unmarshall++;
                                                   >> 257                 if (tmp == 0)
                                                   >> 258                         goto empty_cb_array;
306                                                   259 
307                 fallthrough;                   << 
308         case 4:                                   260         case 4:
309                 _debug("extract discard %zu/%u !! 261                 _debug("extract CB array");
310                        iov_iter_count(call->it !! 262                 ret = afs_extract_data(call, skb, last, call->request,
                                                   >> 263                                        call->count * 3 * 4);
                                                   >> 264                 switch (ret) {
                                                   >> 265                 case 0:         break;
                                                   >> 266                 case -EAGAIN:   return 0;
                                                   >> 267                 default:        return ret;
                                                   >> 268                 }
311                                                   269 
312                 ret = afs_extract_data(call, f !! 270                 _debug("unmarshall CB array");
313                 if (ret < 0)                   !! 271                 cb = call->request;
314                         return ret;            !! 272                 bp = call->buffer;
                                                   >> 273                 for (loop = call->count; loop > 0; loop--, cb++) {
                                                   >> 274                         cb->version     = ntohl(*bp++);
                                                   >> 275                         cb->expiry      = ntohl(*bp++);
                                                   >> 276                         cb->type        = ntohl(*bp++);
                                                   >> 277                 }
315                                                   278 
                                                   >> 279         empty_cb_array:
                                                   >> 280                 call->offset = 0;
316                 call->unmarshall++;               281                 call->unmarshall++;
317                 fallthrough;                   << 
318                                                   282 
319         case 5:                                   283         case 5:
                                                   >> 284                 _debug("trailer");
                                                   >> 285                 if (skb->len != 0)
                                                   >> 286                         return -EBADMSG;
                                                   >> 287 
                                                   >> 288                 /* Record that the message was unmarshalled successfully so
                                                   >> 289                  * that the call destructor can know do the callback breaking
                                                   >> 290                  * work, even if the final ACK isn't received.
                                                   >> 291                  *
                                                   >> 292                  * If the step number changes, then afs_cm_destructor() must be
                                                   >> 293                  * updated also.
                                                   >> 294                  */
                                                   >> 295                 call->unmarshall++;
                                                   >> 296         case 6:
320                 break;                            297                 break;
321         }                                         298         }
322                                                   299 
323         if (!afs_check_call_state(call, AFS_CA !! 300         if (!last)
324                 return afs_io_error(call, afs_ !! 301                 return 0;
                                                   >> 302 
                                                   >> 303         call->state = AFS_CALL_REPLYING;
325                                                   304 
326         /* we'll need the file server record a    305         /* we'll need the file server record as that tells us which set of
327          * vnodes to operate upon */              306          * vnodes to operate upon */
328         return afs_find_cm_server_by_peer(call !! 307         memcpy(&addr, &ip_hdr(skb)->saddr, 4);
                                                   >> 308         server = afs_find_server(&addr);
                                                   >> 309         if (!server)
                                                   >> 310                 return -ENOTCONN;
                                                   >> 311         call->server = server;
                                                   >> 312 
                                                   >> 313         INIT_WORK(&call->work, SRXAFSCB_CallBack);
                                                   >> 314         queue_work(afs_wq, &call->work);
                                                   >> 315         return 0;
329 }                                                 316 }
330                                                   317 
331 /*                                                318 /*
332  * allow the fileserver to request callback st    319  * allow the fileserver to request callback state (re-)initialisation
333  */                                               320  */
334 static void SRXAFSCB_InitCallBackState(struct     321 static void SRXAFSCB_InitCallBackState(struct work_struct *work)
335 {                                                 322 {
336         struct afs_call *call = container_of(w    323         struct afs_call *call = container_of(work, struct afs_call, work);
337                                                   324 
338         _enter("{%p}", call->server);             325         _enter("{%p}", call->server);
339                                                   326 
340         if (call->server)                      !! 327         afs_init_callback_state(call->server);
341                 afs_init_callback_state(call-> << 
342         afs_send_empty_reply(call);               328         afs_send_empty_reply(call);
343         afs_put_call(call);                    << 
344         _leave("");                               329         _leave("");
345 }                                                 330 }
346                                                   331 
347 /*                                                332 /*
348  * deliver request data to a CB.InitCallBackSt    333  * deliver request data to a CB.InitCallBackState call
349  */                                               334  */
350 static int afs_deliver_cb_init_call_back_state !! 335 static int afs_deliver_cb_init_call_back_state(struct afs_call *call,
                                                   >> 336                                                struct sk_buff *skb,
                                                   >> 337                                                bool last)
351 {                                                 338 {
352         int ret;                               !! 339         struct afs_server *server;
                                                   >> 340         struct in_addr addr;
353                                                   341 
354         _enter("");                            !! 342         _enter(",{%u},%d", skb->len, last);
355                                                   343 
356         afs_extract_discard(call, 0);          !! 344         if (skb->len > 0)
357         ret = afs_extract_data(call, false);   !! 345                 return -EBADMSG;
358         if (ret < 0)                           !! 346         if (!last)
359                 return ret;                    !! 347                 return 0;
                                                   >> 348 
                                                   >> 349         /* no unmarshalling required */
                                                   >> 350         call->state = AFS_CALL_REPLYING;
360                                                   351 
361         /* we'll need the file server record a    352         /* we'll need the file server record as that tells us which set of
362          * vnodes to operate upon */              353          * vnodes to operate upon */
363         return afs_find_cm_server_by_peer(call !! 354         memcpy(&addr, &ip_hdr(skb)->saddr, 4);
                                                   >> 355         server = afs_find_server(&addr);
                                                   >> 356         if (!server)
                                                   >> 357                 return -ENOTCONN;
                                                   >> 358         call->server = server;
                                                   >> 359 
                                                   >> 360         INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
                                                   >> 361         queue_work(afs_wq, &call->work);
                                                   >> 362         return 0;
364 }                                                 363 }
365                                                   364 
366 /*                                                365 /*
367  * deliver request data to a CB.InitCallBackSt    366  * deliver request data to a CB.InitCallBackState3 call
368  */                                               367  */
369 static int afs_deliver_cb_init_call_back_state !! 368 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call,
                                                   >> 369                                                 struct sk_buff *skb,
                                                   >> 370                                                 bool last)
370 {                                                 371 {
371         struct afs_uuid *r;                    !! 372         struct afs_server *server;
372         unsigned loop;                         !! 373         struct in_addr addr;
373         __be32 *b;                             << 
374         int ret;                               << 
375                                                << 
376         _enter("");                            << 
377                                                << 
378         _enter("{%u}", call->unmarshall);      << 
379                                                << 
380         switch (call->unmarshall) {            << 
381         case 0:                                << 
382                 call->buffer = kmalloc_array(1 << 
383                 if (!call->buffer)             << 
384                         return -ENOMEM;        << 
385                 afs_extract_to_buf(call, 11 *  << 
386                 call->unmarshall++;            << 
387                                                << 
388                 fallthrough;                   << 
389         case 1:                                << 
390                 _debug("extract UUID");        << 
391                 ret = afs_extract_data(call, f << 
392                 switch (ret) {                 << 
393                 case 0:         break;         << 
394                 case -EAGAIN:   return 0;      << 
395                 default:        return ret;    << 
396                 }                              << 
397                                                << 
398                 _debug("unmarshall UUID");     << 
399                 call->request = kmalloc(sizeof << 
400                 if (!call->request)            << 
401                         return -ENOMEM;        << 
402                                                << 
403                 b = call->buffer;              << 
404                 r = call->request;             << 
405                 r->time_low                    << 
406                 r->time_mid                    << 
407                 r->time_hi_and_version         << 
408                 r->clock_seq_hi_and_reserved   << 
409                 r->clock_seq_low               << 
410                                                << 
411                 for (loop = 0; loop < 6; loop+ << 
412                         r->node[loop] = ntohl( << 
413                                                   374 
414                 call->unmarshall++;            !! 375         _enter(",{%u},%d", skb->len, last);
415                 fallthrough;                   << 
416                                                   376 
417         case 2:                                !! 377         if (!last)
418                 break;                         !! 378                 return 0;
419         }                                      << 
420                                                   379 
421         if (!afs_check_call_state(call, AFS_CA !! 380         /* no unmarshalling required */
422                 return afs_io_error(call, afs_ !! 381         call->state = AFS_CALL_REPLYING;
423                                                   382 
424         /* we'll need the file server record a    383         /* we'll need the file server record as that tells us which set of
425          * vnodes to operate upon */              384          * vnodes to operate upon */
426         return afs_find_cm_server_by_uuid(call !! 385         memcpy(&addr, &ip_hdr(skb)->saddr, 4);
                                                   >> 386         server = afs_find_server(&addr);
                                                   >> 387         if (!server)
                                                   >> 388                 return -ENOTCONN;
                                                   >> 389         call->server = server;
                                                   >> 390 
                                                   >> 391         INIT_WORK(&call->work, SRXAFSCB_InitCallBackState);
                                                   >> 392         queue_work(afs_wq, &call->work);
                                                   >> 393         return 0;
427 }                                                 394 }
428                                                   395 
429 /*                                                396 /*
430  * allow the fileserver to see if the cache ma    397  * allow the fileserver to see if the cache manager is still alive
431  */                                               398  */
432 static void SRXAFSCB_Probe(struct work_struct     399 static void SRXAFSCB_Probe(struct work_struct *work)
433 {                                                 400 {
434         struct afs_call *call = container_of(w    401         struct afs_call *call = container_of(work, struct afs_call, work);
435                                                   402 
436         _enter("");                               403         _enter("");
437         afs_send_empty_reply(call);               404         afs_send_empty_reply(call);
438         afs_put_call(call);                    << 
439         _leave("");                               405         _leave("");
440 }                                                 406 }
441                                                   407 
442 /*                                                408 /*
443  * deliver request data to a CB.Probe call        409  * deliver request data to a CB.Probe call
444  */                                               410  */
445 static int afs_deliver_cb_probe(struct afs_cal !! 411 static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
                                                   >> 412                                 bool last)
446 {                                                 413 {
447         int ret;                               !! 414         _enter(",{%u},%d", skb->len, last);
448                                                   415 
449         _enter("");                            !! 416         if (skb->len > 0)
                                                   >> 417                 return -EBADMSG;
                                                   >> 418         if (!last)
                                                   >> 419                 return 0;
450                                                   420 
451         afs_extract_discard(call, 0);          !! 421         /* no unmarshalling required */
452         ret = afs_extract_data(call, false);   !! 422         call->state = AFS_CALL_REPLYING;
453         if (ret < 0)                           << 
454                 return ret;                    << 
455                                                   423 
456         if (!afs_check_call_state(call, AFS_CA !! 424         INIT_WORK(&call->work, SRXAFSCB_Probe);
457                 return afs_io_error(call, afs_ !! 425         queue_work(afs_wq, &call->work);
458         return afs_find_cm_server_by_peer(call !! 426         return 0;
459 }                                                 427 }
460                                                   428 
461 /*                                                429 /*
462  * Allow the fileserver to quickly find out if !! 430  * allow the fileserver to quickly find out if the fileserver has been rebooted
463  * rebooted.                                   << 
464  */                                               431  */
465 static void SRXAFSCB_ProbeUuid(struct work_str    432 static void SRXAFSCB_ProbeUuid(struct work_struct *work)
466 {                                                 433 {
467         struct afs_call *call = container_of(w    434         struct afs_call *call = container_of(work, struct afs_call, work);
468         struct afs_uuid *r = call->request;       435         struct afs_uuid *r = call->request;
469                                                   436 
                                                   >> 437         struct {
                                                   >> 438                 __be32  match;
                                                   >> 439         } reply;
                                                   >> 440 
470         _enter("");                               441         _enter("");
471                                                   442 
472         if (memcmp(r, &call->net->uuid, sizeof !! 443 
473                 afs_send_empty_reply(call);    !! 444         if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
                                                   >> 445                 reply.match = htonl(0);
474         else                                      446         else
475                 afs_abort_service_call(call, 1 !! 447                 reply.match = htonl(1);
476                                                   448 
477         afs_put_call(call);                    !! 449         afs_send_simple_reply(call, &reply, sizeof(reply));
478         _leave("");                               450         _leave("");
479 }                                                 451 }
480                                                   452 
481 /*                                                453 /*
482  * deliver request data to a CB.ProbeUuid call    454  * deliver request data to a CB.ProbeUuid call
483  */                                               455  */
484 static int afs_deliver_cb_probe_uuid(struct af !! 456 static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
                                                   >> 457                                      bool last)
485 {                                                 458 {
486         struct afs_uuid *r;                       459         struct afs_uuid *r;
487         unsigned loop;                            460         unsigned loop;
488         __be32 *b;                                461         __be32 *b;
489         int ret;                                  462         int ret;
490                                                   463 
491         _enter("{%u}", call->unmarshall);      !! 464         _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
                                                   >> 465 
                                                   >> 466         if (skb->len > 0)
                                                   >> 467                 return -EBADMSG;
                                                   >> 468         if (!last)
                                                   >> 469                 return 0;
492                                                   470 
493         switch (call->unmarshall) {               471         switch (call->unmarshall) {
494         case 0:                                   472         case 0:
495                 call->buffer = kmalloc_array(1 !! 473                 call->offset = 0;
                                                   >> 474                 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
496                 if (!call->buffer)                475                 if (!call->buffer)
497                         return -ENOMEM;           476                         return -ENOMEM;
498                 afs_extract_to_buf(call, 11 *  << 
499                 call->unmarshall++;               477                 call->unmarshall++;
500                                                   478 
501                 fallthrough;                   << 
502         case 1:                                   479         case 1:
503                 _debug("extract UUID");           480                 _debug("extract UUID");
504                 ret = afs_extract_data(call, f !! 481                 ret = afs_extract_data(call, skb, last, call->buffer,
                                                   >> 482                                        11 * sizeof(__be32));
505                 switch (ret) {                    483                 switch (ret) {
506                 case 0:         break;            484                 case 0:         break;
507                 case -EAGAIN:   return 0;         485                 case -EAGAIN:   return 0;
508                 default:        return ret;       486                 default:        return ret;
509                 }                                 487                 }
510                                                   488 
511                 _debug("unmarshall UUID");        489                 _debug("unmarshall UUID");
512                 call->request = kmalloc(sizeof    490                 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
513                 if (!call->request)               491                 if (!call->request)
514                         return -ENOMEM;           492                         return -ENOMEM;
515                                                   493 
516                 b = call->buffer;                 494                 b = call->buffer;
517                 r = call->request;                495                 r = call->request;
518                 r->time_low                    !! 496                 r->time_low                     = ntohl(b[0]);
519                 r->time_mid                    !! 497                 r->time_mid                     = ntohl(b[1]);
520                 r->time_hi_and_version         !! 498                 r->time_hi_and_version          = ntohl(b[2]);
521                 r->clock_seq_hi_and_reserved      499                 r->clock_seq_hi_and_reserved    = ntohl(b[3]);
522                 r->clock_seq_low                  500                 r->clock_seq_low                = ntohl(b[4]);
523                                                   501 
524                 for (loop = 0; loop < 6; loop+    502                 for (loop = 0; loop < 6; loop++)
525                         r->node[loop] = ntohl(    503                         r->node[loop] = ntohl(b[loop + 5]);
526                                                   504 
                                                   >> 505                 call->offset = 0;
527                 call->unmarshall++;               506                 call->unmarshall++;
528                 fallthrough;                   << 
529                                                   507 
530         case 2:                                   508         case 2:
                                                   >> 509                 _debug("trailer");
                                                   >> 510                 if (skb->len != 0)
                                                   >> 511                         return -EBADMSG;
531                 break;                            512                 break;
532         }                                         513         }
533                                                   514 
534         if (!afs_check_call_state(call, AFS_CA !! 515         if (!last)
535                 return afs_io_error(call, afs_ !! 516                 return 0;
536         return afs_find_cm_server_by_peer(call !! 517 
                                                   >> 518         call->state = AFS_CALL_REPLYING;
                                                   >> 519 
                                                   >> 520         INIT_WORK(&call->work, SRXAFSCB_ProbeUuid);
                                                   >> 521         queue_work(afs_wq, &call->work);
                                                   >> 522         return 0;
537 }                                                 523 }
538                                                   524 
539 /*                                                525 /*
540  * allow the fileserver to ask about the cache    526  * allow the fileserver to ask about the cache manager's capabilities
541  */                                               527  */
542 static void SRXAFSCB_TellMeAboutYourself(struc    528 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
543 {                                                 529 {
                                                   >> 530         struct afs_interface *ifs;
544         struct afs_call *call = container_of(w    531         struct afs_call *call = container_of(work, struct afs_call, work);
545         int loop;                              !! 532         int loop, nifs;
546                                                   533 
547         struct {                                  534         struct {
548                 struct /* InterfaceAddr */ {      535                 struct /* InterfaceAddr */ {
549                         __be32 nifs;              536                         __be32 nifs;
550                         __be32 uuid[11];          537                         __be32 uuid[11];
551                         __be32 ifaddr[32];        538                         __be32 ifaddr[32];
552                         __be32 netmask[32];       539                         __be32 netmask[32];
553                         __be32 mtu[32];           540                         __be32 mtu[32];
554                 } ia;                             541                 } ia;
555                 struct /* Capabilities */ {       542                 struct /* Capabilities */ {
556                         __be32 capcount;          543                         __be32 capcount;
557                         __be32 caps[1];           544                         __be32 caps[1];
558                 } cap;                            545                 } cap;
559         } reply;                                  546         } reply;
560                                                   547 
561         _enter("");                               548         _enter("");
562                                                   549 
                                                   >> 550         nifs = 0;
                                                   >> 551         ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
                                                   >> 552         if (ifs) {
                                                   >> 553                 nifs = afs_get_ipv4_interfaces(ifs, 32, false);
                                                   >> 554                 if (nifs < 0) {
                                                   >> 555                         kfree(ifs);
                                                   >> 556                         ifs = NULL;
                                                   >> 557                         nifs = 0;
                                                   >> 558                 }
                                                   >> 559         }
                                                   >> 560 
563         memset(&reply, 0, sizeof(reply));         561         memset(&reply, 0, sizeof(reply));
                                                   >> 562         reply.ia.nifs = htonl(nifs);
564                                                   563 
565         reply.ia.uuid[0] = call->net->uuid.tim !! 564         reply.ia.uuid[0] = htonl(afs_uuid.time_low);
566         reply.ia.uuid[1] = htonl(ntohs(call->n !! 565         reply.ia.uuid[1] = htonl(afs_uuid.time_mid);
567         reply.ia.uuid[2] = htonl(ntohs(call->n !! 566         reply.ia.uuid[2] = htonl(afs_uuid.time_hi_and_version);
568         reply.ia.uuid[3] = htonl((s8) call->ne !! 567         reply.ia.uuid[3] = htonl((s8) afs_uuid.clock_seq_hi_and_reserved);
569         reply.ia.uuid[4] = htonl((s8) call->ne !! 568         reply.ia.uuid[4] = htonl((s8) afs_uuid.clock_seq_low);
570         for (loop = 0; loop < 6; loop++)          569         for (loop = 0; loop < 6; loop++)
571                 reply.ia.uuid[loop + 5] = hton !! 570                 reply.ia.uuid[loop + 5] = htonl((s8) afs_uuid.node[loop]);
                                                   >> 571 
                                                   >> 572         if (ifs) {
                                                   >> 573                 for (loop = 0; loop < nifs; loop++) {
                                                   >> 574                         reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
                                                   >> 575                         reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
                                                   >> 576                         reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
                                                   >> 577                 }
                                                   >> 578                 kfree(ifs);
                                                   >> 579         }
572                                                   580 
573         reply.cap.capcount = htonl(1);            581         reply.cap.capcount = htonl(1);
574         reply.cap.caps[0] = htonl(AFS_CAP_ERRO    582         reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
575         afs_send_simple_reply(call, &reply, si    583         afs_send_simple_reply(call, &reply, sizeof(reply));
576         afs_put_call(call);                    !! 584 
577         _leave("");                               585         _leave("");
578 }                                                 586 }
579                                                   587 
580 /*                                                588 /*
581  * deliver request data to a CB.TellMeAboutYou    589  * deliver request data to a CB.TellMeAboutYourself call
582  */                                               590  */
583 static int afs_deliver_cb_tell_me_about_yourse !! 591 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call,
                                                   >> 592                                                  struct sk_buff *skb, bool last)
584 {                                                 593 {
585         int ret;                               !! 594         _enter(",{%u},%d", skb->len, last);
586                                                << 
587         _enter("");                            << 
588                                                << 
589         afs_extract_discard(call, 0);          << 
590         ret = afs_extract_data(call, false);   << 
591         if (ret < 0)                           << 
592                 return ret;                    << 
593                                                << 
594         if (!afs_check_call_state(call, AFS_CA << 
595                 return afs_io_error(call, afs_ << 
596         return afs_find_cm_server_by_peer(call << 
597 }                                              << 
598                                                << 
599 /*                                             << 
600  * deliver request data to a YFS CB.CallBack c << 
601  */                                            << 
602 static int afs_deliver_yfs_cb_callback(struct  << 
603 {                                              << 
604         struct afs_callback_break *cb;         << 
605         struct yfs_xdr_YFSFid *bp;             << 
606         size_t size;                           << 
607         int ret, loop;                         << 
608                                                << 
609         _enter("{%u}", call->unmarshall);      << 
610                                                << 
611         switch (call->unmarshall) {            << 
612         case 0:                                << 
613                 afs_extract_to_tmp(call);      << 
614                 call->unmarshall++;            << 
615                                                << 
616                 /* extract the FID array and i << 
617                 fallthrough;                   << 
618         case 1:                                << 
619                 _debug("extract FID count");   << 
620                 ret = afs_extract_data(call, t << 
621                 if (ret < 0)                   << 
622                         return ret;            << 
623                                                << 
624                 call->count = ntohl(call->tmp) << 
625                 _debug("FID count: %u", call-> << 
626                 if (call->count > YFSCBMAX)    << 
627                         return afs_protocol_er << 
628                                                << 
629                 size = array_size(call->count, << 
630                 call->buffer = kmalloc(size, G << 
631                 if (!call->buffer)             << 
632                         return -ENOMEM;        << 
633                 afs_extract_to_buf(call, size) << 
634                 call->unmarshall++;            << 
635                                                   595 
636                 fallthrough;                   !! 596         if (skb->len > 0)
637         case 2:                                !! 597                 return -EBADMSG;
638                 _debug("extract FID array");   !! 598         if (!last)
639                 ret = afs_extract_data(call, f !! 599                 return 0;
640                 if (ret < 0)                   << 
641                         return ret;            << 
642                                                << 
643                 _debug("unmarshall FID array") << 
644                 call->request = kcalloc(call-> << 
645                                         sizeof << 
646                                         GFP_KE << 
647                 if (!call->request)            << 
648                         return -ENOMEM;        << 
649                                                << 
650                 cb = call->request;            << 
651                 bp = call->buffer;             << 
652                 for (loop = call->count; loop  << 
653                         cb->fid.vid     = xdr_ << 
654                         cb->fid.vnode   = xdr_ << 
655                         cb->fid.vnode_hi = nto << 
656                         cb->fid.unique  = ntoh << 
657                         bp++;                  << 
658                 }                              << 
659                                                << 
660                 afs_extract_to_tmp(call);      << 
661                 call->unmarshall++;            << 
662                 fallthrough;                   << 
663                                                << 
664         case 3:                                << 
665                 break;                         << 
666         }                                      << 
667                                                   600 
668         if (!afs_check_call_state(call, AFS_CA !! 601         /* no unmarshalling required */
669                 return afs_io_error(call, afs_ !! 602         call->state = AFS_CALL_REPLYING;
670                                                   603 
671         /* We'll need the file server record a !! 604         INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself);
672          * vnodes to operate upon.             !! 605         queue_work(afs_wq, &call->work);
673          */                                    !! 606         return 0;
674         return afs_find_cm_server_by_peer(call << 
675 }                                                 607 }
676                                                   608 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php