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