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 "internal.h"
  17#include "afs_fs.h"
  18
  19/*
  20 * decode an AFSFid block
  21 */
  22static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
  23{
  24        const __be32 *bp = *_bp;
  25
  26        fid->vid                = ntohl(*bp++);
  27        fid->vnode              = ntohl(*bp++);
  28        fid->unique             = ntohl(*bp++);
  29        *_bp = bp;
  30}
  31
  32/*
  33 * decode an AFSFetchStatus block
  34 */
  35static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
  36                                      struct afs_file_status *status,
  37                                      struct afs_vnode *vnode,
  38                                      afs_dataversion_t *store_version)
  39{
  40        afs_dataversion_t expected_version;
  41        const __be32 *bp = *_bp;
  42        umode_t mode;
  43        u64 data_version, size;
  44        u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
  45        kuid_t owner;
  46        kgid_t group;
  47
  48#define EXTRACT(DST)                            \
  49        do {                                    \
  50                u32 x = ntohl(*bp++);           \
  51                changed |= DST - x;             \
  52                DST = x;                        \
  53        } while (0)
  54
  55        status->if_version = ntohl(*bp++);
  56        EXTRACT(status->type);
  57        EXTRACT(status->nlink);
  58        size = ntohl(*bp++);
  59        data_version = ntohl(*bp++);
  60        EXTRACT(status->author);
  61        owner = make_kuid(&init_user_ns, ntohl(*bp++));
  62        changed |= !uid_eq(owner, status->owner);
  63        status->owner = owner;
  64        EXTRACT(status->caller_access); /* call ticket dependent */
  65        EXTRACT(status->anon_access);
  66        EXTRACT(status->mode);
  67        EXTRACT(status->parent.vnode);
  68        EXTRACT(status->parent.unique);
  69        bp++; /* seg size */
  70        status->mtime_client = ntohl(*bp++);
  71        status->mtime_server = ntohl(*bp++);
  72        group = make_kgid(&init_user_ns, ntohl(*bp++));
  73        changed |= !gid_eq(group, status->group);
  74        status->group = group;
  75        bp++; /* sync counter */
  76        data_version |= (u64) ntohl(*bp++) << 32;
  77        EXTRACT(status->lock_count);
  78        size |= (u64) ntohl(*bp++) << 32;
  79        bp++; /* spare 4 */
  80        *_bp = bp;
  81
  82        if (size != status->size) {
  83                status->size = size;
  84                changed |= true;
  85        }
  86        status->mode &= S_IALLUGO;
  87
  88        _debug("vnode time %lx, %lx",
  89               status->mtime_client, status->mtime_server);
  90
  91        if (vnode) {
  92                status->parent.vid = vnode->fid.vid;
  93                if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
  94                        _debug("vnode changed");
  95                        i_size_write(&vnode->vfs_inode, size);
  96                        vnode->vfs_inode.i_uid = status->owner;
  97                        vnode->vfs_inode.i_gid = status->group;
  98                        vnode->vfs_inode.i_generation = vnode->fid.unique;
  99                        set_nlink(&vnode->vfs_inode, status->nlink);
 100
 101                        mode = vnode->vfs_inode.i_mode;
 102                        mode &= ~S_IALLUGO;
 103                        mode |= status->mode;
 104                        barrier();
 105                        vnode->vfs_inode.i_mode = mode;
 106                }
 107
 108                vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server;
 109                vnode->vfs_inode.i_mtime        = vnode->vfs_inode.i_ctime;
 110                vnode->vfs_inode.i_atime        = vnode->vfs_inode.i_ctime;
 111                vnode->vfs_inode.i_version      = data_version;
 112        }
 113
 114        expected_version = status->data_version;
 115        if (store_version)
 116                expected_version = *store_version;
 117
 118        if (expected_version != data_version) {
 119                status->data_version = data_version;
 120                if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
 121                        _debug("vnode modified %llx on {%x:%u}",
 122                               (unsigned long long) data_version,
 123                               vnode->fid.vid, vnode->fid.vnode);
 124                        set_bit(AFS_VNODE_MODIFIED, &vnode->flags);
 125                        set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
 126                }
 127        } else if (store_version) {
 128                status->data_version = data_version;
 129        }
 130}
 131
 132/*
 133 * decode an AFSCallBack block
 134 */
 135static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode)
 136{
 137        const __be32 *bp = *_bp;
 138
 139        vnode->cb_version       = ntohl(*bp++);
 140        vnode->cb_expiry        = ntohl(*bp++);
 141        vnode->cb_type          = ntohl(*bp++);
 142        vnode->cb_expires       = vnode->cb_expiry + get_seconds();
 143        *_bp = bp;
 144}
 145
 146static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
 147                                       struct afs_callback *cb)
 148{
 149        const __be32 *bp = *_bp;
 150
 151        cb->version     = ntohl(*bp++);
 152        cb->expiry      = ntohl(*bp++);
 153        cb->type        = ntohl(*bp++);
 154        *_bp = bp;
 155}
 156
 157/*
 158 * decode an AFSVolSync block
 159 */
 160static void xdr_decode_AFSVolSync(const __be32 **_bp,
 161                                  struct afs_volsync *volsync)
 162{
 163        const __be32 *bp = *_bp;
 164
 165        volsync->creation = ntohl(*bp++);
 166        bp++; /* spare2 */
 167        bp++; /* spare3 */
 168        bp++; /* spare4 */
 169        bp++; /* spare5 */
 170        bp++; /* spare6 */
 171        *_bp = bp;
 172}
 173
 174/*
 175 * encode the requested attributes into an AFSStoreStatus block
 176 */
 177static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
 178{
 179        __be32 *bp = *_bp;
 180        u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
 181
 182        mask = 0;
 183        if (attr->ia_valid & ATTR_MTIME) {
 184                mask |= AFS_SET_MTIME;
 185                mtime = attr->ia_mtime.tv_sec;
 186        }
 187
 188        if (attr->ia_valid & ATTR_UID) {
 189                mask |= AFS_SET_OWNER;
 190                owner = from_kuid(&init_user_ns, attr->ia_uid);
 191        }
 192
 193        if (attr->ia_valid & ATTR_GID) {
 194                mask |= AFS_SET_GROUP;
 195                group = from_kgid(&init_user_ns, attr->ia_gid);
 196        }
 197
 198        if (attr->ia_valid & ATTR_MODE) {
 199                mask |= AFS_SET_MODE;
 200                mode = attr->ia_mode & S_IALLUGO;
 201        }
 202
 203        *bp++ = htonl(mask);
 204        *bp++ = htonl(mtime);
 205        *bp++ = htonl(owner);
 206        *bp++ = htonl(group);
 207        *bp++ = htonl(mode);
 208        *bp++ = 0;              /* segment size */
 209        *_bp = bp;
 210}
 211
 212/*
 213 * decode an AFSFetchVolumeStatus block
 214 */
 215static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
 216                                            struct afs_volume_status *vs)
 217{
 218        const __be32 *bp = *_bp;
 219
 220        vs->vid                 = ntohl(*bp++);
 221        vs->parent_id           = ntohl(*bp++);
 222        vs->online              = ntohl(*bp++);
 223        vs->in_service          = ntohl(*bp++);
 224        vs->blessed             = ntohl(*bp++);
 225        vs->needs_salvage       = ntohl(*bp++);
 226        vs->type                = ntohl(*bp++);
 227        vs->min_quota           = ntohl(*bp++);
 228        vs->max_quota           = ntohl(*bp++);
 229        vs->blocks_in_use       = ntohl(*bp++);
 230        vs->part_blocks_avail   = ntohl(*bp++);
 231        vs->part_max_blocks     = ntohl(*bp++);
 232        *_bp = bp;
 233}
 234
 235/*
 236 * deliver reply data to an FS.FetchStatus
 237 */
 238static int afs_deliver_fs_fetch_status(struct afs_call *call)
 239{
 240        struct afs_vnode *vnode = call->reply;
 241        const __be32 *bp;
 242        int ret;
 243
 244        _enter("");
 245
 246        ret = afs_transfer_reply(call);
 247        if (ret < 0)
 248                return ret;
 249
 250        /* unmarshall the reply once we've received all of it */
 251        bp = call->buffer;
 252        xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
 253        xdr_decode_AFSCallBack(&bp, vnode);
 254        if (call->reply2)
 255                xdr_decode_AFSVolSync(&bp, call->reply2);
 256
 257        _leave(" = 0 [done]");
 258        return 0;
 259}
 260
 261/*
 262 * FS.FetchStatus operation type
 263 */
 264static const struct afs_call_type afs_RXFSFetchStatus = {
 265        .name           = "FS.FetchStatus",
 266        .deliver        = afs_deliver_fs_fetch_status,
 267        .abort_to_error = afs_abort_to_error,
 268        .destructor     = afs_flat_call_destructor,
 269};
 270
 271/*
 272 * fetch the status information for a file
 273 */
 274int afs_fs_fetch_file_status(struct afs_server *server,
 275                             struct key *key,
 276                             struct afs_vnode *vnode,
 277                             struct afs_volsync *volsync,
 278                             const struct afs_wait_mode *wait_mode)
 279{
 280        struct afs_call *call;
 281        __be32 *bp;
 282
 283        _enter(",%x,{%x:%u},,",
 284               key_serial(key), vnode->fid.vid, vnode->fid.vnode);
 285
 286        call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
 287        if (!call)
 288                return -ENOMEM;
 289
 290        call->key = key;
 291        call->reply = vnode;
 292        call->reply2 = volsync;
 293        call->service_id = FS_SERVICE;
 294        call->port = htons(AFS_FS_PORT);
 295
 296        /* marshall the parameters */
 297        bp = call->request;
 298        bp[0] = htonl(FSFETCHSTATUS);
 299        bp[1] = htonl(vnode->fid.vid);
 300        bp[2] = htonl(vnode->fid.vnode);
 301        bp[3] = htonl(vnode->fid.unique);
 302
 303        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 304}
 305
 306/*
 307 * deliver reply data to an FS.FetchData
 308 */
 309static int afs_deliver_fs_fetch_data(struct afs_call *call)
 310{
 311        struct afs_vnode *vnode = call->reply;
 312        const __be32 *bp;
 313        struct page *page;
 314        void *buffer;
 315        int ret;
 316
 317        _enter("{%u}", call->unmarshall);
 318
 319        switch (call->unmarshall) {
 320        case 0:
 321                call->offset = 0;
 322                call->unmarshall++;
 323                if (call->operation_ID != FSFETCHDATA64) {
 324                        call->unmarshall++;
 325                        goto no_msw;
 326                }
 327
 328                /* extract the upper part of the returned data length of an
 329                 * FSFETCHDATA64 op (which should always be 0 using this
 330                 * client) */
 331        case 1:
 332                _debug("extract data length (MSW)");
 333                ret = afs_extract_data(call, &call->tmp, 4, true);
 334                if (ret < 0)
 335                        return ret;
 336
 337                call->count = ntohl(call->tmp);
 338                _debug("DATA length MSW: %u", call->count);
 339                if (call->count > 0)
 340                        return -EBADMSG;
 341                call->offset = 0;
 342                call->unmarshall++;
 343
 344        no_msw:
 345                /* extract the returned data length */
 346        case 2:
 347                _debug("extract data length");
 348                ret = afs_extract_data(call, &call->tmp, 4, true);
 349                if (ret < 0)
 350                        return ret;
 351
 352                call->count = ntohl(call->tmp);
 353                _debug("DATA length: %u", call->count);
 354                if (call->count > PAGE_SIZE)
 355                        return -EBADMSG;
 356                call->offset = 0;
 357                call->unmarshall++;
 358
 359                /* extract the returned data */
 360        case 3:
 361                _debug("extract data");
 362                if (call->count > 0) {
 363                        page = call->reply3;
 364                        buffer = kmap(page);
 365                        ret = afs_extract_data(call, buffer,
 366                                               call->count, true);
 367                        kunmap(page);
 368                        if (ret < 0)
 369                                return ret;
 370                }
 371
 372                call->offset = 0;
 373                call->unmarshall++;
 374
 375                /* extract the metadata */
 376        case 4:
 377                ret = afs_extract_data(call, call->buffer,
 378                                       (21 + 3 + 6) * 4, false);
 379                if (ret < 0)
 380                        return ret;
 381
 382                bp = call->buffer;
 383                xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
 384                xdr_decode_AFSCallBack(&bp, vnode);
 385                if (call->reply2)
 386                        xdr_decode_AFSVolSync(&bp, call->reply2);
 387
 388                call->offset = 0;
 389                call->unmarshall++;
 390
 391        case 5:
 392                break;
 393        }
 394
 395        if (call->count < PAGE_SIZE) {
 396                _debug("clear");
 397                page = call->reply3;
 398                buffer = kmap(page);
 399                memset(buffer + call->count, 0, PAGE_SIZE - call->count);
 400                kunmap(page);
 401        }
 402
 403        _leave(" = 0 [done]");
 404        return 0;
 405}
 406
 407/*
 408 * FS.FetchData operation type
 409 */
 410static const struct afs_call_type afs_RXFSFetchData = {
 411        .name           = "FS.FetchData",
 412        .deliver        = afs_deliver_fs_fetch_data,
 413        .abort_to_error = afs_abort_to_error,
 414        .destructor     = afs_flat_call_destructor,
 415};
 416
 417static const struct afs_call_type afs_RXFSFetchData64 = {
 418        .name           = "FS.FetchData64",
 419        .deliver        = afs_deliver_fs_fetch_data,
 420        .abort_to_error = afs_abort_to_error,
 421        .destructor     = afs_flat_call_destructor,
 422};
 423
 424/*
 425 * fetch data from a very large file
 426 */
 427static int afs_fs_fetch_data64(struct afs_server *server,
 428                               struct key *key,
 429                               struct afs_vnode *vnode,
 430                               off_t offset, size_t length,
 431                               struct page *buffer,
 432                               const struct afs_wait_mode *wait_mode)
 433{
 434        struct afs_call *call;
 435        __be32 *bp;
 436
 437        _enter("");
 438
 439        ASSERTCMP(length, <, ULONG_MAX);
 440
 441        call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
 442        if (!call)
 443                return -ENOMEM;
 444
 445        call->key = key;
 446        call->reply = vnode;
 447        call->reply2 = NULL; /* volsync */
 448        call->reply3 = buffer;
 449        call->service_id = FS_SERVICE;
 450        call->port = htons(AFS_FS_PORT);
 451        call->operation_ID = FSFETCHDATA64;
 452
 453        /* marshall the parameters */
 454        bp = call->request;
 455        bp[0] = htonl(FSFETCHDATA64);
 456        bp[1] = htonl(vnode->fid.vid);
 457        bp[2] = htonl(vnode->fid.vnode);
 458        bp[3] = htonl(vnode->fid.unique);
 459        bp[4] = htonl(upper_32_bits(offset));
 460        bp[5] = htonl((u32) offset);
 461        bp[6] = 0;
 462        bp[7] = htonl((u32) length);
 463
 464        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 465}
 466
 467/*
 468 * fetch data from a file
 469 */
 470int afs_fs_fetch_data(struct afs_server *server,
 471                      struct key *key,
 472                      struct afs_vnode *vnode,
 473                      off_t offset, size_t length,
 474                      struct page *buffer,
 475                      const struct afs_wait_mode *wait_mode)
 476{
 477        struct afs_call *call;
 478        __be32 *bp;
 479
 480        if (upper_32_bits(offset) || upper_32_bits(offset + length))
 481                return afs_fs_fetch_data64(server, key, vnode, offset, length,
 482                                           buffer, wait_mode);
 483
 484        _enter("");
 485
 486        call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
 487        if (!call)
 488                return -ENOMEM;
 489
 490        call->key = key;
 491        call->reply = vnode;
 492        call->reply2 = NULL; /* volsync */
 493        call->reply3 = buffer;
 494        call->service_id = FS_SERVICE;
 495        call->port = htons(AFS_FS_PORT);
 496        call->operation_ID = FSFETCHDATA;
 497
 498        /* marshall the parameters */
 499        bp = call->request;
 500        bp[0] = htonl(FSFETCHDATA);
 501        bp[1] = htonl(vnode->fid.vid);
 502        bp[2] = htonl(vnode->fid.vnode);
 503        bp[3] = htonl(vnode->fid.unique);
 504        bp[4] = htonl(offset);
 505        bp[5] = htonl(length);
 506
 507        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 508}
 509
 510/*
 511 * deliver reply data to an FS.GiveUpCallBacks
 512 */
 513static int afs_deliver_fs_give_up_callbacks(struct afs_call *call)
 514{
 515        _enter("");
 516
 517        /* shouldn't be any reply data */
 518        return afs_extract_data(call, NULL, 0, false);
 519}
 520
 521/*
 522 * FS.GiveUpCallBacks operation type
 523 */
 524static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
 525        .name           = "FS.GiveUpCallBacks",
 526        .deliver        = afs_deliver_fs_give_up_callbacks,
 527        .abort_to_error = afs_abort_to_error,
 528        .destructor     = afs_flat_call_destructor,
 529};
 530
 531/*
 532 * give up a set of callbacks
 533 * - the callbacks are held in the server->cb_break ring
 534 */
 535int afs_fs_give_up_callbacks(struct afs_server *server,
 536                             const struct afs_wait_mode *wait_mode)
 537{
 538        struct afs_call *call;
 539        size_t ncallbacks;
 540        __be32 *bp, *tp;
 541        int loop;
 542
 543        ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
 544                              ARRAY_SIZE(server->cb_break));
 545
 546        _enter("{%zu},", ncallbacks);
 547
 548        if (ncallbacks == 0)
 549                return 0;
 550        if (ncallbacks > AFSCBMAX)
 551                ncallbacks = AFSCBMAX;
 552
 553        _debug("break %zu callbacks", ncallbacks);
 554
 555        call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
 556                                   12 + ncallbacks * 6 * 4, 0);
 557        if (!call)
 558                return -ENOMEM;
 559
 560        call->service_id = FS_SERVICE;
 561        call->port = htons(AFS_FS_PORT);
 562
 563        /* marshall the parameters */
 564        bp = call->request;
 565        tp = bp + 2 + ncallbacks * 3;
 566        *bp++ = htonl(FSGIVEUPCALLBACKS);
 567        *bp++ = htonl(ncallbacks);
 568        *tp++ = htonl(ncallbacks);
 569
 570        atomic_sub(ncallbacks, &server->cb_break_n);
 571        for (loop = ncallbacks; loop > 0; loop--) {
 572                struct afs_callback *cb =
 573                        &server->cb_break[server->cb_break_tail];
 574
 575                *bp++ = htonl(cb->fid.vid);
 576                *bp++ = htonl(cb->fid.vnode);
 577                *bp++ = htonl(cb->fid.unique);
 578                *tp++ = htonl(cb->version);
 579                *tp++ = htonl(cb->expiry);
 580                *tp++ = htonl(cb->type);
 581                smp_mb();
 582                server->cb_break_tail =
 583                        (server->cb_break_tail + 1) &
 584                        (ARRAY_SIZE(server->cb_break) - 1);
 585        }
 586
 587        ASSERT(ncallbacks > 0);
 588        wake_up_nr(&server->cb_break_waitq, ncallbacks);
 589
 590        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 591}
 592
 593/*
 594 * deliver reply data to an FS.CreateFile or an FS.MakeDir
 595 */
 596static int afs_deliver_fs_create_vnode(struct afs_call *call)
 597{
 598        struct afs_vnode *vnode = call->reply;
 599        const __be32 *bp;
 600        int ret;
 601
 602        _enter("{%u}", call->unmarshall);
 603
 604        ret = afs_transfer_reply(call);
 605        if (ret < 0)
 606                return ret;
 607
 608        /* unmarshall the reply once we've received all of it */
 609        bp = call->buffer;
 610        xdr_decode_AFSFid(&bp, call->reply2);
 611        xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
 612        xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
 613        xdr_decode_AFSCallBack_raw(&bp, call->reply4);
 614        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
 615
 616        _leave(" = 0 [done]");
 617        return 0;
 618}
 619
 620/*
 621 * FS.CreateFile and FS.MakeDir operation type
 622 */
 623static const struct afs_call_type afs_RXFSCreateXXXX = {
 624        .name           = "FS.CreateXXXX",
 625        .deliver        = afs_deliver_fs_create_vnode,
 626        .abort_to_error = afs_abort_to_error,
 627        .destructor     = afs_flat_call_destructor,
 628};
 629
 630/*
 631 * create a file or make a directory
 632 */
 633int afs_fs_create(struct afs_server *server,
 634                  struct key *key,
 635                  struct afs_vnode *vnode,
 636                  const char *name,
 637                  umode_t mode,
 638                  struct afs_fid *newfid,
 639                  struct afs_file_status *newstatus,
 640                  struct afs_callback *newcb,
 641                  const struct afs_wait_mode *wait_mode)
 642{
 643        struct afs_call *call;
 644        size_t namesz, reqsz, padsz;
 645        __be32 *bp;
 646
 647        _enter("");
 648
 649        namesz = strlen(name);
 650        padsz = (4 - (namesz & 3)) & 3;
 651        reqsz = (5 * 4) + namesz + padsz + (6 * 4);
 652
 653        call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
 654                                   (3 + 21 + 21 + 3 + 6) * 4);
 655        if (!call)
 656                return -ENOMEM;
 657
 658        call->key = key;
 659        call->reply = vnode;
 660        call->reply2 = newfid;
 661        call->reply3 = newstatus;
 662        call->reply4 = newcb;
 663        call->service_id = FS_SERVICE;
 664        call->port = htons(AFS_FS_PORT);
 665
 666        /* marshall the parameters */
 667        bp = call->request;
 668        *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
 669        *bp++ = htonl(vnode->fid.vid);
 670        *bp++ = htonl(vnode->fid.vnode);
 671        *bp++ = htonl(vnode->fid.unique);
 672        *bp++ = htonl(namesz);
 673        memcpy(bp, name, namesz);
 674        bp = (void *) bp + namesz;
 675        if (padsz > 0) {
 676                memset(bp, 0, padsz);
 677                bp = (void *) bp + padsz;
 678        }
 679        *bp++ = htonl(AFS_SET_MODE);
 680        *bp++ = 0; /* mtime */
 681        *bp++ = 0; /* owner */
 682        *bp++ = 0; /* group */
 683        *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
 684        *bp++ = 0; /* segment size */
 685
 686        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 687}
 688
 689/*
 690 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
 691 */
 692static int afs_deliver_fs_remove(struct afs_call *call)
 693{
 694        struct afs_vnode *vnode = call->reply;
 695        const __be32 *bp;
 696        int ret;
 697
 698        _enter("{%u}", call->unmarshall);
 699
 700        ret = afs_transfer_reply(call);
 701        if (ret < 0)
 702                return ret;
 703
 704        /* unmarshall the reply once we've received all of it */
 705        bp = call->buffer;
 706        xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
 707        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
 708
 709        _leave(" = 0 [done]");
 710        return 0;
 711}
 712
 713/*
 714 * FS.RemoveDir/FS.RemoveFile operation type
 715 */
 716static const struct afs_call_type afs_RXFSRemoveXXXX = {
 717        .name           = "FS.RemoveXXXX",
 718        .deliver        = afs_deliver_fs_remove,
 719        .abort_to_error = afs_abort_to_error,
 720        .destructor     = afs_flat_call_destructor,
 721};
 722
 723/*
 724 * remove a file or directory
 725 */
 726int afs_fs_remove(struct afs_server *server,
 727                  struct key *key,
 728                  struct afs_vnode *vnode,
 729                  const char *name,
 730                  bool isdir,
 731                  const struct afs_wait_mode *wait_mode)
 732{
 733        struct afs_call *call;
 734        size_t namesz, reqsz, padsz;
 735        __be32 *bp;
 736
 737        _enter("");
 738
 739        namesz = strlen(name);
 740        padsz = (4 - (namesz & 3)) & 3;
 741        reqsz = (5 * 4) + namesz + padsz;
 742
 743        call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
 744        if (!call)
 745                return -ENOMEM;
 746
 747        call->key = key;
 748        call->reply = vnode;
 749        call->service_id = FS_SERVICE;
 750        call->port = htons(AFS_FS_PORT);
 751
 752        /* marshall the parameters */
 753        bp = call->request;
 754        *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
 755        *bp++ = htonl(vnode->fid.vid);
 756        *bp++ = htonl(vnode->fid.vnode);
 757        *bp++ = htonl(vnode->fid.unique);
 758        *bp++ = htonl(namesz);
 759        memcpy(bp, name, namesz);
 760        bp = (void *) bp + namesz;
 761        if (padsz > 0) {
 762                memset(bp, 0, padsz);
 763                bp = (void *) bp + padsz;
 764        }
 765
 766        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 767}
 768
 769/*
 770 * deliver reply data to an FS.Link
 771 */
 772static int afs_deliver_fs_link(struct afs_call *call)
 773{
 774        struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
 775        const __be32 *bp;
 776        int ret;
 777
 778        _enter("{%u}", call->unmarshall);
 779
 780        ret = afs_transfer_reply(call);
 781        if (ret < 0)
 782                return ret;
 783
 784        /* unmarshall the reply once we've received all of it */
 785        bp = call->buffer;
 786        xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
 787        xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
 788        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
 789
 790        _leave(" = 0 [done]");
 791        return 0;
 792}
 793
 794/*
 795 * FS.Link operation type
 796 */
 797static const struct afs_call_type afs_RXFSLink = {
 798        .name           = "FS.Link",
 799        .deliver        = afs_deliver_fs_link,
 800        .abort_to_error = afs_abort_to_error,
 801        .destructor     = afs_flat_call_destructor,
 802};
 803
 804/*
 805 * make a hard link
 806 */
 807int afs_fs_link(struct afs_server *server,
 808                struct key *key,
 809                struct afs_vnode *dvnode,
 810                struct afs_vnode *vnode,
 811                const char *name,
 812                const struct afs_wait_mode *wait_mode)
 813{
 814        struct afs_call *call;
 815        size_t namesz, reqsz, padsz;
 816        __be32 *bp;
 817
 818        _enter("");
 819
 820        namesz = strlen(name);
 821        padsz = (4 - (namesz & 3)) & 3;
 822        reqsz = (5 * 4) + namesz + padsz + (3 * 4);
 823
 824        call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
 825        if (!call)
 826                return -ENOMEM;
 827
 828        call->key = key;
 829        call->reply = dvnode;
 830        call->reply2 = vnode;
 831        call->service_id = FS_SERVICE;
 832        call->port = htons(AFS_FS_PORT);
 833
 834        /* marshall the parameters */
 835        bp = call->request;
 836        *bp++ = htonl(FSLINK);
 837        *bp++ = htonl(dvnode->fid.vid);
 838        *bp++ = htonl(dvnode->fid.vnode);
 839        *bp++ = htonl(dvnode->fid.unique);
 840        *bp++ = htonl(namesz);
 841        memcpy(bp, name, namesz);
 842        bp = (void *) bp + namesz;
 843        if (padsz > 0) {
 844                memset(bp, 0, padsz);
 845                bp = (void *) bp + padsz;
 846        }
 847        *bp++ = htonl(vnode->fid.vid);
 848        *bp++ = htonl(vnode->fid.vnode);
 849        *bp++ = htonl(vnode->fid.unique);
 850
 851        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 852}
 853
 854/*
 855 * deliver reply data to an FS.Symlink
 856 */
 857static int afs_deliver_fs_symlink(struct afs_call *call)
 858{
 859        struct afs_vnode *vnode = call->reply;
 860        const __be32 *bp;
 861        int ret;
 862
 863        _enter("{%u}", call->unmarshall);
 864
 865        ret = afs_transfer_reply(call);
 866        if (ret < 0)
 867                return ret;
 868
 869        /* unmarshall the reply once we've received all of it */
 870        bp = call->buffer;
 871        xdr_decode_AFSFid(&bp, call->reply2);
 872        xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
 873        xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
 874        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
 875
 876        _leave(" = 0 [done]");
 877        return 0;
 878}
 879
 880/*
 881 * FS.Symlink operation type
 882 */
 883static const struct afs_call_type afs_RXFSSymlink = {
 884        .name           = "FS.Symlink",
 885        .deliver        = afs_deliver_fs_symlink,
 886        .abort_to_error = afs_abort_to_error,
 887        .destructor     = afs_flat_call_destructor,
 888};
 889
 890/*
 891 * create a symbolic link
 892 */
 893int afs_fs_symlink(struct afs_server *server,
 894                   struct key *key,
 895                   struct afs_vnode *vnode,
 896                   const char *name,
 897                   const char *contents,
 898                   struct afs_fid *newfid,
 899                   struct afs_file_status *newstatus,
 900                   const struct afs_wait_mode *wait_mode)
 901{
 902        struct afs_call *call;
 903        size_t namesz, reqsz, padsz, c_namesz, c_padsz;
 904        __be32 *bp;
 905
 906        _enter("");
 907
 908        namesz = strlen(name);
 909        padsz = (4 - (namesz & 3)) & 3;
 910
 911        c_namesz = strlen(contents);
 912        c_padsz = (4 - (c_namesz & 3)) & 3;
 913
 914        reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
 915
 916        call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
 917                                   (3 + 21 + 21 + 6) * 4);
 918        if (!call)
 919                return -ENOMEM;
 920
 921        call->key = key;
 922        call->reply = vnode;
 923        call->reply2 = newfid;
 924        call->reply3 = newstatus;
 925        call->service_id = FS_SERVICE;
 926        call->port = htons(AFS_FS_PORT);
 927
 928        /* marshall the parameters */
 929        bp = call->request;
 930        *bp++ = htonl(FSSYMLINK);
 931        *bp++ = htonl(vnode->fid.vid);
 932        *bp++ = htonl(vnode->fid.vnode);
 933        *bp++ = htonl(vnode->fid.unique);
 934        *bp++ = htonl(namesz);
 935        memcpy(bp, name, namesz);
 936        bp = (void *) bp + namesz;
 937        if (padsz > 0) {
 938                memset(bp, 0, padsz);
 939                bp = (void *) bp + padsz;
 940        }
 941        *bp++ = htonl(c_namesz);
 942        memcpy(bp, contents, c_namesz);
 943        bp = (void *) bp + c_namesz;
 944        if (c_padsz > 0) {
 945                memset(bp, 0, c_padsz);
 946                bp = (void *) bp + c_padsz;
 947        }
 948        *bp++ = htonl(AFS_SET_MODE);
 949        *bp++ = 0; /* mtime */
 950        *bp++ = 0; /* owner */
 951        *bp++ = 0; /* group */
 952        *bp++ = htonl(S_IRWXUGO); /* unix mode */
 953        *bp++ = 0; /* segment size */
 954
 955        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
 956}
 957
 958/*
 959 * deliver reply data to an FS.Rename
 960 */
 961static int afs_deliver_fs_rename(struct afs_call *call)
 962{
 963        struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
 964        const __be32 *bp;
 965        int ret;
 966
 967        _enter("{%u}", call->unmarshall);
 968
 969        ret = afs_transfer_reply(call);
 970        if (ret < 0)
 971                return ret;
 972
 973        /* unmarshall the reply once we've received all of it */
 974        bp = call->buffer;
 975        xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
 976        if (new_dvnode != orig_dvnode)
 977                xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
 978                                          NULL);
 979        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
 980
 981        _leave(" = 0 [done]");
 982        return 0;
 983}
 984
 985/*
 986 * FS.Rename operation type
 987 */
 988static const struct afs_call_type afs_RXFSRename = {
 989        .name           = "FS.Rename",
 990        .deliver        = afs_deliver_fs_rename,
 991        .abort_to_error = afs_abort_to_error,
 992        .destructor     = afs_flat_call_destructor,
 993};
 994
 995/*
 996 * create a symbolic link
 997 */
 998int afs_fs_rename(struct afs_server *server,
 999                  struct key *key,
1000                  struct afs_vnode *orig_dvnode,
1001                  const char *orig_name,
1002                  struct afs_vnode *new_dvnode,
1003                  const char *new_name,
1004                  const struct afs_wait_mode *wait_mode)
1005{
1006        struct afs_call *call;
1007        size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1008        __be32 *bp;
1009
1010        _enter("");
1011
1012        o_namesz = strlen(orig_name);
1013        o_padsz = (4 - (o_namesz & 3)) & 3;
1014
1015        n_namesz = strlen(new_name);
1016        n_padsz = (4 - (n_namesz & 3)) & 3;
1017
1018        reqsz = (4 * 4) +
1019                4 + o_namesz + o_padsz +
1020                (3 * 4) +
1021                4 + n_namesz + n_padsz;
1022
1023        call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1024        if (!call)
1025                return -ENOMEM;
1026
1027        call->key = key;
1028        call->reply = orig_dvnode;
1029        call->reply2 = new_dvnode;
1030        call->service_id = FS_SERVICE;
1031        call->port = htons(AFS_FS_PORT);
1032
1033        /* marshall the parameters */
1034        bp = call->request;
1035        *bp++ = htonl(FSRENAME);
1036        *bp++ = htonl(orig_dvnode->fid.vid);
1037        *bp++ = htonl(orig_dvnode->fid.vnode);
1038        *bp++ = htonl(orig_dvnode->fid.unique);
1039        *bp++ = htonl(o_namesz);
1040        memcpy(bp, orig_name, o_namesz);
1041        bp = (void *) bp + o_namesz;
1042        if (o_padsz > 0) {
1043                memset(bp, 0, o_padsz);
1044                bp = (void *) bp + o_padsz;
1045        }
1046
1047        *bp++ = htonl(new_dvnode->fid.vid);
1048        *bp++ = htonl(new_dvnode->fid.vnode);
1049        *bp++ = htonl(new_dvnode->fid.unique);
1050        *bp++ = htonl(n_namesz);
1051        memcpy(bp, new_name, n_namesz);
1052        bp = (void *) bp + n_namesz;
1053        if (n_padsz > 0) {
1054                memset(bp, 0, n_padsz);
1055                bp = (void *) bp + n_padsz;
1056        }
1057
1058        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1059}
1060
1061/*
1062 * deliver reply data to an FS.StoreData
1063 */
1064static int afs_deliver_fs_store_data(struct afs_call *call)
1065{
1066        struct afs_vnode *vnode = call->reply;
1067        const __be32 *bp;
1068        int ret;
1069
1070        _enter("");
1071
1072        ret = afs_transfer_reply(call);
1073        if (ret < 0)
1074                return ret;
1075
1076        /* unmarshall the reply once we've received all of it */
1077        bp = call->buffer;
1078        xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1079                                  &call->store_version);
1080        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1081
1082        afs_pages_written_back(vnode, call);
1083
1084        _leave(" = 0 [done]");
1085        return 0;
1086}
1087
1088/*
1089 * FS.StoreData operation type
1090 */
1091static const struct afs_call_type afs_RXFSStoreData = {
1092        .name           = "FS.StoreData",
1093        .deliver        = afs_deliver_fs_store_data,
1094        .abort_to_error = afs_abort_to_error,
1095        .destructor     = afs_flat_call_destructor,
1096};
1097
1098static const struct afs_call_type afs_RXFSStoreData64 = {
1099        .name           = "FS.StoreData64",
1100        .deliver        = afs_deliver_fs_store_data,
1101        .abort_to_error = afs_abort_to_error,
1102        .destructor     = afs_flat_call_destructor,
1103};
1104
1105/*
1106 * store a set of pages to a very large file
1107 */
1108static int afs_fs_store_data64(struct afs_server *server,
1109                               struct afs_writeback *wb,
1110                               pgoff_t first, pgoff_t last,
1111                               unsigned offset, unsigned to,
1112                               loff_t size, loff_t pos, loff_t i_size,
1113                               const struct afs_wait_mode *wait_mode)
1114{
1115        struct afs_vnode *vnode = wb->vnode;
1116        struct afs_call *call;
1117        __be32 *bp;
1118
1119        _enter(",%x,{%x:%u},,",
1120               key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1121
1122        call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1123                                   (4 + 6 + 3 * 2) * 4,
1124                                   (21 + 6) * 4);
1125        if (!call)
1126                return -ENOMEM;
1127
1128        call->wb = wb;
1129        call->key = wb->key;
1130        call->reply = vnode;
1131        call->service_id = FS_SERVICE;
1132        call->port = htons(AFS_FS_PORT);
1133        call->mapping = vnode->vfs_inode.i_mapping;
1134        call->first = first;
1135        call->last = last;
1136        call->first_offset = offset;
1137        call->last_to = to;
1138        call->send_pages = true;
1139        call->store_version = vnode->status.data_version + 1;
1140
1141        /* marshall the parameters */
1142        bp = call->request;
1143        *bp++ = htonl(FSSTOREDATA64);
1144        *bp++ = htonl(vnode->fid.vid);
1145        *bp++ = htonl(vnode->fid.vnode);
1146        *bp++ = htonl(vnode->fid.unique);
1147
1148        *bp++ = 0; /* mask */
1149        *bp++ = 0; /* mtime */
1150        *bp++ = 0; /* owner */
1151        *bp++ = 0; /* group */
1152        *bp++ = 0; /* unix mode */
1153        *bp++ = 0; /* segment size */
1154
1155        *bp++ = htonl(pos >> 32);
1156        *bp++ = htonl((u32) pos);
1157        *bp++ = htonl(size >> 32);
1158        *bp++ = htonl((u32) size);
1159        *bp++ = htonl(i_size >> 32);
1160        *bp++ = htonl((u32) i_size);
1161
1162        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1163}
1164
1165/*
1166 * store a set of pages
1167 */
1168int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1169                      pgoff_t first, pgoff_t last,
1170                      unsigned offset, unsigned to,
1171                      const struct afs_wait_mode *wait_mode)
1172{
1173        struct afs_vnode *vnode = wb->vnode;
1174        struct afs_call *call;
1175        loff_t size, pos, i_size;
1176        __be32 *bp;
1177
1178        _enter(",%x,{%x:%u},,",
1179               key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1180
1181        size = to - offset;
1182        if (first != last)
1183                size += (loff_t)(last - first) << PAGE_SHIFT;
1184        pos = (loff_t)first << PAGE_SHIFT;
1185        pos += offset;
1186
1187        i_size = i_size_read(&vnode->vfs_inode);
1188        if (pos + size > i_size)
1189                i_size = size + pos;
1190
1191        _debug("size %llx, at %llx, i_size %llx",
1192               (unsigned long long) size, (unsigned long long) pos,
1193               (unsigned long long) i_size);
1194
1195        if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1196                return afs_fs_store_data64(server, wb, first, last, offset, to,
1197                                           size, pos, i_size, wait_mode);
1198
1199        call = afs_alloc_flat_call(&afs_RXFSStoreData,
1200                                   (4 + 6 + 3) * 4,
1201                                   (21 + 6) * 4);
1202        if (!call)
1203                return -ENOMEM;
1204
1205        call->wb = wb;
1206        call->key = wb->key;
1207        call->reply = vnode;
1208        call->service_id = FS_SERVICE;
1209        call->port = htons(AFS_FS_PORT);
1210        call->mapping = vnode->vfs_inode.i_mapping;
1211        call->first = first;
1212        call->last = last;
1213        call->first_offset = offset;
1214        call->last_to = to;
1215        call->send_pages = true;
1216        call->store_version = vnode->status.data_version + 1;
1217
1218        /* marshall the parameters */
1219        bp = call->request;
1220        *bp++ = htonl(FSSTOREDATA);
1221        *bp++ = htonl(vnode->fid.vid);
1222        *bp++ = htonl(vnode->fid.vnode);
1223        *bp++ = htonl(vnode->fid.unique);
1224
1225        *bp++ = 0; /* mask */
1226        *bp++ = 0; /* mtime */
1227        *bp++ = 0; /* owner */
1228        *bp++ = 0; /* group */
1229        *bp++ = 0; /* unix mode */
1230        *bp++ = 0; /* segment size */
1231
1232        *bp++ = htonl(pos);
1233        *bp++ = htonl(size);
1234        *bp++ = htonl(i_size);
1235
1236        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1237}
1238
1239/*
1240 * deliver reply data to an FS.StoreStatus
1241 */
1242static int afs_deliver_fs_store_status(struct afs_call *call)
1243{
1244        afs_dataversion_t *store_version;
1245        struct afs_vnode *vnode = call->reply;
1246        const __be32 *bp;
1247        int ret;
1248
1249        _enter("");
1250
1251        ret = afs_transfer_reply(call);
1252        if (ret < 0)
1253                return ret;
1254
1255        /* unmarshall the reply once we've received all of it */
1256        store_version = NULL;
1257        if (call->operation_ID == FSSTOREDATA)
1258                store_version = &call->store_version;
1259
1260        bp = call->buffer;
1261        xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1262        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1263
1264        _leave(" = 0 [done]");
1265        return 0;
1266}
1267
1268/*
1269 * FS.StoreStatus operation type
1270 */
1271static const struct afs_call_type afs_RXFSStoreStatus = {
1272        .name           = "FS.StoreStatus",
1273        .deliver        = afs_deliver_fs_store_status,
1274        .abort_to_error = afs_abort_to_error,
1275        .destructor     = afs_flat_call_destructor,
1276};
1277
1278static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1279        .name           = "FS.StoreData",
1280        .deliver        = afs_deliver_fs_store_status,
1281        .abort_to_error = afs_abort_to_error,
1282        .destructor     = afs_flat_call_destructor,
1283};
1284
1285static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1286        .name           = "FS.StoreData64",
1287        .deliver        = afs_deliver_fs_store_status,
1288        .abort_to_error = afs_abort_to_error,
1289        .destructor     = afs_flat_call_destructor,
1290};
1291
1292/*
1293 * set the attributes on a very large file, using FS.StoreData rather than
1294 * FS.StoreStatus so as to alter the file size also
1295 */
1296static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,
1297                                 struct afs_vnode *vnode, struct iattr *attr,
1298                                 const struct afs_wait_mode *wait_mode)
1299{
1300        struct afs_call *call;
1301        __be32 *bp;
1302
1303        _enter(",%x,{%x:%u},,",
1304               key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1305
1306        ASSERT(attr->ia_valid & ATTR_SIZE);
1307
1308        call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,
1309                                   (4 + 6 + 3 * 2) * 4,
1310                                   (21 + 6) * 4);
1311        if (!call)
1312                return -ENOMEM;
1313
1314        call->key = key;
1315        call->reply = vnode;
1316        call->service_id = FS_SERVICE;
1317        call->port = htons(AFS_FS_PORT);
1318        call->store_version = vnode->status.data_version + 1;
1319        call->operation_ID = FSSTOREDATA;
1320
1321        /* marshall the parameters */
1322        bp = call->request;
1323        *bp++ = htonl(FSSTOREDATA64);
1324        *bp++ = htonl(vnode->fid.vid);
1325        *bp++ = htonl(vnode->fid.vnode);
1326        *bp++ = htonl(vnode->fid.unique);
1327
1328        xdr_encode_AFS_StoreStatus(&bp, attr);
1329
1330        *bp++ = 0;                              /* position of start of write */
1331        *bp++ = 0;
1332        *bp++ = 0;                              /* size of write */
1333        *bp++ = 0;
1334        *bp++ = htonl(attr->ia_size >> 32);     /* new file length */
1335        *bp++ = htonl((u32) attr->ia_size);
1336
1337        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1338}
1339
1340/*
1341 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1342 * so as to alter the file size also
1343 */
1344static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1345                               struct afs_vnode *vnode, struct iattr *attr,
1346                               const struct afs_wait_mode *wait_mode)
1347{
1348        struct afs_call *call;
1349        __be32 *bp;
1350
1351        _enter(",%x,{%x:%u},,",
1352               key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1353
1354        ASSERT(attr->ia_valid & ATTR_SIZE);
1355        if (attr->ia_size >> 32)
1356                return afs_fs_setattr_size64(server, key, vnode, attr,
1357                                             wait_mode);
1358
1359        call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1360                                   (4 + 6 + 3) * 4,
1361                                   (21 + 6) * 4);
1362        if (!call)
1363                return -ENOMEM;
1364
1365        call->key = key;
1366        call->reply = vnode;
1367        call->service_id = FS_SERVICE;
1368        call->port = htons(AFS_FS_PORT);
1369        call->store_version = vnode->status.data_version + 1;
1370        call->operation_ID = FSSTOREDATA;
1371
1372        /* marshall the parameters */
1373        bp = call->request;
1374        *bp++ = htonl(FSSTOREDATA);
1375        *bp++ = htonl(vnode->fid.vid);
1376        *bp++ = htonl(vnode->fid.vnode);
1377        *bp++ = htonl(vnode->fid.unique);
1378
1379        xdr_encode_AFS_StoreStatus(&bp, attr);
1380
1381        *bp++ = 0;                              /* position of start of write */
1382        *bp++ = 0;                              /* size of write */
1383        *bp++ = htonl(attr->ia_size);           /* new file length */
1384
1385        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1386}
1387
1388/*
1389 * set the attributes on a file, using FS.StoreData if there's a change in file
1390 * size, and FS.StoreStatus otherwise
1391 */
1392int afs_fs_setattr(struct afs_server *server, struct key *key,
1393                   struct afs_vnode *vnode, struct iattr *attr,
1394                   const struct afs_wait_mode *wait_mode)
1395{
1396        struct afs_call *call;
1397        __be32 *bp;
1398
1399        if (attr->ia_valid & ATTR_SIZE)
1400                return afs_fs_setattr_size(server, key, vnode, attr,
1401                                           wait_mode);
1402
1403        _enter(",%x,{%x:%u},,",
1404               key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1405
1406        call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1407                                   (4 + 6) * 4,
1408                                   (21 + 6) * 4);
1409        if (!call)
1410                return -ENOMEM;
1411
1412        call->key = key;
1413        call->reply = vnode;
1414        call->service_id = FS_SERVICE;
1415        call->port = htons(AFS_FS_PORT);
1416        call->operation_ID = FSSTORESTATUS;
1417
1418        /* marshall the parameters */
1419        bp = call->request;
1420        *bp++ = htonl(FSSTORESTATUS);
1421        *bp++ = htonl(vnode->fid.vid);
1422        *bp++ = htonl(vnode->fid.vnode);
1423        *bp++ = htonl(vnode->fid.unique);
1424
1425        xdr_encode_AFS_StoreStatus(&bp, attr);
1426
1427        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1428}
1429
1430/*
1431 * deliver reply data to an FS.GetVolumeStatus
1432 */
1433static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1434{
1435        const __be32 *bp;
1436        char *p;
1437        int ret;
1438
1439        _enter("{%u}", call->unmarshall);
1440
1441        switch (call->unmarshall) {
1442        case 0:
1443                call->offset = 0;
1444                call->unmarshall++;
1445
1446                /* extract the returned status record */
1447        case 1:
1448                _debug("extract status");
1449                ret = afs_extract_data(call, call->buffer,
1450                                       12 * 4, true);
1451                if (ret < 0)
1452                        return ret;
1453
1454                bp = call->buffer;
1455                xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
1456                call->offset = 0;
1457                call->unmarshall++;
1458
1459                /* extract the volume name length */
1460        case 2:
1461                ret = afs_extract_data(call, &call->tmp, 4, true);
1462                if (ret < 0)
1463                        return ret;
1464
1465                call->count = ntohl(call->tmp);
1466                _debug("volname length: %u", call->count);
1467                if (call->count >= AFSNAMEMAX)
1468                        return -EBADMSG;
1469                call->offset = 0;
1470                call->unmarshall++;
1471
1472                /* extract the volume name */
1473        case 3:
1474                _debug("extract volname");
1475                if (call->count > 0) {
1476                        ret = afs_extract_data(call, call->reply3,
1477                                               call->count, true);
1478                        if (ret < 0)
1479                                return ret;
1480                }
1481
1482                p = call->reply3;
1483                p[call->count] = 0;
1484                _debug("volname '%s'", p);
1485
1486                call->offset = 0;
1487                call->unmarshall++;
1488
1489                /* extract the volume name padding */
1490                if ((call->count & 3) == 0) {
1491                        call->unmarshall++;
1492                        goto no_volname_padding;
1493                }
1494                call->count = 4 - (call->count & 3);
1495
1496        case 4:
1497                ret = afs_extract_data(call, call->buffer,
1498                                       call->count, true);
1499                if (ret < 0)
1500                        return ret;
1501
1502                call->offset = 0;
1503                call->unmarshall++;
1504        no_volname_padding:
1505
1506                /* extract the offline message length */
1507        case 5:
1508                ret = afs_extract_data(call, &call->tmp, 4, true);
1509                if (ret < 0)
1510                        return ret;
1511
1512                call->count = ntohl(call->tmp);
1513                _debug("offline msg length: %u", call->count);
1514                if (call->count >= AFSNAMEMAX)
1515                        return -EBADMSG;
1516                call->offset = 0;
1517                call->unmarshall++;
1518
1519                /* extract the offline message */
1520        case 6:
1521                _debug("extract offline");
1522                if (call->count > 0) {
1523                        ret = afs_extract_data(call, call->reply3,
1524                                               call->count, true);
1525                        if (ret < 0)
1526                                return ret;
1527                }
1528
1529                p = call->reply3;
1530                p[call->count] = 0;
1531                _debug("offline '%s'", p);
1532
1533                call->offset = 0;
1534                call->unmarshall++;
1535
1536                /* extract the offline message padding */
1537                if ((call->count & 3) == 0) {
1538                        call->unmarshall++;
1539                        goto no_offline_padding;
1540                }
1541                call->count = 4 - (call->count & 3);
1542
1543        case 7:
1544                ret = afs_extract_data(call, call->buffer,
1545                                       call->count, true);
1546                if (ret < 0)
1547                        return ret;
1548
1549                call->offset = 0;
1550                call->unmarshall++;
1551        no_offline_padding:
1552
1553                /* extract the message of the day length */
1554        case 8:
1555                ret = afs_extract_data(call, &call->tmp, 4, true);
1556                if (ret < 0)
1557                        return ret;
1558
1559                call->count = ntohl(call->tmp);
1560                _debug("motd length: %u", call->count);
1561                if (call->count >= AFSNAMEMAX)
1562                        return -EBADMSG;
1563                call->offset = 0;
1564                call->unmarshall++;
1565
1566                /* extract the message of the day */
1567        case 9:
1568                _debug("extract motd");
1569                if (call->count > 0) {
1570                        ret = afs_extract_data(call, call->reply3,
1571                                               call->count, true);
1572                        if (ret < 0)
1573                                return ret;
1574                }
1575
1576                p = call->reply3;
1577                p[call->count] = 0;
1578                _debug("motd '%s'", p);
1579
1580                call->offset = 0;
1581                call->unmarshall++;
1582
1583                /* extract the message of the day padding */
1584                call->count = (4 - (call->count & 3)) & 3;
1585
1586        case 10:
1587                ret = afs_extract_data(call, call->buffer,
1588                                       call->count, false);
1589                if (ret < 0)
1590                        return ret;
1591
1592                call->offset = 0;
1593                call->unmarshall++;
1594        case 11:
1595                break;
1596        }
1597
1598        _leave(" = 0 [done]");
1599        return 0;
1600}
1601
1602/*
1603 * destroy an FS.GetVolumeStatus call
1604 */
1605static void afs_get_volume_status_call_destructor(struct afs_call *call)
1606{
1607        kfree(call->reply3);
1608        call->reply3 = NULL;
1609        afs_flat_call_destructor(call);
1610}
1611
1612/*
1613 * FS.GetVolumeStatus operation type
1614 */
1615static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1616        .name           = "FS.GetVolumeStatus",
1617        .deliver        = afs_deliver_fs_get_volume_status,
1618        .abort_to_error = afs_abort_to_error,
1619        .destructor     = afs_get_volume_status_call_destructor,
1620};
1621
1622/*
1623 * fetch the status of a volume
1624 */
1625int afs_fs_get_volume_status(struct afs_server *server,
1626                             struct key *key,
1627                             struct afs_vnode *vnode,
1628                             struct afs_volume_status *vs,
1629                             const struct afs_wait_mode *wait_mode)
1630{
1631        struct afs_call *call;
1632        __be32 *bp;
1633        void *tmpbuf;
1634
1635        _enter("");
1636
1637        tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1638        if (!tmpbuf)
1639                return -ENOMEM;
1640
1641        call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1642        if (!call) {
1643                kfree(tmpbuf);
1644                return -ENOMEM;
1645        }
1646
1647        call->key = key;
1648        call->reply = vnode;
1649        call->reply2 = vs;
1650        call->reply3 = tmpbuf;
1651        call->service_id = FS_SERVICE;
1652        call->port = htons(AFS_FS_PORT);
1653
1654        /* marshall the parameters */
1655        bp = call->request;
1656        bp[0] = htonl(FSGETVOLUMESTATUS);
1657        bp[1] = htonl(vnode->fid.vid);
1658
1659        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1660}
1661
1662/*
1663 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1664 */
1665static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
1666{
1667        const __be32 *bp;
1668        int ret;
1669
1670        _enter("{%u}", call->unmarshall);
1671
1672        ret = afs_transfer_reply(call);
1673        if (ret < 0)
1674                return ret;
1675
1676        /* unmarshall the reply once we've received all of it */
1677        bp = call->buffer;
1678        /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1679
1680        _leave(" = 0 [done]");
1681        return 0;
1682}
1683
1684/*
1685 * FS.SetLock operation type
1686 */
1687static const struct afs_call_type afs_RXFSSetLock = {
1688        .name           = "FS.SetLock",
1689        .deliver        = afs_deliver_fs_xxxx_lock,
1690        .abort_to_error = afs_abort_to_error,
1691        .destructor     = afs_flat_call_destructor,
1692};
1693
1694/*
1695 * FS.ExtendLock operation type
1696 */
1697static const struct afs_call_type afs_RXFSExtendLock = {
1698        .name           = "FS.ExtendLock",
1699        .deliver        = afs_deliver_fs_xxxx_lock,
1700        .abort_to_error = afs_abort_to_error,
1701        .destructor     = afs_flat_call_destructor,
1702};
1703
1704/*
1705 * FS.ReleaseLock operation type
1706 */
1707static const struct afs_call_type afs_RXFSReleaseLock = {
1708        .name           = "FS.ReleaseLock",
1709        .deliver        = afs_deliver_fs_xxxx_lock,
1710        .abort_to_error = afs_abort_to_error,
1711        .destructor     = afs_flat_call_destructor,
1712};
1713
1714/*
1715 * get a lock on a file
1716 */
1717int afs_fs_set_lock(struct afs_server *server,
1718                    struct key *key,
1719                    struct afs_vnode *vnode,
1720                    afs_lock_type_t type,
1721                    const struct afs_wait_mode *wait_mode)
1722{
1723        struct afs_call *call;
1724        __be32 *bp;
1725
1726        _enter("");
1727
1728        call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);
1729        if (!call)
1730                return -ENOMEM;
1731
1732        call->key = key;
1733        call->reply = vnode;
1734        call->service_id = FS_SERVICE;
1735        call->port = htons(AFS_FS_PORT);
1736
1737        /* marshall the parameters */
1738        bp = call->request;
1739        *bp++ = htonl(FSSETLOCK);
1740        *bp++ = htonl(vnode->fid.vid);
1741        *bp++ = htonl(vnode->fid.vnode);
1742        *bp++ = htonl(vnode->fid.unique);
1743        *bp++ = htonl(type);
1744
1745        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1746}
1747
1748/*
1749 * extend a lock on a file
1750 */
1751int afs_fs_extend_lock(struct afs_server *server,
1752                       struct key *key,
1753                       struct afs_vnode *vnode,
1754                       const struct afs_wait_mode *wait_mode)
1755{
1756        struct afs_call *call;
1757        __be32 *bp;
1758
1759        _enter("");
1760
1761        call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);
1762        if (!call)
1763                return -ENOMEM;
1764
1765        call->key = key;
1766        call->reply = vnode;
1767        call->service_id = FS_SERVICE;
1768        call->port = htons(AFS_FS_PORT);
1769
1770        /* marshall the parameters */
1771        bp = call->request;
1772        *bp++ = htonl(FSEXTENDLOCK);
1773        *bp++ = htonl(vnode->fid.vid);
1774        *bp++ = htonl(vnode->fid.vnode);
1775        *bp++ = htonl(vnode->fid.unique);
1776
1777        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1778}
1779
1780/*
1781 * release a lock on a file
1782 */
1783int afs_fs_release_lock(struct afs_server *server,
1784                        struct key *key,
1785                        struct afs_vnode *vnode,
1786                        const struct afs_wait_mode *wait_mode)
1787{
1788        struct afs_call *call;
1789        __be32 *bp;
1790
1791        _enter("");
1792
1793        call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1794        if (!call)
1795                return -ENOMEM;
1796
1797        call->key = key;
1798        call->reply = vnode;
1799        call->service_id = FS_SERVICE;
1800        call->port = htons(AFS_FS_PORT);
1801
1802        /* marshall the parameters */
1803        bp = call->request;
1804        *bp++ = htonl(FSRELEASELOCK);
1805        *bp++ = htonl(vnode->fid.vid);
1806        *bp++ = htonl(vnode->fid.vnode);
1807        *bp++ = htonl(vnode->fid.unique);
1808
1809        return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1810}
1811