root/fs/afs/yfsclient.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. afs_use_fs_server
  2. xdr_decode_YFSFid
  3. xdr_encode_u32
  4. xdr_encode_u64
  5. xdr_encode_YFSFid
  6. xdr_strlen
  7. xdr_encode_string
  8. linux_to_yfs_time
  9. xdr_encode_YFSStoreStatus_mode
  10. xdr_encode_YFSStoreStatus_mtime
  11. yfs_time_to_linux
  12. xdr_to_time
  13. yfs_check_req
  14. xdr_dump_bad
  15. xdr_decode_YFSFetchStatus
  16. xdr_decode_YFSCallBack
  17. xdr_decode_YFSVolSync
  18. xdr_encode_YFS_StoreStatus
  19. xdr_decode_YFSFetchVolumeStatus
  20. yfs_deliver_fs_status_cb_and_volsync
  21. yfs_deliver_status_and_volsync
  22. yfs_fs_fetch_file_status
  23. yfs_deliver_fs_fetch_data64
  24. yfs_fetch_data_destructor
  25. yfs_fs_fetch_data
  26. yfs_deliver_fs_create_vnode
  27. yfs_fs_create_file
  28. yfs_fs_make_dir
  29. yfs_deliver_fs_remove_file2
  30. yfs_fs_remove_file2
  31. yfs_deliver_fs_remove
  32. yfs_fs_remove
  33. yfs_deliver_fs_link
  34. yfs_fs_link
  35. yfs_deliver_fs_symlink
  36. yfs_fs_symlink
  37. yfs_deliver_fs_rename
  38. yfs_fs_rename
  39. yfs_fs_store_data
  40. yfs_fs_setattr_size
  41. yfs_fs_setattr
  42. yfs_deliver_fs_get_volume_status
  43. yfs_fs_get_volume_status
  44. yfs_fs_set_lock
  45. yfs_fs_extend_lock
  46. yfs_fs_release_lock
  47. yfs_fs_fetch_status
  48. yfs_deliver_fs_inline_bulk_status
  49. yfs_fs_inline_bulk_status
  50. yfs_deliver_fs_fetch_opaque_acl
  51. yfs_free_opaque_acl
  52. yfs_fs_fetch_opaque_acl
  53. yfs_fs_store_opaque_acl2

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

/* [<][>][^][v][top][bottom][index][help] */