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