linux/fs/nfs/nfs42xdr.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
   3 */
   4#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
   5#define __LINUX_FS_NFS_NFS4_2XDR_H
   6
   7#include "nfs42.h"
   8
   9#define encode_fallocate_maxsz          (encode_stateid_maxsz + \
  10                                         2 /* offset */ + \
  11                                         2 /* length */)
  12#define encode_allocate_maxsz           (op_encode_hdr_maxsz + \
  13                                         encode_fallocate_maxsz)
  14#define decode_allocate_maxsz           (op_decode_hdr_maxsz)
  15#define encode_deallocate_maxsz         (op_encode_hdr_maxsz + \
  16                                         encode_fallocate_maxsz)
  17#define decode_deallocate_maxsz         (op_decode_hdr_maxsz)
  18#define encode_seek_maxsz               (op_encode_hdr_maxsz + \
  19                                         encode_stateid_maxsz + \
  20                                         2 /* offset */ + \
  21                                         1 /* whence */)
  22#define decode_seek_maxsz               (op_decode_hdr_maxsz + \
  23                                         1 /* eof */ + \
  24                                         1 /* whence */ + \
  25                                         2 /* offset */ + \
  26                                         2 /* length */)
  27#define encode_io_info_maxsz            4
  28#define encode_layoutstats_maxsz        (op_decode_hdr_maxsz + \
  29                                        2 /* offset */ + \
  30                                        2 /* length */ + \
  31                                        encode_stateid_maxsz + \
  32                                        encode_io_info_maxsz + \
  33                                        encode_io_info_maxsz + \
  34                                        1 /* opaque devaddr4 length */ + \
  35                                        XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
  36#define decode_layoutstats_maxsz        (op_decode_hdr_maxsz)
  37#define encode_clone_maxsz              (encode_stateid_maxsz + \
  38                                        encode_stateid_maxsz + \
  39                                        2 /* src offset */ + \
  40                                        2 /* dst offset */ + \
  41                                        2 /* count */)
  42#define decode_clone_maxsz              (op_decode_hdr_maxsz)
  43
  44#define NFS4_enc_allocate_sz            (compound_encode_hdr_maxsz + \
  45                                         encode_putfh_maxsz + \
  46                                         encode_allocate_maxsz + \
  47                                         encode_getattr_maxsz)
  48#define NFS4_dec_allocate_sz            (compound_decode_hdr_maxsz + \
  49                                         decode_putfh_maxsz + \
  50                                         decode_allocate_maxsz + \
  51                                         decode_getattr_maxsz)
  52#define NFS4_enc_deallocate_sz          (compound_encode_hdr_maxsz + \
  53                                         encode_putfh_maxsz + \
  54                                         encode_deallocate_maxsz + \
  55                                         encode_getattr_maxsz)
  56#define NFS4_dec_deallocate_sz          (compound_decode_hdr_maxsz + \
  57                                         decode_putfh_maxsz + \
  58                                         decode_deallocate_maxsz + \
  59                                         decode_getattr_maxsz)
  60#define NFS4_enc_seek_sz                (compound_encode_hdr_maxsz + \
  61                                         encode_putfh_maxsz + \
  62                                         encode_seek_maxsz)
  63#define NFS4_dec_seek_sz                (compound_decode_hdr_maxsz + \
  64                                         decode_putfh_maxsz + \
  65                                         decode_seek_maxsz)
  66#define NFS4_enc_layoutstats_sz         (compound_encode_hdr_maxsz + \
  67                                         encode_sequence_maxsz + \
  68                                         encode_putfh_maxsz + \
  69                                         PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
  70#define NFS4_dec_layoutstats_sz         (compound_decode_hdr_maxsz + \
  71                                         decode_sequence_maxsz + \
  72                                         decode_putfh_maxsz + \
  73                                         PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
  74#define NFS4_enc_clone_sz               (compound_encode_hdr_maxsz + \
  75                                         encode_sequence_maxsz + \
  76                                         encode_putfh_maxsz + \
  77                                         encode_savefh_maxsz + \
  78                                         encode_putfh_maxsz + \
  79                                         encode_clone_maxsz + \
  80                                         encode_getattr_maxsz)
  81#define NFS4_dec_clone_sz               (compound_decode_hdr_maxsz + \
  82                                         decode_sequence_maxsz + \
  83                                         decode_putfh_maxsz + \
  84                                         decode_savefh_maxsz + \
  85                                         decode_putfh_maxsz + \
  86                                         decode_clone_maxsz + \
  87                                         decode_getattr_maxsz)
  88
  89static void encode_fallocate(struct xdr_stream *xdr,
  90                             struct nfs42_falloc_args *args)
  91{
  92        encode_nfs4_stateid(xdr, &args->falloc_stateid);
  93        encode_uint64(xdr, args->falloc_offset);
  94        encode_uint64(xdr, args->falloc_length);
  95}
  96
  97static void encode_allocate(struct xdr_stream *xdr,
  98                            struct nfs42_falloc_args *args,
  99                            struct compound_hdr *hdr)
 100{
 101        encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
 102        encode_fallocate(xdr, args);
 103}
 104
 105static void encode_deallocate(struct xdr_stream *xdr,
 106                              struct nfs42_falloc_args *args,
 107                              struct compound_hdr *hdr)
 108{
 109        encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
 110        encode_fallocate(xdr, args);
 111}
 112
 113static void encode_seek(struct xdr_stream *xdr,
 114                        struct nfs42_seek_args *args,
 115                        struct compound_hdr *hdr)
 116{
 117        encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
 118        encode_nfs4_stateid(xdr, &args->sa_stateid);
 119        encode_uint64(xdr, args->sa_offset);
 120        encode_uint32(xdr, args->sa_what);
 121}
 122
 123static void encode_layoutstats(struct xdr_stream *xdr,
 124                               struct nfs42_layoutstat_args *args,
 125                               struct nfs42_layoutstat_devinfo *devinfo,
 126                               struct compound_hdr *hdr)
 127{
 128        __be32 *p;
 129
 130        encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
 131        p = reserve_space(xdr, 8 + 8);
 132        p = xdr_encode_hyper(p, devinfo->offset);
 133        p = xdr_encode_hyper(p, devinfo->length);
 134        encode_nfs4_stateid(xdr, &args->stateid);
 135        p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
 136        p = xdr_encode_hyper(p, devinfo->read_count);
 137        p = xdr_encode_hyper(p, devinfo->read_bytes);
 138        p = xdr_encode_hyper(p, devinfo->write_count);
 139        p = xdr_encode_hyper(p, devinfo->write_bytes);
 140        p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
 141                        NFS4_DEVICEID4_SIZE);
 142        /* Encode layoutupdate4 */
 143        *p++ = cpu_to_be32(devinfo->layout_type);
 144        if (devinfo->layoutstats_encode != NULL)
 145                devinfo->layoutstats_encode(xdr, args, devinfo);
 146        else
 147                encode_uint32(xdr, 0);
 148}
 149
 150static void encode_clone(struct xdr_stream *xdr,
 151                         struct nfs42_clone_args *args,
 152                         struct compound_hdr *hdr)
 153{
 154        __be32 *p;
 155
 156        encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
 157        encode_nfs4_stateid(xdr, &args->src_stateid);
 158        encode_nfs4_stateid(xdr, &args->dst_stateid);
 159        p = reserve_space(xdr, 3*8);
 160        p = xdr_encode_hyper(p, args->src_offset);
 161        p = xdr_encode_hyper(p, args->dst_offset);
 162        xdr_encode_hyper(p, args->count);
 163}
 164
 165/*
 166 * Encode ALLOCATE request
 167 */
 168static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
 169                                  struct xdr_stream *xdr,
 170                                  struct nfs42_falloc_args *args)
 171{
 172        struct compound_hdr hdr = {
 173                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 174        };
 175
 176        encode_compound_hdr(xdr, req, &hdr);
 177        encode_sequence(xdr, &args->seq_args, &hdr);
 178        encode_putfh(xdr, args->falloc_fh, &hdr);
 179        encode_allocate(xdr, args, &hdr);
 180        encode_getfattr(xdr, args->falloc_bitmask, &hdr);
 181        encode_nops(&hdr);
 182}
 183
 184/*
 185 * Encode DEALLOCATE request
 186 */
 187static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
 188                                    struct xdr_stream *xdr,
 189                                    struct nfs42_falloc_args *args)
 190{
 191        struct compound_hdr hdr = {
 192                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 193        };
 194
 195        encode_compound_hdr(xdr, req, &hdr);
 196        encode_sequence(xdr, &args->seq_args, &hdr);
 197        encode_putfh(xdr, args->falloc_fh, &hdr);
 198        encode_deallocate(xdr, args, &hdr);
 199        encode_getfattr(xdr, args->falloc_bitmask, &hdr);
 200        encode_nops(&hdr);
 201}
 202
 203/*
 204 * Encode SEEK request
 205 */
 206static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
 207                              struct xdr_stream *xdr,
 208                              struct nfs42_seek_args *args)
 209{
 210        struct compound_hdr hdr = {
 211                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 212        };
 213
 214        encode_compound_hdr(xdr, req, &hdr);
 215        encode_sequence(xdr, &args->seq_args, &hdr);
 216        encode_putfh(xdr, args->sa_fh, &hdr);
 217        encode_seek(xdr, args, &hdr);
 218        encode_nops(&hdr);
 219}
 220
 221/*
 222 * Encode LAYOUTSTATS request
 223 */
 224static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
 225                                     struct xdr_stream *xdr,
 226                                     struct nfs42_layoutstat_args *args)
 227{
 228        int i;
 229
 230        struct compound_hdr hdr = {
 231                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 232        };
 233
 234        encode_compound_hdr(xdr, req, &hdr);
 235        encode_sequence(xdr, &args->seq_args, &hdr);
 236        encode_putfh(xdr, args->fh, &hdr);
 237        WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
 238        for (i = 0; i < args->num_dev; i++)
 239                encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
 240        encode_nops(&hdr);
 241}
 242
 243/*
 244 * Encode CLONE request
 245 */
 246static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
 247                               struct xdr_stream *xdr,
 248                               struct nfs42_clone_args *args)
 249{
 250        struct compound_hdr hdr = {
 251                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 252        };
 253
 254        encode_compound_hdr(xdr, req, &hdr);
 255        encode_sequence(xdr, &args->seq_args, &hdr);
 256        encode_putfh(xdr, args->src_fh, &hdr);
 257        encode_savefh(xdr, &hdr);
 258        encode_putfh(xdr, args->dst_fh, &hdr);
 259        encode_clone(xdr, args, &hdr);
 260        encode_getfattr(xdr, args->dst_bitmask, &hdr);
 261        encode_nops(&hdr);
 262}
 263
 264static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
 265{
 266        return decode_op_hdr(xdr, OP_ALLOCATE);
 267}
 268
 269static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
 270{
 271        return decode_op_hdr(xdr, OP_DEALLOCATE);
 272}
 273
 274static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
 275{
 276        int status;
 277        __be32 *p;
 278
 279        status = decode_op_hdr(xdr, OP_SEEK);
 280        if (status)
 281                return status;
 282
 283        p = xdr_inline_decode(xdr, 4 + 8);
 284        if (unlikely(!p))
 285                goto out_overflow;
 286
 287        res->sr_eof = be32_to_cpup(p++);
 288        p = xdr_decode_hyper(p, &res->sr_offset);
 289        return 0;
 290
 291out_overflow:
 292        print_overflow_msg(__func__, xdr);
 293        return -EIO;
 294}
 295
 296static int decode_layoutstats(struct xdr_stream *xdr)
 297{
 298        return decode_op_hdr(xdr, OP_LAYOUTSTATS);
 299}
 300
 301static int decode_clone(struct xdr_stream *xdr)
 302{
 303        return decode_op_hdr(xdr, OP_CLONE);
 304}
 305
 306/*
 307 * Decode ALLOCATE request
 308 */
 309static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
 310                                 struct xdr_stream *xdr,
 311                                 struct nfs42_falloc_res *res)
 312{
 313        struct compound_hdr hdr;
 314        int status;
 315
 316        status = decode_compound_hdr(xdr, &hdr);
 317        if (status)
 318                goto out;
 319        status = decode_sequence(xdr, &res->seq_res, rqstp);
 320        if (status)
 321                goto out;
 322        status = decode_putfh(xdr);
 323        if (status)
 324                goto out;
 325        status = decode_allocate(xdr, res);
 326        if (status)
 327                goto out;
 328        decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
 329out:
 330        return status;
 331}
 332
 333/*
 334 * Decode DEALLOCATE request
 335 */
 336static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
 337                                   struct xdr_stream *xdr,
 338                                   struct nfs42_falloc_res *res)
 339{
 340        struct compound_hdr hdr;
 341        int status;
 342
 343        status = decode_compound_hdr(xdr, &hdr);
 344        if (status)
 345                goto out;
 346        status = decode_sequence(xdr, &res->seq_res, rqstp);
 347        if (status)
 348                goto out;
 349        status = decode_putfh(xdr);
 350        if (status)
 351                goto out;
 352        status = decode_deallocate(xdr, res);
 353        if (status)
 354                goto out;
 355        decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
 356out:
 357        return status;
 358}
 359
 360/*
 361 * Decode SEEK request
 362 */
 363static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
 364                             struct xdr_stream *xdr,
 365                             struct nfs42_seek_res *res)
 366{
 367        struct compound_hdr hdr;
 368        int status;
 369
 370        status = decode_compound_hdr(xdr, &hdr);
 371        if (status)
 372                goto out;
 373        status = decode_sequence(xdr, &res->seq_res, rqstp);
 374        if (status)
 375                goto out;
 376        status = decode_putfh(xdr);
 377        if (status)
 378                goto out;
 379        status = decode_seek(xdr, res);
 380out:
 381        return status;
 382}
 383
 384/*
 385 * Decode LAYOUTSTATS request
 386 */
 387static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
 388                                    struct xdr_stream *xdr,
 389                                    struct nfs42_layoutstat_res *res)
 390{
 391        struct compound_hdr hdr;
 392        int status, i;
 393
 394        status = decode_compound_hdr(xdr, &hdr);
 395        if (status)
 396                goto out;
 397        status = decode_sequence(xdr, &res->seq_res, rqstp);
 398        if (status)
 399                goto out;
 400        status = decode_putfh(xdr);
 401        if (status)
 402                goto out;
 403        WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
 404        for (i = 0; i < res->num_dev; i++) {
 405                status = decode_layoutstats(xdr);
 406                if (status)
 407                        goto out;
 408        }
 409out:
 410        res->rpc_status = status;
 411        return status;
 412}
 413
 414/*
 415 * Decode CLONE request
 416 */
 417static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
 418                              struct xdr_stream *xdr,
 419                              struct nfs42_clone_res *res)
 420{
 421        struct compound_hdr hdr;
 422        int status;
 423
 424        status = decode_compound_hdr(xdr, &hdr);
 425        if (status)
 426                goto out;
 427        status = decode_sequence(xdr, &res->seq_res, rqstp);
 428        if (status)
 429                goto out;
 430        status = decode_putfh(xdr);
 431        if (status)
 432                goto out;
 433        status = decode_savefh(xdr);
 434        if (status)
 435                goto out;
 436        status = decode_putfh(xdr);
 437        if (status)
 438                goto out;
 439        status = decode_clone(xdr);
 440        if (status)
 441                goto out;
 442        status = decode_getfattr(xdr, res->dst_fattr, res->server);
 443
 444out:
 445        res->rpc_status = status;
 446        return status;
 447}
 448
 449#endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
 450