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