linux/fs/afs/yfsclient.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* YFS File Server client stubs
   3 *
   4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 */
   7
   8#include <linux/init.h>
   9#include <linux/slab.h>
  10#include <linux/sched.h>
  11#include <linux/circ_buf.h>
  12#include <linux/iversion.h>
  13#include "internal.h"
  14#include "afs_fs.h"
  15#include "xdr_fs.h"
  16#include "protocol_yfs.h"
  17
  18static const struct afs_fid afs_zero_fid;
  19
  20static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
  21{
  22        call->cbi = afs_get_cb_interest(cbi);
  23}
  24
  25#define xdr_size(x) (sizeof(*x) / sizeof(__be32))
  26
  27static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
  28{
  29        const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
  30
  31        fid->vid        = xdr_to_u64(x->volume);
  32        fid->vnode      = xdr_to_u64(x->vnode.lo);
  33        fid->vnode_hi   = ntohl(x->vnode.hi);
  34        fid->unique     = ntohl(x->vnode.unique);
  35        *_bp += xdr_size(x);
  36}
  37
  38static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
  39{
  40        *bp++ = htonl(n);
  41        return bp;
  42}
  43
  44static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
  45{
  46        struct yfs_xdr_u64 *x = (void *)bp;
  47
  48        *x = u64_to_xdr(n);
  49        return bp + xdr_size(x);
  50}
  51
  52static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
  53{
  54        struct yfs_xdr_YFSFid *x = (void *)bp;
  55
  56        x->volume       = u64_to_xdr(fid->vid);
  57        x->vnode.lo     = u64_to_xdr(fid->vnode);
  58        x->vnode.hi     = htonl(fid->vnode_hi);
  59        x->vnode.unique = htonl(fid->unique);
  60        return bp + xdr_size(x);
  61}
  62
  63static size_t xdr_strlen(unsigned int len)
  64{
  65        return sizeof(__be32) + round_up(len, sizeof(__be32));
  66}
  67
  68static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
  69{
  70        bp = xdr_encode_u32(bp, len);
  71        bp = memcpy(bp, p, len);
  72        if (len & 3) {
  73                unsigned int pad = 4 - (len & 3);
  74
  75                memset((u8 *)bp + len, 0, pad);
  76                len += pad;
  77        }
  78
  79        return bp + len / sizeof(__be32);
  80}
  81
  82static s64 linux_to_yfs_time(const struct timespec64 *t)
  83{
  84        /* Convert to 100ns intervals. */
  85        return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
  86}
  87
  88static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
  89{
  90        struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
  91
  92        x->mask         = htonl(AFS_SET_MODE);
  93        x->mode         = htonl(mode & S_IALLUGO);
  94        x->mtime_client = u64_to_xdr(0);
  95        x->owner        = u64_to_xdr(0);
  96        x->group        = u64_to_xdr(0);
  97        return bp + xdr_size(x);
  98}
  99
 100static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
 101{
 102        struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
 103        s64 mtime = linux_to_yfs_time(t);
 104
 105        x->mask         = htonl(AFS_SET_MTIME);
 106        x->mode         = htonl(0);
 107        x->mtime_client = u64_to_xdr(mtime);
 108        x->owner        = u64_to_xdr(0);
 109        x->group        = u64_to_xdr(0);
 110        return bp + xdr_size(x);
 111}
 112
 113/*
 114 * Convert a signed 100ns-resolution 64-bit time into a timespec.
 115 */
 116static struct timespec64 yfs_time_to_linux(s64 t)
 117{
 118        struct timespec64 ts;
 119        u64 abs_t;
 120
 121        /*
 122         * Unfortunately can not use normal 64 bit division on 32 bit arch, but
 123         * the alternative, do_div, does not work with negative numbers so have
 124         * to special case them
 125         */
 126        if (t < 0) {
 127                abs_t = -t;
 128                ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
 129                ts.tv_nsec = -ts.tv_nsec;
 130                ts.tv_sec = -abs_t;
 131        } else {
 132                abs_t = t;
 133                ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
 134                ts.tv_sec = abs_t;
 135        }
 136
 137        return ts;
 138}
 139
 140static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
 141{
 142        s64 t = xdr_to_u64(xdr);
 143
 144        return yfs_time_to_linux(t);
 145}
 146
 147static void yfs_check_req(struct afs_call *call, __be32 *bp)
 148{
 149        size_t len = (void *)bp - call->request;
 150
 151        if (len > call->request_size)
 152                pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
 153                       call->type->name, len, call->request_size);
 154        else if (len < call->request_size)
 155                pr_warn("kAFS: %s: Request buffer underflow (%zu<%u)\n",
 156                        call->type->name, len, call->request_size);
 157}
 158
 159/*
 160 * Dump a bad file status record.
 161 */
 162static void xdr_dump_bad(const __be32 *bp)
 163{
 164        __be32 x[4];
 165        int i;
 166
 167        pr_notice("YFS XDR: Bad status record\n");
 168        for (i = 0; i < 5 * 4 * 4; i += 16) {
 169                memcpy(x, bp, 16);
 170                bp += 4;
 171                pr_notice("%03x: %08x %08x %08x %08x\n",
 172                          i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
 173        }
 174
 175        memcpy(x, bp, 4);
 176        pr_notice("0x50: %08x\n", ntohl(x[0]));
 177}
 178
 179/*
 180 * Decode a YFSFetchStatus block
 181 */
 182static int xdr_decode_YFSFetchStatus(const __be32 **_bp,
 183                                     struct afs_call *call,
 184                                     struct afs_status_cb *scb)
 185{
 186        const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
 187        struct afs_file_status *status = &scb->status;
 188        u32 type;
 189
 190        status->abort_code = ntohl(xdr->abort_code);
 191        if (status->abort_code != 0) {
 192                if (status->abort_code == VNOVNODE)
 193                        status->nlink = 0;
 194                scb->have_error = true;
 195                return 0;
 196        }
 197
 198        type = ntohl(xdr->type);
 199        switch (type) {
 200        case AFS_FTYPE_FILE:
 201        case AFS_FTYPE_DIR:
 202        case AFS_FTYPE_SYMLINK:
 203                status->type = type;
 204                break;
 205        default:
 206                goto bad;
 207        }
 208
 209        status->nlink           = ntohl(xdr->nlink);
 210        status->author          = xdr_to_u64(xdr->author);
 211        status->owner           = xdr_to_u64(xdr->owner);
 212        status->caller_access   = ntohl(xdr->caller_access); /* Ticket dependent */
 213        status->anon_access     = ntohl(xdr->anon_access);
 214        status->mode            = ntohl(xdr->mode) & S_IALLUGO;
 215        status->group           = xdr_to_u64(xdr->group);
 216        status->lock_count      = ntohl(xdr->lock_count);
 217
 218        status->mtime_client    = xdr_to_time(xdr->mtime_client);
 219        status->mtime_server    = xdr_to_time(xdr->mtime_server);
 220        status->size            = xdr_to_u64(xdr->size);
 221        status->data_version    = xdr_to_u64(xdr->data_version);
 222        scb->have_status        = true;
 223
 224        *_bp += xdr_size(xdr);
 225        return 0;
 226
 227bad:
 228        xdr_dump_bad(*_bp);
 229        return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
 230}
 231
 232/*
 233 * Decode a YFSCallBack block
 234 */
 235static void xdr_decode_YFSCallBack(const __be32 **_bp,
 236                                   struct afs_call *call,
 237                                   struct afs_status_cb *scb)
 238{
 239        struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
 240        struct afs_callback *cb = &scb->callback;
 241        ktime_t cb_expiry;
 242
 243        cb_expiry = call->reply_time;
 244        cb_expiry = ktime_add(cb_expiry, xdr_to_u64(x->expiration_time) * 100);
 245        cb->expires_at  = ktime_divns(cb_expiry, NSEC_PER_SEC);
 246        scb->have_cb    = true;
 247        *_bp += xdr_size(x);
 248}
 249
 250/*
 251 * Decode a YFSVolSync block
 252 */
 253static void xdr_decode_YFSVolSync(const __be32 **_bp,
 254                                  struct afs_volsync *volsync)
 255{
 256        struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
 257        u64 creation;
 258
 259        if (volsync) {
 260                creation = xdr_to_u64(x->vol_creation_date);
 261                do_div(creation, 10 * 1000 * 1000);
 262                volsync->creation = creation;
 263        }
 264
 265        *_bp += xdr_size(x);
 266}
 267
 268/*
 269 * Encode the requested attributes into a YFSStoreStatus block
 270 */
 271static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
 272{
 273        struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
 274        s64 mtime = 0, owner = 0, group = 0;
 275        u32 mask = 0, mode = 0;
 276
 277        mask = 0;
 278        if (attr->ia_valid & ATTR_MTIME) {
 279                mask |= AFS_SET_MTIME;
 280                mtime = linux_to_yfs_time(&attr->ia_mtime);
 281        }
 282
 283        if (attr->ia_valid & ATTR_UID) {
 284                mask |= AFS_SET_OWNER;
 285                owner = from_kuid(&init_user_ns, attr->ia_uid);
 286        }
 287
 288        if (attr->ia_valid & ATTR_GID) {
 289                mask |= AFS_SET_GROUP;
 290                group = from_kgid(&init_user_ns, attr->ia_gid);
 291        }
 292
 293        if (attr->ia_valid & ATTR_MODE) {
 294                mask |= AFS_SET_MODE;
 295                mode = attr->ia_mode & S_IALLUGO;
 296        }
 297
 298        x->mask         = htonl(mask);
 299        x->mode         = htonl(mode);
 300        x->mtime_client = u64_to_xdr(mtime);
 301        x->owner        = u64_to_xdr(owner);
 302        x->group        = u64_to_xdr(group);
 303        return bp + xdr_size(x);
 304}
 305
 306/*
 307 * Decode a YFSFetchVolumeStatus block.
 308 */
 309static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
 310                                            struct afs_volume_status *vs)
 311{
 312        const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
 313        u32 flags;
 314
 315        vs->vid                 = xdr_to_u64(x->vid);
 316        vs->parent_id           = xdr_to_u64(x->parent_id);
 317        flags                   = ntohl(x->flags);
 318        vs->online              = flags & yfs_FVSOnline;
 319        vs->in_service          = flags & yfs_FVSInservice;
 320        vs->blessed             = flags & yfs_FVSBlessed;
 321        vs->needs_salvage       = flags & yfs_FVSNeedsSalvage;
 322        vs->type                = ntohl(x->type);
 323        vs->min_quota           = 0;
 324        vs->max_quota           = xdr_to_u64(x->max_quota);
 325        vs->blocks_in_use       = xdr_to_u64(x->blocks_in_use);
 326        vs->part_blocks_avail   = xdr_to_u64(x->part_blocks_avail);
 327        vs->part_max_blocks     = xdr_to_u64(x->part_max_blocks);
 328        vs->vol_copy_date       = xdr_to_u64(x->vol_copy_date);
 329        vs->vol_backup_date     = xdr_to_u64(x->vol_backup_date);
 330        *_bp += sizeof(*x) / sizeof(__be32);
 331}
 332
 333/*
 334 * Deliver a reply that's a status, callback and volsync.
 335 */
 336static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call)
 337{
 338        const __be32 *bp;
 339        int ret;
 340
 341        ret = afs_transfer_reply(call);
 342        if (ret < 0)
 343                return ret;
 344
 345        /* unmarshall the reply once we've received all of it */
 346        bp = call->buffer;
 347        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
 348        if (ret < 0)
 349                return ret;
 350        xdr_decode_YFSCallBack(&bp, call, call->out_scb);
 351        xdr_decode_YFSVolSync(&bp, call->out_volsync);
 352
 353        _leave(" = 0 [done]");
 354        return 0;
 355}
 356
 357/*
 358 * Deliver reply data to operations that just return a file status and a volume
 359 * sync record.
 360 */
 361static int yfs_deliver_status_and_volsync(struct afs_call *call)
 362{
 363        const __be32 *bp;
 364        int ret;
 365
 366        ret = afs_transfer_reply(call);
 367        if (ret < 0)
 368                return ret;
 369
 370        bp = call->buffer;
 371        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
 372        if (ret < 0)
 373                return ret;
 374        xdr_decode_YFSVolSync(&bp, call->out_volsync);
 375
 376        _leave(" = 0 [done]");
 377        return 0;
 378}
 379
 380/*
 381 * YFS.FetchStatus operation type
 382 */
 383static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = {
 384        .name           = "YFS.FetchStatus(vnode)",
 385        .op             = yfs_FS_FetchStatus,
 386        .deliver        = yfs_deliver_fs_status_cb_and_volsync,
 387        .destructor     = afs_flat_call_destructor,
 388};
 389
 390/*
 391 * Fetch the status information for a file.
 392 */
 393int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
 394                             struct afs_volsync *volsync)
 395{
 396        struct afs_vnode *vnode = fc->vnode;
 397        struct afs_call *call;
 398        struct afs_net *net = afs_v2net(vnode);
 399        __be32 *bp;
 400
 401        _enter(",%x,{%llx:%llu},,",
 402               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
 403
 404        call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode,
 405                                   sizeof(__be32) * 2 +
 406                                   sizeof(struct yfs_xdr_YFSFid),
 407                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
 408                                   sizeof(struct yfs_xdr_YFSCallBack) +
 409                                   sizeof(struct yfs_xdr_YFSVolSync));
 410        if (!call) {
 411                fc->ac.error = -ENOMEM;
 412                return -ENOMEM;
 413        }
 414
 415        call->key = fc->key;
 416        call->out_scb = scb;
 417        call->out_volsync = volsync;
 418
 419        /* marshall the parameters */
 420        bp = call->request;
 421        bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
 422        bp = xdr_encode_u32(bp, 0); /* RPC flags */
 423        bp = xdr_encode_YFSFid(bp, &vnode->fid);
 424        yfs_check_req(call, bp);
 425
 426        afs_use_fs_server(call, fc->cbi);
 427        trace_afs_make_fs_call(call, &vnode->fid);
 428        afs_set_fc_call(call, fc);
 429        afs_make_call(&fc->ac, call, GFP_NOFS);
 430        return afs_wait_for_call_to_complete(call, &fc->ac);
 431}
 432
 433/*
 434 * Deliver reply data to an YFS.FetchData64.
 435 */
 436static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
 437{
 438        struct afs_read *req = call->read_request;
 439        const __be32 *bp;
 440        unsigned int size;
 441        int ret;
 442
 443        _enter("{%u,%zu/%llu}",
 444               call->unmarshall, iov_iter_count(call->iter), req->actual_len);
 445
 446        switch (call->unmarshall) {
 447        case 0:
 448                req->actual_len = 0;
 449                req->index = 0;
 450                req->offset = req->pos & (PAGE_SIZE - 1);
 451                afs_extract_to_tmp64(call);
 452                call->unmarshall++;
 453                /* Fall through */
 454
 455                /* extract the returned data length */
 456        case 1:
 457                _debug("extract data length");
 458                ret = afs_extract_data(call, true);
 459                if (ret < 0)
 460                        return ret;
 461
 462                req->actual_len = be64_to_cpu(call->tmp64);
 463                _debug("DATA length: %llu", req->actual_len);
 464                req->remain = min(req->len, req->actual_len);
 465                if (req->remain == 0)
 466                        goto no_more_data;
 467
 468                call->unmarshall++;
 469
 470        begin_page:
 471                ASSERTCMP(req->index, <, req->nr_pages);
 472                if (req->remain > PAGE_SIZE - req->offset)
 473                        size = PAGE_SIZE - req->offset;
 474                else
 475                        size = req->remain;
 476                call->bvec[0].bv_len = size;
 477                call->bvec[0].bv_offset = req->offset;
 478                call->bvec[0].bv_page = req->pages[req->index];
 479                iov_iter_bvec(&call->def_iter, READ, call->bvec, 1, size);
 480                ASSERTCMP(size, <=, PAGE_SIZE);
 481                /* Fall through */
 482
 483                /* extract the returned data */
 484        case 2:
 485                _debug("extract data %zu/%llu",
 486                       iov_iter_count(call->iter), req->remain);
 487
 488                ret = afs_extract_data(call, true);
 489                if (ret < 0)
 490                        return ret;
 491                req->remain -= call->bvec[0].bv_len;
 492                req->offset += call->bvec[0].bv_len;
 493                ASSERTCMP(req->offset, <=, PAGE_SIZE);
 494                if (req->offset == PAGE_SIZE) {
 495                        req->offset = 0;
 496                        if (req->page_done)
 497                                req->page_done(req);
 498                        req->index++;
 499                        if (req->remain > 0)
 500                                goto begin_page;
 501                }
 502
 503                ASSERTCMP(req->remain, ==, 0);
 504                if (req->actual_len <= req->len)
 505                        goto no_more_data;
 506
 507                /* Discard any excess data the server gave us */
 508                afs_extract_discard(call, req->actual_len - req->len);
 509                call->unmarshall = 3;
 510                /* Fall through */
 511
 512        case 3:
 513                _debug("extract discard %zu/%llu",
 514                       iov_iter_count(call->iter), req->actual_len - req->len);
 515
 516                ret = afs_extract_data(call, true);
 517                if (ret < 0)
 518                        return ret;
 519
 520        no_more_data:
 521                call->unmarshall = 4;
 522                afs_extract_to_buf(call,
 523                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
 524                                   sizeof(struct yfs_xdr_YFSCallBack) +
 525                                   sizeof(struct yfs_xdr_YFSVolSync));
 526                /* Fall through */
 527
 528                /* extract the metadata */
 529        case 4:
 530                ret = afs_extract_data(call, false);
 531                if (ret < 0)
 532                        return ret;
 533
 534                bp = call->buffer;
 535                ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
 536                if (ret < 0)
 537                        return ret;
 538                xdr_decode_YFSCallBack(&bp, call, call->out_scb);
 539                xdr_decode_YFSVolSync(&bp, call->out_volsync);
 540
 541                req->data_version = call->out_scb->status.data_version;
 542                req->file_size = call->out_scb->status.size;
 543
 544                call->unmarshall++;
 545                /* Fall through */
 546
 547        case 5:
 548                break;
 549        }
 550
 551        for (; req->index < req->nr_pages; req->index++) {
 552                if (req->offset < PAGE_SIZE)
 553                        zero_user_segment(req->pages[req->index],
 554                                          req->offset, PAGE_SIZE);
 555                if (req->page_done)
 556                        req->page_done(req);
 557                req->offset = 0;
 558        }
 559
 560        _leave(" = 0 [done]");
 561        return 0;
 562}
 563
 564static void yfs_fetch_data_destructor(struct afs_call *call)
 565{
 566        afs_put_read(call->read_request);
 567        afs_flat_call_destructor(call);
 568}
 569
 570/*
 571 * YFS.FetchData64 operation type
 572 */
 573static const struct afs_call_type yfs_RXYFSFetchData64 = {
 574        .name           = "YFS.FetchData64",
 575        .op             = yfs_FS_FetchData64,
 576        .deliver        = yfs_deliver_fs_fetch_data64,
 577        .destructor     = yfs_fetch_data_destructor,
 578};
 579
 580/*
 581 * Fetch data from a file.
 582 */
 583int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
 584                      struct afs_read *req)
 585{
 586        struct afs_vnode *vnode = fc->vnode;
 587        struct afs_call *call;
 588        struct afs_net *net = afs_v2net(vnode);
 589        __be32 *bp;
 590
 591        _enter(",%x,{%llx:%llu},%llx,%llx",
 592               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
 593               req->pos, req->len);
 594
 595        call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
 596                                   sizeof(__be32) * 2 +
 597                                   sizeof(struct yfs_xdr_YFSFid) +
 598                                   sizeof(struct yfs_xdr_u64) * 2,
 599                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
 600                                   sizeof(struct yfs_xdr_YFSCallBack) +
 601                                   sizeof(struct yfs_xdr_YFSVolSync));
 602        if (!call)
 603                return -ENOMEM;
 604
 605        call->key = fc->key;
 606        call->out_scb = scb;
 607        call->out_volsync = NULL;
 608        call->read_request = afs_get_read(req);
 609
 610        /* marshall the parameters */
 611        bp = call->request;
 612        bp = xdr_encode_u32(bp, YFSFETCHDATA64);
 613        bp = xdr_encode_u32(bp, 0); /* RPC flags */
 614        bp = xdr_encode_YFSFid(bp, &vnode->fid);
 615        bp = xdr_encode_u64(bp, req->pos);
 616        bp = xdr_encode_u64(bp, req->len);
 617        yfs_check_req(call, bp);
 618
 619        afs_use_fs_server(call, fc->cbi);
 620        trace_afs_make_fs_call(call, &vnode->fid);
 621        afs_set_fc_call(call, fc);
 622        afs_make_call(&fc->ac, call, GFP_NOFS);
 623        return afs_wait_for_call_to_complete(call, &fc->ac);
 624}
 625
 626/*
 627 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
 628 */
 629static int yfs_deliver_fs_create_vnode(struct afs_call *call)
 630{
 631        const __be32 *bp;
 632        int ret;
 633
 634        _enter("{%u}", call->unmarshall);
 635
 636        ret = afs_transfer_reply(call);
 637        if (ret < 0)
 638                return ret;
 639
 640        /* unmarshall the reply once we've received all of it */
 641        bp = call->buffer;
 642        xdr_decode_YFSFid(&bp, call->out_fid);
 643        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
 644        if (ret < 0)
 645                return ret;
 646        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
 647        if (ret < 0)
 648                return ret;
 649        xdr_decode_YFSCallBack(&bp, call, call->out_scb);
 650        xdr_decode_YFSVolSync(&bp, call->out_volsync);
 651
 652        _leave(" = 0 [done]");
 653        return 0;
 654}
 655
 656/*
 657 * FS.CreateFile and FS.MakeDir operation type
 658 */
 659static const struct afs_call_type afs_RXFSCreateFile = {
 660        .name           = "YFS.CreateFile",
 661        .op             = yfs_FS_CreateFile,
 662        .deliver        = yfs_deliver_fs_create_vnode,
 663        .destructor     = afs_flat_call_destructor,
 664};
 665
 666/*
 667 * Create a file.
 668 */
 669int yfs_fs_create_file(struct afs_fs_cursor *fc,
 670                       const char *name,
 671                       umode_t mode,
 672                       struct afs_status_cb *dvnode_scb,
 673                       struct afs_fid *newfid,
 674                       struct afs_status_cb *new_scb)
 675{
 676        struct afs_vnode *dvnode = fc->vnode;
 677        struct afs_call *call;
 678        struct afs_net *net = afs_v2net(dvnode);
 679        size_t namesz, reqsz, rplsz;
 680        __be32 *bp;
 681
 682        _enter("");
 683
 684        namesz = strlen(name);
 685        reqsz = (sizeof(__be32) +
 686                 sizeof(__be32) +
 687                 sizeof(struct yfs_xdr_YFSFid) +
 688                 xdr_strlen(namesz) +
 689                 sizeof(struct yfs_xdr_YFSStoreStatus) +
 690                 sizeof(__be32));
 691        rplsz = (sizeof(struct yfs_xdr_YFSFid) +
 692                 sizeof(struct yfs_xdr_YFSFetchStatus) +
 693                 sizeof(struct yfs_xdr_YFSFetchStatus) +
 694                 sizeof(struct yfs_xdr_YFSCallBack) +
 695                 sizeof(struct yfs_xdr_YFSVolSync));
 696
 697        call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
 698        if (!call)
 699                return -ENOMEM;
 700
 701        call->key = fc->key;
 702        call->out_dir_scb = dvnode_scb;
 703        call->out_fid = newfid;
 704        call->out_scb = new_scb;
 705
 706        /* marshall the parameters */
 707        bp = call->request;
 708        bp = xdr_encode_u32(bp, YFSCREATEFILE);
 709        bp = xdr_encode_u32(bp, 0); /* RPC flags */
 710        bp = xdr_encode_YFSFid(bp, &dvnode->fid);
 711        bp = xdr_encode_string(bp, name, namesz);
 712        bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
 713        bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
 714        yfs_check_req(call, bp);
 715
 716        afs_use_fs_server(call, fc->cbi);
 717        trace_afs_make_fs_call1(call, &dvnode->fid, name);
 718        afs_set_fc_call(call, fc);
 719        afs_make_call(&fc->ac, call, GFP_NOFS);
 720        return afs_wait_for_call_to_complete(call, &fc->ac);
 721}
 722
 723static const struct afs_call_type yfs_RXFSMakeDir = {
 724        .name           = "YFS.MakeDir",
 725        .op             = yfs_FS_MakeDir,
 726        .deliver        = yfs_deliver_fs_create_vnode,
 727        .destructor     = afs_flat_call_destructor,
 728};
 729
 730/*
 731 * Make a directory.
 732 */
 733int yfs_fs_make_dir(struct afs_fs_cursor *fc,
 734                    const char *name,
 735                    umode_t mode,
 736                    struct afs_status_cb *dvnode_scb,
 737                    struct afs_fid *newfid,
 738                    struct afs_status_cb *new_scb)
 739{
 740        struct afs_vnode *dvnode = fc->vnode;
 741        struct afs_call *call;
 742        struct afs_net *net = afs_v2net(dvnode);
 743        size_t namesz, reqsz, rplsz;
 744        __be32 *bp;
 745
 746        _enter("");
 747
 748        namesz = strlen(name);
 749        reqsz = (sizeof(__be32) +
 750                 sizeof(struct yfs_xdr_RPCFlags) +
 751                 sizeof(struct yfs_xdr_YFSFid) +
 752                 xdr_strlen(namesz) +
 753                 sizeof(struct yfs_xdr_YFSStoreStatus));
 754        rplsz = (sizeof(struct yfs_xdr_YFSFid) +
 755                 sizeof(struct yfs_xdr_YFSFetchStatus) +
 756                 sizeof(struct yfs_xdr_YFSFetchStatus) +
 757                 sizeof(struct yfs_xdr_YFSCallBack) +
 758                 sizeof(struct yfs_xdr_YFSVolSync));
 759
 760        call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
 761        if (!call)
 762                return -ENOMEM;
 763
 764        call->key = fc->key;
 765        call->out_dir_scb = dvnode_scb;
 766        call->out_fid = newfid;
 767        call->out_scb = new_scb;
 768
 769        /* marshall the parameters */
 770        bp = call->request;
 771        bp = xdr_encode_u32(bp, YFSMAKEDIR);
 772        bp = xdr_encode_u32(bp, 0); /* RPC flags */
 773        bp = xdr_encode_YFSFid(bp, &dvnode->fid);
 774        bp = xdr_encode_string(bp, name, namesz);
 775        bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
 776        yfs_check_req(call, bp);
 777
 778        afs_use_fs_server(call, fc->cbi);
 779        trace_afs_make_fs_call1(call, &dvnode->fid, name);
 780        afs_set_fc_call(call, fc);
 781        afs_make_call(&fc->ac, call, GFP_NOFS);
 782        return afs_wait_for_call_to_complete(call, &fc->ac);
 783}
 784
 785/*
 786 * Deliver reply data to a YFS.RemoveFile2 operation.
 787 */
 788static int yfs_deliver_fs_remove_file2(struct afs_call *call)
 789{
 790        struct afs_fid fid;
 791        const __be32 *bp;
 792        int ret;
 793
 794        _enter("{%u}", call->unmarshall);
 795
 796        ret = afs_transfer_reply(call);
 797        if (ret < 0)
 798                return ret;
 799
 800        bp = call->buffer;
 801        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
 802        if (ret < 0)
 803                return ret;
 804
 805        xdr_decode_YFSFid(&bp, &fid);
 806        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
 807        if (ret < 0)
 808                return ret;
 809        /* Was deleted if vnode->status.abort_code == VNOVNODE. */
 810
 811        xdr_decode_YFSVolSync(&bp, call->out_volsync);
 812        return 0;
 813}
 814
 815/*
 816 * YFS.RemoveFile2 operation type.
 817 */
 818static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
 819        .name           = "YFS.RemoveFile2",
 820        .op             = yfs_FS_RemoveFile2,
 821        .deliver        = yfs_deliver_fs_remove_file2,
 822        .destructor     = afs_flat_call_destructor,
 823};
 824
 825/*
 826 * Remove a file and retrieve new file status.
 827 */
 828int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
 829                        const char *name, struct afs_status_cb *dvnode_scb,
 830                        struct afs_status_cb *vnode_scb)
 831{
 832        struct afs_vnode *dvnode = fc->vnode;
 833        struct afs_call *call;
 834        struct afs_net *net = afs_v2net(dvnode);
 835        size_t namesz;
 836        __be32 *bp;
 837
 838        _enter("");
 839
 840        namesz = strlen(name);
 841
 842        call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
 843                                   sizeof(__be32) +
 844                                   sizeof(struct yfs_xdr_RPCFlags) +
 845                                   sizeof(struct yfs_xdr_YFSFid) +
 846                                   xdr_strlen(namesz),
 847                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
 848                                   sizeof(struct yfs_xdr_YFSFid) +
 849                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
 850                                   sizeof(struct yfs_xdr_YFSVolSync));
 851        if (!call)
 852                return -ENOMEM;
 853
 854        call->key = fc->key;
 855        call->out_dir_scb = dvnode_scb;
 856        call->out_scb = vnode_scb;
 857
 858        /* marshall the parameters */
 859        bp = call->request;
 860        bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
 861        bp = xdr_encode_u32(bp, 0); /* RPC flags */
 862        bp = xdr_encode_YFSFid(bp, &dvnode->fid);
 863        bp = xdr_encode_string(bp, name, namesz);
 864        yfs_check_req(call, bp);
 865
 866        afs_use_fs_server(call, fc->cbi);
 867        trace_afs_make_fs_call1(call, &dvnode->fid, name);
 868        afs_set_fc_call(call, fc);
 869        afs_make_call(&fc->ac, call, GFP_NOFS);
 870        return afs_wait_for_call_to_complete(call, &fc->ac);
 871}
 872
 873/*
 874 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
 875 */
 876static int yfs_deliver_fs_remove(struct afs_call *call)
 877{
 878        const __be32 *bp;
 879        int ret;
 880
 881        _enter("{%u}", call->unmarshall);
 882
 883        ret = afs_transfer_reply(call);
 884        if (ret < 0)
 885                return ret;
 886
 887        bp = call->buffer;
 888        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
 889        if (ret < 0)
 890                return ret;
 891
 892        xdr_decode_YFSVolSync(&bp, call->out_volsync);
 893        return 0;
 894}
 895
 896/*
 897 * FS.RemoveDir and FS.RemoveFile operation types.
 898 */
 899static const struct afs_call_type yfs_RXYFSRemoveFile = {
 900        .name           = "YFS.RemoveFile",
 901        .op             = yfs_FS_RemoveFile,
 902        .deliver        = yfs_deliver_fs_remove,
 903        .destructor     = afs_flat_call_destructor,
 904};
 905
 906static const struct afs_call_type yfs_RXYFSRemoveDir = {
 907        .name           = "YFS.RemoveDir",
 908        .op             = yfs_FS_RemoveDir,
 909        .deliver        = yfs_deliver_fs_remove,
 910        .destructor     = afs_flat_call_destructor,
 911};
 912
 913/*
 914 * remove a file or directory
 915 */
 916int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
 917                  const char *name, bool isdir,
 918                  struct afs_status_cb *dvnode_scb)
 919{
 920        struct afs_vnode *dvnode = fc->vnode;
 921        struct afs_call *call;
 922        struct afs_net *net = afs_v2net(dvnode);
 923        size_t namesz;
 924        __be32 *bp;
 925
 926        _enter("");
 927
 928        namesz = strlen(name);
 929        call = afs_alloc_flat_call(
 930                net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
 931                sizeof(__be32) +
 932                sizeof(struct yfs_xdr_RPCFlags) +
 933                sizeof(struct yfs_xdr_YFSFid) +
 934                xdr_strlen(namesz),
 935                sizeof(struct yfs_xdr_YFSFetchStatus) +
 936                sizeof(struct yfs_xdr_YFSVolSync));
 937        if (!call)
 938                return -ENOMEM;
 939
 940        call->key = fc->key;
 941        call->out_dir_scb = dvnode_scb;
 942
 943        /* marshall the parameters */
 944        bp = call->request;
 945        bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
 946        bp = xdr_encode_u32(bp, 0); /* RPC flags */
 947        bp = xdr_encode_YFSFid(bp, &dvnode->fid);
 948        bp = xdr_encode_string(bp, name, namesz);
 949        yfs_check_req(call, bp);
 950
 951        afs_use_fs_server(call, fc->cbi);
 952        trace_afs_make_fs_call1(call, &dvnode->fid, name);
 953        afs_set_fc_call(call, fc);
 954        afs_make_call(&fc->ac, call, GFP_NOFS);
 955        return afs_wait_for_call_to_complete(call, &fc->ac);
 956}
 957
 958/*
 959 * Deliver reply data to a YFS.Link operation.
 960 */
 961static int yfs_deliver_fs_link(struct afs_call *call)
 962{
 963        const __be32 *bp;
 964        int ret;
 965
 966        _enter("{%u}", call->unmarshall);
 967
 968        ret = afs_transfer_reply(call);
 969        if (ret < 0)
 970                return ret;
 971
 972        bp = call->buffer;
 973        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
 974        if (ret < 0)
 975                return ret;
 976        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
 977        if (ret < 0)
 978                return ret;
 979        xdr_decode_YFSVolSync(&bp, call->out_volsync);
 980        _leave(" = 0 [done]");
 981        return 0;
 982}
 983
 984/*
 985 * YFS.Link operation type.
 986 */
 987static const struct afs_call_type yfs_RXYFSLink = {
 988        .name           = "YFS.Link",
 989        .op             = yfs_FS_Link,
 990        .deliver        = yfs_deliver_fs_link,
 991        .destructor     = afs_flat_call_destructor,
 992};
 993
 994/*
 995 * Make a hard link.
 996 */
 997int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
 998                const char *name,
 999                struct afs_status_cb *dvnode_scb,
1000                struct afs_status_cb *vnode_scb)
1001{
1002        struct afs_vnode *dvnode = fc->vnode;
1003        struct afs_call *call;
1004        struct afs_net *net = afs_v2net(vnode);
1005        size_t namesz;
1006        __be32 *bp;
1007
1008        _enter("");
1009
1010        namesz = strlen(name);
1011        call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1012                                   sizeof(__be32) +
1013                                   sizeof(struct yfs_xdr_RPCFlags) +
1014                                   sizeof(struct yfs_xdr_YFSFid) +
1015                                   xdr_strlen(namesz) +
1016                                   sizeof(struct yfs_xdr_YFSFid),
1017                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1018                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1019                                   sizeof(struct yfs_xdr_YFSVolSync));
1020        if (!call)
1021                return -ENOMEM;
1022
1023        call->key = fc->key;
1024        call->out_dir_scb = dvnode_scb;
1025        call->out_scb = vnode_scb;
1026
1027        /* marshall the parameters */
1028        bp = call->request;
1029        bp = xdr_encode_u32(bp, YFSLINK);
1030        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1031        bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1032        bp = xdr_encode_string(bp, name, namesz);
1033        bp = xdr_encode_YFSFid(bp, &vnode->fid);
1034        yfs_check_req(call, bp);
1035
1036        afs_use_fs_server(call, fc->cbi);
1037        trace_afs_make_fs_call1(call, &vnode->fid, name);
1038        afs_set_fc_call(call, fc);
1039        afs_make_call(&fc->ac, call, GFP_NOFS);
1040        return afs_wait_for_call_to_complete(call, &fc->ac);
1041}
1042
1043/*
1044 * Deliver reply data to a YFS.Symlink operation.
1045 */
1046static int yfs_deliver_fs_symlink(struct afs_call *call)
1047{
1048        const __be32 *bp;
1049        int ret;
1050
1051        _enter("{%u}", call->unmarshall);
1052
1053        ret = afs_transfer_reply(call);
1054        if (ret < 0)
1055                return ret;
1056
1057        /* unmarshall the reply once we've received all of it */
1058        bp = call->buffer;
1059        xdr_decode_YFSFid(&bp, call->out_fid);
1060        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1061        if (ret < 0)
1062                return ret;
1063        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1064        if (ret < 0)
1065                return ret;
1066        xdr_decode_YFSVolSync(&bp, call->out_volsync);
1067
1068        _leave(" = 0 [done]");
1069        return 0;
1070}
1071
1072/*
1073 * YFS.Symlink operation type
1074 */
1075static const struct afs_call_type yfs_RXYFSSymlink = {
1076        .name           = "YFS.Symlink",
1077        .op             = yfs_FS_Symlink,
1078        .deliver        = yfs_deliver_fs_symlink,
1079        .destructor     = afs_flat_call_destructor,
1080};
1081
1082/*
1083 * Create a symbolic link.
1084 */
1085int yfs_fs_symlink(struct afs_fs_cursor *fc,
1086                   const char *name,
1087                   const char *contents,
1088                   struct afs_status_cb *dvnode_scb,
1089                   struct afs_fid *newfid,
1090                   struct afs_status_cb *vnode_scb)
1091{
1092        struct afs_vnode *dvnode = fc->vnode;
1093        struct afs_call *call;
1094        struct afs_net *net = afs_v2net(dvnode);
1095        size_t namesz, contents_sz;
1096        __be32 *bp;
1097
1098        _enter("");
1099
1100        namesz = strlen(name);
1101        contents_sz = strlen(contents);
1102        call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1103                                   sizeof(__be32) +
1104                                   sizeof(struct yfs_xdr_RPCFlags) +
1105                                   sizeof(struct yfs_xdr_YFSFid) +
1106                                   xdr_strlen(namesz) +
1107                                   xdr_strlen(contents_sz) +
1108                                   sizeof(struct yfs_xdr_YFSStoreStatus),
1109                                   sizeof(struct yfs_xdr_YFSFid) +
1110                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1111                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1112                                   sizeof(struct yfs_xdr_YFSVolSync));
1113        if (!call)
1114                return -ENOMEM;
1115
1116        call->key = fc->key;
1117        call->out_dir_scb = dvnode_scb;
1118        call->out_fid = newfid;
1119        call->out_scb = vnode_scb;
1120
1121        /* marshall the parameters */
1122        bp = call->request;
1123        bp = xdr_encode_u32(bp, YFSSYMLINK);
1124        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1125        bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1126        bp = xdr_encode_string(bp, name, namesz);
1127        bp = xdr_encode_string(bp, contents, contents_sz);
1128        bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1129        yfs_check_req(call, bp);
1130
1131        afs_use_fs_server(call, fc->cbi);
1132        trace_afs_make_fs_call1(call, &dvnode->fid, name);
1133        afs_set_fc_call(call, fc);
1134        afs_make_call(&fc->ac, call, GFP_NOFS);
1135        return afs_wait_for_call_to_complete(call, &fc->ac);
1136}
1137
1138/*
1139 * Deliver reply data to a YFS.Rename operation.
1140 */
1141static int yfs_deliver_fs_rename(struct afs_call *call)
1142{
1143        const __be32 *bp;
1144        int ret;
1145
1146        _enter("{%u}", call->unmarshall);
1147
1148        ret = afs_transfer_reply(call);
1149        if (ret < 0)
1150                return ret;
1151
1152        bp = call->buffer;
1153        ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1154        if (ret < 0)
1155                return ret;
1156        if (call->out_dir_scb != call->out_scb) {
1157                ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1158                if (ret < 0)
1159                        return ret;
1160        }
1161
1162        xdr_decode_YFSVolSync(&bp, call->out_volsync);
1163        _leave(" = 0 [done]");
1164        return 0;
1165}
1166
1167/*
1168 * YFS.Rename operation type
1169 */
1170static const struct afs_call_type yfs_RXYFSRename = {
1171        .name           = "FS.Rename",
1172        .op             = yfs_FS_Rename,
1173        .deliver        = yfs_deliver_fs_rename,
1174        .destructor     = afs_flat_call_destructor,
1175};
1176
1177/*
1178 * Rename a file or directory.
1179 */
1180int yfs_fs_rename(struct afs_fs_cursor *fc,
1181                  const char *orig_name,
1182                  struct afs_vnode *new_dvnode,
1183                  const char *new_name,
1184                  struct afs_status_cb *orig_dvnode_scb,
1185                  struct afs_status_cb *new_dvnode_scb)
1186{
1187        struct afs_vnode *orig_dvnode = fc->vnode;
1188        struct afs_call *call;
1189        struct afs_net *net = afs_v2net(orig_dvnode);
1190        size_t o_namesz, n_namesz;
1191        __be32 *bp;
1192
1193        _enter("");
1194
1195        o_namesz = strlen(orig_name);
1196        n_namesz = strlen(new_name);
1197        call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1198                                   sizeof(__be32) +
1199                                   sizeof(struct yfs_xdr_RPCFlags) +
1200                                   sizeof(struct yfs_xdr_YFSFid) +
1201                                   xdr_strlen(o_namesz) +
1202                                   sizeof(struct yfs_xdr_YFSFid) +
1203                                   xdr_strlen(n_namesz),
1204                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1205                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1206                                   sizeof(struct yfs_xdr_YFSVolSync));
1207        if (!call)
1208                return -ENOMEM;
1209
1210        call->key = fc->key;
1211        call->out_dir_scb = orig_dvnode_scb;
1212        call->out_scb = new_dvnode_scb;
1213
1214        /* marshall the parameters */
1215        bp = call->request;
1216        bp = xdr_encode_u32(bp, YFSRENAME);
1217        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1218        bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1219        bp = xdr_encode_string(bp, orig_name, o_namesz);
1220        bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1221        bp = xdr_encode_string(bp, new_name, n_namesz);
1222        yfs_check_req(call, bp);
1223
1224        afs_use_fs_server(call, fc->cbi);
1225        trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
1226        afs_set_fc_call(call, fc);
1227        afs_make_call(&fc->ac, call, GFP_NOFS);
1228        return afs_wait_for_call_to_complete(call, &fc->ac);
1229}
1230
1231/*
1232 * YFS.StoreData64 operation type.
1233 */
1234static const struct afs_call_type yfs_RXYFSStoreData64 = {
1235        .name           = "YFS.StoreData64",
1236        .op             = yfs_FS_StoreData64,
1237        .deliver        = yfs_deliver_status_and_volsync,
1238        .destructor     = afs_flat_call_destructor,
1239};
1240
1241/*
1242 * Store a set of pages to a large file.
1243 */
1244int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1245                      pgoff_t first, pgoff_t last,
1246                      unsigned offset, unsigned to,
1247                      struct afs_status_cb *scb)
1248{
1249        struct afs_vnode *vnode = fc->vnode;
1250        struct afs_call *call;
1251        struct afs_net *net = afs_v2net(vnode);
1252        loff_t size, pos, i_size;
1253        __be32 *bp;
1254
1255        _enter(",%x,{%llx:%llu},,",
1256               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1257
1258        size = (loff_t)to - (loff_t)offset;
1259        if (first != last)
1260                size += (loff_t)(last - first) << PAGE_SHIFT;
1261        pos = (loff_t)first << PAGE_SHIFT;
1262        pos += offset;
1263
1264        i_size = i_size_read(&vnode->vfs_inode);
1265        if (pos + size > i_size)
1266                i_size = size + pos;
1267
1268        _debug("size %llx, at %llx, i_size %llx",
1269               (unsigned long long)size, (unsigned long long)pos,
1270               (unsigned long long)i_size);
1271
1272        call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1273                                   sizeof(__be32) +
1274                                   sizeof(__be32) +
1275                                   sizeof(struct yfs_xdr_YFSFid) +
1276                                   sizeof(struct yfs_xdr_YFSStoreStatus) +
1277                                   sizeof(struct yfs_xdr_u64) * 3,
1278                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1279                                   sizeof(struct yfs_xdr_YFSVolSync));
1280        if (!call)
1281                return -ENOMEM;
1282
1283        call->key = fc->key;
1284        call->mapping = mapping;
1285        call->first = first;
1286        call->last = last;
1287        call->first_offset = offset;
1288        call->last_to = to;
1289        call->send_pages = true;
1290        call->out_scb = scb;
1291
1292        /* marshall the parameters */
1293        bp = call->request;
1294        bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1295        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1296        bp = xdr_encode_YFSFid(bp, &vnode->fid);
1297        bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1298        bp = xdr_encode_u64(bp, pos);
1299        bp = xdr_encode_u64(bp, size);
1300        bp = xdr_encode_u64(bp, i_size);
1301        yfs_check_req(call, bp);
1302
1303        afs_use_fs_server(call, fc->cbi);
1304        trace_afs_make_fs_call(call, &vnode->fid);
1305        afs_set_fc_call(call, fc);
1306        afs_make_call(&fc->ac, call, GFP_NOFS);
1307        return afs_wait_for_call_to_complete(call, &fc->ac);
1308}
1309
1310/*
1311 * YFS.StoreStatus operation type
1312 */
1313static const struct afs_call_type yfs_RXYFSStoreStatus = {
1314        .name           = "YFS.StoreStatus",
1315        .op             = yfs_FS_StoreStatus,
1316        .deliver        = yfs_deliver_status_and_volsync,
1317        .destructor     = afs_flat_call_destructor,
1318};
1319
1320static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1321        .name           = "YFS.StoreData64",
1322        .op             = yfs_FS_StoreData64,
1323        .deliver        = yfs_deliver_status_and_volsync,
1324        .destructor     = afs_flat_call_destructor,
1325};
1326
1327/*
1328 * Set the attributes on a file, using YFS.StoreData64 rather than
1329 * YFS.StoreStatus so as to alter the file size also.
1330 */
1331static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr,
1332                               struct afs_status_cb *scb)
1333{
1334        struct afs_vnode *vnode = fc->vnode;
1335        struct afs_call *call;
1336        struct afs_net *net = afs_v2net(vnode);
1337        __be32 *bp;
1338
1339        _enter(",%x,{%llx:%llu},,",
1340               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1341
1342        call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1343                                   sizeof(__be32) * 2 +
1344                                   sizeof(struct yfs_xdr_YFSFid) +
1345                                   sizeof(struct yfs_xdr_YFSStoreStatus) +
1346                                   sizeof(struct yfs_xdr_u64) * 3,
1347                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1348                                   sizeof(struct yfs_xdr_YFSVolSync));
1349        if (!call)
1350                return -ENOMEM;
1351
1352        call->key = fc->key;
1353        call->out_scb = scb;
1354
1355        /* marshall the parameters */
1356        bp = call->request;
1357        bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1358        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1359        bp = xdr_encode_YFSFid(bp, &vnode->fid);
1360        bp = xdr_encode_YFS_StoreStatus(bp, attr);
1361        bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1362        bp = xdr_encode_u64(bp, 0);             /* size of write */
1363        bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1364        yfs_check_req(call, bp);
1365
1366        afs_use_fs_server(call, fc->cbi);
1367        trace_afs_make_fs_call(call, &vnode->fid);
1368        afs_set_fc_call(call, fc);
1369        afs_make_call(&fc->ac, call, GFP_NOFS);
1370        return afs_wait_for_call_to_complete(call, &fc->ac);
1371}
1372
1373/*
1374 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1375 * file size, and YFS.StoreStatus otherwise.
1376 */
1377int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr,
1378                   struct afs_status_cb *scb)
1379{
1380        struct afs_vnode *vnode = fc->vnode;
1381        struct afs_call *call;
1382        struct afs_net *net = afs_v2net(vnode);
1383        __be32 *bp;
1384
1385        if (attr->ia_valid & ATTR_SIZE)
1386                return yfs_fs_setattr_size(fc, attr, scb);
1387
1388        _enter(",%x,{%llx:%llu},,",
1389               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1390
1391        call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1392                                   sizeof(__be32) * 2 +
1393                                   sizeof(struct yfs_xdr_YFSFid) +
1394                                   sizeof(struct yfs_xdr_YFSStoreStatus),
1395                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1396                                   sizeof(struct yfs_xdr_YFSVolSync));
1397        if (!call)
1398                return -ENOMEM;
1399
1400        call->key = fc->key;
1401        call->out_scb = scb;
1402
1403        /* marshall the parameters */
1404        bp = call->request;
1405        bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1406        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1407        bp = xdr_encode_YFSFid(bp, &vnode->fid);
1408        bp = xdr_encode_YFS_StoreStatus(bp, attr);
1409        yfs_check_req(call, bp);
1410
1411        afs_use_fs_server(call, fc->cbi);
1412        trace_afs_make_fs_call(call, &vnode->fid);
1413        afs_set_fc_call(call, fc);
1414        afs_make_call(&fc->ac, call, GFP_NOFS);
1415        return afs_wait_for_call_to_complete(call, &fc->ac);
1416}
1417
1418/*
1419 * Deliver reply data to a YFS.GetVolumeStatus operation.
1420 */
1421static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1422{
1423        const __be32 *bp;
1424        char *p;
1425        u32 size;
1426        int ret;
1427
1428        _enter("{%u}", call->unmarshall);
1429
1430        switch (call->unmarshall) {
1431        case 0:
1432                call->unmarshall++;
1433                afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1434                /* Fall through */
1435
1436                /* extract the returned status record */
1437        case 1:
1438                _debug("extract status");
1439                ret = afs_extract_data(call, true);
1440                if (ret < 0)
1441                        return ret;
1442
1443                bp = call->buffer;
1444                xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus);
1445                call->unmarshall++;
1446                afs_extract_to_tmp(call);
1447                /* Fall through */
1448
1449                /* extract the volume name length */
1450        case 2:
1451                ret = afs_extract_data(call, true);
1452                if (ret < 0)
1453                        return ret;
1454
1455                call->count = ntohl(call->tmp);
1456                _debug("volname length: %u", call->count);
1457                if (call->count >= AFSNAMEMAX)
1458                        return afs_protocol_error(call, -EBADMSG,
1459                                                  afs_eproto_volname_len);
1460                size = (call->count + 3) & ~3; /* It's padded */
1461                afs_extract_to_buf(call, size);
1462                call->unmarshall++;
1463                /* Fall through */
1464
1465                /* extract the volume name */
1466        case 3:
1467                _debug("extract volname");
1468                ret = afs_extract_data(call, true);
1469                if (ret < 0)
1470                        return ret;
1471
1472                p = call->buffer;
1473                p[call->count] = 0;
1474                _debug("volname '%s'", p);
1475                afs_extract_to_tmp(call);
1476                call->unmarshall++;
1477                /* Fall through */
1478
1479                /* extract the offline message length */
1480        case 4:
1481                ret = afs_extract_data(call, true);
1482                if (ret < 0)
1483                        return ret;
1484
1485                call->count = ntohl(call->tmp);
1486                _debug("offline msg length: %u", call->count);
1487                if (call->count >= AFSNAMEMAX)
1488                        return afs_protocol_error(call, -EBADMSG,
1489                                                  afs_eproto_offline_msg_len);
1490                size = (call->count + 3) & ~3; /* It's padded */
1491                afs_extract_to_buf(call, size);
1492                call->unmarshall++;
1493                /* Fall through */
1494
1495                /* extract the offline message */
1496        case 5:
1497                _debug("extract offline");
1498                ret = afs_extract_data(call, true);
1499                if (ret < 0)
1500                        return ret;
1501
1502                p = call->buffer;
1503                p[call->count] = 0;
1504                _debug("offline '%s'", p);
1505
1506                afs_extract_to_tmp(call);
1507                call->unmarshall++;
1508                /* Fall through */
1509
1510                /* extract the message of the day length */
1511        case 6:
1512                ret = afs_extract_data(call, true);
1513                if (ret < 0)
1514                        return ret;
1515
1516                call->count = ntohl(call->tmp);
1517                _debug("motd length: %u", call->count);
1518                if (call->count >= AFSNAMEMAX)
1519                        return afs_protocol_error(call, -EBADMSG,
1520                                                  afs_eproto_motd_len);
1521                size = (call->count + 3) & ~3; /* It's padded */
1522                afs_extract_to_buf(call, size);
1523                call->unmarshall++;
1524                /* Fall through */
1525
1526                /* extract the message of the day */
1527        case 7:
1528                _debug("extract motd");
1529                ret = afs_extract_data(call, false);
1530                if (ret < 0)
1531                        return ret;
1532
1533                p = call->buffer;
1534                p[call->count] = 0;
1535                _debug("motd '%s'", p);
1536
1537                call->unmarshall++;
1538                /* Fall through */
1539
1540        case 8:
1541                break;
1542        }
1543
1544        _leave(" = 0 [done]");
1545        return 0;
1546}
1547
1548/*
1549 * YFS.GetVolumeStatus operation type
1550 */
1551static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1552        .name           = "YFS.GetVolumeStatus",
1553        .op             = yfs_FS_GetVolumeStatus,
1554        .deliver        = yfs_deliver_fs_get_volume_status,
1555        .destructor     = afs_flat_call_destructor,
1556};
1557
1558/*
1559 * fetch the status of a volume
1560 */
1561int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1562                             struct afs_volume_status *vs)
1563{
1564        struct afs_vnode *vnode = fc->vnode;
1565        struct afs_call *call;
1566        struct afs_net *net = afs_v2net(vnode);
1567        __be32 *bp;
1568
1569        _enter("");
1570
1571        call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1572                                   sizeof(__be32) * 2 +
1573                                   sizeof(struct yfs_xdr_u64),
1574                                   max_t(size_t,
1575                                         sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1576                                         sizeof(__be32),
1577                                         AFSOPAQUEMAX + 1));
1578        if (!call)
1579                return -ENOMEM;
1580
1581        call->key = fc->key;
1582        call->out_volstatus = vs;
1583
1584        /* marshall the parameters */
1585        bp = call->request;
1586        bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1587        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1588        bp = xdr_encode_u64(bp, vnode->fid.vid);
1589        yfs_check_req(call, bp);
1590
1591        afs_use_fs_server(call, fc->cbi);
1592        trace_afs_make_fs_call(call, &vnode->fid);
1593        afs_set_fc_call(call, fc);
1594        afs_make_call(&fc->ac, call, GFP_NOFS);
1595        return afs_wait_for_call_to_complete(call, &fc->ac);
1596}
1597
1598/*
1599 * YFS.SetLock operation type
1600 */
1601static const struct afs_call_type yfs_RXYFSSetLock = {
1602        .name           = "YFS.SetLock",
1603        .op             = yfs_FS_SetLock,
1604        .deliver        = yfs_deliver_status_and_volsync,
1605        .done           = afs_lock_op_done,
1606        .destructor     = afs_flat_call_destructor,
1607};
1608
1609/*
1610 * YFS.ExtendLock operation type
1611 */
1612static const struct afs_call_type yfs_RXYFSExtendLock = {
1613        .name           = "YFS.ExtendLock",
1614        .op             = yfs_FS_ExtendLock,
1615        .deliver        = yfs_deliver_status_and_volsync,
1616        .done           = afs_lock_op_done,
1617        .destructor     = afs_flat_call_destructor,
1618};
1619
1620/*
1621 * YFS.ReleaseLock operation type
1622 */
1623static const struct afs_call_type yfs_RXYFSReleaseLock = {
1624        .name           = "YFS.ReleaseLock",
1625        .op             = yfs_FS_ReleaseLock,
1626        .deliver        = yfs_deliver_status_and_volsync,
1627        .destructor     = afs_flat_call_destructor,
1628};
1629
1630/*
1631 * Set a lock on a file
1632 */
1633int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,
1634                    struct afs_status_cb *scb)
1635{
1636        struct afs_vnode *vnode = fc->vnode;
1637        struct afs_call *call;
1638        struct afs_net *net = afs_v2net(vnode);
1639        __be32 *bp;
1640
1641        _enter("");
1642
1643        call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1644                                   sizeof(__be32) * 2 +
1645                                   sizeof(struct yfs_xdr_YFSFid) +
1646                                   sizeof(__be32),
1647                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1648                                   sizeof(struct yfs_xdr_YFSVolSync));
1649        if (!call)
1650                return -ENOMEM;
1651
1652        call->key = fc->key;
1653        call->lvnode = vnode;
1654        call->out_scb = scb;
1655
1656        /* marshall the parameters */
1657        bp = call->request;
1658        bp = xdr_encode_u32(bp, YFSSETLOCK);
1659        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1660        bp = xdr_encode_YFSFid(bp, &vnode->fid);
1661        bp = xdr_encode_u32(bp, type);
1662        yfs_check_req(call, bp);
1663
1664        afs_use_fs_server(call, fc->cbi);
1665        trace_afs_make_fs_calli(call, &vnode->fid, type);
1666        afs_set_fc_call(call, fc);
1667        afs_make_call(&fc->ac, call, GFP_NOFS);
1668        return afs_wait_for_call_to_complete(call, &fc->ac);
1669}
1670
1671/*
1672 * extend a lock on a file
1673 */
1674int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1675{
1676        struct afs_vnode *vnode = fc->vnode;
1677        struct afs_call *call;
1678        struct afs_net *net = afs_v2net(vnode);
1679        __be32 *bp;
1680
1681        _enter("");
1682
1683        call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1684                                   sizeof(__be32) * 2 +
1685                                   sizeof(struct yfs_xdr_YFSFid),
1686                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1687                                   sizeof(struct yfs_xdr_YFSVolSync));
1688        if (!call)
1689                return -ENOMEM;
1690
1691        call->key = fc->key;
1692        call->lvnode = vnode;
1693        call->out_scb = scb;
1694
1695        /* marshall the parameters */
1696        bp = call->request;
1697        bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1698        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1699        bp = xdr_encode_YFSFid(bp, &vnode->fid);
1700        yfs_check_req(call, bp);
1701
1702        afs_use_fs_server(call, fc->cbi);
1703        trace_afs_make_fs_call(call, &vnode->fid);
1704        afs_set_fc_call(call, fc);
1705        afs_make_call(&fc->ac, call, GFP_NOFS);
1706        return afs_wait_for_call_to_complete(call, &fc->ac);
1707}
1708
1709/*
1710 * release a lock on a file
1711 */
1712int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1713{
1714        struct afs_vnode *vnode = fc->vnode;
1715        struct afs_call *call;
1716        struct afs_net *net = afs_v2net(vnode);
1717        __be32 *bp;
1718
1719        _enter("");
1720
1721        call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1722                                   sizeof(__be32) * 2 +
1723                                   sizeof(struct yfs_xdr_YFSFid),
1724                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1725                                   sizeof(struct yfs_xdr_YFSVolSync));
1726        if (!call)
1727                return -ENOMEM;
1728
1729        call->key = fc->key;
1730        call->lvnode = vnode;
1731        call->out_scb = scb;
1732
1733        /* marshall the parameters */
1734        bp = call->request;
1735        bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1736        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1737        bp = xdr_encode_YFSFid(bp, &vnode->fid);
1738        yfs_check_req(call, bp);
1739
1740        afs_use_fs_server(call, fc->cbi);
1741        trace_afs_make_fs_call(call, &vnode->fid);
1742        afs_set_fc_call(call, fc);
1743        afs_make_call(&fc->ac, call, GFP_NOFS);
1744        return afs_wait_for_call_to_complete(call, &fc->ac);
1745}
1746
1747/*
1748 * YFS.FetchStatus operation type
1749 */
1750static const struct afs_call_type yfs_RXYFSFetchStatus = {
1751        .name           = "YFS.FetchStatus",
1752        .op             = yfs_FS_FetchStatus,
1753        .deliver        = yfs_deliver_fs_status_cb_and_volsync,
1754        .destructor     = afs_flat_call_destructor,
1755};
1756
1757/*
1758 * Fetch the status information for a fid without needing a vnode handle.
1759 */
1760int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1761                        struct afs_net *net,
1762                        struct afs_fid *fid,
1763                        struct afs_status_cb *scb,
1764                        struct afs_volsync *volsync)
1765{
1766        struct afs_call *call;
1767        __be32 *bp;
1768
1769        _enter(",%x,{%llx:%llu},,",
1770               key_serial(fc->key), fid->vid, fid->vnode);
1771
1772        call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1773                                   sizeof(__be32) * 2 +
1774                                   sizeof(struct yfs_xdr_YFSFid),
1775                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
1776                                   sizeof(struct yfs_xdr_YFSCallBack) +
1777                                   sizeof(struct yfs_xdr_YFSVolSync));
1778        if (!call) {
1779                fc->ac.error = -ENOMEM;
1780                return -ENOMEM;
1781        }
1782
1783        call->key = fc->key;
1784        call->out_scb = scb;
1785        call->out_volsync = volsync;
1786
1787        /* marshall the parameters */
1788        bp = call->request;
1789        bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1790        bp = xdr_encode_u32(bp, 0); /* RPC flags */
1791        bp = xdr_encode_YFSFid(bp, fid);
1792        yfs_check_req(call, bp);
1793
1794        afs_use_fs_server(call, fc->cbi);
1795        trace_afs_make_fs_call(call, fid);
1796        afs_set_fc_call(call, fc);
1797        afs_make_call(&fc->ac, call, GFP_NOFS);
1798        return afs_wait_for_call_to_complete(call, &fc->ac);
1799}
1800
1801/*
1802 * Deliver reply data to an YFS.InlineBulkStatus call
1803 */
1804static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1805{
1806        struct afs_status_cb *scb;
1807        const __be32 *bp;
1808        u32 tmp;
1809        int ret;
1810
1811        _enter("{%u}", call->unmarshall);
1812
1813        switch (call->unmarshall) {
1814        case 0:
1815                afs_extract_to_tmp(call);
1816                call->unmarshall++;
1817                /* Fall through */
1818
1819                /* Extract the file status count and array in two steps */
1820        case 1:
1821                _debug("extract status count");
1822                ret = afs_extract_data(call, true);
1823                if (ret < 0)
1824                        return ret;
1825
1826                tmp = ntohl(call->tmp);
1827                _debug("status count: %u/%u", tmp, call->count2);
1828                if (tmp != call->count2)
1829                        return afs_protocol_error(call, -EBADMSG,
1830                                                  afs_eproto_ibulkst_count);
1831
1832                call->count = 0;
1833                call->unmarshall++;
1834        more_counts:
1835                afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1836                /* Fall through */
1837
1838        case 2:
1839                _debug("extract status array %u", call->count);
1840                ret = afs_extract_data(call, true);
1841                if (ret < 0)
1842                        return ret;
1843
1844                bp = call->buffer;
1845                scb = &call->out_scb[call->count];
1846                ret = xdr_decode_YFSFetchStatus(&bp, call, scb);
1847                if (ret < 0)
1848                        return ret;
1849
1850                call->count++;
1851                if (call->count < call->count2)
1852                        goto more_counts;
1853
1854                call->count = 0;
1855                call->unmarshall++;
1856                afs_extract_to_tmp(call);
1857                /* Fall through */
1858
1859                /* Extract the callback count and array in two steps */
1860        case 3:
1861                _debug("extract CB count");
1862                ret = afs_extract_data(call, true);
1863                if (ret < 0)
1864                        return ret;
1865
1866                tmp = ntohl(call->tmp);
1867                _debug("CB count: %u", tmp);
1868                if (tmp != call->count2)
1869                        return afs_protocol_error(call, -EBADMSG,
1870                                                  afs_eproto_ibulkst_cb_count);
1871                call->count = 0;
1872                call->unmarshall++;
1873        more_cbs:
1874                afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1875                /* Fall through */
1876
1877        case 4:
1878                _debug("extract CB array");
1879                ret = afs_extract_data(call, true);
1880                if (ret < 0)
1881                        return ret;
1882
1883                _debug("unmarshall CB array");
1884                bp = call->buffer;
1885                scb = &call->out_scb[call->count];
1886                xdr_decode_YFSCallBack(&bp, call, scb);
1887                call->count++;
1888                if (call->count < call->count2)
1889                        goto more_cbs;
1890
1891                afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1892                call->unmarshall++;
1893                /* Fall through */
1894
1895        case 5:
1896                ret = afs_extract_data(call, false);
1897                if (ret < 0)
1898                        return ret;
1899
1900                bp = call->buffer;
1901                xdr_decode_YFSVolSync(&bp, call->out_volsync);
1902
1903                call->unmarshall++;
1904                /* Fall through */
1905
1906        case 6:
1907                break;
1908        }
1909
1910        _leave(" = 0 [done]");
1911        return 0;
1912}
1913
1914/*
1915 * FS.InlineBulkStatus operation type
1916 */
1917static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1918        .name           = "YFS.InlineBulkStatus",
1919        .op             = yfs_FS_InlineBulkStatus,
1920        .deliver        = yfs_deliver_fs_inline_bulk_status,
1921        .destructor     = afs_flat_call_destructor,
1922};
1923
1924/*
1925 * Fetch the status information for up to 1024 files
1926 */
1927int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
1928                              struct afs_net *net,
1929                              struct afs_fid *fids,
1930                              struct afs_status_cb *statuses,
1931                              unsigned int nr_fids,
1932                              struct afs_volsync *volsync)
1933{
1934        struct afs_call *call;
1935        __be32 *bp;
1936        int i;
1937
1938        _enter(",%x,{%llx:%llu},%u",
1939               key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
1940
1941        call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
1942                                   sizeof(__be32) +
1943                                   sizeof(__be32) +
1944                                   sizeof(__be32) +
1945                                   sizeof(struct yfs_xdr_YFSFid) * nr_fids,
1946                                   sizeof(struct yfs_xdr_YFSFetchStatus));
1947        if (!call) {
1948                fc->ac.error = -ENOMEM;
1949                return -ENOMEM;
1950        }
1951
1952        call->key = fc->key;
1953        call->out_scb = statuses;
1954        call->out_volsync = volsync;
1955        call->count2 = nr_fids;
1956
1957        /* marshall the parameters */
1958        bp = call->request;
1959        bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1960        bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1961        bp = xdr_encode_u32(bp, nr_fids);
1962        for (i = 0; i < nr_fids; i++)
1963                bp = xdr_encode_YFSFid(bp, &fids[i]);
1964        yfs_check_req(call, bp);
1965
1966        afs_use_fs_server(call, fc->cbi);
1967        trace_afs_make_fs_call(call, &fids[0]);
1968        afs_set_fc_call(call, fc);
1969        afs_make_call(&fc->ac, call, GFP_NOFS);
1970        return afs_wait_for_call_to_complete(call, &fc->ac);
1971}
1972
1973/*
1974 * Deliver reply data to an YFS.FetchOpaqueACL.
1975 */
1976static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1977{
1978        struct yfs_acl *yacl = call->out_yacl;
1979        struct afs_acl *acl;
1980        const __be32 *bp;
1981        unsigned int size;
1982        int ret;
1983
1984        _enter("{%u}", call->unmarshall);
1985
1986        switch (call->unmarshall) {
1987        case 0:
1988                afs_extract_to_tmp(call);
1989                call->unmarshall++;
1990                /* Fall through */
1991
1992                /* Extract the file ACL length */
1993        case 1:
1994                ret = afs_extract_data(call, true);
1995                if (ret < 0)
1996                        return ret;
1997
1998                size = call->count2 = ntohl(call->tmp);
1999                size = round_up(size, 4);
2000
2001                if (yacl->flags & YFS_ACL_WANT_ACL) {
2002                        acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2003                        if (!acl)
2004                                return -ENOMEM;
2005                        yacl->acl = acl;
2006                        acl->size = call->count2;
2007                        afs_extract_begin(call, acl->data, size);
2008                } else {
2009                        afs_extract_discard(call, size);
2010                }
2011                call->unmarshall++;
2012                /* Fall through */
2013
2014                /* Extract the file ACL */
2015        case 2:
2016                ret = afs_extract_data(call, true);
2017                if (ret < 0)
2018                        return ret;
2019
2020                afs_extract_to_tmp(call);
2021                call->unmarshall++;
2022                /* Fall through */
2023
2024                /* Extract the volume ACL length */
2025        case 3:
2026                ret = afs_extract_data(call, true);
2027                if (ret < 0)
2028                        return ret;
2029
2030                size = call->count2 = ntohl(call->tmp);
2031                size = round_up(size, 4);
2032
2033                if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2034                        acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2035                        if (!acl)
2036                                return -ENOMEM;
2037                        yacl->vol_acl = acl;
2038                        acl->size = call->count2;
2039                        afs_extract_begin(call, acl->data, size);
2040                } else {
2041                        afs_extract_discard(call, size);
2042                }
2043                call->unmarshall++;
2044                /* Fall through */
2045
2046                /* Extract the volume ACL */
2047        case 4:
2048                ret = afs_extract_data(call, true);
2049                if (ret < 0)
2050                        return ret;
2051
2052                afs_extract_to_buf(call,
2053                                   sizeof(__be32) * 2 +
2054                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
2055                                   sizeof(struct yfs_xdr_YFSVolSync));
2056                call->unmarshall++;
2057                /* Fall through */
2058
2059                /* extract the metadata */
2060        case 5:
2061                ret = afs_extract_data(call, false);
2062                if (ret < 0)
2063                        return ret;
2064
2065                bp = call->buffer;
2066                yacl->inherit_flag = ntohl(*bp++);
2067                yacl->num_cleaned = ntohl(*bp++);
2068                ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
2069                if (ret < 0)
2070                        return ret;
2071                xdr_decode_YFSVolSync(&bp, call->out_volsync);
2072
2073                call->unmarshall++;
2074                /* Fall through */
2075
2076        case 6:
2077                break;
2078        }
2079
2080        _leave(" = 0 [done]");
2081        return 0;
2082}
2083
2084void yfs_free_opaque_acl(struct yfs_acl *yacl)
2085{
2086        if (yacl) {
2087                kfree(yacl->acl);
2088                kfree(yacl->vol_acl);
2089                kfree(yacl);
2090        }
2091}
2092
2093/*
2094 * YFS.FetchOpaqueACL operation type
2095 */
2096static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2097        .name           = "YFS.FetchOpaqueACL",
2098        .op             = yfs_FS_FetchOpaqueACL,
2099        .deliver        = yfs_deliver_fs_fetch_opaque_acl,
2100        .destructor     = afs_flat_call_destructor,
2101};
2102
2103/*
2104 * Fetch the YFS advanced ACLs for a file.
2105 */
2106struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
2107                                        struct yfs_acl *yacl,
2108                                        struct afs_status_cb *scb)
2109{
2110        struct afs_vnode *vnode = fc->vnode;
2111        struct afs_call *call;
2112        struct afs_net *net = afs_v2net(vnode);
2113        __be32 *bp;
2114
2115        _enter(",%x,{%llx:%llu},,",
2116               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2117
2118        call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,
2119                                   sizeof(__be32) * 2 +
2120                                   sizeof(struct yfs_xdr_YFSFid),
2121                                   sizeof(__be32) * 2 +
2122                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
2123                                   sizeof(struct yfs_xdr_YFSVolSync));
2124        if (!call) {
2125                fc->ac.error = -ENOMEM;
2126                return ERR_PTR(-ENOMEM);
2127        }
2128
2129        call->key = fc->key;
2130        call->out_yacl = yacl;
2131        call->out_scb = scb;
2132        call->out_volsync = NULL;
2133
2134        /* marshall the parameters */
2135        bp = call->request;
2136        bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2137        bp = xdr_encode_u32(bp, 0); /* RPC flags */
2138        bp = xdr_encode_YFSFid(bp, &vnode->fid);
2139        yfs_check_req(call, bp);
2140
2141        afs_use_fs_server(call, fc->cbi);
2142        trace_afs_make_fs_call(call, &vnode->fid);
2143        afs_make_call(&fc->ac, call, GFP_KERNEL);
2144        return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2145}
2146
2147/*
2148 * YFS.StoreOpaqueACL2 operation type
2149 */
2150static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2151        .name           = "YFS.StoreOpaqueACL2",
2152        .op             = yfs_FS_StoreOpaqueACL2,
2153        .deliver        = yfs_deliver_status_and_volsync,
2154        .destructor     = afs_flat_call_destructor,
2155};
2156
2157/*
2158 * Fetch the YFS ACL for a file.
2159 */
2160int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl,
2161                             struct afs_status_cb *scb)
2162{
2163        struct afs_vnode *vnode = fc->vnode;
2164        struct afs_call *call;
2165        struct afs_net *net = afs_v2net(vnode);
2166        size_t size;
2167        __be32 *bp;
2168
2169        _enter(",%x,{%llx:%llu},,",
2170               key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2171
2172        size = round_up(acl->size, 4);
2173        call = afs_alloc_flat_call(net, &yfs_RXYFSStoreOpaqueACL2,
2174                                   sizeof(__be32) * 2 +
2175                                   sizeof(struct yfs_xdr_YFSFid) +
2176                                   sizeof(__be32) + size,
2177                                   sizeof(struct yfs_xdr_YFSFetchStatus) +
2178                                   sizeof(struct yfs_xdr_YFSVolSync));
2179        if (!call) {
2180                fc->ac.error = -ENOMEM;
2181                return -ENOMEM;
2182        }
2183
2184        call->key = fc->key;
2185        call->out_scb = scb;
2186        call->out_volsync = NULL;
2187
2188        /* marshall the parameters */
2189        bp = call->request;
2190        bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2191        bp = xdr_encode_u32(bp, 0); /* RPC flags */
2192        bp = xdr_encode_YFSFid(bp, &vnode->fid);
2193        bp = xdr_encode_u32(bp, acl->size);
2194        memcpy(bp, acl->data, acl->size);
2195        if (acl->size != size)
2196                memset((void *)bp + acl->size, 0, size - acl->size);
2197        yfs_check_req(call, bp);
2198
2199        trace_afs_make_fs_call(call, &vnode->fid);
2200        afs_make_call(&fc->ac, call, GFP_KERNEL);
2201        return afs_wait_for_call_to_complete(call, &fc->ac);
2202}
2203