callback_xdr.c (e6f684f6443dd37384c63d2f27571350e0b5c8aa) | callback_xdr.c (5704fdeb41c9fb282ae576516f221ea0b8f64b2b) |
---|---|
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/kernel.h> --- 27 unchanged lines hidden (view full) --- 36 37static struct callback_op callback_ops[]; 38 39static __be32 nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp) 40{ 41 return htonl(NFS4_OK); 42} 43 | 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/kernel.h> --- 27 unchanged lines hidden (view full) --- 36 37static struct callback_op callback_ops[]; 38 39static __be32 nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp) 40{ 41 return htonl(NFS4_OK); 42} 43 |
44static int nfs4_decode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy) | 44static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) |
45{ 46 return xdr_argsize_check(rqstp, p); 47} 48 | 45{ 46 return xdr_argsize_check(rqstp, p); 47} 48 |
49static int nfs4_encode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy) | 49static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) |
50{ 51 return xdr_ressize_check(rqstp, p); 52} 53 | 50{ 51 return xdr_ressize_check(rqstp, p); 52} 53 |
54static uint32_t *read_buf(struct xdr_stream *xdr, int nbytes) | 54static __be32 *read_buf(struct xdr_stream *xdr, int nbytes) |
55{ | 55{ |
56 uint32_t *p; | 56 __be32 *p; |
57 58 p = xdr_inline_decode(xdr, nbytes); 59 if (unlikely(p == NULL)) 60 printk(KERN_WARNING "NFSv4 callback reply buffer overflowed!\n"); 61 return p; 62} 63 64static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str) 65{ | 57 58 p = xdr_inline_decode(xdr, nbytes); 59 if (unlikely(p == NULL)) 60 printk(KERN_WARNING "NFSv4 callback reply buffer overflowed!\n"); 61 return p; 62} 63 64static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str) 65{ |
66 uint32_t *p; | 66 __be32 *p; |
67 68 p = read_buf(xdr, 4); 69 if (unlikely(p == NULL)) 70 return htonl(NFS4ERR_RESOURCE); 71 *len = ntohl(*p); 72 73 if (*len != 0) { 74 p = read_buf(xdr, *len); 75 if (unlikely(p == NULL)) 76 return htonl(NFS4ERR_RESOURCE); 77 *str = (const char *)p; 78 } else 79 *str = NULL; 80 81 return 0; 82} 83 84static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) 85{ | 67 68 p = read_buf(xdr, 4); 69 if (unlikely(p == NULL)) 70 return htonl(NFS4ERR_RESOURCE); 71 *len = ntohl(*p); 72 73 if (*len != 0) { 74 p = read_buf(xdr, *len); 75 if (unlikely(p == NULL)) 76 return htonl(NFS4ERR_RESOURCE); 77 *str = (const char *)p; 78 } else 79 *str = NULL; 80 81 return 0; 82} 83 84static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) 85{ |
86 uint32_t *p; | 86 __be32 *p; |
87 88 p = read_buf(xdr, 4); 89 if (unlikely(p == NULL)) 90 return htonl(NFS4ERR_RESOURCE); 91 fh->size = ntohl(*p); 92 if (fh->size > NFS4_FHSIZE) 93 return htonl(NFS4ERR_BADHANDLE); 94 p = read_buf(xdr, fh->size); 95 if (unlikely(p == NULL)) 96 return htonl(NFS4ERR_RESOURCE); 97 memcpy(&fh->data[0], p, fh->size); 98 memset(&fh->data[fh->size], 0, sizeof(fh->data) - fh->size); 99 return 0; 100} 101 102static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) 103{ | 87 88 p = read_buf(xdr, 4); 89 if (unlikely(p == NULL)) 90 return htonl(NFS4ERR_RESOURCE); 91 fh->size = ntohl(*p); 92 if (fh->size > NFS4_FHSIZE) 93 return htonl(NFS4ERR_BADHANDLE); 94 p = read_buf(xdr, fh->size); 95 if (unlikely(p == NULL)) 96 return htonl(NFS4ERR_RESOURCE); 97 memcpy(&fh->data[0], p, fh->size); 98 memset(&fh->data[fh->size], 0, sizeof(fh->data) - fh->size); 99 return 0; 100} 101 102static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) 103{ |
104 uint32_t *p; | 104 __be32 *p; |
105 unsigned int attrlen; 106 107 p = read_buf(xdr, 4); 108 if (unlikely(p == NULL)) 109 return htonl(NFS4ERR_RESOURCE); 110 attrlen = ntohl(*p); 111 p = read_buf(xdr, attrlen << 2); 112 if (unlikely(p == NULL)) 113 return htonl(NFS4ERR_RESOURCE); 114 if (likely(attrlen > 0)) 115 bitmap[0] = ntohl(*p++); 116 if (attrlen > 1) 117 bitmap[1] = ntohl(*p); 118 return 0; 119} 120 121static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 122{ | 105 unsigned int attrlen; 106 107 p = read_buf(xdr, 4); 108 if (unlikely(p == NULL)) 109 return htonl(NFS4ERR_RESOURCE); 110 attrlen = ntohl(*p); 111 p = read_buf(xdr, attrlen << 2); 112 if (unlikely(p == NULL)) 113 return htonl(NFS4ERR_RESOURCE); 114 if (likely(attrlen > 0)) 115 bitmap[0] = ntohl(*p++); 116 if (attrlen > 1) 117 bitmap[1] = ntohl(*p); 118 return 0; 119} 120 121static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 122{ |
123 uint32_t *p; | 123 __be32 *p; |
124 125 p = read_buf(xdr, 16); 126 if (unlikely(p == NULL)) 127 return htonl(NFS4ERR_RESOURCE); 128 memcpy(stateid->data, p, 16); 129 return 0; 130} 131 132static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr) 133{ | 124 125 p = read_buf(xdr, 16); 126 if (unlikely(p == NULL)) 127 return htonl(NFS4ERR_RESOURCE); 128 memcpy(stateid->data, p, 16); 129 return 0; 130} 131 132static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr) 133{ |
134 uint32_t *p; | 134 __be32 *p; |
135 unsigned int minor_version; 136 __be32 status; 137 138 status = decode_string(xdr, &hdr->taglen, &hdr->tag); 139 if (unlikely(status != 0)) 140 return status; 141 /* We do not like overly long tags! */ 142 if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) { --- 13 unchanged lines hidden (view full) --- 156 } 157 hdr->callback_ident = ntohl(*p++); 158 hdr->nops = ntohl(*p); 159 return 0; 160} 161 162static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) 163{ | 135 unsigned int minor_version; 136 __be32 status; 137 138 status = decode_string(xdr, &hdr->taglen, &hdr->tag); 139 if (unlikely(status != 0)) 140 return status; 141 /* We do not like overly long tags! */ 142 if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) { --- 13 unchanged lines hidden (view full) --- 156 } 157 hdr->callback_ident = ntohl(*p++); 158 hdr->nops = ntohl(*p); 159 return 0; 160} 161 162static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) 163{ |
164 uint32_t *p; | 164 __be32 *p; |
165 p = read_buf(xdr, 4); 166 if (unlikely(p == NULL)) 167 return htonl(NFS4ERR_RESOURCE); 168 *op = ntohl(*p); 169 return 0; 170} 171 172static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args) --- 7 unchanged lines hidden (view full) --- 180 status = decode_bitmap(xdr, args->bitmap); 181out: 182 dprintk("%s: exit with status = %d\n", __FUNCTION__, status); 183 return status; 184} 185 186static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args) 187{ | 165 p = read_buf(xdr, 4); 166 if (unlikely(p == NULL)) 167 return htonl(NFS4ERR_RESOURCE); 168 *op = ntohl(*p); 169 return 0; 170} 171 172static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args) --- 7 unchanged lines hidden (view full) --- 180 status = decode_bitmap(xdr, args->bitmap); 181out: 182 dprintk("%s: exit with status = %d\n", __FUNCTION__, status); 183 return status; 184} 185 186static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args) 187{ |
188 uint32_t *p; | 188 __be32 *p; |
189 __be32 status; 190 191 args->addr = &rqstp->rq_addr; 192 status = decode_stateid(xdr, &args->stateid); 193 if (unlikely(status != 0)) 194 goto out; 195 p = read_buf(xdr, 4); 196 if (unlikely(p == NULL)) { --- 4 unchanged lines hidden (view full) --- 201 status = decode_fh(xdr, &args->fh); 202out: 203 dprintk("%s: exit with status = %d\n", __FUNCTION__, status); 204 return status; 205} 206 207static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) 208{ | 189 __be32 status; 190 191 args->addr = &rqstp->rq_addr; 192 status = decode_stateid(xdr, &args->stateid); 193 if (unlikely(status != 0)) 194 goto out; 195 p = read_buf(xdr, 4); 196 if (unlikely(p == NULL)) { --- 4 unchanged lines hidden (view full) --- 201 status = decode_fh(xdr, &args->fh); 202out: 203 dprintk("%s: exit with status = %d\n", __FUNCTION__, status); 204 return status; 205} 206 207static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) 208{ |
209 uint32_t *p; | 209 __be32 *p; |
210 211 p = xdr_reserve_space(xdr, 4 + len); 212 if (unlikely(p == NULL)) 213 return htonl(NFS4ERR_RESOURCE); 214 xdr_encode_opaque(p, str, len); 215 return 0; 216} 217 218#define CB_SUPPORTED_ATTR0 (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) 219#define CB_SUPPORTED_ATTR1 (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) | 210 211 p = xdr_reserve_space(xdr, 4 + len); 212 if (unlikely(p == NULL)) 213 return htonl(NFS4ERR_RESOURCE); 214 xdr_encode_opaque(p, str, len); 215 return 0; 216} 217 218#define CB_SUPPORTED_ATTR0 (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) 219#define CB_SUPPORTED_ATTR1 (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY) |
220static __be32 encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, uint32_t **savep) | 220static __be32 encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, __be32 **savep) |
221{ | 221{ |
222 uint32_t bm[2]; 223 uint32_t *p; | 222 __be32 bm[2]; 223 __be32 *p; |
224 225 bm[0] = htonl(bitmap[0] & CB_SUPPORTED_ATTR0); 226 bm[1] = htonl(bitmap[1] & CB_SUPPORTED_ATTR1); 227 if (bm[1] != 0) { 228 p = xdr_reserve_space(xdr, 16); 229 if (unlikely(p == NULL)) 230 return htonl(NFS4ERR_RESOURCE); 231 *p++ = htonl(2); --- 12 unchanged lines hidden (view full) --- 244 *p++ = htonl(0); 245 } 246 *savep = p; 247 return 0; 248} 249 250static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change) 251{ | 224 225 bm[0] = htonl(bitmap[0] & CB_SUPPORTED_ATTR0); 226 bm[1] = htonl(bitmap[1] & CB_SUPPORTED_ATTR1); 227 if (bm[1] != 0) { 228 p = xdr_reserve_space(xdr, 16); 229 if (unlikely(p == NULL)) 230 return htonl(NFS4ERR_RESOURCE); 231 *p++ = htonl(2); --- 12 unchanged lines hidden (view full) --- 244 *p++ = htonl(0); 245 } 246 *savep = p; 247 return 0; 248} 249 250static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change) 251{ |
252 uint32_t *p; | 252 __be32 *p; |
253 254 if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) 255 return 0; 256 p = xdr_reserve_space(xdr, 8); 257 if (unlikely(p == 0)) 258 return htonl(NFS4ERR_RESOURCE); 259 p = xdr_encode_hyper(p, change); 260 return 0; 261} 262 263static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size) 264{ | 253 254 if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) 255 return 0; 256 p = xdr_reserve_space(xdr, 8); 257 if (unlikely(p == 0)) 258 return htonl(NFS4ERR_RESOURCE); 259 p = xdr_encode_hyper(p, change); 260 return 0; 261} 262 263static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size) 264{ |
265 uint32_t *p; | 265 __be32 *p; |
266 267 if (!(bitmap[0] & FATTR4_WORD0_SIZE)) 268 return 0; 269 p = xdr_reserve_space(xdr, 8); 270 if (unlikely(p == 0)) 271 return htonl(NFS4ERR_RESOURCE); 272 p = xdr_encode_hyper(p, size); 273 return 0; 274} 275 276static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time) 277{ | 266 267 if (!(bitmap[0] & FATTR4_WORD0_SIZE)) 268 return 0; 269 p = xdr_reserve_space(xdr, 8); 270 if (unlikely(p == 0)) 271 return htonl(NFS4ERR_RESOURCE); 272 p = xdr_encode_hyper(p, size); 273 return 0; 274} 275 276static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time) 277{ |
278 uint32_t *p; | 278 __be32 *p; |
279 280 p = xdr_reserve_space(xdr, 12); 281 if (unlikely(p == 0)) 282 return htonl(NFS4ERR_RESOURCE); 283 p = xdr_encode_hyper(p, time->tv_sec); 284 *p = htonl(time->tv_nsec); 285 return 0; 286} --- 25 unchanged lines hidden (view full) --- 312 hdr->nops = xdr_reserve_space(xdr, 4); 313 if (unlikely(hdr->nops == NULL)) 314 return htonl(NFS4ERR_RESOURCE); 315 return 0; 316} 317 318static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res) 319{ | 279 280 p = xdr_reserve_space(xdr, 12); 281 if (unlikely(p == 0)) 282 return htonl(NFS4ERR_RESOURCE); 283 p = xdr_encode_hyper(p, time->tv_sec); 284 *p = htonl(time->tv_nsec); 285 return 0; 286} --- 25 unchanged lines hidden (view full) --- 312 hdr->nops = xdr_reserve_space(xdr, 4); 313 if (unlikely(hdr->nops == NULL)) 314 return htonl(NFS4ERR_RESOURCE); 315 return 0; 316} 317 318static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res) 319{ |
320 uint32_t *p; | 320 __be32 *p; |
321 322 p = xdr_reserve_space(xdr, 8); 323 if (unlikely(p == NULL)) 324 return htonl(NFS4ERR_RESOURCE); 325 *p++ = htonl(op); 326 *p = res; 327 return 0; 328} 329 330static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res) 331{ | 321 322 p = xdr_reserve_space(xdr, 8); 323 if (unlikely(p == NULL)) 324 return htonl(NFS4ERR_RESOURCE); 325 *p++ = htonl(op); 326 *p = res; 327 return 0; 328} 329 330static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res) 331{ |
332 uint32_t *savep = NULL; | 332 __be32 *savep = NULL; |
333 __be32 status = res->status; 334 335 if (unlikely(status != 0)) 336 goto out; 337 status = encode_attr_bitmap(xdr, res->bitmap, &savep); 338 if (unlikely(status != 0)) 339 goto out; 340 status = encode_attr_change(xdr, res->bitmap, res->change_attr); --- 58 unchanged lines hidden (view full) --- 399/* 400 * Decode, process and encode a COMPOUND 401 */ 402static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp) 403{ 404 struct cb_compound_hdr_arg hdr_arg; 405 struct cb_compound_hdr_res hdr_res; 406 struct xdr_stream xdr_in, xdr_out; | 333 __be32 status = res->status; 334 335 if (unlikely(status != 0)) 336 goto out; 337 status = encode_attr_bitmap(xdr, res->bitmap, &savep); 338 if (unlikely(status != 0)) 339 goto out; 340 status = encode_attr_change(xdr, res->bitmap, res->change_attr); --- 58 unchanged lines hidden (view full) --- 399/* 400 * Decode, process and encode a COMPOUND 401 */ 402static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp) 403{ 404 struct cb_compound_hdr_arg hdr_arg; 405 struct cb_compound_hdr_res hdr_res; 406 struct xdr_stream xdr_in, xdr_out; |
407 uint32_t *p; | 407 __be32 *p; |
408 __be32 status; 409 unsigned int nops = 1; 410 411 dprintk("%s: start\n", __FUNCTION__); 412 413 xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base); 414 | 408 __be32 status; 409 unsigned int nops = 1; 410 411 dprintk("%s: start\n", __FUNCTION__); 412 413 xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base); 414 |
415 p = (uint32_t*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); | 415 p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); |
416 xdr_init_encode(&xdr_out, &rqstp->rq_res, p); 417 418 decode_compound_hdr_arg(&xdr_in, &hdr_arg); 419 hdr_res.taglen = hdr_arg.taglen; 420 hdr_res.tag = hdr_arg.tag; 421 hdr_res.nops = NULL; 422 encode_compound_hdr_res(&xdr_out, &hdr_res); 423 --- 61 unchanged lines hidden --- | 416 xdr_init_encode(&xdr_out, &rqstp->rq_res, p); 417 418 decode_compound_hdr_arg(&xdr_in, &hdr_arg); 419 hdr_res.taglen = hdr_arg.taglen; 420 hdr_res.tag = hdr_arg.tag; 421 hdr_res.nops = NULL; 422 encode_compound_hdr_res(&xdr_out, &hdr_res); 423 --- 61 unchanged lines hidden --- |