Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* YFS File Server client stubs
0003  *
0004  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 #include <linux/init.h>
0009 #include <linux/slab.h>
0010 #include <linux/sched.h>
0011 #include <linux/circ_buf.h>
0012 #include <linux/iversion.h>
0013 #include "internal.h"
0014 #include "afs_fs.h"
0015 #include "xdr_fs.h"
0016 #include "protocol_yfs.h"
0017 
0018 #define xdr_size(x) (sizeof(*x) / sizeof(__be32))
0019 
0020 static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
0021 {
0022     const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
0023 
0024     fid->vid    = xdr_to_u64(x->volume);
0025     fid->vnode  = xdr_to_u64(x->vnode.lo);
0026     fid->vnode_hi   = ntohl(x->vnode.hi);
0027     fid->unique = ntohl(x->vnode.unique);
0028     *_bp += xdr_size(x);
0029 }
0030 
0031 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
0032 {
0033     *bp++ = htonl(n);
0034     return bp;
0035 }
0036 
0037 static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
0038 {
0039     struct yfs_xdr_u64 *x = (void *)bp;
0040 
0041     *x = u64_to_xdr(n);
0042     return bp + xdr_size(x);
0043 }
0044 
0045 static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
0046 {
0047     struct yfs_xdr_YFSFid *x = (void *)bp;
0048 
0049     x->volume   = u64_to_xdr(fid->vid);
0050     x->vnode.lo = u64_to_xdr(fid->vnode);
0051     x->vnode.hi = htonl(fid->vnode_hi);
0052     x->vnode.unique = htonl(fid->unique);
0053     return bp + xdr_size(x);
0054 }
0055 
0056 static size_t xdr_strlen(unsigned int len)
0057 {
0058     return sizeof(__be32) + round_up(len, sizeof(__be32));
0059 }
0060 
0061 static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
0062 {
0063     bp = xdr_encode_u32(bp, len);
0064     bp = memcpy(bp, p, len);
0065     if (len & 3) {
0066         unsigned int pad = 4 - (len & 3);
0067 
0068         memset((u8 *)bp + len, 0, pad);
0069         len += pad;
0070     }
0071 
0072     return bp + len / sizeof(__be32);
0073 }
0074 
0075 static __be32 *xdr_encode_name(__be32 *bp, const struct qstr *p)
0076 {
0077     return xdr_encode_string(bp, p->name, p->len);
0078 }
0079 
0080 static s64 linux_to_yfs_time(const struct timespec64 *t)
0081 {
0082     /* Convert to 100ns intervals. */
0083     return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
0084 }
0085 
0086 static __be32 *xdr_encode_YFSStoreStatus(__be32 *bp, mode_t *mode,
0087                      const struct timespec64 *t)
0088 {
0089     struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
0090     mode_t masked_mode = mode ? *mode & S_IALLUGO : 0;
0091     s64 mtime = linux_to_yfs_time(t);
0092     u32 mask = AFS_SET_MTIME;
0093 
0094     mask |= mode ? AFS_SET_MODE : 0;
0095 
0096     x->mask     = htonl(mask);
0097     x->mode     = htonl(masked_mode);
0098     x->mtime_client = u64_to_xdr(mtime);
0099     x->owner    = u64_to_xdr(0);
0100     x->group    = u64_to_xdr(0);
0101     return bp + xdr_size(x);
0102 }
0103 
0104 /*
0105  * Convert a signed 100ns-resolution 64-bit time into a timespec.
0106  */
0107 static struct timespec64 yfs_time_to_linux(s64 t)
0108 {
0109     struct timespec64 ts;
0110     u64 abs_t;
0111 
0112     /*
0113      * Unfortunately can not use normal 64 bit division on 32 bit arch, but
0114      * the alternative, do_div, does not work with negative numbers so have
0115      * to special case them
0116      */
0117     if (t < 0) {
0118         abs_t = -t;
0119         ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
0120         ts.tv_nsec = -ts.tv_nsec;
0121         ts.tv_sec = -abs_t;
0122     } else {
0123         abs_t = t;
0124         ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
0125         ts.tv_sec = abs_t;
0126     }
0127 
0128     return ts;
0129 }
0130 
0131 static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
0132 {
0133     s64 t = xdr_to_u64(xdr);
0134 
0135     return yfs_time_to_linux(t);
0136 }
0137 
0138 static void yfs_check_req(struct afs_call *call, __be32 *bp)
0139 {
0140     size_t len = (void *)bp - call->request;
0141 
0142     if (len > call->request_size)
0143         pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
0144                call->type->name, len, call->request_size);
0145     else if (len < call->request_size)
0146         pr_warn("kAFS: %s: Request buffer underflow (%zu<%u)\n",
0147             call->type->name, len, call->request_size);
0148 }
0149 
0150 /*
0151  * Dump a bad file status record.
0152  */
0153 static void xdr_dump_bad(const __be32 *bp)
0154 {
0155     __be32 x[4];
0156     int i;
0157 
0158     pr_notice("YFS XDR: Bad status record\n");
0159     for (i = 0; i < 6 * 4 * 4; i += 16) {
0160         memcpy(x, bp, 16);
0161         bp += 4;
0162         pr_notice("%03x: %08x %08x %08x %08x\n",
0163               i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
0164     }
0165 
0166     memcpy(x, bp, 8);
0167     pr_notice("0x60: %08x %08x\n", ntohl(x[0]), ntohl(x[1]));
0168 }
0169 
0170 /*
0171  * Decode a YFSFetchStatus block
0172  */
0173 static void xdr_decode_YFSFetchStatus(const __be32 **_bp,
0174                       struct afs_call *call,
0175                       struct afs_status_cb *scb)
0176 {
0177     const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
0178     struct afs_file_status *status = &scb->status;
0179     u32 type;
0180 
0181     status->abort_code = ntohl(xdr->abort_code);
0182     if (status->abort_code != 0) {
0183         if (status->abort_code == VNOVNODE)
0184             status->nlink = 0;
0185         scb->have_error = true;
0186         goto advance;
0187     }
0188 
0189     type = ntohl(xdr->type);
0190     switch (type) {
0191     case AFS_FTYPE_FILE:
0192     case AFS_FTYPE_DIR:
0193     case AFS_FTYPE_SYMLINK:
0194         status->type = type;
0195         break;
0196     default:
0197         goto bad;
0198     }
0199 
0200     status->nlink       = ntohl(xdr->nlink);
0201     status->author      = xdr_to_u64(xdr->author);
0202     status->owner       = xdr_to_u64(xdr->owner);
0203     status->caller_access   = ntohl(xdr->caller_access); /* Ticket dependent */
0204     status->anon_access = ntohl(xdr->anon_access);
0205     status->mode        = ntohl(xdr->mode) & S_IALLUGO;
0206     status->group       = xdr_to_u64(xdr->group);
0207     status->lock_count  = ntohl(xdr->lock_count);
0208 
0209     status->mtime_client    = xdr_to_time(xdr->mtime_client);
0210     status->mtime_server    = xdr_to_time(xdr->mtime_server);
0211     status->size        = xdr_to_u64(xdr->size);
0212     status->data_version    = xdr_to_u64(xdr->data_version);
0213     scb->have_status    = true;
0214 advance:
0215     *_bp += xdr_size(xdr);
0216     return;
0217 
0218 bad:
0219     xdr_dump_bad(*_bp);
0220     afs_protocol_error(call, afs_eproto_bad_status);
0221     goto advance;
0222 }
0223 
0224 /*
0225  * Decode a YFSCallBack block
0226  */
0227 static void xdr_decode_YFSCallBack(const __be32 **_bp,
0228                    struct afs_call *call,
0229                    struct afs_status_cb *scb)
0230 {
0231     struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
0232     struct afs_callback *cb = &scb->callback;
0233     ktime_t cb_expiry;
0234 
0235     cb_expiry = ktime_add(call->issue_time, xdr_to_u64(x->expiration_time) * 100);
0236     cb->expires_at  = ktime_divns(cb_expiry, NSEC_PER_SEC);
0237     scb->have_cb    = true;
0238     *_bp += xdr_size(x);
0239 }
0240 
0241 /*
0242  * Decode a YFSVolSync block
0243  */
0244 static void xdr_decode_YFSVolSync(const __be32 **_bp,
0245                   struct afs_volsync *volsync)
0246 {
0247     struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
0248     u64 creation;
0249 
0250     if (volsync) {
0251         creation = xdr_to_u64(x->vol_creation_date);
0252         do_div(creation, 10 * 1000 * 1000);
0253         volsync->creation = creation;
0254     }
0255 
0256     *_bp += xdr_size(x);
0257 }
0258 
0259 /*
0260  * Encode the requested attributes into a YFSStoreStatus block
0261  */
0262 static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
0263 {
0264     struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
0265     s64 mtime = 0, owner = 0, group = 0;
0266     u32 mask = 0, mode = 0;
0267 
0268     mask = 0;
0269     if (attr->ia_valid & ATTR_MTIME) {
0270         mask |= AFS_SET_MTIME;
0271         mtime = linux_to_yfs_time(&attr->ia_mtime);
0272     }
0273 
0274     if (attr->ia_valid & ATTR_UID) {
0275         mask |= AFS_SET_OWNER;
0276         owner = from_kuid(&init_user_ns, attr->ia_uid);
0277     }
0278 
0279     if (attr->ia_valid & ATTR_GID) {
0280         mask |= AFS_SET_GROUP;
0281         group = from_kgid(&init_user_ns, attr->ia_gid);
0282     }
0283 
0284     if (attr->ia_valid & ATTR_MODE) {
0285         mask |= AFS_SET_MODE;
0286         mode = attr->ia_mode & S_IALLUGO;
0287     }
0288 
0289     x->mask     = htonl(mask);
0290     x->mode     = htonl(mode);
0291     x->mtime_client = u64_to_xdr(mtime);
0292     x->owner    = u64_to_xdr(owner);
0293     x->group    = u64_to_xdr(group);
0294     return bp + xdr_size(x);
0295 }
0296 
0297 /*
0298  * Decode a YFSFetchVolumeStatus block.
0299  */
0300 static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
0301                         struct afs_volume_status *vs)
0302 {
0303     const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
0304     u32 flags;
0305 
0306     vs->vid         = xdr_to_u64(x->vid);
0307     vs->parent_id       = xdr_to_u64(x->parent_id);
0308     flags           = ntohl(x->flags);
0309     vs->online      = flags & yfs_FVSOnline;
0310     vs->in_service      = flags & yfs_FVSInservice;
0311     vs->blessed     = flags & yfs_FVSBlessed;
0312     vs->needs_salvage   = flags & yfs_FVSNeedsSalvage;
0313     vs->type        = ntohl(x->type);
0314     vs->min_quota       = 0;
0315     vs->max_quota       = xdr_to_u64(x->max_quota);
0316     vs->blocks_in_use   = xdr_to_u64(x->blocks_in_use);
0317     vs->part_blocks_avail   = xdr_to_u64(x->part_blocks_avail);
0318     vs->part_max_blocks = xdr_to_u64(x->part_max_blocks);
0319     vs->vol_copy_date   = xdr_to_u64(x->vol_copy_date);
0320     vs->vol_backup_date = xdr_to_u64(x->vol_backup_date);
0321     *_bp += sizeof(*x) / sizeof(__be32);
0322 }
0323 
0324 /*
0325  * Deliver reply data to operations that just return a file status and a volume
0326  * sync record.
0327  */
0328 static int yfs_deliver_status_and_volsync(struct afs_call *call)
0329 {
0330     struct afs_operation *op = call->op;
0331     const __be32 *bp;
0332     int ret;
0333 
0334     ret = afs_transfer_reply(call);
0335     if (ret < 0)
0336         return ret;
0337 
0338     bp = call->buffer;
0339     xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb);
0340     xdr_decode_YFSVolSync(&bp, &op->volsync);
0341 
0342     _leave(" = 0 [done]");
0343     return 0;
0344 }
0345 
0346 /*
0347  * Deliver reply data to an YFS.FetchData64.
0348  */
0349 static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
0350 {
0351     struct afs_operation *op = call->op;
0352     struct afs_vnode_param *vp = &op->file[0];
0353     struct afs_read *req = op->fetch.req;
0354     const __be32 *bp;
0355     int ret;
0356 
0357     _enter("{%u,%zu, %zu/%llu}",
0358            call->unmarshall, call->iov_len, iov_iter_count(call->iter),
0359            req->actual_len);
0360 
0361     switch (call->unmarshall) {
0362     case 0:
0363         req->actual_len = 0;
0364         afs_extract_to_tmp64(call);
0365         call->unmarshall++;
0366         fallthrough;
0367 
0368         /* Extract the returned data length into ->actual_len.  This
0369          * may indicate more or less data than was requested will be
0370          * returned.
0371          */
0372     case 1:
0373         _debug("extract data length");
0374         ret = afs_extract_data(call, true);
0375         if (ret < 0)
0376             return ret;
0377 
0378         req->actual_len = be64_to_cpu(call->tmp64);
0379         _debug("DATA length: %llu", req->actual_len);
0380 
0381         if (req->actual_len == 0)
0382             goto no_more_data;
0383 
0384         call->iter = req->iter;
0385         call->iov_len = min(req->actual_len, req->len);
0386         call->unmarshall++;
0387         fallthrough;
0388 
0389         /* extract the returned data */
0390     case 2:
0391         _debug("extract data %zu/%llu",
0392                iov_iter_count(call->iter), req->actual_len);
0393 
0394         ret = afs_extract_data(call, true);
0395         if (ret < 0)
0396             return ret;
0397 
0398         call->iter = &call->def_iter;
0399         if (req->actual_len <= req->len)
0400             goto no_more_data;
0401 
0402         /* Discard any excess data the server gave us */
0403         afs_extract_discard(call, req->actual_len - req->len);
0404         call->unmarshall = 3;
0405         fallthrough;
0406 
0407     case 3:
0408         _debug("extract discard %zu/%llu",
0409                iov_iter_count(call->iter), req->actual_len - req->len);
0410 
0411         ret = afs_extract_data(call, true);
0412         if (ret < 0)
0413             return ret;
0414 
0415     no_more_data:
0416         call->unmarshall = 4;
0417         afs_extract_to_buf(call,
0418                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0419                    sizeof(struct yfs_xdr_YFSCallBack) +
0420                    sizeof(struct yfs_xdr_YFSVolSync));
0421         fallthrough;
0422 
0423         /* extract the metadata */
0424     case 4:
0425         ret = afs_extract_data(call, false);
0426         if (ret < 0)
0427             return ret;
0428 
0429         bp = call->buffer;
0430         xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
0431         xdr_decode_YFSCallBack(&bp, call, &vp->scb);
0432         xdr_decode_YFSVolSync(&bp, &op->volsync);
0433 
0434         req->data_version = vp->scb.status.data_version;
0435         req->file_size = vp->scb.status.size;
0436 
0437         call->unmarshall++;
0438         fallthrough;
0439 
0440     case 5:
0441         break;
0442     }
0443 
0444     _leave(" = 0 [done]");
0445     return 0;
0446 }
0447 
0448 /*
0449  * YFS.FetchData64 operation type
0450  */
0451 static const struct afs_call_type yfs_RXYFSFetchData64 = {
0452     .name       = "YFS.FetchData64",
0453     .op     = yfs_FS_FetchData64,
0454     .deliver    = yfs_deliver_fs_fetch_data64,
0455     .destructor = afs_flat_call_destructor,
0456 };
0457 
0458 /*
0459  * Fetch data from a file.
0460  */
0461 void yfs_fs_fetch_data(struct afs_operation *op)
0462 {
0463     struct afs_vnode_param *vp = &op->file[0];
0464     struct afs_read *req = op->fetch.req;
0465     struct afs_call *call;
0466     __be32 *bp;
0467 
0468     _enter(",%x,{%llx:%llu},%llx,%llx",
0469            key_serial(op->key), vp->fid.vid, vp->fid.vnode,
0470            req->pos, req->len);
0471 
0472     call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchData64,
0473                    sizeof(__be32) * 2 +
0474                    sizeof(struct yfs_xdr_YFSFid) +
0475                    sizeof(struct yfs_xdr_u64) * 2,
0476                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0477                    sizeof(struct yfs_xdr_YFSCallBack) +
0478                    sizeof(struct yfs_xdr_YFSVolSync));
0479     if (!call)
0480         return afs_op_nomem(op);
0481 
0482     req->call_debug_id = call->debug_id;
0483 
0484     /* marshall the parameters */
0485     bp = call->request;
0486     bp = xdr_encode_u32(bp, YFSFETCHDATA64);
0487     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0488     bp = xdr_encode_YFSFid(bp, &vp->fid);
0489     bp = xdr_encode_u64(bp, req->pos);
0490     bp = xdr_encode_u64(bp, req->len);
0491     yfs_check_req(call, bp);
0492 
0493     trace_afs_make_fs_call(call, &vp->fid);
0494     afs_make_op_call(op, call, GFP_NOFS);
0495 }
0496 
0497 /*
0498  * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
0499  */
0500 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
0501 {
0502     struct afs_operation *op = call->op;
0503     struct afs_vnode_param *dvp = &op->file[0];
0504     struct afs_vnode_param *vp = &op->file[1];
0505     const __be32 *bp;
0506     int ret;
0507 
0508     _enter("{%u}", call->unmarshall);
0509 
0510     ret = afs_transfer_reply(call);
0511     if (ret < 0)
0512         return ret;
0513 
0514     /* unmarshall the reply once we've received all of it */
0515     bp = call->buffer;
0516     xdr_decode_YFSFid(&bp, &op->file[1].fid);
0517     xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
0518     xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
0519     xdr_decode_YFSCallBack(&bp, call, &vp->scb);
0520     xdr_decode_YFSVolSync(&bp, &op->volsync);
0521 
0522     _leave(" = 0 [done]");
0523     return 0;
0524 }
0525 
0526 /*
0527  * FS.CreateFile and FS.MakeDir operation type
0528  */
0529 static const struct afs_call_type afs_RXFSCreateFile = {
0530     .name       = "YFS.CreateFile",
0531     .op     = yfs_FS_CreateFile,
0532     .deliver    = yfs_deliver_fs_create_vnode,
0533     .destructor = afs_flat_call_destructor,
0534 };
0535 
0536 /*
0537  * Create a file.
0538  */
0539 void yfs_fs_create_file(struct afs_operation *op)
0540 {
0541     const struct qstr *name = &op->dentry->d_name;
0542     struct afs_vnode_param *dvp = &op->file[0];
0543     struct afs_call *call;
0544     size_t reqsz, rplsz;
0545     __be32 *bp;
0546 
0547     _enter("");
0548 
0549     reqsz = (sizeof(__be32) +
0550          sizeof(__be32) +
0551          sizeof(struct yfs_xdr_YFSFid) +
0552          xdr_strlen(name->len) +
0553          sizeof(struct yfs_xdr_YFSStoreStatus) +
0554          sizeof(__be32));
0555     rplsz = (sizeof(struct yfs_xdr_YFSFid) +
0556          sizeof(struct yfs_xdr_YFSFetchStatus) +
0557          sizeof(struct yfs_xdr_YFSFetchStatus) +
0558          sizeof(struct yfs_xdr_YFSCallBack) +
0559          sizeof(struct yfs_xdr_YFSVolSync));
0560 
0561     call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, reqsz, rplsz);
0562     if (!call)
0563         return afs_op_nomem(op);
0564 
0565     /* marshall the parameters */
0566     bp = call->request;
0567     bp = xdr_encode_u32(bp, YFSCREATEFILE);
0568     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0569     bp = xdr_encode_YFSFid(bp, &dvp->fid);
0570     bp = xdr_encode_name(bp, name);
0571     bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
0572     bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
0573     yfs_check_req(call, bp);
0574 
0575     trace_afs_make_fs_call1(call, &dvp->fid, name);
0576     afs_make_op_call(op, call, GFP_NOFS);
0577 }
0578 
0579 static const struct afs_call_type yfs_RXFSMakeDir = {
0580     .name       = "YFS.MakeDir",
0581     .op     = yfs_FS_MakeDir,
0582     .deliver    = yfs_deliver_fs_create_vnode,
0583     .destructor = afs_flat_call_destructor,
0584 };
0585 
0586 /*
0587  * Make a directory.
0588  */
0589 void yfs_fs_make_dir(struct afs_operation *op)
0590 {
0591     const struct qstr *name = &op->dentry->d_name;
0592     struct afs_vnode_param *dvp = &op->file[0];
0593     struct afs_call *call;
0594     size_t reqsz, rplsz;
0595     __be32 *bp;
0596 
0597     _enter("");
0598 
0599     reqsz = (sizeof(__be32) +
0600          sizeof(struct yfs_xdr_RPCFlags) +
0601          sizeof(struct yfs_xdr_YFSFid) +
0602          xdr_strlen(name->len) +
0603          sizeof(struct yfs_xdr_YFSStoreStatus));
0604     rplsz = (sizeof(struct yfs_xdr_YFSFid) +
0605          sizeof(struct yfs_xdr_YFSFetchStatus) +
0606          sizeof(struct yfs_xdr_YFSFetchStatus) +
0607          sizeof(struct yfs_xdr_YFSCallBack) +
0608          sizeof(struct yfs_xdr_YFSVolSync));
0609 
0610     call = afs_alloc_flat_call(op->net, &yfs_RXFSMakeDir, reqsz, rplsz);
0611     if (!call)
0612         return afs_op_nomem(op);
0613 
0614     /* marshall the parameters */
0615     bp = call->request;
0616     bp = xdr_encode_u32(bp, YFSMAKEDIR);
0617     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0618     bp = xdr_encode_YFSFid(bp, &dvp->fid);
0619     bp = xdr_encode_name(bp, name);
0620     bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
0621     yfs_check_req(call, bp);
0622 
0623     trace_afs_make_fs_call1(call, &dvp->fid, name);
0624     afs_make_op_call(op, call, GFP_NOFS);
0625 }
0626 
0627 /*
0628  * Deliver reply data to a YFS.RemoveFile2 operation.
0629  */
0630 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
0631 {
0632     struct afs_operation *op = call->op;
0633     struct afs_vnode_param *dvp = &op->file[0];
0634     struct afs_vnode_param *vp = &op->file[1];
0635     struct afs_fid fid;
0636     const __be32 *bp;
0637     int ret;
0638 
0639     _enter("{%u}", call->unmarshall);
0640 
0641     ret = afs_transfer_reply(call);
0642     if (ret < 0)
0643         return ret;
0644 
0645     bp = call->buffer;
0646     xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
0647     xdr_decode_YFSFid(&bp, &fid);
0648     xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
0649     /* Was deleted if vnode->status.abort_code == VNOVNODE. */
0650 
0651     xdr_decode_YFSVolSync(&bp, &op->volsync);
0652     return 0;
0653 }
0654 
0655 static void yfs_done_fs_remove_file2(struct afs_call *call)
0656 {
0657     if (call->error == -ECONNABORTED &&
0658         call->abort_code == RX_INVALID_OPERATION) {
0659         set_bit(AFS_SERVER_FL_NO_RM2, &call->server->flags);
0660         call->op->flags |= AFS_OPERATION_DOWNGRADE;
0661     }
0662 }
0663 
0664 /*
0665  * YFS.RemoveFile2 operation type.
0666  */
0667 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
0668     .name       = "YFS.RemoveFile2",
0669     .op     = yfs_FS_RemoveFile2,
0670     .deliver    = yfs_deliver_fs_remove_file2,
0671     .done       = yfs_done_fs_remove_file2,
0672     .destructor = afs_flat_call_destructor,
0673 };
0674 
0675 /*
0676  * Remove a file and retrieve new file status.
0677  */
0678 void yfs_fs_remove_file2(struct afs_operation *op)
0679 {
0680     struct afs_vnode_param *dvp = &op->file[0];
0681     const struct qstr *name = &op->dentry->d_name;
0682     struct afs_call *call;
0683     __be32 *bp;
0684 
0685     _enter("");
0686 
0687     call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile2,
0688                    sizeof(__be32) +
0689                    sizeof(struct yfs_xdr_RPCFlags) +
0690                    sizeof(struct yfs_xdr_YFSFid) +
0691                    xdr_strlen(name->len),
0692                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0693                    sizeof(struct yfs_xdr_YFSFid) +
0694                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0695                    sizeof(struct yfs_xdr_YFSVolSync));
0696     if (!call)
0697         return afs_op_nomem(op);
0698 
0699     /* marshall the parameters */
0700     bp = call->request;
0701     bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
0702     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0703     bp = xdr_encode_YFSFid(bp, &dvp->fid);
0704     bp = xdr_encode_name(bp, name);
0705     yfs_check_req(call, bp);
0706 
0707     trace_afs_make_fs_call1(call, &dvp->fid, name);
0708     afs_make_op_call(op, call, GFP_NOFS);
0709 }
0710 
0711 /*
0712  * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
0713  */
0714 static int yfs_deliver_fs_remove(struct afs_call *call)
0715 {
0716     struct afs_operation *op = call->op;
0717     struct afs_vnode_param *dvp = &op->file[0];
0718     const __be32 *bp;
0719     int ret;
0720 
0721     _enter("{%u}", call->unmarshall);
0722 
0723     ret = afs_transfer_reply(call);
0724     if (ret < 0)
0725         return ret;
0726 
0727     bp = call->buffer;
0728     xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
0729     xdr_decode_YFSVolSync(&bp, &op->volsync);
0730     return 0;
0731 }
0732 
0733 /*
0734  * FS.RemoveDir and FS.RemoveFile operation types.
0735  */
0736 static const struct afs_call_type yfs_RXYFSRemoveFile = {
0737     .name       = "YFS.RemoveFile",
0738     .op     = yfs_FS_RemoveFile,
0739     .deliver    = yfs_deliver_fs_remove,
0740     .destructor = afs_flat_call_destructor,
0741 };
0742 
0743 /*
0744  * Remove a file.
0745  */
0746 void yfs_fs_remove_file(struct afs_operation *op)
0747 {
0748     const struct qstr *name = &op->dentry->d_name;
0749     struct afs_vnode_param *dvp = &op->file[0];
0750     struct afs_call *call;
0751     __be32 *bp;
0752 
0753     _enter("");
0754 
0755     if (!test_bit(AFS_SERVER_FL_NO_RM2, &op->server->flags))
0756         return yfs_fs_remove_file2(op);
0757 
0758     call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile,
0759                    sizeof(__be32) +
0760                    sizeof(struct yfs_xdr_RPCFlags) +
0761                    sizeof(struct yfs_xdr_YFSFid) +
0762                    xdr_strlen(name->len),
0763                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0764                    sizeof(struct yfs_xdr_YFSVolSync));
0765     if (!call)
0766         return afs_op_nomem(op);
0767 
0768     /* marshall the parameters */
0769     bp = call->request;
0770     bp = xdr_encode_u32(bp, YFSREMOVEFILE);
0771     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0772     bp = xdr_encode_YFSFid(bp, &dvp->fid);
0773     bp = xdr_encode_name(bp, name);
0774     yfs_check_req(call, bp);
0775 
0776     trace_afs_make_fs_call1(call, &dvp->fid, name);
0777     afs_make_op_call(op, call, GFP_NOFS);
0778 }
0779 
0780 static const struct afs_call_type yfs_RXYFSRemoveDir = {
0781     .name       = "YFS.RemoveDir",
0782     .op     = yfs_FS_RemoveDir,
0783     .deliver    = yfs_deliver_fs_remove,
0784     .destructor = afs_flat_call_destructor,
0785 };
0786 
0787 /*
0788  * Remove a directory.
0789  */
0790 void yfs_fs_remove_dir(struct afs_operation *op)
0791 {
0792     const struct qstr *name = &op->dentry->d_name;
0793     struct afs_vnode_param *dvp = &op->file[0];
0794     struct afs_call *call;
0795     __be32 *bp;
0796 
0797     _enter("");
0798 
0799     call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveDir,
0800                    sizeof(__be32) +
0801                    sizeof(struct yfs_xdr_RPCFlags) +
0802                    sizeof(struct yfs_xdr_YFSFid) +
0803                    xdr_strlen(name->len),
0804                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0805                    sizeof(struct yfs_xdr_YFSVolSync));
0806     if (!call)
0807         return afs_op_nomem(op);
0808 
0809     /* marshall the parameters */
0810     bp = call->request;
0811     bp = xdr_encode_u32(bp, YFSREMOVEDIR);
0812     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0813     bp = xdr_encode_YFSFid(bp, &dvp->fid);
0814     bp = xdr_encode_name(bp, name);
0815     yfs_check_req(call, bp);
0816 
0817     trace_afs_make_fs_call1(call, &dvp->fid, name);
0818     afs_make_op_call(op, call, GFP_NOFS);
0819 }
0820 
0821 /*
0822  * Deliver reply data to a YFS.Link operation.
0823  */
0824 static int yfs_deliver_fs_link(struct afs_call *call)
0825 {
0826     struct afs_operation *op = call->op;
0827     struct afs_vnode_param *dvp = &op->file[0];
0828     struct afs_vnode_param *vp = &op->file[1];
0829     const __be32 *bp;
0830     int ret;
0831 
0832     _enter("{%u}", call->unmarshall);
0833 
0834     ret = afs_transfer_reply(call);
0835     if (ret < 0)
0836         return ret;
0837 
0838     bp = call->buffer;
0839     xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
0840     xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
0841     xdr_decode_YFSVolSync(&bp, &op->volsync);
0842     _leave(" = 0 [done]");
0843     return 0;
0844 }
0845 
0846 /*
0847  * YFS.Link operation type.
0848  */
0849 static const struct afs_call_type yfs_RXYFSLink = {
0850     .name       = "YFS.Link",
0851     .op     = yfs_FS_Link,
0852     .deliver    = yfs_deliver_fs_link,
0853     .destructor = afs_flat_call_destructor,
0854 };
0855 
0856 /*
0857  * Make a hard link.
0858  */
0859 void yfs_fs_link(struct afs_operation *op)
0860 {
0861     const struct qstr *name = &op->dentry->d_name;
0862     struct afs_vnode_param *dvp = &op->file[0];
0863     struct afs_vnode_param *vp = &op->file[1];
0864     struct afs_call *call;
0865     __be32 *bp;
0866 
0867     _enter("");
0868 
0869     call = afs_alloc_flat_call(op->net, &yfs_RXYFSLink,
0870                    sizeof(__be32) +
0871                    sizeof(struct yfs_xdr_RPCFlags) +
0872                    sizeof(struct yfs_xdr_YFSFid) +
0873                    xdr_strlen(name->len) +
0874                    sizeof(struct yfs_xdr_YFSFid),
0875                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0876                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0877                    sizeof(struct yfs_xdr_YFSVolSync));
0878     if (!call)
0879         return afs_op_nomem(op);
0880 
0881     /* marshall the parameters */
0882     bp = call->request;
0883     bp = xdr_encode_u32(bp, YFSLINK);
0884     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0885     bp = xdr_encode_YFSFid(bp, &dvp->fid);
0886     bp = xdr_encode_name(bp, name);
0887     bp = xdr_encode_YFSFid(bp, &vp->fid);
0888     yfs_check_req(call, bp);
0889 
0890     trace_afs_make_fs_call1(call, &vp->fid, name);
0891     afs_make_op_call(op, call, GFP_NOFS);
0892 }
0893 
0894 /*
0895  * Deliver reply data to a YFS.Symlink operation.
0896  */
0897 static int yfs_deliver_fs_symlink(struct afs_call *call)
0898 {
0899     struct afs_operation *op = call->op;
0900     struct afs_vnode_param *dvp = &op->file[0];
0901     struct afs_vnode_param *vp = &op->file[1];
0902     const __be32 *bp;
0903     int ret;
0904 
0905     _enter("{%u}", call->unmarshall);
0906 
0907     ret = afs_transfer_reply(call);
0908     if (ret < 0)
0909         return ret;
0910 
0911     /* unmarshall the reply once we've received all of it */
0912     bp = call->buffer;
0913     xdr_decode_YFSFid(&bp, &vp->fid);
0914     xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
0915     xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
0916     xdr_decode_YFSVolSync(&bp, &op->volsync);
0917 
0918     _leave(" = 0 [done]");
0919     return 0;
0920 }
0921 
0922 /*
0923  * YFS.Symlink operation type
0924  */
0925 static const struct afs_call_type yfs_RXYFSSymlink = {
0926     .name       = "YFS.Symlink",
0927     .op     = yfs_FS_Symlink,
0928     .deliver    = yfs_deliver_fs_symlink,
0929     .destructor = afs_flat_call_destructor,
0930 };
0931 
0932 /*
0933  * Create a symbolic link.
0934  */
0935 void yfs_fs_symlink(struct afs_operation *op)
0936 {
0937     const struct qstr *name = &op->dentry->d_name;
0938     struct afs_vnode_param *dvp = &op->file[0];
0939     struct afs_call *call;
0940     size_t contents_sz;
0941     mode_t mode = 0777;
0942     __be32 *bp;
0943 
0944     _enter("");
0945 
0946     contents_sz = strlen(op->create.symlink);
0947     call = afs_alloc_flat_call(op->net, &yfs_RXYFSSymlink,
0948                    sizeof(__be32) +
0949                    sizeof(struct yfs_xdr_RPCFlags) +
0950                    sizeof(struct yfs_xdr_YFSFid) +
0951                    xdr_strlen(name->len) +
0952                    xdr_strlen(contents_sz) +
0953                    sizeof(struct yfs_xdr_YFSStoreStatus),
0954                    sizeof(struct yfs_xdr_YFSFid) +
0955                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0956                    sizeof(struct yfs_xdr_YFSFetchStatus) +
0957                    sizeof(struct yfs_xdr_YFSVolSync));
0958     if (!call)
0959         return afs_op_nomem(op);
0960 
0961     /* marshall the parameters */
0962     bp = call->request;
0963     bp = xdr_encode_u32(bp, YFSSYMLINK);
0964     bp = xdr_encode_u32(bp, 0); /* RPC flags */
0965     bp = xdr_encode_YFSFid(bp, &dvp->fid);
0966     bp = xdr_encode_name(bp, name);
0967     bp = xdr_encode_string(bp, op->create.symlink, contents_sz);
0968     bp = xdr_encode_YFSStoreStatus(bp, &mode, &op->mtime);
0969     yfs_check_req(call, bp);
0970 
0971     trace_afs_make_fs_call1(call, &dvp->fid, name);
0972     afs_make_op_call(op, call, GFP_NOFS);
0973 }
0974 
0975 /*
0976  * Deliver reply data to a YFS.Rename operation.
0977  */
0978 static int yfs_deliver_fs_rename(struct afs_call *call)
0979 {
0980     struct afs_operation *op = call->op;
0981     struct afs_vnode_param *orig_dvp = &op->file[0];
0982     struct afs_vnode_param *new_dvp = &op->file[1];
0983     const __be32 *bp;
0984     int ret;
0985 
0986     _enter("{%u}", call->unmarshall);
0987 
0988     ret = afs_transfer_reply(call);
0989     if (ret < 0)
0990         return ret;
0991 
0992     bp = call->buffer;
0993     /* If the two dirs are the same, we have two copies of the same status
0994      * report, so we just decode it twice.
0995      */
0996     xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
0997     xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
0998     xdr_decode_YFSVolSync(&bp, &op->volsync);
0999     _leave(" = 0 [done]");
1000     return 0;
1001 }
1002 
1003 /*
1004  * YFS.Rename operation type
1005  */
1006 static const struct afs_call_type yfs_RXYFSRename = {
1007     .name       = "FS.Rename",
1008     .op     = yfs_FS_Rename,
1009     .deliver    = yfs_deliver_fs_rename,
1010     .destructor = afs_flat_call_destructor,
1011 };
1012 
1013 /*
1014  * Rename a file or directory.
1015  */
1016 void yfs_fs_rename(struct afs_operation *op)
1017 {
1018     struct afs_vnode_param *orig_dvp = &op->file[0];
1019     struct afs_vnode_param *new_dvp = &op->file[1];
1020     const struct qstr *orig_name = &op->dentry->d_name;
1021     const struct qstr *new_name = &op->dentry_2->d_name;
1022     struct afs_call *call;
1023     __be32 *bp;
1024 
1025     _enter("");
1026 
1027     call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename,
1028                    sizeof(__be32) +
1029                    sizeof(struct yfs_xdr_RPCFlags) +
1030                    sizeof(struct yfs_xdr_YFSFid) +
1031                    xdr_strlen(orig_name->len) +
1032                    sizeof(struct yfs_xdr_YFSFid) +
1033                    xdr_strlen(new_name->len),
1034                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1035                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1036                    sizeof(struct yfs_xdr_YFSVolSync));
1037     if (!call)
1038         return afs_op_nomem(op);
1039 
1040     /* marshall the parameters */
1041     bp = call->request;
1042     bp = xdr_encode_u32(bp, YFSRENAME);
1043     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1044     bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1045     bp = xdr_encode_name(bp, orig_name);
1046     bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1047     bp = xdr_encode_name(bp, new_name);
1048     yfs_check_req(call, bp);
1049 
1050     trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1051     afs_make_op_call(op, call, GFP_NOFS);
1052 }
1053 
1054 /*
1055  * YFS.StoreData64 operation type.
1056  */
1057 static const struct afs_call_type yfs_RXYFSStoreData64 = {
1058     .name       = "YFS.StoreData64",
1059     .op     = yfs_FS_StoreData64,
1060     .deliver    = yfs_deliver_status_and_volsync,
1061     .destructor = afs_flat_call_destructor,
1062 };
1063 
1064 /*
1065  * Store a set of pages to a large file.
1066  */
1067 void yfs_fs_store_data(struct afs_operation *op)
1068 {
1069     struct afs_vnode_param *vp = &op->file[0];
1070     struct afs_call *call;
1071     __be32 *bp;
1072 
1073     _enter(",%x,{%llx:%llu},,",
1074            key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1075 
1076     _debug("size %llx, at %llx, i_size %llx",
1077            (unsigned long long)op->store.size,
1078            (unsigned long long)op->store.pos,
1079            (unsigned long long)op->store.i_size);
1080 
1081     call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64,
1082                    sizeof(__be32) +
1083                    sizeof(__be32) +
1084                    sizeof(struct yfs_xdr_YFSFid) +
1085                    sizeof(struct yfs_xdr_YFSStoreStatus) +
1086                    sizeof(struct yfs_xdr_u64) * 3,
1087                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1088                    sizeof(struct yfs_xdr_YFSVolSync));
1089     if (!call)
1090         return afs_op_nomem(op);
1091 
1092     call->write_iter = op->store.write_iter;
1093 
1094     /* marshall the parameters */
1095     bp = call->request;
1096     bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1097     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1098     bp = xdr_encode_YFSFid(bp, &vp->fid);
1099     bp = xdr_encode_YFSStoreStatus(bp, NULL, &op->mtime);
1100     bp = xdr_encode_u64(bp, op->store.pos);
1101     bp = xdr_encode_u64(bp, op->store.size);
1102     bp = xdr_encode_u64(bp, op->store.i_size);
1103     yfs_check_req(call, bp);
1104 
1105     trace_afs_make_fs_call(call, &vp->fid);
1106     afs_make_op_call(op, call, GFP_NOFS);
1107 }
1108 
1109 /*
1110  * YFS.StoreStatus operation type
1111  */
1112 static const struct afs_call_type yfs_RXYFSStoreStatus = {
1113     .name       = "YFS.StoreStatus",
1114     .op     = yfs_FS_StoreStatus,
1115     .deliver    = yfs_deliver_status_and_volsync,
1116     .destructor = afs_flat_call_destructor,
1117 };
1118 
1119 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1120     .name       = "YFS.StoreData64",
1121     .op     = yfs_FS_StoreData64,
1122     .deliver    = yfs_deliver_status_and_volsync,
1123     .destructor = afs_flat_call_destructor,
1124 };
1125 
1126 /*
1127  * Set the attributes on a file, using YFS.StoreData64 rather than
1128  * YFS.StoreStatus so as to alter the file size also.
1129  */
1130 static void yfs_fs_setattr_size(struct afs_operation *op)
1131 {
1132     struct afs_vnode_param *vp = &op->file[0];
1133     struct afs_call *call;
1134     struct iattr *attr = op->setattr.attr;
1135     __be32 *bp;
1136 
1137     _enter(",%x,{%llx:%llu},,",
1138            key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1139 
1140     call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64_as_Status,
1141                    sizeof(__be32) * 2 +
1142                    sizeof(struct yfs_xdr_YFSFid) +
1143                    sizeof(struct yfs_xdr_YFSStoreStatus) +
1144                    sizeof(struct yfs_xdr_u64) * 3,
1145                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1146                    sizeof(struct yfs_xdr_YFSVolSync));
1147     if (!call)
1148         return afs_op_nomem(op);
1149 
1150     /* marshall the parameters */
1151     bp = call->request;
1152     bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1153     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1154     bp = xdr_encode_YFSFid(bp, &vp->fid);
1155     bp = xdr_encode_YFS_StoreStatus(bp, attr);
1156     bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1157     bp = xdr_encode_u64(bp, 0);     /* size of write */
1158     bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1159     yfs_check_req(call, bp);
1160 
1161     trace_afs_make_fs_call(call, &vp->fid);
1162     afs_make_op_call(op, call, GFP_NOFS);
1163 }
1164 
1165 /*
1166  * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1167  * file size, and YFS.StoreStatus otherwise.
1168  */
1169 void yfs_fs_setattr(struct afs_operation *op)
1170 {
1171     struct afs_vnode_param *vp = &op->file[0];
1172     struct afs_call *call;
1173     struct iattr *attr = op->setattr.attr;
1174     __be32 *bp;
1175 
1176     if (attr->ia_valid & ATTR_SIZE)
1177         return yfs_fs_setattr_size(op);
1178 
1179     _enter(",%x,{%llx:%llu},,",
1180            key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1181 
1182     call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreStatus,
1183                    sizeof(__be32) * 2 +
1184                    sizeof(struct yfs_xdr_YFSFid) +
1185                    sizeof(struct yfs_xdr_YFSStoreStatus),
1186                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1187                    sizeof(struct yfs_xdr_YFSVolSync));
1188     if (!call)
1189         return afs_op_nomem(op);
1190 
1191     /* marshall the parameters */
1192     bp = call->request;
1193     bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1194     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1195     bp = xdr_encode_YFSFid(bp, &vp->fid);
1196     bp = xdr_encode_YFS_StoreStatus(bp, attr);
1197     yfs_check_req(call, bp);
1198 
1199     trace_afs_make_fs_call(call, &vp->fid);
1200     afs_make_op_call(op, call, GFP_NOFS);
1201 }
1202 
1203 /*
1204  * Deliver reply data to a YFS.GetVolumeStatus operation.
1205  */
1206 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1207 {
1208     struct afs_operation *op = call->op;
1209     const __be32 *bp;
1210     char *p;
1211     u32 size;
1212     int ret;
1213 
1214     _enter("{%u}", call->unmarshall);
1215 
1216     switch (call->unmarshall) {
1217     case 0:
1218         call->unmarshall++;
1219         afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1220         fallthrough;
1221 
1222         /* extract the returned status record */
1223     case 1:
1224         _debug("extract status");
1225         ret = afs_extract_data(call, true);
1226         if (ret < 0)
1227             return ret;
1228 
1229         bp = call->buffer;
1230         xdr_decode_YFSFetchVolumeStatus(&bp, &op->volstatus.vs);
1231         call->unmarshall++;
1232         afs_extract_to_tmp(call);
1233         fallthrough;
1234 
1235         /* extract the volume name length */
1236     case 2:
1237         ret = afs_extract_data(call, true);
1238         if (ret < 0)
1239             return ret;
1240 
1241         call->count = ntohl(call->tmp);
1242         _debug("volname length: %u", call->count);
1243         if (call->count >= AFSNAMEMAX)
1244             return afs_protocol_error(call, afs_eproto_volname_len);
1245         size = (call->count + 3) & ~3; /* It's padded */
1246         afs_extract_to_buf(call, size);
1247         call->unmarshall++;
1248         fallthrough;
1249 
1250         /* extract the volume name */
1251     case 3:
1252         _debug("extract volname");
1253         ret = afs_extract_data(call, true);
1254         if (ret < 0)
1255             return ret;
1256 
1257         p = call->buffer;
1258         p[call->count] = 0;
1259         _debug("volname '%s'", p);
1260         afs_extract_to_tmp(call);
1261         call->unmarshall++;
1262         fallthrough;
1263 
1264         /* extract the offline message length */
1265     case 4:
1266         ret = afs_extract_data(call, true);
1267         if (ret < 0)
1268             return ret;
1269 
1270         call->count = ntohl(call->tmp);
1271         _debug("offline msg length: %u", call->count);
1272         if (call->count >= AFSNAMEMAX)
1273             return afs_protocol_error(call, afs_eproto_offline_msg_len);
1274         size = (call->count + 3) & ~3; /* It's padded */
1275         afs_extract_to_buf(call, size);
1276         call->unmarshall++;
1277         fallthrough;
1278 
1279         /* extract the offline message */
1280     case 5:
1281         _debug("extract offline");
1282         ret = afs_extract_data(call, true);
1283         if (ret < 0)
1284             return ret;
1285 
1286         p = call->buffer;
1287         p[call->count] = 0;
1288         _debug("offline '%s'", p);
1289 
1290         afs_extract_to_tmp(call);
1291         call->unmarshall++;
1292         fallthrough;
1293 
1294         /* extract the message of the day length */
1295     case 6:
1296         ret = afs_extract_data(call, true);
1297         if (ret < 0)
1298             return ret;
1299 
1300         call->count = ntohl(call->tmp);
1301         _debug("motd length: %u", call->count);
1302         if (call->count >= AFSNAMEMAX)
1303             return afs_protocol_error(call, afs_eproto_motd_len);
1304         size = (call->count + 3) & ~3; /* It's padded */
1305         afs_extract_to_buf(call, size);
1306         call->unmarshall++;
1307         fallthrough;
1308 
1309         /* extract the message of the day */
1310     case 7:
1311         _debug("extract motd");
1312         ret = afs_extract_data(call, false);
1313         if (ret < 0)
1314             return ret;
1315 
1316         p = call->buffer;
1317         p[call->count] = 0;
1318         _debug("motd '%s'", p);
1319 
1320         call->unmarshall++;
1321         fallthrough;
1322 
1323     case 8:
1324         break;
1325     }
1326 
1327     _leave(" = 0 [done]");
1328     return 0;
1329 }
1330 
1331 /*
1332  * YFS.GetVolumeStatus operation type
1333  */
1334 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1335     .name       = "YFS.GetVolumeStatus",
1336     .op     = yfs_FS_GetVolumeStatus,
1337     .deliver    = yfs_deliver_fs_get_volume_status,
1338     .destructor = afs_flat_call_destructor,
1339 };
1340 
1341 /*
1342  * fetch the status of a volume
1343  */
1344 void yfs_fs_get_volume_status(struct afs_operation *op)
1345 {
1346     struct afs_vnode_param *vp = &op->file[0];
1347     struct afs_call *call;
1348     __be32 *bp;
1349 
1350     _enter("");
1351 
1352     call = afs_alloc_flat_call(op->net, &yfs_RXYFSGetVolumeStatus,
1353                    sizeof(__be32) * 2 +
1354                    sizeof(struct yfs_xdr_u64),
1355                    max_t(size_t,
1356                      sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1357                      sizeof(__be32),
1358                      AFSOPAQUEMAX + 1));
1359     if (!call)
1360         return afs_op_nomem(op);
1361 
1362     /* marshall the parameters */
1363     bp = call->request;
1364     bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1365     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1366     bp = xdr_encode_u64(bp, vp->fid.vid);
1367     yfs_check_req(call, bp);
1368 
1369     trace_afs_make_fs_call(call, &vp->fid);
1370     afs_make_op_call(op, call, GFP_NOFS);
1371 }
1372 
1373 /*
1374  * YFS.SetLock operation type
1375  */
1376 static const struct afs_call_type yfs_RXYFSSetLock = {
1377     .name       = "YFS.SetLock",
1378     .op     = yfs_FS_SetLock,
1379     .deliver    = yfs_deliver_status_and_volsync,
1380     .done       = afs_lock_op_done,
1381     .destructor = afs_flat_call_destructor,
1382 };
1383 
1384 /*
1385  * YFS.ExtendLock operation type
1386  */
1387 static const struct afs_call_type yfs_RXYFSExtendLock = {
1388     .name       = "YFS.ExtendLock",
1389     .op     = yfs_FS_ExtendLock,
1390     .deliver    = yfs_deliver_status_and_volsync,
1391     .done       = afs_lock_op_done,
1392     .destructor = afs_flat_call_destructor,
1393 };
1394 
1395 /*
1396  * YFS.ReleaseLock operation type
1397  */
1398 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1399     .name       = "YFS.ReleaseLock",
1400     .op     = yfs_FS_ReleaseLock,
1401     .deliver    = yfs_deliver_status_and_volsync,
1402     .destructor = afs_flat_call_destructor,
1403 };
1404 
1405 /*
1406  * Set a lock on a file
1407  */
1408 void yfs_fs_set_lock(struct afs_operation *op)
1409 {
1410     struct afs_vnode_param *vp = &op->file[0];
1411     struct afs_call *call;
1412     __be32 *bp;
1413 
1414     _enter("");
1415 
1416     call = afs_alloc_flat_call(op->net, &yfs_RXYFSSetLock,
1417                    sizeof(__be32) * 2 +
1418                    sizeof(struct yfs_xdr_YFSFid) +
1419                    sizeof(__be32),
1420                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1421                    sizeof(struct yfs_xdr_YFSVolSync));
1422     if (!call)
1423         return afs_op_nomem(op);
1424 
1425     /* marshall the parameters */
1426     bp = call->request;
1427     bp = xdr_encode_u32(bp, YFSSETLOCK);
1428     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1429     bp = xdr_encode_YFSFid(bp, &vp->fid);
1430     bp = xdr_encode_u32(bp, op->lock.type);
1431     yfs_check_req(call, bp);
1432 
1433     trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);
1434     afs_make_op_call(op, call, GFP_NOFS);
1435 }
1436 
1437 /*
1438  * extend a lock on a file
1439  */
1440 void yfs_fs_extend_lock(struct afs_operation *op)
1441 {
1442     struct afs_vnode_param *vp = &op->file[0];
1443     struct afs_call *call;
1444     __be32 *bp;
1445 
1446     _enter("");
1447 
1448     call = afs_alloc_flat_call(op->net, &yfs_RXYFSExtendLock,
1449                    sizeof(__be32) * 2 +
1450                    sizeof(struct yfs_xdr_YFSFid),
1451                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1452                    sizeof(struct yfs_xdr_YFSVolSync));
1453     if (!call)
1454         return afs_op_nomem(op);
1455 
1456     /* marshall the parameters */
1457     bp = call->request;
1458     bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1459     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1460     bp = xdr_encode_YFSFid(bp, &vp->fid);
1461     yfs_check_req(call, bp);
1462 
1463     trace_afs_make_fs_call(call, &vp->fid);
1464     afs_make_op_call(op, call, GFP_NOFS);
1465 }
1466 
1467 /*
1468  * release a lock on a file
1469  */
1470 void yfs_fs_release_lock(struct afs_operation *op)
1471 {
1472     struct afs_vnode_param *vp = &op->file[0];
1473     struct afs_call *call;
1474     __be32 *bp;
1475 
1476     _enter("");
1477 
1478     call = afs_alloc_flat_call(op->net, &yfs_RXYFSReleaseLock,
1479                    sizeof(__be32) * 2 +
1480                    sizeof(struct yfs_xdr_YFSFid),
1481                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1482                    sizeof(struct yfs_xdr_YFSVolSync));
1483     if (!call)
1484         return afs_op_nomem(op);
1485 
1486     /* marshall the parameters */
1487     bp = call->request;
1488     bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1489     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1490     bp = xdr_encode_YFSFid(bp, &vp->fid);
1491     yfs_check_req(call, bp);
1492 
1493     trace_afs_make_fs_call(call, &vp->fid);
1494     afs_make_op_call(op, call, GFP_NOFS);
1495 }
1496 
1497 /*
1498  * Deliver a reply to YFS.FetchStatus
1499  */
1500 static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1501 {
1502     struct afs_operation *op = call->op;
1503     struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1504     const __be32 *bp;
1505     int ret;
1506 
1507     ret = afs_transfer_reply(call);
1508     if (ret < 0)
1509         return ret;
1510 
1511     /* unmarshall the reply once we've received all of it */
1512     bp = call->buffer;
1513     xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
1514     xdr_decode_YFSCallBack(&bp, call, &vp->scb);
1515     xdr_decode_YFSVolSync(&bp, &op->volsync);
1516 
1517     _leave(" = 0 [done]");
1518     return 0;
1519 }
1520 
1521 /*
1522  * YFS.FetchStatus operation type
1523  */
1524 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1525     .name       = "YFS.FetchStatus",
1526     .op     = yfs_FS_FetchStatus,
1527     .deliver    = yfs_deliver_fs_fetch_status,
1528     .destructor = afs_flat_call_destructor,
1529 };
1530 
1531 /*
1532  * Fetch the status information for a fid without needing a vnode handle.
1533  */
1534 void yfs_fs_fetch_status(struct afs_operation *op)
1535 {
1536     struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1537     struct afs_call *call;
1538     __be32 *bp;
1539 
1540     _enter(",%x,{%llx:%llu},,",
1541            key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1542 
1543     call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus,
1544                    sizeof(__be32) * 2 +
1545                    sizeof(struct yfs_xdr_YFSFid),
1546                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1547                    sizeof(struct yfs_xdr_YFSCallBack) +
1548                    sizeof(struct yfs_xdr_YFSVolSync));
1549     if (!call)
1550         return afs_op_nomem(op);
1551 
1552     /* marshall the parameters */
1553     bp = call->request;
1554     bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1555     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1556     bp = xdr_encode_YFSFid(bp, &vp->fid);
1557     yfs_check_req(call, bp);
1558 
1559     trace_afs_make_fs_call(call, &vp->fid);
1560     afs_make_op_call(op, call, GFP_NOFS);
1561 }
1562 
1563 /*
1564  * Deliver reply data to an YFS.InlineBulkStatus call
1565  */
1566 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1567 {
1568     struct afs_operation *op = call->op;
1569     struct afs_status_cb *scb;
1570     const __be32 *bp;
1571     u32 tmp;
1572     int ret;
1573 
1574     _enter("{%u}", call->unmarshall);
1575 
1576     switch (call->unmarshall) {
1577     case 0:
1578         afs_extract_to_tmp(call);
1579         call->unmarshall++;
1580         fallthrough;
1581 
1582         /* Extract the file status count and array in two steps */
1583     case 1:
1584         _debug("extract status count");
1585         ret = afs_extract_data(call, true);
1586         if (ret < 0)
1587             return ret;
1588 
1589         tmp = ntohl(call->tmp);
1590         _debug("status count: %u/%u", tmp, op->nr_files);
1591         if (tmp != op->nr_files)
1592             return afs_protocol_error(call, afs_eproto_ibulkst_count);
1593 
1594         call->count = 0;
1595         call->unmarshall++;
1596     more_counts:
1597         afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1598         fallthrough;
1599 
1600     case 2:
1601         _debug("extract status array %u", call->count);
1602         ret = afs_extract_data(call, true);
1603         if (ret < 0)
1604             return ret;
1605 
1606         switch (call->count) {
1607         case 0:
1608             scb = &op->file[0].scb;
1609             break;
1610         case 1:
1611             scb = &op->file[1].scb;
1612             break;
1613         default:
1614             scb = &op->more_files[call->count - 2].scb;
1615             break;
1616         }
1617 
1618         bp = call->buffer;
1619         xdr_decode_YFSFetchStatus(&bp, call, scb);
1620 
1621         call->count++;
1622         if (call->count < op->nr_files)
1623             goto more_counts;
1624 
1625         call->count = 0;
1626         call->unmarshall++;
1627         afs_extract_to_tmp(call);
1628         fallthrough;
1629 
1630         /* Extract the callback count and array in two steps */
1631     case 3:
1632         _debug("extract CB count");
1633         ret = afs_extract_data(call, true);
1634         if (ret < 0)
1635             return ret;
1636 
1637         tmp = ntohl(call->tmp);
1638         _debug("CB count: %u", tmp);
1639         if (tmp != op->nr_files)
1640             return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
1641         call->count = 0;
1642         call->unmarshall++;
1643     more_cbs:
1644         afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1645         fallthrough;
1646 
1647     case 4:
1648         _debug("extract CB array");
1649         ret = afs_extract_data(call, true);
1650         if (ret < 0)
1651             return ret;
1652 
1653         _debug("unmarshall CB array");
1654         switch (call->count) {
1655         case 0:
1656             scb = &op->file[0].scb;
1657             break;
1658         case 1:
1659             scb = &op->file[1].scb;
1660             break;
1661         default:
1662             scb = &op->more_files[call->count - 2].scb;
1663             break;
1664         }
1665 
1666         bp = call->buffer;
1667         xdr_decode_YFSCallBack(&bp, call, scb);
1668         call->count++;
1669         if (call->count < op->nr_files)
1670             goto more_cbs;
1671 
1672         afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1673         call->unmarshall++;
1674         fallthrough;
1675 
1676     case 5:
1677         ret = afs_extract_data(call, false);
1678         if (ret < 0)
1679             return ret;
1680 
1681         bp = call->buffer;
1682         xdr_decode_YFSVolSync(&bp, &op->volsync);
1683 
1684         call->unmarshall++;
1685         fallthrough;
1686 
1687     case 6:
1688         break;
1689     }
1690 
1691     _leave(" = 0 [done]");
1692     return 0;
1693 }
1694 
1695 /*
1696  * FS.InlineBulkStatus operation type
1697  */
1698 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1699     .name       = "YFS.InlineBulkStatus",
1700     .op     = yfs_FS_InlineBulkStatus,
1701     .deliver    = yfs_deliver_fs_inline_bulk_status,
1702     .destructor = afs_flat_call_destructor,
1703 };
1704 
1705 /*
1706  * Fetch the status information for up to 1024 files
1707  */
1708 void yfs_fs_inline_bulk_status(struct afs_operation *op)
1709 {
1710     struct afs_vnode_param *dvp = &op->file[0];
1711     struct afs_vnode_param *vp = &op->file[1];
1712     struct afs_call *call;
1713     __be32 *bp;
1714     int i;
1715 
1716     _enter(",%x,{%llx:%llu},%u",
1717            key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);
1718 
1719     call = afs_alloc_flat_call(op->net, &yfs_RXYFSInlineBulkStatus,
1720                    sizeof(__be32) +
1721                    sizeof(__be32) +
1722                    sizeof(__be32) +
1723                    sizeof(struct yfs_xdr_YFSFid) * op->nr_files,
1724                    sizeof(struct yfs_xdr_YFSFetchStatus));
1725     if (!call)
1726         return afs_op_nomem(op);
1727 
1728     /* marshall the parameters */
1729     bp = call->request;
1730     bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1731     bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1732     bp = xdr_encode_u32(bp, op->nr_files);
1733     bp = xdr_encode_YFSFid(bp, &dvp->fid);
1734     bp = xdr_encode_YFSFid(bp, &vp->fid);
1735     for (i = 0; i < op->nr_files - 2; i++)
1736         bp = xdr_encode_YFSFid(bp, &op->more_files[i].fid);
1737     yfs_check_req(call, bp);
1738 
1739     trace_afs_make_fs_call(call, &vp->fid);
1740     afs_make_op_call(op, call, GFP_NOFS);
1741 }
1742 
1743 /*
1744  * Deliver reply data to an YFS.FetchOpaqueACL.
1745  */
1746 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1747 {
1748     struct afs_operation *op = call->op;
1749     struct afs_vnode_param *vp = &op->file[0];
1750     struct yfs_acl *yacl = op->yacl;
1751     struct afs_acl *acl;
1752     const __be32 *bp;
1753     unsigned int size;
1754     int ret;
1755 
1756     _enter("{%u}", call->unmarshall);
1757 
1758     switch (call->unmarshall) {
1759     case 0:
1760         afs_extract_to_tmp(call);
1761         call->unmarshall++;
1762         fallthrough;
1763 
1764         /* Extract the file ACL length */
1765     case 1:
1766         ret = afs_extract_data(call, true);
1767         if (ret < 0)
1768             return ret;
1769 
1770         size = call->count2 = ntohl(call->tmp);
1771         size = round_up(size, 4);
1772 
1773         if (yacl->flags & YFS_ACL_WANT_ACL) {
1774             acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1775             if (!acl)
1776                 return -ENOMEM;
1777             yacl->acl = acl;
1778             acl->size = call->count2;
1779             afs_extract_begin(call, acl->data, size);
1780         } else {
1781             afs_extract_discard(call, size);
1782         }
1783         call->unmarshall++;
1784         fallthrough;
1785 
1786         /* Extract the file ACL */
1787     case 2:
1788         ret = afs_extract_data(call, true);
1789         if (ret < 0)
1790             return ret;
1791 
1792         afs_extract_to_tmp(call);
1793         call->unmarshall++;
1794         fallthrough;
1795 
1796         /* Extract the volume ACL length */
1797     case 3:
1798         ret = afs_extract_data(call, true);
1799         if (ret < 0)
1800             return ret;
1801 
1802         size = call->count2 = ntohl(call->tmp);
1803         size = round_up(size, 4);
1804 
1805         if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
1806             acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1807             if (!acl)
1808                 return -ENOMEM;
1809             yacl->vol_acl = acl;
1810             acl->size = call->count2;
1811             afs_extract_begin(call, acl->data, size);
1812         } else {
1813             afs_extract_discard(call, size);
1814         }
1815         call->unmarshall++;
1816         fallthrough;
1817 
1818         /* Extract the volume ACL */
1819     case 4:
1820         ret = afs_extract_data(call, true);
1821         if (ret < 0)
1822             return ret;
1823 
1824         afs_extract_to_buf(call,
1825                    sizeof(__be32) * 2 +
1826                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1827                    sizeof(struct yfs_xdr_YFSVolSync));
1828         call->unmarshall++;
1829         fallthrough;
1830 
1831         /* extract the metadata */
1832     case 5:
1833         ret = afs_extract_data(call, false);
1834         if (ret < 0)
1835             return ret;
1836 
1837         bp = call->buffer;
1838         yacl->inherit_flag = ntohl(*bp++);
1839         yacl->num_cleaned = ntohl(*bp++);
1840         xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
1841         xdr_decode_YFSVolSync(&bp, &op->volsync);
1842 
1843         call->unmarshall++;
1844         fallthrough;
1845 
1846     case 6:
1847         break;
1848     }
1849 
1850     _leave(" = 0 [done]");
1851     return 0;
1852 }
1853 
1854 void yfs_free_opaque_acl(struct yfs_acl *yacl)
1855 {
1856     if (yacl) {
1857         kfree(yacl->acl);
1858         kfree(yacl->vol_acl);
1859         kfree(yacl);
1860     }
1861 }
1862 
1863 /*
1864  * YFS.FetchOpaqueACL operation type
1865  */
1866 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
1867     .name       = "YFS.FetchOpaqueACL",
1868     .op     = yfs_FS_FetchOpaqueACL,
1869     .deliver    = yfs_deliver_fs_fetch_opaque_acl,
1870     .destructor = afs_flat_call_destructor,
1871 };
1872 
1873 /*
1874  * Fetch the YFS advanced ACLs for a file.
1875  */
1876 void yfs_fs_fetch_opaque_acl(struct afs_operation *op)
1877 {
1878     struct afs_vnode_param *vp = &op->file[0];
1879     struct afs_call *call;
1880     __be32 *bp;
1881 
1882     _enter(",%x,{%llx:%llu},,",
1883            key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1884 
1885     call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchOpaqueACL,
1886                    sizeof(__be32) * 2 +
1887                    sizeof(struct yfs_xdr_YFSFid),
1888                    sizeof(__be32) * 2 +
1889                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1890                    sizeof(struct yfs_xdr_YFSVolSync));
1891     if (!call)
1892         return afs_op_nomem(op);
1893 
1894     /* marshall the parameters */
1895     bp = call->request;
1896     bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
1897     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1898     bp = xdr_encode_YFSFid(bp, &vp->fid);
1899     yfs_check_req(call, bp);
1900 
1901     trace_afs_make_fs_call(call, &vp->fid);
1902     afs_make_op_call(op, call, GFP_KERNEL);
1903 }
1904 
1905 /*
1906  * YFS.StoreOpaqueACL2 operation type
1907  */
1908 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
1909     .name       = "YFS.StoreOpaqueACL2",
1910     .op     = yfs_FS_StoreOpaqueACL2,
1911     .deliver    = yfs_deliver_status_and_volsync,
1912     .destructor = afs_flat_call_destructor,
1913 };
1914 
1915 /*
1916  * Fetch the YFS ACL for a file.
1917  */
1918 void yfs_fs_store_opaque_acl2(struct afs_operation *op)
1919 {
1920     struct afs_vnode_param *vp = &op->file[0];
1921     struct afs_call *call;
1922     struct afs_acl *acl = op->acl;
1923     size_t size;
1924     __be32 *bp;
1925 
1926     _enter(",%x,{%llx:%llu},,",
1927            key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1928 
1929     size = round_up(acl->size, 4);
1930     call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreOpaqueACL2,
1931                    sizeof(__be32) * 2 +
1932                    sizeof(struct yfs_xdr_YFSFid) +
1933                    sizeof(__be32) + size,
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, YFSSTOREOPAQUEACL2);
1942     bp = xdr_encode_u32(bp, 0); /* RPC flags */
1943     bp = xdr_encode_YFSFid(bp, &vp->fid);
1944     bp = xdr_encode_u32(bp, acl->size);
1945     memcpy(bp, acl->data, acl->size);
1946     if (acl->size != size)
1947         memset((void *)bp + acl->size, 0, size - acl->size);
1948     bp += size / sizeof(__be32);
1949     yfs_check_req(call, bp);
1950 
1951     trace_afs_make_fs_call(call, &vp->fid);
1952     afs_make_op_call(op, call, GFP_KERNEL);
1953 }