CTC++ Coverage Report - Execution Profile    #970/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: fs/nfs/callback_xdr.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/317)

Start/ End/    
True False - Line Source

  1 /*
  2  * linux/fs/nfs/callback_xdr.c
  3  *
  4  * Copyright (C) 2004 Trond Myklebust
  5  *
  6  * NFSv4 callback encode/decode procedures
  7  */
  8 #include <linux/config.h>
  9 #include <linux/kernel.h>
  10 #include <linux/sunrpc/svc.h>
  11 #include <linux/nfs4.h>
  12 #include <linux/nfs_fs.h>
  13 #include "nfs4_fs.h"
  14 #include "callback.h"
  15 
  16 #define CB_OP_TAGLEN_MAXSZ   (512)
  17 #define CB_OP_HDR_RES_MAXSZ   (2 + CB_OP_TAGLEN_MAXSZ)
  18 #define CB_OP_GETATTR_BITMAP_MAXSZ   (4)
  19 #define CB_OP_GETATTR_RES_MAXSZ   (CB_OP_HDR_RES_MAXSZ + \
  20             CB_OP_GETATTR_BITMAP_MAXSZ + \
  21             2 + 2 + 3 + 3)
  22 #define CB_OP_RECALL_RES_MAXSZ   (CB_OP_HDR_RES_MAXSZ)
  23 
  24 #define NFSDBG_FACILITY NFSDBG_CALLBACK
  25 
  26 typedef unsigned (*callback_process_op_t)(void *, void *);
  27 typedef unsigned (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *);
  28 typedef unsigned (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *);
  29 
  30 
  31 struct callback_op {
  32    callback_process_op_t process_op;
  33    callback_decode_arg_t decode_args;
  34    callback_encode_res_t encode_res;
  35    long res_maxsize;
  36 };
  37 
  38 static struct callback_op callback_ops[];
  39 
 
- 40 static int nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp)
  41 {
    42    return htonl(NFS4_OK);
- 42 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
 - 42 return ( ( __be32 ) ( __builtin_constant_p ( (..
  43 }
  44 
 
- 45 static int nfs4_decode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy)
  46 {
 - 47    return xdr_argsize_check(rqstp, p);
  48 }
  49 
 
- 50 static int nfs4_encode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy)
  51 {
 - 52    return xdr_ressize_check(rqstp, p);
  53 }
  54 
 
- 55 static uint32_t *read_buf(struct xdr_stream *xdr, int nbytes)
  56 {
  57    uint32_t *p;
  58 
  59    p = xdr_inline_decode(xdr, nbytes);
- 60    if (unlikely(p == NULL))
  61       printk(KERN_WARNING "NFSv4 callback reply buffer overflowed!\n");
 - 62    return p;
  63 }
  64 
 
- 65 static unsigned decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str)
  66 {
  67    uint32_t *p;
  68 
  69    p = read_buf(xdr, 4);
- 70    if (unlikely(p == NULL))
    71       return htonl(NFS4ERR_RESOURCE);
- 71   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 71   return ( ( __be32 ) ( __builtin_constant_p (..
    72    *len = ntohl(*p);
- 72 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
  73 
- 74    if (*len != 0) {
  75       p = read_buf(xdr, *len);
- 76       if (unlikely(p == NULL))
    77          return htonl(NFS4ERR_RESOURCE);
- 77     ternary-?: __builtin_constant_p ( ( __u32 ..
 - 77     return ( ( __be32 ) ( __builtin_constant_p..
  78       *str = (const char *)p;
    79    } else
  80       *str = NULL;
  81 
 - 82    return 0;
  83 }
  84 
 
- 85 static unsigned decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
  86 {
  87    uint32_t *p;
  88 
  89    p = read_buf(xdr, 4);
- 90    if (unlikely(p == NULL))
    91       return htonl(NFS4ERR_RESOURCE);
- 91   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 91   return ( ( __be32 ) ( __builtin_constant_p (..
    92    fh->size = ntohl(*p);
- 92 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
- 93    if (fh->size > NFS4_FHSIZE)
    94       return htonl(NFS4ERR_BADHANDLE);
- 94   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 94   return ( ( __be32 ) ( __builtin_constant_p (..
  95    p = read_buf(xdr, fh->size);
- 96    if (unlikely(p == NULL))
    97       return htonl(NFS4ERR_RESOURCE);
- 97   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 97   return ( ( __be32 ) ( __builtin_constant_p (..
  98    memcpy(&fh->data[0], p, fh->size);
  99    memset(&fh->data[fh->size], 0, sizeof(fh->data) - fh->size);
 - 100    return 0;
  101 }
  102 
 
- 103 static unsigned decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
  104 {
  105    uint32_t *p;
  106    unsigned int attrlen;
  107 
  108    p = read_buf(xdr, 4);
- 109    if (unlikely(p == NULL))
    110       return htonl(NFS4ERR_RESOURCE);
- 110   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 110   return ( ( __be32 ) ( __builtin_constant_p (..
    111    attrlen = ntohl(*p);
- 111 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
  112    p = read_buf(xdr, attrlen << 2);
- 113    if (unlikely(p == NULL))
    114       return htonl(NFS4ERR_RESOURCE);
- 114   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 114   return ( ( __be32 ) ( __builtin_constant_p (..
- 115    if (likely(attrlen > 0))
    116       bitmap[0] = ntohl(*p++);
- 116   ternary-?: __builtin_constant_p ( ( __u32 ) ..
- 117    if (attrlen > 1)
    118       bitmap[1] = ntohl(*p);
- 118   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 119    return 0;
  120 }
  121 
 
- 122 static unsigned decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
  123 {
  124    uint32_t *p;
  125 
  126    p = read_buf(xdr, 16);
- 127    if (unlikely(p == NULL))
    128       return htonl(NFS4ERR_RESOURCE);
- 128   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 128   return ( ( __be32 ) ( __builtin_constant_p (..
  129    memcpy(stateid->data, p, 16);
 - 130    return 0;
  131 }
  132 
 
- 133 static unsigned decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
  134 {
  135    uint32_t *p;
  136    unsigned int minor_version;
  137    unsigned status;
  138 
  139    status = decode_string(xdr, &hdr->taglen, &hdr->tag);
- 140    if (unlikely(status != 0))
 - 141       return status;
  142    /* We do not like overly long tags! */
- 143    if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
 - 143   T || _
 - 143   F || T
 - 143   F || F
  144       printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
  145             __FUNCTION__, hdr->taglen);
    146       return htonl(NFS4ERR_RESOURCE);
- 146   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 146   return ( ( __be32 ) ( __builtin_constant_p (..
  147    }
  148    p = read_buf(xdr, 12);
- 149    if (unlikely(p == NULL))
    150       return htonl(NFS4ERR_RESOURCE);
- 150   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 150   return ( ( __be32 ) ( __builtin_constant_p (..
    151    minor_version = ntohl(*p++);
- 151 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
  152    /* Check minor version is zero. */
- 153    if (minor_version != 0) {
  154       printk(KERN_WARNING "%s: NFSv4 server callback with illegal minor version %u!\n",
  155             __FUNCTION__, minor_version);
    156       return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
- 156   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 156   return ( ( __be32 ) ( __builtin_constant_p (..
  157    }
    158    hdr->callback_ident = ntohl(*p++);
- 158 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
    159    hdr->nops = ntohl(*p);
- 159 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
 - 160    return 0;
  161 }
  162 
 
- 163 static unsigned decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
  164 {
  165    uint32_t *p;
  166    p = read_buf(xdr, 4);
- 167    if (unlikely(p == NULL))
    168       return htonl(NFS4ERR_RESOURCE);
- 168   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 168   return ( ( __be32 ) ( __builtin_constant_p (..
    169    *op = ntohl(*p);
- 169 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
 - 170    return 0;
  171 }
  172 
 
- 173 static unsigned decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args)
  174 {
  175    unsigned status;
  176 
  177    status = decode_fh(xdr, &args->fh);
- 178    if (unlikely(status != 0))
 - 179       goto out;
  180    args->addr = &rqstp->rq_addr;
  181    status = decode_bitmap(xdr, args->bitmap);
  182 out:
    183    dprintk("%s: exit with status = %d\n", __FUNCTION__, status);
- 183   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 183 do-while (0)
 - 184    return status;
  185 }
  186 
 
- 187 static unsigned decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args)
  188 {
  189    uint32_t *p;
  190    unsigned status;
  191 
  192    args->addr = &rqstp->rq_addr;
  193    status = decode_stateid(xdr, &args->stateid);
- 194    if (unlikely(status != 0))
 - 195       goto out;
  196    p = read_buf(xdr, 4);
- 197    if (unlikely(p == NULL)) {
    198       status = htonl(NFS4ERR_RESOURCE);
- 198   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 199       goto out;
  200    }
    201    args->truncate = ntohl(*p);
- 201 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
  202    status = decode_fh(xdr, &args->fh);
  203 out:
    204    dprintk("%s: exit with status = %d\n", __FUNCTION__, status);
- 204   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 204 do-while (0)
 - 205    return 0;
  206 }
  207 
 
- 208 static unsigned encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
  209 {
  210    uint32_t *p;
  211 
  212    p = xdr_reserve_space(xdr, 4 + len);
- 213    if (unlikely(p == NULL))
    214       return htonl(NFS4ERR_RESOURCE);
- 214   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 214   return ( ( __be32 ) ( __builtin_constant_p (..
  215    xdr_encode_opaque(p, str, len);
 - 216    return 0;
  217 }
  218 
  219 #define CB_SUPPORTED_ATTR0 (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE)
  220 #define CB_SUPPORTED_ATTR1 (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY)
 
- 221 static unsigned encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, uint32_t **savep)
  222 {
  223    uint32_t bm[2];
  224    uint32_t *p;
  225 
    226    bm[0] = htonl(bitmap[0] & CB_SUPPORTED_ATTR0);
- 226 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
    227    bm[1] = htonl(bitmap[1] & CB_SUPPORTED_ATTR1);
- 227 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
- 228    if (bm[1] != 0) {
  229       p = xdr_reserve_space(xdr, 16);
- 230       if (unlikely(p == NULL))
    231          return htonl(NFS4ERR_RESOURCE);
- 231     ternary-?: __builtin_constant_p ( ( __u32 ..
 - 231     return ( ( __be32 ) ( __builtin_constant_p..
    232       *p++ = htonl(2);
- 232   ternary-?: __builtin_constant_p ( ( __u32 ) ..
  233       *p++ = bm[0];
  234       *p++ = bm[1];
- 235    } else if (bm[0] != 0) {
  236       p = xdr_reserve_space(xdr, 12);
- 237       if (unlikely(p == NULL))
    238          return htonl(NFS4ERR_RESOURCE);
- 238     ternary-?: __builtin_constant_p ( ( __u32 ..
 - 238     return ( ( __be32 ) ( __builtin_constant_p..
    239       *p++ = htonl(1);
- 239   ternary-?: __builtin_constant_p ( ( __u32 ) ..
  240       *p++ = bm[0];
    241    } else {
  242       p = xdr_reserve_space(xdr, 8);
- 243       if (unlikely(p == NULL))
    244          return htonl(NFS4ERR_RESOURCE);
- 244     ternary-?: __builtin_constant_p ( ( __u32 ..
 - 244     return ( ( __be32 ) ( __builtin_constant_p..
    245       *p++ = htonl(0);
- 245   ternary-?: __builtin_constant_p ( ( __u32 ) ..
  246    }
  247    *savep = p;
 - 248    return 0;
  249 }
  250 
 
- 251 static unsigned encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change)
  252 {
  253    uint32_t *p;
  254 
- 255    if (!(bitmap[0] & FATTR4_WORD0_CHANGE))
 - 256       return 0;
  257    p = xdr_reserve_space(xdr, 8);
- 258    if (unlikely(p == 0))
    259       return htonl(NFS4ERR_RESOURCE);
- 259   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 259   return ( ( __be32 ) ( __builtin_constant_p (..
  260    p = xdr_encode_hyper(p, change);
 - 261    return 0;
  262 }
  263 
 
- 264 static unsigned encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size)
  265 {
  266    uint32_t *p;
  267 
- 268    if (!(bitmap[0] & FATTR4_WORD0_SIZE))
 - 269       return 0;
  270    p = xdr_reserve_space(xdr, 8);
- 271    if (unlikely(p == 0))
    272       return htonl(NFS4ERR_RESOURCE);
- 272   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 272   return ( ( __be32 ) ( __builtin_constant_p (..
  273    p = xdr_encode_hyper(p, size);
 - 274    return 0;
  275 }
  276 
 
- 277 static unsigned encode_attr_time(struct xdr_stream *xdr, const struct timespec *time)
  278 {
  279    uint32_t *p;
  280 
  281    p = xdr_reserve_space(xdr, 12);
- 282    if (unlikely(p == 0))
    283       return htonl(NFS4ERR_RESOURCE);
- 283   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 283   return ( ( __be32 ) ( __builtin_constant_p (..
  284    p = xdr_encode_hyper(p, time->tv_sec);
    285    *p = htonl(time->tv_nsec);
- 285 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
 - 286    return 0;
  287 }
  288 
 
- 289 static unsigned encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
  290 {
- 291    if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
 - 292       return 0;
 - 293    return encode_attr_time(xdr,time);
  294 }
  295 
 
- 296 static unsigned encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
  297 {
- 298    if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY))
 - 299       return 0;
 - 300    return encode_attr_time(xdr,time);
  301 }
  302 
 
- 303 static unsigned encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
  304 {
  305    unsigned status;
  306 
  307    hdr->status = xdr_reserve_space(xdr, 4);
- 308    if (unlikely(hdr->status == NULL))
    309       return htonl(NFS4ERR_RESOURCE);
- 309   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 309   return ( ( __be32 ) ( __builtin_constant_p (..
  310    status = encode_string(xdr, hdr->taglen, hdr->tag);
- 311    if (unlikely(status != 0))
 - 312       return status;
  313    hdr->nops = xdr_reserve_space(xdr, 4);
- 314    if (unlikely(hdr->nops == NULL))
    315       return htonl(NFS4ERR_RESOURCE);
- 315   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 315   return ( ( __be32 ) ( __builtin_constant_p (..
 - 316    return 0;
  317 }
  318 
 
- 319 static unsigned encode_op_hdr(struct xdr_stream *xdr, uint32_t op, uint32_t res)
  320 {
  321    uint32_t *p;
  322    
  323    p = xdr_reserve_space(xdr, 8);
- 324    if (unlikely(p == NULL))
    325       return htonl(NFS4ERR_RESOURCE);
- 325   ternary-?: __builtin_constant_p ( ( __u32 ) ..
 - 325   return ( ( __be32 ) ( __builtin_constant_p (..
    326    *p++ = htonl(op);
- 326 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
  327    *p = res;
 - 328    return 0;
  329 }
  330 
 
- 331 static unsigned encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res)
  332 {
  333    uint32_t *savep;
  334    unsigned status = res->status;
  335    
- 336    if (unlikely(status != 0))
 - 337       goto out;
  338    status = encode_attr_bitmap(xdr, res->bitmap, &savep);
- 339    if (unlikely(status != 0))
 - 340       goto out;
  341    status = encode_attr_change(xdr, res->bitmap, res->change_attr);
- 342    if (unlikely(status != 0))
 - 343       goto out;
  344    status = encode_attr_size(xdr, res->bitmap, res->size);
- 345    if (unlikely(status != 0))
 - 346       goto out;
  347    status = encode_attr_ctime(xdr, res->bitmap, &res->ctime);
- 348    if (unlikely(status != 0))
 - 349       goto out;
  350    status = encode_attr_mtime(xdr, res->bitmap, &res->mtime);
    351    *savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1)));
- 351 ternary-?: __builtin_constant_p ( ( __u32 ) ( ..
  352 out:
    353    dprintk("%s: exit with status = %d\n", __FUNCTION__, status);
- 353   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 353 do-while (0)
 - 354    return status;
  355 }
  356 
 
- 357 static unsigned process_op(struct svc_rqst *rqstp,
  358       struct xdr_stream *xdr_in, void *argp,
  359       struct xdr_stream *xdr_out, void *resp)
  360 {
  361    struct callback_op *op;
  362    unsigned int op_nr;
  363    unsigned int status = 0;
  364    long maxlen;
  365    unsigned res;
  366 
    367    dprintk("%s: start\n", __FUNCTION__);
- 367   if (__builtin_expect ( ! ! ( nfs_debug & 0x0..
- 367 do-while (0)
  368    status = decode_op_hdr(xdr_in, &op_nr);
- 369    if (unlikely(status != 0)) {
  370       op_nr = OP_CB_ILLEGAL;
  371       op = &callback_ops[0];
- 372    } else if (unlikely(op_nr != OP_CB_GETATTR && op_nr != OP_CB_RECALL)) {
  373       op_nr = OP_CB_ILLEGAL;
  374       op = &callback_ops[0];
    375       status = htonl(NFS4ERR_OP_ILLEGAL);
- 375   ternary-?: __builtin_constant_p ( ( __u32 ) ..
    376    } else
  377       op = &callback_ops[op_nr];
  378 
  379    maxlen = xdr_out->end - xdr_out->p;
- 380    if (maxlen > 0 && maxlen < PAGE_SIZE) {
 - 380   T && T
 - 380   T && F
 - 380   F && _
- 381       if (likely(status == 0 && op->decode_args != NULL))
  382          status = op->decode_args(rqstp, xdr_in, argp);
- 383       if (likely(status == 0 && op->process_op != NULL))
  384          status = op->process_op(argp, resp);
    385    } else
    386       status = htonl(NFS4ERR_RESOURCE);
- 386   ternary-?: __builtin_constant_p ( ( __u32 ) ..
  387 
  388    res = encode_op_hdr(xdr_out, op_nr, status);