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