linux/fs/afs/fsclient.c
<<
>>
Prefs
   1/* AFS File Server client stubs
   2 *
   3 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
   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.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/slab.h>
  14#include <linux/sched.h>
  15#include <linux/circ_buf.h>
  16#include <linux/iversion.h>
  17#include "internal.h"
  18#include "afs_fs.h"
  19#include "xdr_fs.h"
  20
  21static const struct afs_fid afs_zero_fid;
  22
  23/*
  24 * We need somewhere to discard into in case the server helpfully returns more
  25 * than we asked for in FS.FetchData{,64}.
  26 */
  27static u8 afs_discard_buffer[64];
  28
  29static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
  30{
  31        call->cbi = afs_get_cb_interest(cbi);
  32}
  33
  34/*
  35 * decode an AFSFid block
  36 */
  37static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
  38{
  39        const __be32 *bp = *_bp;
  40
  41        fid->vid                = ntohl(*bp++);
  42        fid->vnode              = ntohl(*bp++);
  43        fid->unique             = ntohl(*bp++);
  44        *_bp = bp;
  45}
  46
  47/*
  48 * Dump a bad file status record.
  49 */
  50static void xdr_dump_bad(const __be32 *bp)
  51{
  52        __be32 x[4];
  53        int i;
  54
  55        pr_notice("AFS XDR: Bad status record\n");
  56        for (i = 0; i < 5 * 4 * 4; i += 16) {
  57                memcpy(x, bp, 16);
  58                bp += 4;
  59                pr_notice("%03x: %08x %08x %08x %08x\n",
  60                          i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
  61        }
  62
  63        memcpy(x, bp, 4);
  64        pr_notice("0x50: %08x\n", ntohl(x[0]));
  65}
  66
  67/*
  68 * Update the core inode struct from a returned status record.
  69 */
  70void afs_update_inode_from_status(struct afs_vnode *vnode,
  71                                  struct afs_file_status *status,
  72                                  const afs_dataversion_t *expected_version,
  73                                  u8 flags)
  74{
  75        struct timespec t;
  76        umode_t mode;
  77
  78        t.tv_sec = status->mtime_client;
  79        t.tv_nsec = 0;
  80        vnode->vfs_inode.i_ctime = t;
  81        vnode->vfs_inode.i_mtime = t;
  82        vnode->vfs_inode.i_atime = t;
  83
  84        if (flags & (AFS_VNODE_META_CHANGED | AFS_VNODE_NOT_YET_SET)) {
  85                vnode->vfs_inode.i_uid = make_kuid(&init_user_ns, status->owner);
  86                vnode->vfs_inode.i_gid = make_kgid(&init_user_ns, status->group);
  87                set_nlink(&vnode->vfs_inode, status->nlink);
  88
  89                mode = vnode->vfs_inode.i_mode;
  90                mode &= ~S_IALLUGO;
  91                mode |= status->mode;
  92                barrier();
  93                vnode->vfs_inode.i_mode = mode;
  94        }
  95
  96        if (!(flags & AFS_VNODE_NOT_YET_SET)) {
  97                if (expected_version &&
  98                    *expected_version != status->data_version) {
  99                        _debug("vnode modified %llx on {%x:%u} [exp %llx]",
 100                               (unsigned long long) status->data_version,
 101                               vnode->fid.vid, vnode->fid.vnode,
 102                               (unsigned long long) *expected_version);
 103                        vnode->invalid_before = status->data_version;
 104                        if (vnode->status.type == AFS_FTYPE_DIR) {
 105                                if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
 106                                        afs_stat_v(vnode, n_inval);
 107                        } else {
 108                                set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
 109                        }
 110                } else if (vnode->status.type == AFS_FTYPE_DIR) {
 111                        /* Expected directory change is handled elsewhere so
 112                         * that we can locally edit the directory and save on a
 113                         * download.
 114                         */
 115                        if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
 116                                flags &= ~AFS_VNODE_DATA_CHANGED;
 117                }
 118        }
 119
 120        if (flags & (AFS_VNODE_DATA_CHANGED | AFS_VNODE_NOT_YET_SET)) {
 121                inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
 122                i_size_write(&vnode->vfs_inode, status->size);
 123        }
 124}
 125
 126/*
 127 * decode an AFSFetchStatus block
 128 */
 129static int xdr_decode_AFSFetchStatus(struct afs_call *call,
 130                                     const __be32 **_bp,
 131                                     struct afs_file_status *status,
 132                                     struct afs_vnode *vnode,
 133                                     const afs_dataversion_t *expected_version,
 134                                     struct afs_read *read_req)
 135{
 136        const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
 137        bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
 138        u64 data_version, size;
 139        u32 type, abort_code;
 140        u8 flags = 0;
 141        int ret;
 142
 143        if (vnode)
 144                write_seqlock(&vnode->cb_lock);
 145
 146        abort_code = ntohl(xdr->abort_code);
 147
 148        if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {
 149                if (xdr->if_version == htonl(0) &&
 150                    abort_code != 0 &&
 151                    inline_error) {
 152                        /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus
 153                         * whereby it doesn't set the interface version in the error
 154                         * case.
 155                         */
 156                        status->abort_code = abort_code;
 157                        ret = 0;
 158                        goto out;
 159                }
 160
 161                pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
 162                goto bad;
 163        }
 164
 165        if (abort_code != 0 && inline_error) {
 166                status->abort_code = abort_code;
 167                ret = 0;
 168                goto out;
 169        }
 170
 171        type = ntohl(xdr->type);
 172        switch (type) {
 173        case AFS_FTYPE_FILE:
 174        case AFS_FTYPE_DIR:
 175        case AFS_FTYPE_SYMLINK:
 176                if (type != status->type &&
 177                    vnode &&
 178                    !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
 179                        pr_warning("Vnode %x:%x:%x changed type %u to %u\n",
 180                                   vnode->fid.vid,
 181                                   vnode->fid.vnode,
 182                                   vnode->fid.unique,
 183                                   status->type, type);
 184                        goto bad;
 185                }
 186                status->type = type;
 187                break;
 188        default:
 189                goto bad;
 190        }
 191
 192#define EXTRACT_M(FIELD)                                        \
 193        do {                                                    \
 194                u32 x = ntohl(xdr->FIELD);                      \
 195                if (status->FIELD != x) {                       \
 196                        flags |= AFS_VNODE_META_CHANGED;        \
 197                        status->FIELD = x;                      \
 198                }                                               \
 199        } while (0)
 200
 201        EXTRACT_M(nlink);
 202        EXTRACT_M(author);
 203        EXTRACT_M(owner);
 204        EXTRACT_M(caller_access); /* call ticket dependent */
 205        EXTRACT_M(anon_access);
 206        EXTRACT_M(mode);
 207        EXTRACT_M(group);
 208
 209        status->mtime_client = ntohl(xdr->mtime_client);
 210        status->mtime_server = ntohl(xdr->mtime_server);
 211        status->lock_count   = ntohl(xdr->lock_count);
 212
 213        size  = (u64)ntohl(xdr->size_lo);
 214        size |= (u64)ntohl(xdr->size_hi) << 32;
 215        status->size = size;
 216
 217        data_version  = (u64)ntohl(xdr->data_version_lo);
 218        data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
 219        if (data_version != status->data_version) {
 220                status->data_version = data_version;
 221                flags |= AFS_VNODE_DATA_CHANGED;
 222        }
 223
 224        if (read_req) {
 225                read_req->data_version = data_version;
 226                read_req->file_size = size;
 227        }
 228
 229        *_bp = (const void *)*_bp + sizeof(*xdr);
 230
 231        if (vnode) {
 232                if (test_bit(AFS_VNODE_UNSET, &vnode->flags))
 233                        flags |= AFS_VNODE_NOT_YET_SET;
 234                afs_update_inode_from_status(vnode, status, expected_version,
 235                                             flags);
 236        }
 237
 238        ret = 0;
 239
 240out:
 241        if (vnode)
 242                write_sequnlock(&vnode->cb_lock);
 243        return ret;
 244
 245bad:
 246        xdr_dump_bad(*_bp);
 247        ret = afs_protocol_error(call, -EBADMSG);
 248        goto out;
 249}
 250
 251/*
 252 * decode an AFSCallBack block
 253 */
 254static void xdr_decode_AFSCallBack(struct afs_call *call,
 255                                   struct afs_vnode *vnode,
 256                                   const __be32 **_bp)
 257{
 258        struct afs_cb_interest *old, *cbi = call->cbi;
 259        const __be32 *bp = *_bp;
 260        u32 cb_expiry;
 261
 262        write_seqlock(&vnode->cb_lock);
 263
 264        if (call->cb_break == afs_cb_break_sum(vnode, cbi)) {
 265                vnode->cb_version       = ntohl(*bp++);
 266                cb_expiry               = ntohl(*bp++);
 267                vnode->cb_type          = ntohl(*bp++);
 268                vnode->cb_expires_at    = cb_expiry + ktime_get_real_seconds();
 269                old = vnode->cb_interest;
 270                if (old != call->cbi) {
 271                        vnode->cb_interest = cbi;
 272                        cbi = old;
 273                }
 274                set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
 275        } else {
 276                bp += 3;
 277        }
 278
 279        write_sequnlock(&vnode->cb_lock);
 280        call->cbi = cbi;
 281        *_bp = bp;
 282}
 283
 284static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
 285                                       struct afs_callback *cb)
 286{
 287        const __be32 *bp = *_bp;
 288
 289        cb->version     = ntohl(*bp++);
 290        cb->expiry      = ntohl(*bp++);
 291        cb->type        = ntohl(*bp++);
 292        *_bp = bp;
 293}
 294
 295/*
 296 * decode an AFSVolSync block
 297 */
 298static void xdr_decode_AFSVolSync(const __be32 **_bp,
 299                                  struct afs_volsync *volsync)
 300{
 301        const __be32 *bp = *_bp;
 302
 303        volsync->creation = ntohl(*bp++);
 304        bp++; /* spare2 */
 305        bp++; /* spare3 */
 306        bp++; /* spare4 */
 307        bp++; /* spare5 */
 308        bp++; /* spare6 */
 309        *_bp = bp;
 310}
 311
 312/*
 313 * encode the requested attributes into an AFSStoreStatus block
 314 */
 315static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
 316{
 317        __be32 *bp = *_bp;
 318        u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
 319
 320        mask = 0;
 321        if (attr->ia_valid & ATTR_MTIME) {
 322                mask |= AFS_SET_MTIME;
 323                mtime = attr->ia_mtime.tv_sec;
 324        }
 325
 326        if (attr->ia_valid & ATTR_UID) {
 327                mask |= AFS_SET_OWNER;
 328                owner = from_kuid(&init_user_ns, attr->ia_uid);
 329        }
 330
 331        if (attr->ia_valid & ATTR_GID) {
 332                mask |= AFS_SET_GROUP;
 333                group = from_kgid(&init_user_ns, attr->ia_gid);
 334        }
 335
 336        if (attr->ia_valid & ATTR_MODE) {
 337                mask |= AFS_SET_MODE;
 338                mode = attr->ia_mode & S_IALLUGO;
 339        }
 340
 341        *bp++ = htonl(mask);
 342        *bp++ = htonl(mtime);
 343        *bp++ = htonl(owner);
 344        *bp++ = htonl(group);
 345        *bp++ = htonl(mode);
 346        *bp++ = 0;              /* segment size */
 347        *_bp = bp;
 348}
 349
 350/*
 351 * decode an AFSFetchVolumeStatus block
 352 */
 353static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
 354                                            struct afs_volume_status *vs)
 355{
 356        const __be32 *bp = *_bp;
 357
 358        vs->vid                 = ntohl(*bp++);
 359        vs->parent_id           = ntohl(*bp++);
 360        vs->online              = ntohl(*bp++);
 361        vs->in_service          = ntohl(*bp++);
 362        vs->blessed             = ntohl(*bp++);
 363        vs->needs_salvage       = ntohl(*bp++);
 364        vs->type                = ntohl(*bp++);
 365        vs->min_quota           = ntohl(*bp++);
 366        vs->max_quota           = ntohl(*bp++);
 367        vs->blocks_in_use       = ntohl(*bp++);
 368        vs->part_blocks_avail   = ntohl(*bp++);
 369        vs->part_max_blocks     = ntohl(*bp++);
 370        *_bp = bp;
 371}
 372
 373/*
 374 * deliver reply data to an FS.FetchStatus
 375 */
 376static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
 377{
 378        struct afs_vnode *vnode = call->reply[0];
 379        const __be32 *bp;
 380        int ret;
 381
 382        ret = afs_transfer_reply(call);
 383        if (ret < 0)
 384                return ret;
 385
 386        _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
 387
 388        /* unmarshall the reply once we've received all of it */
 389        bp = call->buffer;
 390        if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
 391                                      &call->expected_version, NULL) < 0)
 392                return afs_protocol_error(call, -EBADMSG);
 393        xdr_decode_AFSCallBack(call, vnode, &bp);
 394        if (call->reply[1])
 395                xdr_decode_AFSVolSync(&bp, call->reply[1]);
 396
 397        _leave(" = 0 [done]");
 398        return 0;
 399}
 400
 401/*
 402 * FS.FetchStatus operation type
 403 */
 404static const struct afs_call_type afs_RXFSFetchStatus_vnode = {
 405        .name           = "FS.FetchStatus(vnode)",
 406        .op             = afs_FS_FetchStatus,
 407        .deliver        = afs_deliver_fs_fetch_status_vnode,
 408        .destructor     = afs_flat_call_destructor,
 409};
 410
 411/*
 412 * fetch the status information for a file
 413 */
 414int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
 415                             bool new_inode)
 416{
 417        struct afs_vnode *vnode = fc->vnode;
 418        struct afs_call *call;
 419        struct afs_net *net = afs_v2net(vnode);
 420        __be32 *bp;
 421
 422        _enter(",%x,{%x:%u},,",
 423               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
 424
 425        call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode,
 426                                   16, (21 + 3 + 6) * 4);
 427        if (!call) {
 428                fc->ac.error = -ENOMEM;
 429                return -ENOMEM;
 430        }
 431
 432        call->key = fc->key;
 433        call->reply[0] = vnode;
 434        call->reply[1] = volsync;
 435        call->expected_version = new_inode ? 1 : vnode->status.data_version;
 436
 437        /* marshall the parameters */
 438        bp = call->request;
 439        bp[0] = htonl(FSFETCHSTATUS);
 440        bp[1] = htonl(vnode->fid.vid);
 441        bp[2] = htonl(vnode->fid.vnode);
 442        bp[3] = htonl(vnode->fid.unique);
 443
 444        call->cb_break = fc->cb_break;
 445        afs_use_fs_server(call, fc->cbi);
 446        trace_afs_make_fs_call(call, &vnode->fid);
 447        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
 448}
 449
 450/*
 451 * deliver reply data to an FS.FetchData
 452 */
 453static int afs_deliver_fs_fetch_data(struct afs_call *call)
 454{
 455        struct afs_vnode *vnode = call->reply[0];
 456        struct afs_read *req = call->reply[2];
 457        const __be32 *bp;
 458        unsigned int size;
 459        void *buffer;
 460        int ret;
 461
 462        _enter("{%u,%zu/%u;%llu/%llu}",
 463               call->unmarshall, call->offset, call->count,
 464               req->remain, req->actual_len);
 465
 466        switch (call->unmarshall) {
 467        case 0:
 468                req->actual_len = 0;
 469                call->offset = 0;
 470                call->unmarshall++;
 471                if (call->operation_ID != FSFETCHDATA64) {
 472                        call->unmarshall++;
 473                        goto no_msw;
 474                }
 475
 476                /* extract the upper part of the returned data length of an
 477                 * FSFETCHDATA64 op (which should always be 0 using this
 478                 * client) */
 479        case 1:
 480                _debug("extract data length (MSW)");
 481                ret = afs_extract_data(call, &call->tmp, 4, true);
 482                if (ret < 0)
 483                        return ret;
 484
 485                req->actual_len = ntohl(call->tmp);
 486                req->actual_len <<= 32;
 487                call->offset = 0;
 488                call->unmarshall++;
 489
 490        no_msw:
 491                /* extract the returned data length */
 492        case 2:
 493                _debug("extract data length");
 494                ret = afs_extract_data(call, &call->tmp, 4, true);
 495                if (ret < 0)
 496                        return ret;
 497
 498                req->actual_len |= ntohl(call->tmp);
 499                _debug("DATA length: %llu", req->actual_len);
 500
 501                req->remain = req->actual_len;
 502                call->offset = req->pos & (PAGE_SIZE - 1);
 503                req->index = 0;
 504                if (req->actual_len == 0)
 505                        goto no_more_data;
 506                call->unmarshall++;
 507
 508        begin_page:
 509                ASSERTCMP(req->index, <, req->nr_pages);
 510                if (req->remain > PAGE_SIZE - call->offset)
 511                        size = PAGE_SIZE - call->offset;
 512                else
 513                        size = req->remain;
 514                call->count = call->offset + size;
 515                ASSERTCMP(call->count, <=, PAGE_SIZE);
 516                req->remain -= size;
 517
 518                /* extract the returned data */
 519        case 3:
 520                _debug("extract data %llu/%llu %zu/%u",
 521                       req->remain, req->actual_len, call->offset, call->count);
 522
 523                buffer = kmap(req->pages[req->index]);
 524                ret = afs_extract_data(call, buffer, call->count, true);
 525                kunmap(req->pages[req->index]);
 526                if (ret < 0)
 527                        return ret;
 528                if (call->offset == PAGE_SIZE) {
 529                        if (req->page_done)
 530                                req->page_done(call, req);
 531                        req->index++;
 532                        if (req->remain > 0) {
 533                                call->offset = 0;
 534                                if (req->index >= req->nr_pages) {
 535                                        call->unmarshall = 4;
 536                                        goto begin_discard;
 537                                }
 538                                goto begin_page;
 539                        }
 540                }
 541                goto no_more_data;
 542
 543                /* Discard any excess data the server gave us */
 544        begin_discard:
 545        case 4:
 546                size = min_t(loff_t, sizeof(afs_discard_buffer), req->remain);
 547                call->count = size;
 548                _debug("extract discard %llu/%llu %zu/%u",
 549                       req->remain, req->actual_len, call->offset, call->count);
 550
 551                call->offset = 0;
 552                ret = afs_extract_data(call, afs_discard_buffer, call->count, true);
 553                req->remain -= call->offset;
 554                if (ret < 0)
 555                        return ret;
 556                if (req->remain > 0)
 557                        goto begin_discard;
 558
 559        no_more_data:
 560                call->offset = 0;
 561                call->unmarshall = 5;
 562
 563                /* extract the metadata */
 564        case 5:
 565                ret = afs_extract_data(call, call->buffer,
 566                                       (21 + 3 + 6) * 4, false);
 567                if (ret < 0)
 568                        return ret;
 569
 570                bp = call->buffer;
 571                if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
 572                                              &vnode->status.data_version, req) < 0)
 573                        return afs_protocol_error(call, -EBADMSG);
 574                xdr_decode_AFSCallBack(call, vnode, &bp);
 575                if (call->reply[1])
 576                        xdr_decode_AFSVolSync(&bp, call->reply[1]);
 577
 578                call->offset = 0;
 579                call->unmarshall++;
 580
 581        case 6:
 582                break;
 583        }
 584
 585        for (; req->index < req->nr_pages; req->index++) {
 586                if (call->count < PAGE_SIZE)
 587                        zero_user_segment(req->pages[req->index],
 588                                          call->count, PAGE_SIZE);
 589                if (req->page_done)
 590                        req->page_done(call, req);
 591                call->count = 0;
 592        }
 593
 594        _leave(" = 0 [done]");
 595        return 0;
 596}
 597
 598static void afs_fetch_data_destructor(struct afs_call *call)
 599{
 600        struct afs_read *req = call->reply[2];
 601
 602        afs_put_read(req);
 603        afs_flat_call_destructor(call);
 604}
 605
 606/*
 607 * FS.FetchData operation type
 608 */
 609static const struct afs_call_type afs_RXFSFetchData = {
 610        .name           = "FS.FetchData",
 611        .op             = afs_FS_FetchData,
 612        .deliver        = afs_deliver_fs_fetch_data,
 613        .destructor     = afs_fetch_data_destructor,
 614};
 615
 616static const struct afs_call_type afs_RXFSFetchData64 = {
 617        .name           = "FS.FetchData64",
 618        .op             = afs_FS_FetchData64,
 619        .deliver        = afs_deliver_fs_fetch_data,
 620        .destructor     = afs_fetch_data_destructor,
 621};
 622
 623/*
 624 * fetch data from a very large file
 625 */
 626static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
 627{
 628        struct afs_vnode *vnode = fc->vnode;
 629        struct afs_call *call;
 630        struct afs_net *net = afs_v2net(vnode);
 631        __be32 *bp;
 632
 633        _enter("");
 634
 635        call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
 636        if (!call)
 637                return -ENOMEM;
 638
 639        call->key = fc->key;
 640        call->reply[0] = vnode;
 641        call->reply[1] = NULL; /* volsync */
 642        call->reply[2] = req;
 643        call->expected_version = vnode->status.data_version;
 644
 645        /* marshall the parameters */
 646        bp = call->request;
 647        bp[0] = htonl(FSFETCHDATA64);
 648        bp[1] = htonl(vnode->fid.vid);
 649        bp[2] = htonl(vnode->fid.vnode);
 650        bp[3] = htonl(vnode->fid.unique);
 651        bp[4] = htonl(upper_32_bits(req->pos));
 652        bp[5] = htonl(lower_32_bits(req->pos));
 653        bp[6] = 0;
 654        bp[7] = htonl(lower_32_bits(req->len));
 655
 656        refcount_inc(&req->usage);
 657        call->cb_break = fc->cb_break;
 658        afs_use_fs_server(call, fc->cbi);
 659        trace_afs_make_fs_call(call, &vnode->fid);
 660        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
 661}
 662
 663/*
 664 * fetch data from a file
 665 */
 666int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
 667{
 668        struct afs_vnode *vnode = fc->vnode;
 669        struct afs_call *call;
 670        struct afs_net *net = afs_v2net(vnode);
 671        __be32 *bp;
 672
 673        if (upper_32_bits(req->pos) ||
 674            upper_32_bits(req->len) ||
 675            upper_32_bits(req->pos + req->len))
 676                return afs_fs_fetch_data64(fc, req);
 677
 678        _enter("");
 679
 680        call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
 681        if (!call)
 682                return -ENOMEM;
 683
 684        call->key = fc->key;
 685        call->reply[0] = vnode;
 686        call->reply[1] = NULL; /* volsync */
 687        call->reply[2] = req;
 688        call->expected_version = vnode->status.data_version;
 689
 690        /* marshall the parameters */
 691        bp = call->request;
 692        bp[0] = htonl(FSFETCHDATA);
 693        bp[1] = htonl(vnode->fid.vid);
 694        bp[2] = htonl(vnode->fid.vnode);
 695        bp[3] = htonl(vnode->fid.unique);
 696        bp[4] = htonl(lower_32_bits(req->pos));
 697        bp[5] = htonl(lower_32_bits(req->len));
 698
 699        refcount_inc(&req->usage);
 700        call->cb_break = fc->cb_break;
 701        afs_use_fs_server(call, fc->cbi);
 702        trace_afs_make_fs_call(call, &vnode->fid);
 703        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
 704}
 705
 706/*
 707 * deliver reply data to an FS.CreateFile or an FS.MakeDir
 708 */
 709static int afs_deliver_fs_create_vnode(struct afs_call *call)
 710{
 711        struct afs_vnode *vnode = call->reply[0];
 712        const __be32 *bp;
 713        int ret;
 714
 715        _enter("{%u}", call->unmarshall);
 716
 717        ret = afs_transfer_reply(call);
 718        if (ret < 0)
 719                return ret;
 720
 721        /* unmarshall the reply once we've received all of it */
 722        bp = call->buffer;
 723        xdr_decode_AFSFid(&bp, call->reply[1]);
 724        if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 ||
 725            xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
 726                                      &call->expected_version, NULL) < 0)
 727                return afs_protocol_error(call, -EBADMSG);
 728        xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
 729        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
 730
 731        _leave(" = 0 [done]");
 732        return 0;
 733}
 734
 735/*
 736 * FS.CreateFile and FS.MakeDir operation type
 737 */
 738static const struct afs_call_type afs_RXFSCreateFile = {
 739        .name           = "FS.CreateFile",
 740        .op             = afs_FS_CreateFile,
 741        .deliver        = afs_deliver_fs_create_vnode,
 742        .destructor     = afs_flat_call_destructor,
 743};
 744
 745static const struct afs_call_type afs_RXFSMakeDir = {
 746        .name           = "FS.MakeDir",
 747        .op             = afs_FS_MakeDir,
 748        .deliver        = afs_deliver_fs_create_vnode,
 749        .destructor     = afs_flat_call_destructor,
 750};
 751
 752/*
 753 * create a file or make a directory
 754 */
 755int afs_fs_create(struct afs_fs_cursor *fc,
 756                  const char *name,
 757                  umode_t mode,
 758                  u64 current_data_version,
 759                  struct afs_fid *newfid,
 760                  struct afs_file_status *newstatus,
 761                  struct afs_callback *newcb)
 762{
 763        struct afs_vnode *vnode = fc->vnode;
 764        struct afs_call *call;
 765        struct afs_net *net = afs_v2net(vnode);
 766        size_t namesz, reqsz, padsz;
 767        __be32 *bp;
 768
 769        _enter("");
 770
 771        namesz = strlen(name);
 772        padsz = (4 - (namesz & 3)) & 3;
 773        reqsz = (5 * 4) + namesz + padsz + (6 * 4);
 774
 775        call = afs_alloc_flat_call(
 776                net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile,
 777                reqsz, (3 + 21 + 21 + 3 + 6) * 4);
 778        if (!call)
 779                return -ENOMEM;
 780
 781        call->key = fc->key;
 782        call->reply[0] = vnode;
 783        call->reply[1] = newfid;
 784        call->reply[2] = newstatus;
 785        call->reply[3] = newcb;
 786        call->expected_version = current_data_version + 1;
 787
 788        /* marshall the parameters */
 789        bp = call->request;
 790        *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
 791        *bp++ = htonl(vnode->fid.vid);
 792        *bp++ = htonl(vnode->fid.vnode);
 793        *bp++ = htonl(vnode->fid.unique);
 794        *bp++ = htonl(namesz);
 795        memcpy(bp, name, namesz);
 796        bp = (void *) bp + namesz;
 797        if (padsz > 0) {
 798                memset(bp, 0, padsz);
 799                bp = (void *) bp + padsz;
 800        }
 801        *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
 802        *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
 803        *bp++ = 0; /* owner */
 804        *bp++ = 0; /* group */
 805        *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
 806        *bp++ = 0; /* segment size */
 807
 808        afs_use_fs_server(call, fc->cbi);
 809        trace_afs_make_fs_call(call, &vnode->fid);
 810        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
 811}
 812
 813/*
 814 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
 815 */
 816static int afs_deliver_fs_remove(struct afs_call *call)
 817{
 818        struct afs_vnode *vnode = call->reply[0];
 819        const __be32 *bp;
 820        int ret;
 821
 822        _enter("{%u}", call->unmarshall);
 823
 824        ret = afs_transfer_reply(call);
 825        if (ret < 0)
 826                return ret;
 827
 828        /* unmarshall the reply once we've received all of it */
 829        bp = call->buffer;
 830        if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
 831                                      &call->expected_version, NULL) < 0)
 832                return afs_protocol_error(call, -EBADMSG);
 833        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
 834
 835        _leave(" = 0 [done]");
 836        return 0;
 837}
 838
 839/*
 840 * FS.RemoveDir/FS.RemoveFile operation type
 841 */
 842static const struct afs_call_type afs_RXFSRemoveFile = {
 843        .name           = "FS.RemoveFile",
 844        .op             = afs_FS_RemoveFile,
 845        .deliver        = afs_deliver_fs_remove,
 846        .destructor     = afs_flat_call_destructor,
 847};
 848
 849static const struct afs_call_type afs_RXFSRemoveDir = {
 850        .name           = "FS.RemoveDir",
 851        .op             = afs_FS_RemoveDir,
 852        .deliver        = afs_deliver_fs_remove,
 853        .destructor     = afs_flat_call_destructor,
 854};
 855
 856/*
 857 * remove a file or directory
 858 */
 859int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
 860                  u64 current_data_version)
 861{
 862        struct afs_vnode *vnode = fc->vnode;
 863        struct afs_call *call;
 864        struct afs_net *net = afs_v2net(vnode);
 865        size_t namesz, reqsz, padsz;
 866        __be32 *bp;
 867
 868        _enter("");
 869
 870        namesz = strlen(name);
 871        padsz = (4 - (namesz & 3)) & 3;
 872        reqsz = (5 * 4) + namesz + padsz;
 873
 874        call = afs_alloc_flat_call(
 875                net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile,
 876                reqsz, (21 + 6) * 4);
 877        if (!call)
 878                return -ENOMEM;
 879
 880        call->key = fc->key;
 881        call->reply[0] = vnode;
 882        call->expected_version = current_data_version + 1;
 883
 884        /* marshall the parameters */
 885        bp = call->request;
 886        *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
 887        *bp++ = htonl(vnode->fid.vid);
 888        *bp++ = htonl(vnode->fid.vnode);
 889        *bp++ = htonl(vnode->fid.unique);
 890        *bp++ = htonl(namesz);
 891        memcpy(bp, name, namesz);
 892        bp = (void *) bp + namesz;
 893        if (padsz > 0) {
 894                memset(bp, 0, padsz);
 895                bp = (void *) bp + padsz;
 896        }
 897
 898        afs_use_fs_server(call, fc->cbi);
 899        trace_afs_make_fs_call(call, &vnode->fid);
 900        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
 901}
 902
 903/*
 904 * deliver reply data to an FS.Link
 905 */
 906static int afs_deliver_fs_link(struct afs_call *call)
 907{
 908        struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
 909        const __be32 *bp;
 910        int ret;
 911
 912        _enter("{%u}", call->unmarshall);
 913
 914        ret = afs_transfer_reply(call);
 915        if (ret < 0)
 916                return ret;
 917
 918        /* unmarshall the reply once we've received all of it */
 919        bp = call->buffer;
 920        if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 ||
 921            xdr_decode_AFSFetchStatus(call, &bp, &dvnode->status, dvnode,
 922                                      &call->expected_version, NULL) < 0)
 923                return afs_protocol_error(call, -EBADMSG);
 924        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
 925
 926        _leave(" = 0 [done]");
 927        return 0;
 928}
 929
 930/*
 931 * FS.Link operation type
 932 */
 933static const struct afs_call_type afs_RXFSLink = {
 934        .name           = "FS.Link",
 935        .op             = afs_FS_Link,
 936        .deliver        = afs_deliver_fs_link,
 937        .destructor     = afs_flat_call_destructor,
 938};
 939
 940/*
 941 * make a hard link
 942 */
 943int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
 944                const char *name, u64 current_data_version)
 945{
 946        struct afs_vnode *dvnode = fc->vnode;
 947        struct afs_call *call;
 948        struct afs_net *net = afs_v2net(vnode);
 949        size_t namesz, reqsz, padsz;
 950        __be32 *bp;
 951
 952        _enter("");
 953
 954        namesz = strlen(name);
 955        padsz = (4 - (namesz & 3)) & 3;
 956        reqsz = (5 * 4) + namesz + padsz + (3 * 4);
 957
 958        call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
 959        if (!call)
 960                return -ENOMEM;
 961
 962        call->key = fc->key;
 963        call->reply[0] = dvnode;
 964        call->reply[1] = vnode;
 965        call->expected_version = current_data_version + 1;
 966
 967        /* marshall the parameters */
 968        bp = call->request;
 969        *bp++ = htonl(FSLINK);
 970        *bp++ = htonl(dvnode->fid.vid);
 971        *bp++ = htonl(dvnode->fid.vnode);
 972        *bp++ = htonl(dvnode->fid.unique);
 973        *bp++ = htonl(namesz);
 974        memcpy(bp, name, namesz);
 975        bp = (void *) bp + namesz;
 976        if (padsz > 0) {
 977                memset(bp, 0, padsz);
 978                bp = (void *) bp + padsz;
 979        }
 980        *bp++ = htonl(vnode->fid.vid);
 981        *bp++ = htonl(vnode->fid.vnode);
 982        *bp++ = htonl(vnode->fid.unique);
 983
 984        afs_use_fs_server(call, fc->cbi);
 985        trace_afs_make_fs_call(call, &vnode->fid);
 986        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
 987}
 988
 989/*
 990 * deliver reply data to an FS.Symlink
 991 */
 992static int afs_deliver_fs_symlink(struct afs_call *call)
 993{
 994        struct afs_vnode *vnode = call->reply[0];
 995        const __be32 *bp;
 996        int ret;
 997
 998        _enter("{%u}", call->unmarshall);
 999
1000        ret = afs_transfer_reply(call);
1001        if (ret < 0)
1002                return ret;
1003
1004        /* unmarshall the reply once we've received all of it */
1005        bp = call->buffer;
1006        xdr_decode_AFSFid(&bp, call->reply[1]);
1007        if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) ||
1008            xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
1009                                      &call->expected_version, NULL) < 0)
1010                return afs_protocol_error(call, -EBADMSG);
1011        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1012
1013        _leave(" = 0 [done]");
1014        return 0;
1015}
1016
1017/*
1018 * FS.Symlink operation type
1019 */
1020static const struct afs_call_type afs_RXFSSymlink = {
1021        .name           = "FS.Symlink",
1022        .op             = afs_FS_Symlink,
1023        .deliver        = afs_deliver_fs_symlink,
1024        .destructor     = afs_flat_call_destructor,
1025};
1026
1027/*
1028 * create a symbolic link
1029 */
1030int afs_fs_symlink(struct afs_fs_cursor *fc,
1031                   const char *name,
1032                   const char *contents,
1033                   u64 current_data_version,
1034                   struct afs_fid *newfid,
1035                   struct afs_file_status *newstatus)
1036{
1037        struct afs_vnode *vnode = fc->vnode;
1038        struct afs_call *call;
1039        struct afs_net *net = afs_v2net(vnode);
1040        size_t namesz, reqsz, padsz, c_namesz, c_padsz;
1041        __be32 *bp;
1042
1043        _enter("");
1044
1045        namesz = strlen(name);
1046        padsz = (4 - (namesz & 3)) & 3;
1047
1048        c_namesz = strlen(contents);
1049        c_padsz = (4 - (c_namesz & 3)) & 3;
1050
1051        reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
1052
1053        call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,
1054                                   (3 + 21 + 21 + 6) * 4);
1055        if (!call)
1056                return -ENOMEM;
1057
1058        call->key = fc->key;
1059        call->reply[0] = vnode;
1060        call->reply[1] = newfid;
1061        call->reply[2] = newstatus;
1062        call->expected_version = current_data_version + 1;
1063
1064        /* marshall the parameters */
1065        bp = call->request;
1066        *bp++ = htonl(FSSYMLINK);
1067        *bp++ = htonl(vnode->fid.vid);
1068        *bp++ = htonl(vnode->fid.vnode);
1069        *bp++ = htonl(vnode->fid.unique);
1070        *bp++ = htonl(namesz);
1071        memcpy(bp, name, namesz);
1072        bp = (void *) bp + namesz;
1073        if (padsz > 0) {
1074                memset(bp, 0, padsz);
1075                bp = (void *) bp + padsz;
1076        }
1077        *bp++ = htonl(c_namesz);
1078        memcpy(bp, contents, c_namesz);
1079        bp = (void *) bp + c_namesz;
1080        if (c_padsz > 0) {
1081                memset(bp, 0, c_padsz);
1082                bp = (void *) bp + c_padsz;
1083        }
1084        *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
1085        *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1086        *bp++ = 0; /* owner */
1087        *bp++ = 0; /* group */
1088        *bp++ = htonl(S_IRWXUGO); /* unix mode */
1089        *bp++ = 0; /* segment size */
1090
1091        afs_use_fs_server(call, fc->cbi);
1092        trace_afs_make_fs_call(call, &vnode->fid);
1093        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1094}
1095
1096/*
1097 * deliver reply data to an FS.Rename
1098 */
1099static int afs_deliver_fs_rename(struct afs_call *call)
1100{
1101        struct afs_vnode *orig_dvnode = call->reply[0], *new_dvnode = call->reply[1];
1102        const __be32 *bp;
1103        int ret;
1104
1105        _enter("{%u}", call->unmarshall);
1106
1107        ret = afs_transfer_reply(call);
1108        if (ret < 0)
1109                return ret;
1110
1111        /* unmarshall the reply once we've received all of it */
1112        bp = call->buffer;
1113        if (xdr_decode_AFSFetchStatus(call, &bp, &orig_dvnode->status, orig_dvnode,
1114                                      &call->expected_version, NULL) < 0)
1115                return afs_protocol_error(call, -EBADMSG);
1116        if (new_dvnode != orig_dvnode &&
1117            xdr_decode_AFSFetchStatus(call, &bp, &new_dvnode->status, new_dvnode,
1118                                      &call->expected_version_2, NULL) < 0)
1119                return afs_protocol_error(call, -EBADMSG);
1120        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1121
1122        _leave(" = 0 [done]");
1123        return 0;
1124}
1125
1126/*
1127 * FS.Rename operation type
1128 */
1129static const struct afs_call_type afs_RXFSRename = {
1130        .name           = "FS.Rename",
1131        .op             = afs_FS_Rename,
1132        .deliver        = afs_deliver_fs_rename,
1133        .destructor     = afs_flat_call_destructor,
1134};
1135
1136/*
1137 * create a symbolic link
1138 */
1139int afs_fs_rename(struct afs_fs_cursor *fc,
1140                  const char *orig_name,
1141                  struct afs_vnode *new_dvnode,
1142                  const char *new_name,
1143                  u64 current_orig_data_version,
1144                  u64 current_new_data_version)
1145{
1146        struct afs_vnode *orig_dvnode = fc->vnode;
1147        struct afs_call *call;
1148        struct afs_net *net = afs_v2net(orig_dvnode);
1149        size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1150        __be32 *bp;
1151
1152        _enter("");
1153
1154        o_namesz = strlen(orig_name);
1155        o_padsz = (4 - (o_namesz & 3)) & 3;
1156
1157        n_namesz = strlen(new_name);
1158        n_padsz = (4 - (n_namesz & 3)) & 3;
1159
1160        reqsz = (4 * 4) +
1161                4 + o_namesz + o_padsz +
1162                (3 * 4) +
1163                4 + n_namesz + n_padsz;
1164
1165        call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1166        if (!call)
1167                return -ENOMEM;
1168
1169        call->key = fc->key;
1170        call->reply[0] = orig_dvnode;
1171        call->reply[1] = new_dvnode;
1172        call->expected_version = current_orig_data_version + 1;
1173        call->expected_version_2 = current_new_data_version + 1;
1174
1175        /* marshall the parameters */
1176        bp = call->request;
1177        *bp++ = htonl(FSRENAME);
1178        *bp++ = htonl(orig_dvnode->fid.vid);
1179        *bp++ = htonl(orig_dvnode->fid.vnode);
1180        *bp++ = htonl(orig_dvnode->fid.unique);
1181        *bp++ = htonl(o_namesz);
1182        memcpy(bp, orig_name, o_namesz);
1183        bp = (void *) bp + o_namesz;
1184        if (o_padsz > 0) {
1185                memset(bp, 0, o_padsz);
1186                bp = (void *) bp + o_padsz;
1187        }
1188
1189        *bp++ = htonl(new_dvnode->fid.vid);
1190        *bp++ = htonl(new_dvnode->fid.vnode);
1191        *bp++ = htonl(new_dvnode->fid.unique);
1192        *bp++ = htonl(n_namesz);
1193        memcpy(bp, new_name, n_namesz);
1194        bp = (void *) bp + n_namesz;
1195        if (n_padsz > 0) {
1196                memset(bp, 0, n_padsz);
1197                bp = (void *) bp + n_padsz;
1198        }
1199
1200        afs_use_fs_server(call, fc->cbi);
1201        trace_afs_make_fs_call(call, &orig_dvnode->fid);
1202        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1203}
1204
1205/*
1206 * deliver reply data to an FS.StoreData
1207 */
1208static int afs_deliver_fs_store_data(struct afs_call *call)
1209{
1210        struct afs_vnode *vnode = call->reply[0];
1211        const __be32 *bp;
1212        int ret;
1213
1214        _enter("");
1215
1216        ret = afs_transfer_reply(call);
1217        if (ret < 0)
1218                return ret;
1219
1220        /* unmarshall the reply once we've received all of it */
1221        bp = call->buffer;
1222        if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
1223                                      &call->expected_version, NULL) < 0)
1224                return afs_protocol_error(call, -EBADMSG);
1225        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1226
1227        afs_pages_written_back(vnode, call);
1228
1229        _leave(" = 0 [done]");
1230        return 0;
1231}
1232
1233/*
1234 * FS.StoreData operation type
1235 */
1236static const struct afs_call_type afs_RXFSStoreData = {
1237        .name           = "FS.StoreData",
1238        .op             = afs_FS_StoreData,
1239        .deliver        = afs_deliver_fs_store_data,
1240        .destructor     = afs_flat_call_destructor,
1241};
1242
1243static const struct afs_call_type afs_RXFSStoreData64 = {
1244        .name           = "FS.StoreData64",
1245        .op             = afs_FS_StoreData64,
1246        .deliver        = afs_deliver_fs_store_data,
1247        .destructor     = afs_flat_call_destructor,
1248};
1249
1250/*
1251 * store a set of pages to a very large file
1252 */
1253static int afs_fs_store_data64(struct afs_fs_cursor *fc,
1254                               struct address_space *mapping,
1255                               pgoff_t first, pgoff_t last,
1256                               unsigned offset, unsigned to,
1257                               loff_t size, loff_t pos, loff_t i_size)
1258{
1259        struct afs_vnode *vnode = fc->vnode;
1260        struct afs_call *call;
1261        struct afs_net *net = afs_v2net(vnode);
1262        __be32 *bp;
1263
1264        _enter(",%x,{%x:%u},,",
1265               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1266
1267        call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,
1268                                   (4 + 6 + 3 * 2) * 4,
1269                                   (21 + 6) * 4);
1270        if (!call)
1271                return -ENOMEM;
1272
1273        call->key = fc->key;
1274        call->mapping = mapping;
1275        call->reply[0] = vnode;
1276        call->first = first;
1277        call->last = last;
1278        call->first_offset = offset;
1279        call->last_to = to;
1280        call->send_pages = true;
1281        call->expected_version = vnode->status.data_version + 1;
1282
1283        /* marshall the parameters */
1284        bp = call->request;
1285        *bp++ = htonl(FSSTOREDATA64);
1286        *bp++ = htonl(vnode->fid.vid);
1287        *bp++ = htonl(vnode->fid.vnode);
1288        *bp++ = htonl(vnode->fid.unique);
1289
1290        *bp++ = htonl(AFS_SET_MTIME); /* mask */
1291        *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1292        *bp++ = 0; /* owner */
1293        *bp++ = 0; /* group */
1294        *bp++ = 0; /* unix mode */
1295        *bp++ = 0; /* segment size */
1296
1297        *bp++ = htonl(pos >> 32);
1298        *bp++ = htonl((u32) pos);
1299        *bp++ = htonl(size >> 32);
1300        *bp++ = htonl((u32) size);
1301        *bp++ = htonl(i_size >> 32);
1302        *bp++ = htonl((u32) i_size);
1303
1304        trace_afs_make_fs_call(call, &vnode->fid);
1305        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1306}
1307
1308/*
1309 * store a set of pages
1310 */
1311int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1312                      pgoff_t first, pgoff_t last,
1313                      unsigned offset, unsigned to)
1314{
1315        struct afs_vnode *vnode = fc->vnode;
1316        struct afs_call *call;
1317        struct afs_net *net = afs_v2net(vnode);
1318        loff_t size, pos, i_size;
1319        __be32 *bp;
1320
1321        _enter(",%x,{%x:%u},,",
1322               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1323
1324        size = (loff_t)to - (loff_t)offset;
1325        if (first != last)
1326                size += (loff_t)(last - first) << PAGE_SHIFT;
1327        pos = (loff_t)first << PAGE_SHIFT;
1328        pos += offset;
1329
1330        i_size = i_size_read(&vnode->vfs_inode);
1331        if (pos + size > i_size)
1332                i_size = size + pos;
1333
1334        _debug("size %llx, at %llx, i_size %llx",
1335               (unsigned long long) size, (unsigned long long) pos,
1336               (unsigned long long) i_size);
1337
1338        if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1339                return afs_fs_store_data64(fc, mapping, first, last, offset, to,
1340                                           size, pos, i_size);
1341
1342        call = afs_alloc_flat_call(net, &afs_RXFSStoreData,
1343                                   (4 + 6 + 3) * 4,
1344                                   (21 + 6) * 4);
1345        if (!call)
1346                return -ENOMEM;
1347
1348        call->key = fc->key;
1349        call->mapping = mapping;
1350        call->reply[0] = vnode;
1351        call->first = first;
1352        call->last = last;
1353        call->first_offset = offset;
1354        call->last_to = to;
1355        call->send_pages = true;
1356        call->expected_version = vnode->status.data_version + 1;
1357
1358        /* marshall the parameters */
1359        bp = call->request;
1360        *bp++ = htonl(FSSTOREDATA);
1361        *bp++ = htonl(vnode->fid.vid);
1362        *bp++ = htonl(vnode->fid.vnode);
1363        *bp++ = htonl(vnode->fid.unique);
1364
1365        *bp++ = htonl(AFS_SET_MTIME); /* mask */
1366        *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1367        *bp++ = 0; /* owner */
1368        *bp++ = 0; /* group */
1369        *bp++ = 0; /* unix mode */
1370        *bp++ = 0; /* segment size */
1371
1372        *bp++ = htonl(pos);
1373        *bp++ = htonl(size);
1374        *bp++ = htonl(i_size);
1375
1376        afs_use_fs_server(call, fc->cbi);
1377        trace_afs_make_fs_call(call, &vnode->fid);
1378        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1379}
1380
1381/*
1382 * deliver reply data to an FS.StoreStatus
1383 */
1384static int afs_deliver_fs_store_status(struct afs_call *call)
1385{
1386        struct afs_vnode *vnode = call->reply[0];
1387        const __be32 *bp;
1388        int ret;
1389
1390        _enter("");
1391
1392        ret = afs_transfer_reply(call);
1393        if (ret < 0)
1394                return ret;
1395
1396        /* unmarshall the reply once we've received all of it */
1397        bp = call->buffer;
1398        if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
1399                                      &call->expected_version, NULL) < 0)
1400                return afs_protocol_error(call, -EBADMSG);
1401        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1402
1403        _leave(" = 0 [done]");
1404        return 0;
1405}
1406
1407/*
1408 * FS.StoreStatus operation type
1409 */
1410static const struct afs_call_type afs_RXFSStoreStatus = {
1411        .name           = "FS.StoreStatus",
1412        .op             = afs_FS_StoreStatus,
1413        .deliver        = afs_deliver_fs_store_status,
1414        .destructor     = afs_flat_call_destructor,
1415};
1416
1417static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1418        .name           = "FS.StoreData",
1419        .op             = afs_FS_StoreData,
1420        .deliver        = afs_deliver_fs_store_status,
1421        .destructor     = afs_flat_call_destructor,
1422};
1423
1424static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1425        .name           = "FS.StoreData64",
1426        .op             = afs_FS_StoreData64,
1427        .deliver        = afs_deliver_fs_store_status,
1428        .destructor     = afs_flat_call_destructor,
1429};
1430
1431/*
1432 * set the attributes on a very large file, using FS.StoreData rather than
1433 * FS.StoreStatus so as to alter the file size also
1434 */
1435static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
1436{
1437        struct afs_vnode *vnode = fc->vnode;
1438        struct afs_call *call;
1439        struct afs_net *net = afs_v2net(vnode);
1440        __be32 *bp;
1441
1442        _enter(",%x,{%x:%u},,",
1443               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1444
1445        ASSERT(attr->ia_valid & ATTR_SIZE);
1446
1447        call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,
1448                                   (4 + 6 + 3 * 2) * 4,
1449                                   (21 + 6) * 4);
1450        if (!call)
1451                return -ENOMEM;
1452
1453        call->key = fc->key;
1454        call->reply[0] = vnode;
1455        call->expected_version = vnode->status.data_version + 1;
1456
1457        /* marshall the parameters */
1458        bp = call->request;
1459        *bp++ = htonl(FSSTOREDATA64);
1460        *bp++ = htonl(vnode->fid.vid);
1461        *bp++ = htonl(vnode->fid.vnode);
1462        *bp++ = htonl(vnode->fid.unique);
1463
1464        xdr_encode_AFS_StoreStatus(&bp, attr);
1465
1466        *bp++ = 0;                              /* position of start of write */
1467        *bp++ = 0;
1468        *bp++ = 0;                              /* size of write */
1469        *bp++ = 0;
1470        *bp++ = htonl(attr->ia_size >> 32);     /* new file length */
1471        *bp++ = htonl((u32) attr->ia_size);
1472
1473        afs_use_fs_server(call, fc->cbi);
1474        trace_afs_make_fs_call(call, &vnode->fid);
1475        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1476}
1477
1478/*
1479 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1480 * so as to alter the file size also
1481 */
1482static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1483{
1484        struct afs_vnode *vnode = fc->vnode;
1485        struct afs_call *call;
1486        struct afs_net *net = afs_v2net(vnode);
1487        __be32 *bp;
1488
1489        _enter(",%x,{%x:%u},,",
1490               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1491
1492        ASSERT(attr->ia_valid & ATTR_SIZE);
1493        if (attr->ia_size >> 32)
1494                return afs_fs_setattr_size64(fc, attr);
1495
1496        call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,
1497                                   (4 + 6 + 3) * 4,
1498                                   (21 + 6) * 4);
1499        if (!call)
1500                return -ENOMEM;
1501
1502        call->key = fc->key;
1503        call->reply[0] = vnode;
1504        call->expected_version = vnode->status.data_version + 1;
1505
1506        /* marshall the parameters */
1507        bp = call->request;
1508        *bp++ = htonl(FSSTOREDATA);
1509        *bp++ = htonl(vnode->fid.vid);
1510        *bp++ = htonl(vnode->fid.vnode);
1511        *bp++ = htonl(vnode->fid.unique);
1512
1513        xdr_encode_AFS_StoreStatus(&bp, attr);
1514
1515        *bp++ = 0;                              /* position of start of write */
1516        *bp++ = 0;                              /* size of write */
1517        *bp++ = htonl(attr->ia_size);           /* new file length */
1518
1519        afs_use_fs_server(call, fc->cbi);
1520        trace_afs_make_fs_call(call, &vnode->fid);
1521        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1522}
1523
1524/*
1525 * set the attributes on a file, using FS.StoreData if there's a change in file
1526 * size, and FS.StoreStatus otherwise
1527 */
1528int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1529{
1530        struct afs_vnode *vnode = fc->vnode;
1531        struct afs_call *call;
1532        struct afs_net *net = afs_v2net(vnode);
1533        __be32 *bp;
1534
1535        if (attr->ia_valid & ATTR_SIZE)
1536                return afs_fs_setattr_size(fc, attr);
1537
1538        _enter(",%x,{%x:%u},,",
1539               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1540
1541        call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,
1542                                   (4 + 6) * 4,
1543                                   (21 + 6) * 4);
1544        if (!call)
1545                return -ENOMEM;
1546
1547        call->key = fc->key;
1548        call->reply[0] = vnode;
1549        call->expected_version = vnode->status.data_version;
1550
1551        /* marshall the parameters */
1552        bp = call->request;
1553        *bp++ = htonl(FSSTORESTATUS);
1554        *bp++ = htonl(vnode->fid.vid);
1555        *bp++ = htonl(vnode->fid.vnode);
1556        *bp++ = htonl(vnode->fid.unique);
1557
1558        xdr_encode_AFS_StoreStatus(&bp, attr);
1559
1560        afs_use_fs_server(call, fc->cbi);
1561        trace_afs_make_fs_call(call, &vnode->fid);
1562        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1563}
1564
1565/*
1566 * deliver reply data to an FS.GetVolumeStatus
1567 */
1568static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1569{
1570        const __be32 *bp;
1571        char *p;
1572        int ret;
1573
1574        _enter("{%u}", call->unmarshall);
1575
1576        switch (call->unmarshall) {
1577        case 0:
1578                call->offset = 0;
1579                call->unmarshall++;
1580
1581                /* extract the returned status record */
1582        case 1:
1583                _debug("extract status");
1584                ret = afs_extract_data(call, call->buffer,
1585                                       12 * 4, true);
1586                if (ret < 0)
1587                        return ret;
1588
1589                bp = call->buffer;
1590                xdr_decode_AFSFetchVolumeStatus(&bp, call->reply[1]);
1591                call->offset = 0;
1592                call->unmarshall++;
1593
1594                /* extract the volume name length */
1595        case 2:
1596                ret = afs_extract_data(call, &call->tmp, 4, true);
1597                if (ret < 0)
1598                        return ret;
1599
1600                call->count = ntohl(call->tmp);
1601                _debug("volname length: %u", call->count);
1602                if (call->count >= AFSNAMEMAX)
1603                        return afs_protocol_error(call, -EBADMSG);
1604                call->offset = 0;
1605                call->unmarshall++;
1606
1607                /* extract the volume name */
1608        case 3:
1609                _debug("extract volname");
1610                if (call->count > 0) {
1611                        ret = afs_extract_data(call, call->reply[2],
1612                                               call->count, true);
1613                        if (ret < 0)
1614                                return ret;
1615                }
1616
1617                p = call->reply[2];
1618                p[call->count] = 0;
1619                _debug("volname '%s'", p);
1620
1621                call->offset = 0;
1622                call->unmarshall++;
1623
1624                /* extract the volume name padding */
1625                if ((call->count & 3) == 0) {
1626                        call->unmarshall++;
1627                        goto no_volname_padding;
1628                }
1629                call->count = 4 - (call->count & 3);
1630
1631        case 4:
1632                ret = afs_extract_data(call, call->buffer,
1633                                       call->count, true);
1634                if (ret < 0)
1635                        return ret;
1636
1637                call->offset = 0;
1638                call->unmarshall++;
1639        no_volname_padding:
1640
1641                /* extract the offline message length */
1642        case 5:
1643                ret = afs_extract_data(call, &call->tmp, 4, true);
1644                if (ret < 0)
1645                        return ret;
1646
1647                call->count = ntohl(call->tmp);
1648                _debug("offline msg length: %u", call->count);
1649                if (call->count >= AFSNAMEMAX)
1650                        return afs_protocol_error(call, -EBADMSG);
1651                call->offset = 0;
1652                call->unmarshall++;
1653
1654                /* extract the offline message */
1655        case 6:
1656                _debug("extract offline");
1657                if (call->count > 0) {
1658                        ret = afs_extract_data(call, call->reply[2],
1659                                               call->count, true);
1660                        if (ret < 0)
1661                                return ret;
1662                }
1663
1664                p = call->reply[2];
1665                p[call->count] = 0;
1666                _debug("offline '%s'", p);
1667
1668                call->offset = 0;
1669                call->unmarshall++;
1670
1671                /* extract the offline message padding */
1672                if ((call->count & 3) == 0) {
1673                        call->unmarshall++;
1674                        goto no_offline_padding;
1675                }
1676                call->count = 4 - (call->count & 3);
1677
1678        case 7:
1679                ret = afs_extract_data(call, call->buffer,
1680                                       call->count, true);
1681                if (ret < 0)
1682                        return ret;
1683
1684                call->offset = 0;
1685                call->unmarshall++;
1686        no_offline_padding:
1687
1688                /* extract the message of the day length */
1689        case 8:
1690                ret = afs_extract_data(call, &call->tmp, 4, true);
1691                if (ret < 0)
1692                        return ret;
1693
1694                call->count = ntohl(call->tmp);
1695                _debug("motd length: %u", call->count);
1696                if (call->count >= AFSNAMEMAX)
1697                        return afs_protocol_error(call, -EBADMSG);
1698                call->offset = 0;
1699                call->unmarshall++;
1700
1701                /* extract the message of the day */
1702        case 9:
1703                _debug("extract motd");
1704                if (call->count > 0) {
1705                        ret = afs_extract_data(call, call->reply[2],
1706                                               call->count, true);
1707                        if (ret < 0)
1708                                return ret;
1709                }
1710
1711                p = call->reply[2];
1712                p[call->count] = 0;
1713                _debug("motd '%s'", p);
1714
1715                call->offset = 0;
1716                call->unmarshall++;
1717
1718                /* extract the message of the day padding */
1719                call->count = (4 - (call->count & 3)) & 3;
1720
1721        case 10:
1722                ret = afs_extract_data(call, call->buffer,
1723                                       call->count, false);
1724                if (ret < 0)
1725                        return ret;
1726
1727                call->offset = 0;
1728                call->unmarshall++;
1729        case 11:
1730                break;
1731        }
1732
1733        _leave(" = 0 [done]");
1734        return 0;
1735}
1736
1737/*
1738 * destroy an FS.GetVolumeStatus call
1739 */
1740static void afs_get_volume_status_call_destructor(struct afs_call *call)
1741{
1742        kfree(call->reply[2]);
1743        call->reply[2] = NULL;
1744        afs_flat_call_destructor(call);
1745}
1746
1747/*
1748 * FS.GetVolumeStatus operation type
1749 */
1750static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1751        .name           = "FS.GetVolumeStatus",
1752        .op             = afs_FS_GetVolumeStatus,
1753        .deliver        = afs_deliver_fs_get_volume_status,
1754        .destructor     = afs_get_volume_status_call_destructor,
1755};
1756
1757/*
1758 * fetch the status of a volume
1759 */
1760int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
1761                             struct afs_volume_status *vs)
1762{
1763        struct afs_vnode *vnode = fc->vnode;
1764        struct afs_call *call;
1765        struct afs_net *net = afs_v2net(vnode);
1766        __be32 *bp;
1767        void *tmpbuf;
1768
1769        _enter("");
1770
1771        tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1772        if (!tmpbuf)
1773                return -ENOMEM;
1774
1775        call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1776        if (!call) {
1777                kfree(tmpbuf);
1778                return -ENOMEM;
1779        }
1780
1781        call->key = fc->key;
1782        call->reply[0] = vnode;
1783        call->reply[1] = vs;
1784        call->reply[2] = tmpbuf;
1785
1786        /* marshall the parameters */
1787        bp = call->request;
1788        bp[0] = htonl(FSGETVOLUMESTATUS);
1789        bp[1] = htonl(vnode->fid.vid);
1790
1791        afs_use_fs_server(call, fc->cbi);
1792        trace_afs_make_fs_call(call, &vnode->fid);
1793        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1794}
1795
1796/*
1797 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1798 */
1799static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
1800{
1801        const __be32 *bp;
1802        int ret;
1803
1804        _enter("{%u}", call->unmarshall);
1805
1806        ret = afs_transfer_reply(call);
1807        if (ret < 0)
1808                return ret;
1809
1810        /* unmarshall the reply once we've received all of it */
1811        bp = call->buffer;
1812        /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1813
1814        _leave(" = 0 [done]");
1815        return 0;
1816}
1817
1818/*
1819 * FS.SetLock operation type
1820 */
1821static const struct afs_call_type afs_RXFSSetLock = {
1822        .name           = "FS.SetLock",
1823        .op             = afs_FS_SetLock,
1824        .deliver        = afs_deliver_fs_xxxx_lock,
1825        .destructor     = afs_flat_call_destructor,
1826};
1827
1828/*
1829 * FS.ExtendLock operation type
1830 */
1831static const struct afs_call_type afs_RXFSExtendLock = {
1832        .name           = "FS.ExtendLock",
1833        .op             = afs_FS_ExtendLock,
1834        .deliver        = afs_deliver_fs_xxxx_lock,
1835        .destructor     = afs_flat_call_destructor,
1836};
1837
1838/*
1839 * FS.ReleaseLock operation type
1840 */
1841static const struct afs_call_type afs_RXFSReleaseLock = {
1842        .name           = "FS.ReleaseLock",
1843        .op             = afs_FS_ReleaseLock,
1844        .deliver        = afs_deliver_fs_xxxx_lock,
1845        .destructor     = afs_flat_call_destructor,
1846};
1847
1848/*
1849 * Set a lock on a file
1850 */
1851int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1852{
1853        struct afs_vnode *vnode = fc->vnode;
1854        struct afs_call *call;
1855        struct afs_net *net = afs_v2net(vnode);
1856        __be32 *bp;
1857
1858        _enter("");
1859
1860        call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
1861        if (!call)
1862                return -ENOMEM;
1863
1864        call->key = fc->key;
1865        call->reply[0] = vnode;
1866
1867        /* marshall the parameters */
1868        bp = call->request;
1869        *bp++ = htonl(FSSETLOCK);
1870        *bp++ = htonl(vnode->fid.vid);
1871        *bp++ = htonl(vnode->fid.vnode);
1872        *bp++ = htonl(vnode->fid.unique);
1873        *bp++ = htonl(type);
1874
1875        afs_use_fs_server(call, fc->cbi);
1876        trace_afs_make_fs_call(call, &vnode->fid);
1877        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1878}
1879
1880/*
1881 * extend a lock on a file
1882 */
1883int afs_fs_extend_lock(struct afs_fs_cursor *fc)
1884{
1885        struct afs_vnode *vnode = fc->vnode;
1886        struct afs_call *call;
1887        struct afs_net *net = afs_v2net(vnode);
1888        __be32 *bp;
1889
1890        _enter("");
1891
1892        call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
1893        if (!call)
1894                return -ENOMEM;
1895
1896        call->key = fc->key;
1897        call->reply[0] = vnode;
1898
1899        /* marshall the parameters */
1900        bp = call->request;
1901        *bp++ = htonl(FSEXTENDLOCK);
1902        *bp++ = htonl(vnode->fid.vid);
1903        *bp++ = htonl(vnode->fid.vnode);
1904        *bp++ = htonl(vnode->fid.unique);
1905
1906        afs_use_fs_server(call, fc->cbi);
1907        trace_afs_make_fs_call(call, &vnode->fid);
1908        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1909}
1910
1911/*
1912 * release a lock on a file
1913 */
1914int afs_fs_release_lock(struct afs_fs_cursor *fc)
1915{
1916        struct afs_vnode *vnode = fc->vnode;
1917        struct afs_call *call;
1918        struct afs_net *net = afs_v2net(vnode);
1919        __be32 *bp;
1920
1921        _enter("");
1922
1923        call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1924        if (!call)
1925                return -ENOMEM;
1926
1927        call->key = fc->key;
1928        call->reply[0] = vnode;
1929
1930        /* marshall the parameters */
1931        bp = call->request;
1932        *bp++ = htonl(FSRELEASELOCK);
1933        *bp++ = htonl(vnode->fid.vid);
1934        *bp++ = htonl(vnode->fid.vnode);
1935        *bp++ = htonl(vnode->fid.unique);
1936
1937        afs_use_fs_server(call, fc->cbi);
1938        trace_afs_make_fs_call(call, &vnode->fid);
1939        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1940}
1941
1942/*
1943 * Deliver reply data to an FS.GiveUpAllCallBacks operation.
1944 */
1945static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)
1946{
1947        return afs_transfer_reply(call);
1948}
1949
1950/*
1951 * FS.GiveUpAllCallBacks operation type
1952 */
1953static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
1954        .name           = "FS.GiveUpAllCallBacks",
1955        .op             = afs_FS_GiveUpAllCallBacks,
1956        .deliver        = afs_deliver_fs_give_up_all_callbacks,
1957        .destructor     = afs_flat_call_destructor,
1958};
1959
1960/*
1961 * Flush all the callbacks we have on a server.
1962 */
1963int afs_fs_give_up_all_callbacks(struct afs_net *net,
1964                                 struct afs_server *server,
1965                                 struct afs_addr_cursor *ac,
1966                                 struct key *key)
1967{
1968        struct afs_call *call;
1969        __be32 *bp;
1970
1971        _enter("");
1972
1973        call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);
1974        if (!call)
1975                return -ENOMEM;
1976
1977        call->key = key;
1978
1979        /* marshall the parameters */
1980        bp = call->request;
1981        *bp++ = htonl(FSGIVEUPALLCALLBACKS);
1982
1983        /* Can't take a ref on server */
1984        return afs_make_call(ac, call, GFP_NOFS, false);
1985}
1986
1987/*
1988 * Deliver reply data to an FS.GetCapabilities operation.
1989 */
1990static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1991{
1992        u32 count;
1993        int ret;
1994
1995        _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count);
1996
1997again:
1998        switch (call->unmarshall) {
1999        case 0:
2000                call->offset = 0;
2001                call->unmarshall++;
2002
2003                /* Extract the capabilities word count */
2004        case 1:
2005                ret = afs_extract_data(call, &call->tmp,
2006                                       1 * sizeof(__be32),
2007                                       true);
2008                if (ret < 0)
2009                        return ret;
2010
2011                count = ntohl(call->tmp);
2012
2013                call->count = count;
2014                call->count2 = count;
2015                call->offset = 0;
2016                call->unmarshall++;
2017
2018                /* Extract capabilities words */
2019        case 2:
2020                count = min(call->count, 16U);
2021                ret = afs_extract_data(call, call->buffer,
2022                                       count * sizeof(__be32),
2023                                       call->count > 16);
2024                if (ret < 0)
2025                        return ret;
2026
2027                /* TODO: Examine capabilities */
2028
2029                call->count -= count;
2030                if (call->count > 0)
2031                        goto again;
2032                call->offset = 0;
2033                call->unmarshall++;
2034                break;
2035        }
2036
2037        _leave(" = 0 [done]");
2038        return 0;
2039}
2040
2041/*
2042 * FS.GetCapabilities operation type
2043 */
2044static const struct afs_call_type afs_RXFSGetCapabilities = {
2045        .name           = "FS.GetCapabilities",
2046        .op             = afs_FS_GetCapabilities,
2047        .deliver        = afs_deliver_fs_get_capabilities,
2048        .destructor     = afs_flat_call_destructor,
2049};
2050
2051/*
2052 * Probe a fileserver for the capabilities that it supports.  This can
2053 * return up to 196 words.
2054 */
2055int afs_fs_get_capabilities(struct afs_net *net,
2056                            struct afs_server *server,
2057                            struct afs_addr_cursor *ac,
2058                            struct key *key)
2059{
2060        struct afs_call *call;
2061        __be32 *bp;
2062
2063        _enter("");
2064
2065        call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
2066        if (!call)
2067                return -ENOMEM;
2068
2069        call->key = key;
2070
2071        /* marshall the parameters */
2072        bp = call->request;
2073        *bp++ = htonl(FSGETCAPABILITIES);
2074
2075        /* Can't take a ref on server */
2076        trace_afs_make_fs_call(call, NULL);
2077        return afs_make_call(ac, call, GFP_NOFS, false);
2078}
2079
2080/*
2081 * Deliver reply data to an FS.FetchStatus with no vnode.
2082 */
2083static int afs_deliver_fs_fetch_status(struct afs_call *call)
2084{
2085        struct afs_file_status *status = call->reply[1];
2086        struct afs_callback *callback = call->reply[2];
2087        struct afs_volsync *volsync = call->reply[3];
2088        struct afs_vnode *vnode = call->reply[0];
2089        const __be32 *bp;
2090        int ret;
2091
2092        ret = afs_transfer_reply(call);
2093        if (ret < 0)
2094                return ret;
2095
2096        _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
2097
2098        /* unmarshall the reply once we've received all of it */
2099        bp = call->buffer;
2100        xdr_decode_AFSFetchStatus(call, &bp, status, vnode,
2101                                  &call->expected_version, NULL);
2102        callback[call->count].version   = ntohl(bp[0]);
2103        callback[call->count].expiry    = ntohl(bp[1]);
2104        callback[call->count].type      = ntohl(bp[2]);
2105        if (vnode)
2106                xdr_decode_AFSCallBack(call, vnode, &bp);
2107        else
2108                bp += 3;
2109        if (volsync)
2110                xdr_decode_AFSVolSync(&bp, volsync);
2111
2112        _leave(" = 0 [done]");
2113        return 0;
2114}
2115
2116/*
2117 * FS.FetchStatus operation type
2118 */
2119static const struct afs_call_type afs_RXFSFetchStatus = {
2120        .name           = "FS.FetchStatus",
2121        .op             = afs_FS_FetchStatus,
2122        .deliver        = afs_deliver_fs_fetch_status,
2123        .destructor     = afs_flat_call_destructor,
2124};
2125
2126/*
2127 * Fetch the status information for a fid without needing a vnode handle.
2128 */
2129int afs_fs_fetch_status(struct afs_fs_cursor *fc,
2130                        struct afs_net *net,
2131                        struct afs_fid *fid,
2132                        struct afs_file_status *status,
2133                        struct afs_callback *callback,
2134                        struct afs_volsync *volsync)
2135{
2136        struct afs_call *call;
2137        __be32 *bp;
2138
2139        _enter(",%x,{%x:%u},,",
2140               key_serial(fc->key), fid->vid, fid->vnode);
2141
2142        call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
2143        if (!call) {
2144                fc->ac.error = -ENOMEM;
2145                return -ENOMEM;
2146        }
2147
2148        call->key = fc->key;
2149        call->reply[0] = NULL; /* vnode for fid[0] */
2150        call->reply[1] = status;
2151        call->reply[2] = callback;
2152        call->reply[3] = volsync;
2153        call->expected_version = 1; /* vnode->status.data_version */
2154
2155        /* marshall the parameters */
2156        bp = call->request;
2157        bp[0] = htonl(FSFETCHSTATUS);
2158        bp[1] = htonl(fid->vid);
2159        bp[2] = htonl(fid->vnode);
2160        bp[3] = htonl(fid->unique);
2161
2162        call->cb_break = fc->cb_break;
2163        afs_use_fs_server(call, fc->cbi);
2164        trace_afs_make_fs_call(call, fid);
2165        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2166}
2167
2168/*
2169 * Deliver reply data to an FS.InlineBulkStatus call
2170 */
2171static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
2172{
2173        struct afs_file_status *statuses;
2174        struct afs_callback *callbacks;
2175        struct afs_vnode *vnode = call->reply[0];
2176        const __be32 *bp;
2177        u32 tmp;
2178        int ret;
2179
2180        _enter("{%u}", call->unmarshall);
2181
2182        switch (call->unmarshall) {
2183        case 0:
2184                call->offset = 0;
2185                call->unmarshall++;
2186
2187                /* Extract the file status count and array in two steps */
2188        case 1:
2189                _debug("extract status count");
2190                ret = afs_extract_data(call, &call->tmp, 4, true);
2191                if (ret < 0)
2192                        return ret;
2193
2194                tmp = ntohl(call->tmp);
2195                _debug("status count: %u/%u", tmp, call->count2);
2196                if (tmp != call->count2)
2197                        return afs_protocol_error(call, -EBADMSG);
2198
2199                call->count = 0;
2200                call->unmarshall++;
2201        more_counts:
2202                call->offset = 0;
2203
2204        case 2:
2205                _debug("extract status array %u", call->count);
2206                ret = afs_extract_data(call, call->buffer, 21 * 4, true);
2207                if (ret < 0)
2208                        return ret;
2209
2210                bp = call->buffer;
2211                statuses = call->reply[1];
2212                if (xdr_decode_AFSFetchStatus(call, &bp, &statuses[call->count],
2213                                              call->count == 0 ? vnode : NULL,
2214                                              NULL, NULL) < 0)
2215                        return afs_protocol_error(call, -EBADMSG);
2216
2217                call->count++;
2218                if (call->count < call->count2)
2219                        goto more_counts;
2220
2221                call->count = 0;
2222                call->unmarshall++;
2223                call->offset = 0;
2224
2225                /* Extract the callback count and array in two steps */
2226        case 3:
2227                _debug("extract CB count");
2228                ret = afs_extract_data(call, &call->tmp, 4, true);
2229                if (ret < 0)
2230                        return ret;
2231
2232                tmp = ntohl(call->tmp);
2233                _debug("CB count: %u", tmp);
2234                if (tmp != call->count2)
2235                        return afs_protocol_error(call, -EBADMSG);
2236                call->count = 0;
2237                call->unmarshall++;
2238        more_cbs:
2239                call->offset = 0;
2240
2241        case 4:
2242                _debug("extract CB array");
2243                ret = afs_extract_data(call, call->buffer, 3 * 4, true);
2244                if (ret < 0)
2245                        return ret;
2246
2247                _debug("unmarshall CB array");
2248                bp = call->buffer;
2249                callbacks = call->reply[2];
2250                callbacks[call->count].version  = ntohl(bp[0]);
2251                callbacks[call->count].expiry   = ntohl(bp[1]);
2252                callbacks[call->count].type     = ntohl(bp[2]);
2253                statuses = call->reply[1];
2254                if (call->count == 0 && vnode && statuses[0].abort_code == 0)
2255                        xdr_decode_AFSCallBack(call, vnode, &bp);
2256                call->count++;
2257                if (call->count < call->count2)
2258                        goto more_cbs;
2259
2260                call->offset = 0;
2261                call->unmarshall++;
2262
2263        case 5:
2264                ret = afs_extract_data(call, call->buffer, 6 * 4, false);
2265                if (ret < 0)
2266                        return ret;
2267
2268                bp = call->buffer;
2269                if (call->reply[3])
2270                        xdr_decode_AFSVolSync(&bp, call->reply[3]);
2271
2272                call->offset = 0;
2273                call->unmarshall++;
2274
2275        case 6:
2276                break;
2277        }
2278
2279        _leave(" = 0 [done]");
2280        return 0;
2281}
2282
2283/*
2284 * FS.InlineBulkStatus operation type
2285 */
2286static const struct afs_call_type afs_RXFSInlineBulkStatus = {
2287        .name           = "FS.InlineBulkStatus",
2288        .op             = afs_FS_InlineBulkStatus,
2289        .deliver        = afs_deliver_fs_inline_bulk_status,
2290        .destructor     = afs_flat_call_destructor,
2291};
2292
2293/*
2294 * Fetch the status information for up to 50 files
2295 */
2296int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2297                              struct afs_net *net,
2298                              struct afs_fid *fids,
2299                              struct afs_file_status *statuses,
2300                              struct afs_callback *callbacks,
2301                              unsigned int nr_fids,
2302                              struct afs_volsync *volsync)
2303{
2304        struct afs_call *call;
2305        __be32 *bp;
2306        int i;
2307
2308        _enter(",%x,{%x:%u},%u",
2309               key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2310
2311        call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus,
2312                                   (2 + nr_fids * 3) * 4,
2313                                   21 * 4);
2314        if (!call) {
2315                fc->ac.error = -ENOMEM;
2316                return -ENOMEM;
2317        }
2318
2319        call->key = fc->key;
2320        call->reply[0] = NULL; /* vnode for fid[0] */
2321        call->reply[1] = statuses;
2322        call->reply[2] = callbacks;
2323        call->reply[3] = volsync;
2324        call->count2 = nr_fids;
2325
2326        /* marshall the parameters */
2327        bp = call->request;
2328        *bp++ = htonl(FSINLINEBULKSTATUS);
2329        *bp++ = htonl(nr_fids);
2330        for (i = 0; i < nr_fids; i++) {
2331                *bp++ = htonl(fids[i].vid);
2332                *bp++ = htonl(fids[i].vnode);
2333                *bp++ = htonl(fids[i].unique);
2334        }
2335
2336        call->cb_break = fc->cb_break;
2337        afs_use_fs_server(call, fc->cbi);
2338        trace_afs_make_fs_call(call, &fids[0]);
2339        return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2340}
2341