root/fs/afs/cmservice.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. afs_cm_incoming_call
  2. afs_record_cm_probe
  3. afs_find_cm_server_by_peer
  4. afs_find_cm_server_by_uuid
  5. afs_cm_destructor
  6. afs_abort_service_call
  7. SRXAFSCB_CallBack
  8. afs_deliver_cb_callback
  9. SRXAFSCB_InitCallBackState
  10. afs_deliver_cb_init_call_back_state
  11. afs_deliver_cb_init_call_back_state3
  12. SRXAFSCB_Probe
  13. afs_deliver_cb_probe
  14. SRXAFSCB_ProbeUuid
  15. afs_deliver_cb_probe_uuid
  16. SRXAFSCB_TellMeAboutYourself
  17. afs_deliver_cb_tell_me_about_yourself
  18. afs_deliver_yfs_cb_callback

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* AFS Cache Manager Service
   3  *
   4  * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
   5  * Written by David Howells (dhowells@redhat.com)
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/init.h>
  10 #include <linux/slab.h>
  11 #include <linux/sched.h>
  12 #include <linux/ip.h>
  13 #include "internal.h"
  14 #include "afs_cm.h"
  15 #include "protocol_yfs.h"
  16 
  17 static int afs_deliver_cb_init_call_back_state(struct afs_call *);
  18 static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
  19 static int afs_deliver_cb_probe(struct afs_call *);
  20 static int afs_deliver_cb_callback(struct afs_call *);
  21 static int afs_deliver_cb_probe_uuid(struct afs_call *);
  22 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
  23 static void afs_cm_destructor(struct afs_call *);
  24 static void SRXAFSCB_CallBack(struct work_struct *);
  25 static void SRXAFSCB_InitCallBackState(struct work_struct *);
  26 static void SRXAFSCB_Probe(struct work_struct *);
  27 static void SRXAFSCB_ProbeUuid(struct work_struct *);
  28 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);
  29 
  30 static int afs_deliver_yfs_cb_callback(struct afs_call *);
  31 
  32 #define CM_NAME(name) \
  33         char afs_SRXCB##name##_name[] __tracepoint_string =     \
  34                 "CB." #name
  35 
  36 /*
  37  * CB.CallBack operation type
  38  */
  39 static CM_NAME(CallBack);
  40 static const struct afs_call_type afs_SRXCBCallBack = {
  41         .name           = afs_SRXCBCallBack_name,
  42         .deliver        = afs_deliver_cb_callback,
  43         .destructor     = afs_cm_destructor,
  44         .work           = SRXAFSCB_CallBack,
  45 };
  46 
  47 /*
  48  * CB.InitCallBackState operation type
  49  */
  50 static CM_NAME(InitCallBackState);
  51 static const struct afs_call_type afs_SRXCBInitCallBackState = {
  52         .name           = afs_SRXCBInitCallBackState_name,
  53         .deliver        = afs_deliver_cb_init_call_back_state,
  54         .destructor     = afs_cm_destructor,
  55         .work           = SRXAFSCB_InitCallBackState,
  56 };
  57 
  58 /*
  59  * CB.InitCallBackState3 operation type
  60  */
  61 static CM_NAME(InitCallBackState3);
  62 static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
  63         .name           = afs_SRXCBInitCallBackState3_name,
  64         .deliver        = afs_deliver_cb_init_call_back_state3,
  65         .destructor     = afs_cm_destructor,
  66         .work           = SRXAFSCB_InitCallBackState,
  67 };
  68 
  69 /*
  70  * CB.Probe operation type
  71  */
  72 static CM_NAME(Probe);
  73 static const struct afs_call_type afs_SRXCBProbe = {
  74         .name           = afs_SRXCBProbe_name,
  75         .deliver        = afs_deliver_cb_probe,
  76         .destructor     = afs_cm_destructor,
  77         .work           = SRXAFSCB_Probe,
  78 };
  79 
  80 /*
  81  * CB.ProbeUuid operation type
  82  */
  83 static CM_NAME(ProbeUuid);
  84 static const struct afs_call_type afs_SRXCBProbeUuid = {
  85         .name           = afs_SRXCBProbeUuid_name,
  86         .deliver        = afs_deliver_cb_probe_uuid,
  87         .destructor     = afs_cm_destructor,
  88         .work           = SRXAFSCB_ProbeUuid,
  89 };
  90 
  91 /*
  92  * CB.TellMeAboutYourself operation type
  93  */
  94 static CM_NAME(TellMeAboutYourself);
  95 static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
  96         .name           = afs_SRXCBTellMeAboutYourself_name,
  97         .deliver        = afs_deliver_cb_tell_me_about_yourself,
  98         .destructor     = afs_cm_destructor,
  99         .work           = SRXAFSCB_TellMeAboutYourself,
 100 };
 101 
 102 /*
 103  * YFS CB.CallBack operation type
 104  */
 105 static CM_NAME(YFS_CallBack);
 106 static const struct afs_call_type afs_SRXYFSCB_CallBack = {
 107         .name           = afs_SRXCBYFS_CallBack_name,
 108         .deliver        = afs_deliver_yfs_cb_callback,
 109         .destructor     = afs_cm_destructor,
 110         .work           = SRXAFSCB_CallBack,
 111 };
 112 
 113 /*
 114  * route an incoming cache manager call
 115  * - return T if supported, F if not
 116  */
 117 bool afs_cm_incoming_call(struct afs_call *call)
 118 {
 119         _enter("{%u, CB.OP %u}", call->service_id, call->operation_ID);
 120 
 121         call->epoch = rxrpc_kernel_get_epoch(call->net->socket, call->rxcall);
 122 
 123         switch (call->operation_ID) {
 124         case CBCallBack:
 125                 call->type = &afs_SRXCBCallBack;
 126                 return true;
 127         case CBInitCallBackState:
 128                 call->type = &afs_SRXCBInitCallBackState;
 129                 return true;
 130         case CBInitCallBackState3:
 131                 call->type = &afs_SRXCBInitCallBackState3;
 132                 return true;
 133         case CBProbe:
 134                 call->type = &afs_SRXCBProbe;
 135                 return true;
 136         case CBProbeUuid:
 137                 call->type = &afs_SRXCBProbeUuid;
 138                 return true;
 139         case CBTellMeAboutYourself:
 140                 call->type = &afs_SRXCBTellMeAboutYourself;
 141                 return true;
 142         case YFSCBCallBack:
 143                 if (call->service_id != YFS_CM_SERVICE)
 144                         return false;
 145                 call->type = &afs_SRXYFSCB_CallBack;
 146                 return true;
 147         default:
 148                 return false;
 149         }
 150 }
 151 
 152 /*
 153  * Record a probe to the cache manager from a server.
 154  */
 155 static int afs_record_cm_probe(struct afs_call *call, struct afs_server *server)
 156 {
 157         _enter("");
 158 
 159         if (test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags) &&
 160             !test_bit(AFS_SERVER_FL_PROBING, &server->flags)) {
 161                 if (server->cm_epoch == call->epoch)
 162                         return 0;
 163 
 164                 if (!server->probe.said_rebooted) {
 165                         pr_notice("kAFS: FS rebooted %pU\n", &server->uuid);
 166                         server->probe.said_rebooted = true;
 167                 }
 168         }
 169 
 170         spin_lock(&server->probe_lock);
 171 
 172         if (!test_and_set_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) {
 173                 server->cm_epoch = call->epoch;
 174                 server->probe.cm_epoch = call->epoch;
 175                 goto out;
 176         }
 177 
 178         if (server->probe.cm_probed &&
 179             call->epoch != server->probe.cm_epoch &&
 180             !server->probe.said_inconsistent) {
 181                 pr_notice("kAFS: FS endpoints inconsistent %pU\n",
 182                           &server->uuid);
 183                 server->probe.said_inconsistent = true;
 184         }
 185 
 186         if (!server->probe.cm_probed || call->epoch == server->cm_epoch)
 187                 server->probe.cm_epoch = server->cm_epoch;
 188 
 189 out:
 190         server->probe.cm_probed = true;
 191         spin_unlock(&server->probe_lock);
 192         return 0;
 193 }
 194 
 195 /*
 196  * Find the server record by peer address and record a probe to the cache
 197  * manager from a server.
 198  */
 199 static int afs_find_cm_server_by_peer(struct afs_call *call)
 200 {
 201         struct sockaddr_rxrpc srx;
 202         struct afs_server *server;
 203 
 204         rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
 205 
 206         server = afs_find_server(call->net, &srx);
 207         if (!server) {
 208                 trace_afs_cm_no_server(call, &srx);
 209                 return 0;
 210         }
 211 
 212         call->server = server;
 213         return afs_record_cm_probe(call, server);
 214 }
 215 
 216 /*
 217  * Find the server record by server UUID and record a probe to the cache
 218  * manager from a server.
 219  */
 220 static int afs_find_cm_server_by_uuid(struct afs_call *call,
 221                                       struct afs_uuid *uuid)
 222 {
 223         struct afs_server *server;
 224 
 225         rcu_read_lock();
 226         server = afs_find_server_by_uuid(call->net, call->request);
 227         rcu_read_unlock();
 228         if (!server) {
 229                 trace_afs_cm_no_server_u(call, call->request);
 230                 return 0;
 231         }
 232 
 233         call->server = server;
 234         return afs_record_cm_probe(call, server);
 235 }
 236 
 237 /*
 238  * Clean up a cache manager call.
 239  */
 240 static void afs_cm_destructor(struct afs_call *call)
 241 {
 242         kfree(call->buffer);
 243         call->buffer = NULL;
 244 }
 245 
 246 /*
 247  * Abort a service call from within an action function.
 248  */
 249 static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error,
 250                                    const char *why)
 251 {
 252         rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
 253                                 abort_code, error, why);
 254         afs_set_call_complete(call, error, 0);
 255 }
 256 
 257 /*
 258  * The server supplied a list of callbacks that it wanted to break.
 259  */
 260 static void SRXAFSCB_CallBack(struct work_struct *work)
 261 {
 262         struct afs_call *call = container_of(work, struct afs_call, work);
 263 
 264         _enter("");
 265 
 266         /* We need to break the callbacks before sending the reply as the
 267          * server holds up change visibility till it receives our reply so as
 268          * to maintain cache coherency.
 269          */
 270         if (call->server) {
 271                 trace_afs_server(call->server, atomic_read(&call->server->usage),
 272                                  afs_server_trace_callback);
 273                 afs_break_callbacks(call->server, call->count, call->request);
 274         }
 275 
 276         afs_send_empty_reply(call);
 277         afs_put_call(call);
 278         _leave("");
 279 }
 280 
 281 /*
 282  * deliver request data to a CB.CallBack call
 283  */
 284 static int afs_deliver_cb_callback(struct afs_call *call)
 285 {
 286         struct afs_callback_break *cb;
 287         __be32 *bp;
 288         int ret, loop;
 289 
 290         _enter("{%u}", call->unmarshall);
 291 
 292         switch (call->unmarshall) {
 293         case 0:
 294                 afs_extract_to_tmp(call);
 295                 call->unmarshall++;
 296 
 297                 /* extract the FID array and its count in two steps */
 298                 /* fall through */
 299         case 1:
 300                 _debug("extract FID count");
 301                 ret = afs_extract_data(call, true);
 302                 if (ret < 0)
 303                         return ret;
 304 
 305                 call->count = ntohl(call->tmp);
 306                 _debug("FID count: %u", call->count);
 307                 if (call->count > AFSCBMAX)
 308                         return afs_protocol_error(call, -EBADMSG,
 309                                                   afs_eproto_cb_fid_count);
 310 
 311                 call->buffer = kmalloc(array3_size(call->count, 3, 4),
 312                                        GFP_KERNEL);
 313                 if (!call->buffer)
 314                         return -ENOMEM;
 315                 afs_extract_to_buf(call, call->count * 3 * 4);
 316                 call->unmarshall++;
 317 
 318                 /* Fall through */
 319         case 2:
 320                 _debug("extract FID array");
 321                 ret = afs_extract_data(call, true);
 322                 if (ret < 0)
 323                         return ret;
 324 
 325                 _debug("unmarshall FID array");
 326                 call->request = kcalloc(call->count,
 327                                         sizeof(struct afs_callback_break),
 328                                         GFP_KERNEL);
 329                 if (!call->request)
 330                         return -ENOMEM;
 331 
 332                 cb = call->request;
 333                 bp = call->buffer;
 334                 for (loop = call->count; loop > 0; loop--, cb++) {
 335                         cb->fid.vid     = ntohl(*bp++);
 336                         cb->fid.vnode   = ntohl(*bp++);
 337                         cb->fid.unique  = ntohl(*bp++);
 338                 }
 339 
 340                 afs_extract_to_tmp(call);
 341                 call->unmarshall++;
 342 
 343                 /* extract the callback array and its count in two steps */
 344                 /* fall through */
 345         case 3:
 346                 _debug("extract CB count");
 347                 ret = afs_extract_data(call, true);
 348                 if (ret < 0)
 349                         return ret;
 350 
 351                 call->count2 = ntohl(call->tmp);
 352                 _debug("CB count: %u", call->count2);
 353                 if (call->count2 != call->count && call->count2 != 0)
 354                         return afs_protocol_error(call, -EBADMSG,
 355                                                   afs_eproto_cb_count);
 356                 call->_iter = &call->iter;
 357                 iov_iter_discard(&call->iter, READ, call->count2 * 3 * 4);
 358                 call->unmarshall++;
 359 
 360                 /* Fall through */
 361         case 4:
 362                 _debug("extract discard %zu/%u",
 363                        iov_iter_count(&call->iter), call->count2 * 3 * 4);
 364 
 365                 ret = afs_extract_data(call, false);
 366                 if (ret < 0)
 367                         return ret;
 368 
 369                 call->unmarshall++;
 370         case 5:
 371                 break;
 372         }
 373 
 374         if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
 375                 return afs_io_error(call, afs_io_error_cm_reply);
 376 
 377         /* we'll need the file server record as that tells us which set of
 378          * vnodes to operate upon */
 379         return afs_find_cm_server_by_peer(call);
 380 }
 381 
 382 /*
 383  * allow the fileserver to request callback state (re-)initialisation
 384  */
 385 static void SRXAFSCB_InitCallBackState(struct work_struct *work)
 386 {
 387         struct afs_call *call = container_of(work, struct afs_call, work);
 388 
 389         _enter("{%p}", call->server);
 390 
 391         if (call->server)
 392                 afs_init_callback_state(call->server);
 393         afs_send_empty_reply(call);
 394         afs_put_call(call);
 395         _leave("");
 396 }
 397 
 398 /*
 399  * deliver request data to a CB.InitCallBackState call
 400  */
 401 static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
 402 {
 403         int ret;
 404 
 405         _enter("");
 406 
 407         afs_extract_discard(call, 0);
 408         ret = afs_extract_data(call, false);
 409         if (ret < 0)
 410                 return ret;
 411 
 412         /* we'll need the file server record as that tells us which set of
 413          * vnodes to operate upon */
 414         return afs_find_cm_server_by_peer(call);
 415 }
 416 
 417 /*
 418  * deliver request data to a CB.InitCallBackState3 call
 419  */
 420 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
 421 {
 422         struct afs_uuid *r;
 423         unsigned loop;
 424         __be32 *b;
 425         int ret;
 426 
 427         _enter("");
 428 
 429         _enter("{%u}", call->unmarshall);
 430 
 431         switch (call->unmarshall) {
 432         case 0:
 433                 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
 434                 if (!call->buffer)
 435                         return -ENOMEM;
 436                 afs_extract_to_buf(call, 11 * sizeof(__be32));
 437                 call->unmarshall++;
 438 
 439                 /* Fall through */
 440         case 1:
 441                 _debug("extract UUID");
 442                 ret = afs_extract_data(call, false);
 443                 switch (ret) {
 444                 case 0:         break;
 445                 case -EAGAIN:   return 0;
 446                 default:        return ret;
 447                 }
 448 
 449                 _debug("unmarshall UUID");
 450                 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
 451                 if (!call->request)
 452                         return -ENOMEM;
 453 
 454                 b = call->buffer;
 455                 r = call->request;
 456                 r->time_low                     = b[0];
 457                 r->time_mid                     = htons(ntohl(b[1]));
 458                 r->time_hi_and_version          = htons(ntohl(b[2]));
 459                 r->clock_seq_hi_and_reserved    = ntohl(b[3]);
 460                 r->clock_seq_low                = ntohl(b[4]);
 461 
 462                 for (loop = 0; loop < 6; loop++)
 463                         r->node[loop] = ntohl(b[loop + 5]);
 464 
 465                 call->unmarshall++;
 466 
 467         case 2:
 468                 break;
 469         }
 470 
 471         if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
 472                 return afs_io_error(call, afs_io_error_cm_reply);
 473 
 474         /* we'll need the file server record as that tells us which set of
 475          * vnodes to operate upon */
 476         return afs_find_cm_server_by_uuid(call, call->request);
 477 }
 478 
 479 /*
 480  * allow the fileserver to see if the cache manager is still alive
 481  */
 482 static void SRXAFSCB_Probe(struct work_struct *work)
 483 {
 484         struct afs_call *call = container_of(work, struct afs_call, work);
 485 
 486         _enter("");
 487         afs_send_empty_reply(call);
 488         afs_put_call(call);
 489         _leave("");
 490 }
 491 
 492 /*
 493  * deliver request data to a CB.Probe call
 494  */
 495 static int afs_deliver_cb_probe(struct afs_call *call)
 496 {
 497         int ret;
 498 
 499         _enter("");
 500 
 501         afs_extract_discard(call, 0);
 502         ret = afs_extract_data(call, false);
 503         if (ret < 0)
 504                 return ret;
 505 
 506         if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
 507                 return afs_io_error(call, afs_io_error_cm_reply);
 508         return afs_find_cm_server_by_peer(call);
 509 }
 510 
 511 /*
 512  * allow the fileserver to quickly find out if the fileserver has been rebooted
 513  */
 514 static void SRXAFSCB_ProbeUuid(struct work_struct *work)
 515 {
 516         struct afs_call *call = container_of(work, struct afs_call, work);
 517         struct afs_uuid *r = call->request;
 518 
 519         _enter("");
 520 
 521         if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
 522                 afs_send_empty_reply(call);
 523         else
 524                 afs_abort_service_call(call, 1, 1, "K-1");
 525 
 526         afs_put_call(call);
 527         _leave("");
 528 }
 529 
 530 /*
 531  * deliver request data to a CB.ProbeUuid call
 532  */
 533 static int afs_deliver_cb_probe_uuid(struct afs_call *call)
 534 {
 535         struct afs_uuid *r;
 536         unsigned loop;
 537         __be32 *b;
 538         int ret;
 539 
 540         _enter("{%u}", call->unmarshall);
 541 
 542         switch (call->unmarshall) {
 543         case 0:
 544                 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
 545                 if (!call->buffer)
 546                         return -ENOMEM;
 547                 afs_extract_to_buf(call, 11 * sizeof(__be32));
 548                 call->unmarshall++;
 549 
 550                 /* Fall through */
 551         case 1:
 552                 _debug("extract UUID");
 553                 ret = afs_extract_data(call, false);
 554                 switch (ret) {
 555                 case 0:         break;
 556                 case -EAGAIN:   return 0;
 557                 default:        return ret;
 558                 }
 559 
 560                 _debug("unmarshall UUID");
 561                 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
 562                 if (!call->request)
 563                         return -ENOMEM;
 564 
 565                 b = call->buffer;
 566                 r = call->request;
 567                 r->time_low                     = b[0];
 568                 r->time_mid                     = htons(ntohl(b[1]));
 569                 r->time_hi_and_version          = htons(ntohl(b[2]));
 570                 r->clock_seq_hi_and_reserved    = ntohl(b[3]);
 571                 r->clock_seq_low                = ntohl(b[4]);
 572 
 573                 for (loop = 0; loop < 6; loop++)
 574                         r->node[loop] = ntohl(b[loop + 5]);
 575 
 576                 call->unmarshall++;
 577 
 578         case 2:
 579                 break;
 580         }
 581 
 582         if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
 583                 return afs_io_error(call, afs_io_error_cm_reply);
 584         return afs_find_cm_server_by_uuid(call, call->request);
 585 }
 586 
 587 /*
 588  * allow the fileserver to ask about the cache manager's capabilities
 589  */
 590 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
 591 {
 592         struct afs_call *call = container_of(work, struct afs_call, work);
 593         int loop;
 594 
 595         struct {
 596                 struct /* InterfaceAddr */ {
 597                         __be32 nifs;
 598                         __be32 uuid[11];
 599                         __be32 ifaddr[32];
 600                         __be32 netmask[32];
 601                         __be32 mtu[32];
 602                 } ia;
 603                 struct /* Capabilities */ {
 604                         __be32 capcount;
 605                         __be32 caps[1];
 606                 } cap;
 607         } reply;
 608 
 609         _enter("");
 610 
 611         memset(&reply, 0, sizeof(reply));
 612 
 613         reply.ia.uuid[0] = call->net->uuid.time_low;
 614         reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
 615         reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
 616         reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
 617         reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
 618         for (loop = 0; loop < 6; loop++)
 619                 reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
 620 
 621         reply.cap.capcount = htonl(1);
 622         reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
 623         afs_send_simple_reply(call, &reply, sizeof(reply));
 624         afs_put_call(call);
 625         _leave("");
 626 }
 627 
 628 /*
 629  * deliver request data to a CB.TellMeAboutYourself call
 630  */
 631 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
 632 {
 633         int ret;
 634 
 635         _enter("");
 636 
 637         afs_extract_discard(call, 0);
 638         ret = afs_extract_data(call, false);
 639         if (ret < 0)
 640                 return ret;
 641 
 642         if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
 643                 return afs_io_error(call, afs_io_error_cm_reply);
 644         return afs_find_cm_server_by_peer(call);
 645 }
 646 
 647 /*
 648  * deliver request data to a YFS CB.CallBack call
 649  */
 650 static int afs_deliver_yfs_cb_callback(struct afs_call *call)
 651 {
 652         struct afs_callback_break *cb;
 653         struct yfs_xdr_YFSFid *bp;
 654         size_t size;
 655         int ret, loop;
 656 
 657         _enter("{%u}", call->unmarshall);
 658 
 659         switch (call->unmarshall) {
 660         case 0:
 661                 afs_extract_to_tmp(call);
 662                 call->unmarshall++;
 663 
 664                 /* extract the FID array and its count in two steps */
 665                 /* Fall through */
 666         case 1:
 667                 _debug("extract FID count");
 668                 ret = afs_extract_data(call, true);
 669                 if (ret < 0)
 670                         return ret;
 671 
 672                 call->count = ntohl(call->tmp);
 673                 _debug("FID count: %u", call->count);
 674                 if (call->count > YFSCBMAX)
 675                         return afs_protocol_error(call, -EBADMSG,
 676                                                   afs_eproto_cb_fid_count);
 677 
 678                 size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid));
 679                 call->buffer = kmalloc(size, GFP_KERNEL);
 680                 if (!call->buffer)
 681                         return -ENOMEM;
 682                 afs_extract_to_buf(call, size);
 683                 call->unmarshall++;
 684 
 685                 /* Fall through */
 686         case 2:
 687                 _debug("extract FID array");
 688                 ret = afs_extract_data(call, false);
 689                 if (ret < 0)
 690                         return ret;
 691 
 692                 _debug("unmarshall FID array");
 693                 call->request = kcalloc(call->count,
 694                                         sizeof(struct afs_callback_break),
 695                                         GFP_KERNEL);
 696                 if (!call->request)
 697                         return -ENOMEM;
 698 
 699                 cb = call->request;
 700                 bp = call->buffer;
 701                 for (loop = call->count; loop > 0; loop--, cb++) {
 702                         cb->fid.vid     = xdr_to_u64(bp->volume);
 703                         cb->fid.vnode   = xdr_to_u64(bp->vnode.lo);
 704                         cb->fid.vnode_hi = ntohl(bp->vnode.hi);
 705                         cb->fid.unique  = ntohl(bp->vnode.unique);
 706                         bp++;
 707                 }
 708 
 709                 afs_extract_to_tmp(call);
 710                 call->unmarshall++;
 711 
 712         case 3:
 713                 break;
 714         }
 715 
 716         if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
 717                 return afs_io_error(call, afs_io_error_cm_reply);
 718 
 719         /* We'll need the file server record as that tells us which set of
 720          * vnodes to operate upon.
 721          */
 722         return afs_find_cm_server_by_peer(call);
 723 }

/* [<][>][^][v][top][bottom][index][help] */