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