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