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