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