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
  38#define NFS4_enc_allocate_sz            (compound_encode_hdr_maxsz + \
  39                                         encode_putfh_maxsz + \
  40                                         encode_allocate_maxsz + \
  41                                         encode_getattr_maxsz)
  42#define NFS4_dec_allocate_sz            (compound_decode_hdr_maxsz + \
  43                                         decode_putfh_maxsz + \
  44                                         decode_allocate_maxsz + \
  45                                         decode_getattr_maxsz)
  46#define NFS4_enc_deallocate_sz          (compound_encode_hdr_maxsz + \
  47                                         encode_putfh_maxsz + \
  48                                         encode_deallocate_maxsz + \
  49                                         encode_getattr_maxsz)
  50#define NFS4_dec_deallocate_sz          (compound_decode_hdr_maxsz + \
  51                                         decode_putfh_maxsz + \
  52                                         decode_deallocate_maxsz + \
  53                                         decode_getattr_maxsz)
  54#define NFS4_enc_seek_sz                (compound_encode_hdr_maxsz + \
  55                                         encode_putfh_maxsz + \
  56                                         encode_seek_maxsz)
  57#define NFS4_dec_seek_sz                (compound_decode_hdr_maxsz + \
  58                                         decode_putfh_maxsz + \
  59                                         decode_seek_maxsz)
  60#define NFS4_enc_layoutstats_sz         (compound_encode_hdr_maxsz + \
  61                                         encode_sequence_maxsz + \
  62                                         encode_putfh_maxsz + \
  63                                         PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
  64#define NFS4_dec_layoutstats_sz         (compound_decode_hdr_maxsz + \
  65                                         decode_sequence_maxsz + \
  66                                         decode_putfh_maxsz + \
  67                                         PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
  68
  69
  70static void encode_fallocate(struct xdr_stream *xdr,
  71                             struct nfs42_falloc_args *args)
  72{
  73        encode_nfs4_stateid(xdr, &args->falloc_stateid);
  74        encode_uint64(xdr, args->falloc_offset);
  75        encode_uint64(xdr, args->falloc_length);
  76}
  77
  78static void encode_allocate(struct xdr_stream *xdr,
  79                            struct nfs42_falloc_args *args,
  80                            struct compound_hdr *hdr)
  81{
  82        encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
  83        encode_fallocate(xdr, args);
  84}
  85
  86static void encode_deallocate(struct xdr_stream *xdr,
  87                              struct nfs42_falloc_args *args,
  88                              struct compound_hdr *hdr)
  89{
  90        encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
  91        encode_fallocate(xdr, args);
  92}
  93
  94static void encode_seek(struct xdr_stream *xdr,
  95                        struct nfs42_seek_args *args,
  96                        struct compound_hdr *hdr)
  97{
  98        encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
  99        encode_nfs4_stateid(xdr, &args->sa_stateid);
 100        encode_uint64(xdr, args->sa_offset);
 101        encode_uint32(xdr, args->sa_what);
 102}
 103
 104static void encode_layoutstats(struct xdr_stream *xdr,
 105                               struct nfs42_layoutstat_args *args,
 106                               struct nfs42_layoutstat_devinfo *devinfo,
 107                               struct compound_hdr *hdr)
 108{
 109        __be32 *p;
 110
 111        encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
 112        p = reserve_space(xdr, 8 + 8);
 113        p = xdr_encode_hyper(p, devinfo->offset);
 114        p = xdr_encode_hyper(p, devinfo->length);
 115        encode_nfs4_stateid(xdr, &args->stateid);
 116        p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
 117        p = xdr_encode_hyper(p, devinfo->read_count);
 118        p = xdr_encode_hyper(p, devinfo->read_bytes);
 119        p = xdr_encode_hyper(p, devinfo->write_count);
 120        p = xdr_encode_hyper(p, devinfo->write_bytes);
 121        p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
 122                        NFS4_DEVICEID4_SIZE);
 123        /* Encode layoutupdate4 */
 124        *p++ = cpu_to_be32(devinfo->layout_type);
 125        if (devinfo->layoutstats_encode != NULL)
 126                devinfo->layoutstats_encode(xdr, args, devinfo);
 127        else
 128                encode_uint32(xdr, 0);
 129}
 130
 131/*
 132 * Encode ALLOCATE request
 133 */
 134static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
 135                                  struct xdr_stream *xdr,
 136                                  struct nfs42_falloc_args *args)
 137{
 138        struct compound_hdr hdr = {
 139                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 140        };
 141
 142        encode_compound_hdr(xdr, req, &hdr);
 143        encode_sequence(xdr, &args->seq_args, &hdr);
 144        encode_putfh(xdr, args->falloc_fh, &hdr);
 145        encode_allocate(xdr, args, &hdr);
 146        encode_getfattr(xdr, args->falloc_bitmask, &hdr);
 147        encode_nops(&hdr);
 148}
 149
 150/*
 151 * Encode DEALLOCATE request
 152 */
 153static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
 154                                    struct xdr_stream *xdr,
 155                                    struct nfs42_falloc_args *args)
 156{
 157        struct compound_hdr hdr = {
 158                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 159        };
 160
 161        encode_compound_hdr(xdr, req, &hdr);
 162        encode_sequence(xdr, &args->seq_args, &hdr);
 163        encode_putfh(xdr, args->falloc_fh, &hdr);
 164        encode_deallocate(xdr, args, &hdr);
 165        encode_getfattr(xdr, args->falloc_bitmask, &hdr);
 166        encode_nops(&hdr);
 167}
 168
 169/*
 170 * Encode SEEK request
 171 */
 172static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
 173                              struct xdr_stream *xdr,
 174                              struct nfs42_seek_args *args)
 175{
 176        struct compound_hdr hdr = {
 177                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 178        };
 179
 180        encode_compound_hdr(xdr, req, &hdr);
 181        encode_sequence(xdr, &args->seq_args, &hdr);
 182        encode_putfh(xdr, args->sa_fh, &hdr);
 183        encode_seek(xdr, args, &hdr);
 184        encode_nops(&hdr);
 185}
 186
 187/*
 188 * Encode LAYOUTSTATS request
 189 */
 190static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
 191                                     struct xdr_stream *xdr,
 192                                     struct nfs42_layoutstat_args *args)
 193{
 194        int i;
 195
 196        struct compound_hdr hdr = {
 197                .minorversion = nfs4_xdr_minorversion(&args->seq_args),
 198        };
 199
 200        encode_compound_hdr(xdr, req, &hdr);
 201        encode_sequence(xdr, &args->seq_args, &hdr);
 202        encode_putfh(xdr, args->fh, &hdr);
 203        WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
 204        for (i = 0; i < args->num_dev; i++)
 205                encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
 206        encode_nops(&hdr);
 207}
 208
 209static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
 210{
 211        return decode_op_hdr(xdr, OP_ALLOCATE);
 212}
 213
 214static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
 215{
 216        return decode_op_hdr(xdr, OP_DEALLOCATE);
 217}
 218
 219static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
 220{
 221        int status;
 222        __be32 *p;
 223
 224        status = decode_op_hdr(xdr, OP_SEEK);
 225        if (status)
 226                return status;
 227
 228        p = xdr_inline_decode(xdr, 4 + 8);
 229        if (unlikely(!p))
 230                goto out_overflow;
 231
 232        res->sr_eof = be32_to_cpup(p++);
 233        p = xdr_decode_hyper(p, &res->sr_offset);
 234        return 0;
 235
 236out_overflow:
 237        print_overflow_msg(__func__, xdr);
 238        return -EIO;
 239}
 240
 241static int decode_layoutstats(struct xdr_stream *xdr,
 242                              struct nfs42_layoutstat_res *res)
 243{
 244        return decode_op_hdr(xdr, OP_LAYOUTSTATS);
 245}
 246
 247/*
 248 * Decode ALLOCATE request
 249 */
 250static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
 251                                 struct xdr_stream *xdr,
 252                                 struct nfs42_falloc_res *res)
 253{
 254        struct compound_hdr hdr;
 255        int status;
 256
 257        status = decode_compound_hdr(xdr, &hdr);
 258        if (status)
 259                goto out;
 260        status = decode_sequence(xdr, &res->seq_res, rqstp);
 261        if (status)
 262                goto out;
 263        status = decode_putfh(xdr);
 264        if (status)
 265                goto out;
 266        status = decode_allocate(xdr, res);
 267        if (status)
 268                goto out;
 269        decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
 270out:
 271        return status;
 272}
 273
 274/*
 275 * Decode DEALLOCATE request
 276 */
 277static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
 278                                   struct xdr_stream *xdr,
 279                                   struct nfs42_falloc_res *res)
 280{
 281        struct compound_hdr hdr;
 282        int status;
 283
 284        status = decode_compound_hdr(xdr, &hdr);
 285        if (status)
 286                goto out;
 287        status = decode_sequence(xdr, &res->seq_res, rqstp);
 288        if (status)
 289                goto out;
 290        status = decode_putfh(xdr);
 291        if (status)
 292                goto out;
 293        status = decode_deallocate(xdr, res);
 294        if (status)
 295                goto out;
 296        decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
 297out:
 298        return status;
 299}
 300
 301/*
 302 * Decode SEEK request
 303 */
 304static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
 305                             struct xdr_stream *xdr,
 306                             struct nfs42_seek_res *res)
 307{
 308        struct compound_hdr hdr;
 309        int status;
 310
 311        status = decode_compound_hdr(xdr, &hdr);
 312        if (status)
 313                goto out;
 314        status = decode_sequence(xdr, &res->seq_res, rqstp);
 315        if (status)
 316                goto out;
 317        status = decode_putfh(xdr);
 318        if (status)
 319                goto out;
 320        status = decode_seek(xdr, res);
 321out:
 322        return status;
 323}
 324
 325/*
 326 * Decode LAYOUTSTATS request
 327 */
 328static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
 329                                    struct xdr_stream *xdr,
 330                                    struct nfs42_layoutstat_res *res)
 331{
 332        struct compound_hdr hdr;
 333        int status, i;
 334
 335        status = decode_compound_hdr(xdr, &hdr);
 336        if (status)
 337                goto out;
 338        status = decode_sequence(xdr, &res->seq_res, rqstp);
 339        if (status)
 340                goto out;
 341        status = decode_putfh(xdr);
 342        if (status)
 343                goto out;
 344        WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
 345        for (i = 0; i < res->num_dev; i++) {
 346                status = decode_layoutstats(xdr, res);
 347                if (status)
 348                        goto out;
 349        }
 350out:
 351        res->rpc_status = status;
 352        return status;
 353}
 354
 355#endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
 356