1 /* 2 * linux/fs/nfs/nfs2xdr.c 3 * 4 * XDR functions to encode/decode NFS RPC arguments and results. 5 * 6 * Copyright (C) 1992, 1993, 1994 Rick Sladkey 7 * Copyright (C) 1996 Olaf Kirch 8 * 04 Aug 1998 Ion Badulescu <ionut@cs.columbia.edu> 9 * FIFO's need special handling in NFSv2 10 */ 11 12 #include <linux/param.h> 13 #include <linux/time.h> 14 #include <linux/mm.h> 15 #include <linux/errno.h> 16 #include <linux/string.h> 17 #include <linux/in.h> 18 #include <linux/pagemap.h> 19 #include <linux/proc_fs.h> 20 #include <linux/sunrpc/clnt.h> 21 #include <linux/nfs.h> 22 #include <linux/nfs2.h> 23 #include <linux/nfs_fs.h> 24 #include "internal.h" 25 26 #define NFSDBG_FACILITY NFSDBG_XDR 27 28 /* Mapping from NFS error code to "errno" error code. */ 29 #define errno_NFSERR_IO EIO 30 31 /* 32 * Declare the space requirements for NFS arguments and replies as 33 * number of 32bit-words 34 */ 35 #define NFS_fhandle_sz (8) 36 #define NFS_sattr_sz (8) 37 #define NFS_filename_sz (1+(NFS2_MAXNAMLEN>>2)) 38 #define NFS_path_sz (1+(NFS2_MAXPATHLEN>>2)) 39 #define NFS_fattr_sz (17) 40 #define NFS_info_sz (5) 41 #define NFS_entry_sz (NFS_filename_sz+3) 42 43 #define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz) 44 #define NFS_removeargs_sz (NFS_fhandle_sz+NFS_filename_sz) 45 #define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz) 46 #define NFS_readlinkargs_sz (NFS_fhandle_sz) 47 #define NFS_readargs_sz (NFS_fhandle_sz+3) 48 #define NFS_writeargs_sz (NFS_fhandle_sz+4) 49 #define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz) 50 #define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz) 51 #define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz) 52 #define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz) 53 #define NFS_readdirargs_sz (NFS_fhandle_sz+2) 54 55 #define NFS_attrstat_sz (1+NFS_fattr_sz) 56 #define NFS_diropres_sz (1+NFS_fhandle_sz+NFS_fattr_sz) 57 #define NFS_readlinkres_sz (2) 58 #define NFS_readres_sz (1+NFS_fattr_sz+1) 59 #define NFS_writeres_sz (NFS_attrstat_sz) 60 #define NFS_stat_sz (1) 61 #define NFS_readdirres_sz (1) 62 #define NFS_statfsres_sz (1+NFS_info_sz) 63 64 65 /* 66 * While encoding arguments, set up the reply buffer in advance to 67 * receive reply data directly into the page cache. 68 */ 69 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, 70 unsigned int base, unsigned int len, 71 unsigned int bufsize) 72 { 73 struct rpc_auth *auth = req->rq_cred->cr_auth; 74 unsigned int replen; 75 76 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize; 77 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); 78 } 79 80 81 /* 82 * Common NFS XDR functions as inlines 83 */ 84 static inline __be32 * 85 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle) 86 { 87 /* NFSv2 handles have a fixed length */ 88 fhandle->size = NFS2_FHSIZE; 89 memcpy(fhandle->data, p, NFS2_FHSIZE); 90 return p + XDR_QUADLEN(NFS2_FHSIZE); 91 } 92 93 static inline __be32* 94 xdr_encode_time(__be32 *p, const struct timespec *timep) 95 { 96 *p++ = htonl(timep->tv_sec); 97 /* Convert nanoseconds into microseconds */ 98 *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0); 99 return p; 100 } 101 102 static inline __be32* 103 xdr_encode_current_server_time(__be32 *p, const struct timespec *timep) 104 { 105 /* 106 * Passing the invalid value useconds=1000000 is a 107 * Sun convention for "set to current server time". 108 * It's needed to make permissions checks for the 109 * "touch" program across v2 mounts to Solaris and 110 * Irix boxes work correctly. See description of 111 * sattr in section 6.1 of "NFS Illustrated" by 112 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5 113 */ 114 *p++ = htonl(timep->tv_sec); 115 *p++ = htonl(1000000); 116 return p; 117 } 118 119 static inline __be32* 120 xdr_decode_time(__be32 *p, struct timespec *timep) 121 { 122 timep->tv_sec = ntohl(*p++); 123 /* Convert microseconds into nanoseconds */ 124 timep->tv_nsec = ntohl(*p++) * 1000; 125 return p; 126 } 127 128 static __be32 * 129 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) 130 { 131 u32 rdev, type; 132 type = ntohl(*p++); 133 fattr->mode = ntohl(*p++); 134 fattr->nlink = ntohl(*p++); 135 fattr->uid = ntohl(*p++); 136 fattr->gid = ntohl(*p++); 137 fattr->size = ntohl(*p++); 138 fattr->du.nfs2.blocksize = ntohl(*p++); 139 rdev = ntohl(*p++); 140 fattr->du.nfs2.blocks = ntohl(*p++); 141 fattr->fsid.major = ntohl(*p++); 142 fattr->fsid.minor = 0; 143 fattr->fileid = ntohl(*p++); 144 p = xdr_decode_time(p, &fattr->atime); 145 p = xdr_decode_time(p, &fattr->mtime); 146 p = xdr_decode_time(p, &fattr->ctime); 147 fattr->valid |= NFS_ATTR_FATTR_V2; 148 fattr->rdev = new_decode_dev(rdev); 149 if (type == NFCHR && rdev == NFS2_FIFO_DEV) { 150 fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO; 151 fattr->rdev = 0; 152 } 153 return p; 154 } 155 156 /* 157 * Encode/decode NFSv2 basic data types 158 * 159 * Basic NFSv2 data types are defined in section 2.3 of RFC 1094: 160 * "NFS: Network File System Protocol Specification". 161 * 162 * Not all basic data types have their own encoding and decoding 163 * functions. For run-time efficiency, some data types are encoded 164 * or decoded inline. 165 */ 166 167 /* 168 * 2.3.3. fhandle 169 * 170 * typedef opaque fhandle[FHSIZE]; 171 */ 172 static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh) 173 { 174 __be32 *p; 175 176 BUG_ON(fh->size != NFS2_FHSIZE); 177 p = xdr_reserve_space(xdr, NFS2_FHSIZE); 178 memcpy(p, fh->data, NFS2_FHSIZE); 179 } 180 181 /* 182 * 2.3.6. sattr 183 * 184 * struct sattr { 185 * unsigned int mode; 186 * unsigned int uid; 187 * unsigned int gid; 188 * unsigned int size; 189 * timeval atime; 190 * timeval mtime; 191 * }; 192 */ 193 194 #define NFS2_SATTR_NOT_SET (0xffffffff) 195 196 static __be32 *xdr_time_not_set(__be32 *p) 197 { 198 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); 199 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); 200 return p; 201 } 202 203 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr) 204 { 205 __be32 *p; 206 207 p = xdr_reserve_space(xdr, NFS_sattr_sz << 2); 208 209 if (attr->ia_valid & ATTR_MODE) 210 *p++ = cpu_to_be32(attr->ia_mode); 211 else 212 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); 213 if (attr->ia_valid & ATTR_UID) 214 *p++ = cpu_to_be32(attr->ia_uid); 215 else 216 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); 217 if (attr->ia_valid & ATTR_GID) 218 *p++ = cpu_to_be32(attr->ia_gid); 219 else 220 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); 221 if (attr->ia_valid & ATTR_SIZE) 222 *p++ = cpu_to_be32((u32)attr->ia_size); 223 else 224 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); 225 226 if (attr->ia_valid & ATTR_ATIME_SET) 227 p = xdr_encode_time(p, &attr->ia_atime); 228 else if (attr->ia_valid & ATTR_ATIME) 229 p = xdr_encode_current_server_time(p, &attr->ia_atime); 230 else 231 p = xdr_time_not_set(p); 232 if (attr->ia_valid & ATTR_MTIME_SET) 233 xdr_encode_time(p, &attr->ia_mtime); 234 else if (attr->ia_valid & ATTR_MTIME) 235 xdr_encode_current_server_time(p, &attr->ia_mtime); 236 else 237 xdr_time_not_set(p); 238 } 239 240 /* 241 * 2.3.7. filename 242 * 243 * typedef string filename<MAXNAMLEN>; 244 */ 245 static void encode_filename(struct xdr_stream *xdr, 246 const char *name, u32 length) 247 { 248 __be32 *p; 249 250 BUG_ON(length > NFS2_MAXNAMLEN); 251 p = xdr_reserve_space(xdr, 4 + length); 252 xdr_encode_opaque(p, name, length); 253 } 254 255 /* 256 * 2.3.8. path 257 * 258 * typedef string path<MAXPATHLEN>; 259 */ 260 static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length) 261 { 262 __be32 *p; 263 264 BUG_ON(length > NFS2_MAXPATHLEN); 265 p = xdr_reserve_space(xdr, 4); 266 *p = cpu_to_be32(length); 267 xdr_write_pages(xdr, pages, 0, length); 268 } 269 270 /* 271 * 2.3.10. diropargs 272 * 273 * struct diropargs { 274 * fhandle dir; 275 * filename name; 276 * }; 277 */ 278 static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh, 279 const char *name, u32 length) 280 { 281 encode_fhandle(xdr, fh); 282 encode_filename(xdr, name, length); 283 } 284 285 286 /* 287 * NFSv2 XDR encode functions 288 * 289 * NFSv2 argument types are defined in section 2.2 of RFC 1094: 290 * "NFS: Network File System Protocol Specification". 291 */ 292 293 static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p, 294 const struct nfs_fh *fh) 295 { 296 struct xdr_stream xdr; 297 298 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 299 encode_fhandle(&xdr, fh); 300 return 0; 301 } 302 303 /* 304 * 2.2.3. sattrargs 305 * 306 * struct sattrargs { 307 * fhandle file; 308 * sattr attributes; 309 * }; 310 */ 311 static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p, 312 const struct nfs_sattrargs *args) 313 { 314 struct xdr_stream xdr; 315 316 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 317 encode_fhandle(&xdr, args->fh); 318 encode_sattr(&xdr, args->sattr); 319 return 0; 320 } 321 322 static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p, 323 const struct nfs_diropargs *args) 324 { 325 struct xdr_stream xdr; 326 327 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 328 encode_diropargs(&xdr, args->fh, args->name, args->len); 329 return 0; 330 } 331 332 static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p, 333 const struct nfs_readlinkargs *args) 334 { 335 struct xdr_stream xdr; 336 337 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 338 encode_fhandle(&xdr, args->fh); 339 prepare_reply_buffer(req, args->pages, args->pgbase, 340 args->pglen, NFS_readlinkres_sz); 341 return 0; 342 } 343 344 /* 345 * 2.2.7. readargs 346 * 347 * struct readargs { 348 * fhandle file; 349 * unsigned offset; 350 * unsigned count; 351 * unsigned totalcount; 352 * }; 353 */ 354 static void encode_readargs(struct xdr_stream *xdr, 355 const struct nfs_readargs *args) 356 { 357 u32 offset = args->offset; 358 u32 count = args->count; 359 __be32 *p; 360 361 encode_fhandle(xdr, args->fh); 362 363 p = xdr_reserve_space(xdr, 4 + 4 + 4); 364 *p++ = cpu_to_be32(offset); 365 *p++ = cpu_to_be32(count); 366 *p = cpu_to_be32(count); 367 } 368 369 static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p, 370 const struct nfs_readargs *args) 371 { 372 struct xdr_stream xdr; 373 374 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 375 encode_readargs(&xdr, args); 376 prepare_reply_buffer(req, args->pages, args->pgbase, 377 args->count, NFS_readres_sz); 378 req->rq_rcv_buf.flags |= XDRBUF_READ; 379 return 0; 380 } 381 382 /* 383 * Decode READ reply 384 */ 385 static int 386 nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) 387 { 388 struct kvec *iov = req->rq_rcv_buf.head; 389 size_t hdrlen; 390 u32 count, recvd; 391 int status; 392 393 if ((status = ntohl(*p++))) 394 return nfs_stat_to_errno(status); 395 p = xdr_decode_fattr(p, res->fattr); 396 397 count = ntohl(*p++); 398 res->eof = 0; 399 hdrlen = (u8 *) p - (u8 *) iov->iov_base; 400 if (iov->iov_len < hdrlen) { 401 dprintk("NFS: READ reply header overflowed:" 402 "length %Zu > %Zu\n", hdrlen, iov->iov_len); 403 return -errno_NFSERR_IO; 404 } else if (iov->iov_len != hdrlen) { 405 dprintk("NFS: READ header is short. iovec will be shifted.\n"); 406 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen); 407 } 408 409 recvd = req->rq_rcv_buf.len - hdrlen; 410 if (count > recvd) { 411 dprintk("NFS: server cheating in read reply: " 412 "count %u > recvd %u\n", count, recvd); 413 count = recvd; 414 } 415 416 dprintk("RPC: readres OK count %u\n", count); 417 if (count < res->count) 418 res->count = count; 419 420 return count; 421 } 422 423 424 /* 425 * 2.2.9. writeargs 426 * 427 * struct writeargs { 428 * fhandle file; 429 * unsigned beginoffset; 430 * unsigned offset; 431 * unsigned totalcount; 432 * nfsdata data; 433 * }; 434 */ 435 static void encode_writeargs(struct xdr_stream *xdr, 436 const struct nfs_writeargs *args) 437 { 438 u32 offset = args->offset; 439 u32 count = args->count; 440 __be32 *p; 441 442 encode_fhandle(xdr, args->fh); 443 444 p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4); 445 *p++ = cpu_to_be32(offset); 446 *p++ = cpu_to_be32(offset); 447 *p++ = cpu_to_be32(count); 448 449 /* nfsdata */ 450 *p = cpu_to_be32(count); 451 xdr_write_pages(xdr, args->pages, args->pgbase, count); 452 } 453 454 static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p, 455 const struct nfs_writeargs *args) 456 { 457 struct xdr_stream xdr; 458 459 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 460 encode_writeargs(&xdr, args); 461 xdr.buf->flags |= XDRBUF_WRITE; 462 return 0; 463 } 464 465 /* 466 * 2.2.10. createargs 467 * 468 * struct createargs { 469 * diropargs where; 470 * sattr attributes; 471 * }; 472 */ 473 static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p, 474 const struct nfs_createargs *args) 475 { 476 struct xdr_stream xdr; 477 478 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 479 encode_diropargs(&xdr, args->fh, args->name, args->len); 480 encode_sattr(&xdr, args->sattr); 481 return 0; 482 } 483 484 static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p, 485 const struct nfs_removeargs *args) 486 { 487 struct xdr_stream xdr; 488 489 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 490 encode_diropargs(&xdr, args->fh, args->name.name, args->name.len); 491 return 0; 492 } 493 494 /* 495 * 2.2.12. renameargs 496 * 497 * struct renameargs { 498 * diropargs from; 499 * diropargs to; 500 * }; 501 */ 502 static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p, 503 const struct nfs_renameargs *args) 504 { 505 const struct qstr *old = args->old_name; 506 const struct qstr *new = args->new_name; 507 struct xdr_stream xdr; 508 509 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 510 encode_diropargs(&xdr, args->old_dir, old->name, old->len); 511 encode_diropargs(&xdr, args->new_dir, new->name, new->len); 512 return 0; 513 } 514 515 /* 516 * 2.2.13. linkargs 517 * 518 * struct linkargs { 519 * fhandle from; 520 * diropargs to; 521 * }; 522 */ 523 static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p, 524 const struct nfs_linkargs *args) 525 { 526 struct xdr_stream xdr; 527 528 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 529 encode_fhandle(&xdr, args->fromfh); 530 encode_diropargs(&xdr, args->tofh, args->toname, args->tolen); 531 return 0; 532 } 533 534 /* 535 * 2.2.14. symlinkargs 536 * 537 * struct symlinkargs { 538 * diropargs from; 539 * path to; 540 * sattr attributes; 541 * }; 542 */ 543 static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p, 544 const struct nfs_symlinkargs *args) 545 { 546 struct xdr_stream xdr; 547 548 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 549 encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen); 550 encode_path(&xdr, args->pages, args->pathlen); 551 encode_sattr(&xdr, args->sattr); 552 return 0; 553 } 554 555 /* 556 * 2.2.17. readdirargs 557 * 558 * struct readdirargs { 559 * fhandle dir; 560 * nfscookie cookie; 561 * unsigned count; 562 * }; 563 */ 564 static void encode_readdirargs(struct xdr_stream *xdr, 565 const struct nfs_readdirargs *args) 566 { 567 __be32 *p; 568 569 encode_fhandle(xdr, args->fh); 570 571 p = xdr_reserve_space(xdr, 4 + 4); 572 *p++ = cpu_to_be32(args->cookie); 573 *p = cpu_to_be32(args->count); 574 } 575 576 static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p, 577 const struct nfs_readdirargs *args) 578 { 579 struct xdr_stream xdr; 580 581 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 582 encode_readdirargs(&xdr, args); 583 prepare_reply_buffer(req, args->pages, 0, 584 args->count, NFS_readdirres_sz); 585 return 0; 586 } 587 588 /* 589 * Decode the result of a readdir call. 590 * We're not really decoding anymore, we just leave the buffer untouched 591 * and only check that it is syntactically correct. 592 * The real decoding happens in nfs_decode_entry below, called directly 593 * from nfs_readdir for each entry. 594 */ 595 static int 596 nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) 597 { 598 struct xdr_buf *rcvbuf = &req->rq_rcv_buf; 599 struct kvec *iov = rcvbuf->head; 600 struct page **page; 601 size_t hdrlen; 602 unsigned int pglen, recvd; 603 int status; 604 605 if ((status = ntohl(*p++))) 606 return nfs_stat_to_errno(status); 607 608 hdrlen = (u8 *) p - (u8 *) iov->iov_base; 609 if (iov->iov_len < hdrlen) { 610 dprintk("NFS: READDIR reply header overflowed:" 611 "length %Zu > %Zu\n", hdrlen, iov->iov_len); 612 return -errno_NFSERR_IO; 613 } else if (iov->iov_len != hdrlen) { 614 dprintk("NFS: READDIR header is short. iovec will be shifted.\n"); 615 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen); 616 } 617 618 pglen = rcvbuf->page_len; 619 recvd = rcvbuf->len - hdrlen; 620 if (pglen > recvd) 621 pglen = recvd; 622 page = rcvbuf->pages; 623 return pglen; 624 } 625 626 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) 627 { 628 dprintk("nfs: %s: prematurely hit end of receive buffer. " 629 "Remaining buffer length is %tu words.\n", 630 func, xdr->end - xdr->p); 631 } 632 633 __be32 * 634 nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus) 635 { 636 __be32 *p; 637 p = xdr_inline_decode(xdr, 4); 638 if (unlikely(!p)) 639 goto out_overflow; 640 if (!ntohl(*p++)) { 641 p = xdr_inline_decode(xdr, 4); 642 if (unlikely(!p)) 643 goto out_overflow; 644 if (!ntohl(*p++)) 645 return ERR_PTR(-EAGAIN); 646 entry->eof = 1; 647 return ERR_PTR(-EBADCOOKIE); 648 } 649 650 p = xdr_inline_decode(xdr, 8); 651 if (unlikely(!p)) 652 goto out_overflow; 653 654 entry->ino = ntohl(*p++); 655 entry->len = ntohl(*p++); 656 657 p = xdr_inline_decode(xdr, entry->len + 4); 658 if (unlikely(!p)) 659 goto out_overflow; 660 entry->name = (const char *) p; 661 p += XDR_QUADLEN(entry->len); 662 entry->prev_cookie = entry->cookie; 663 entry->cookie = ntohl(*p++); 664 665 entry->d_type = DT_UNKNOWN; 666 667 p = xdr_inline_peek(xdr, 8); 668 if (p != NULL) 669 entry->eof = !p[0] && p[1]; 670 else 671 entry->eof = 0; 672 673 return p; 674 675 out_overflow: 676 print_overflow_msg(__func__, xdr); 677 return ERR_PTR(-EAGAIN); 678 } 679 680 /* 681 * NFS XDR decode functions 682 */ 683 /* 684 * Decode simple status reply 685 */ 686 static int 687 nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy) 688 { 689 int status; 690 691 if ((status = ntohl(*p++)) != 0) 692 status = nfs_stat_to_errno(status); 693 return status; 694 } 695 696 /* 697 * Decode attrstat reply 698 * GETATTR, SETATTR, WRITE 699 */ 700 static int 701 nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) 702 { 703 int status; 704 705 if ((status = ntohl(*p++))) 706 return nfs_stat_to_errno(status); 707 xdr_decode_fattr(p, fattr); 708 return 0; 709 } 710 711 /* 712 * Decode diropres reply 713 * LOOKUP, CREATE, MKDIR 714 */ 715 static int 716 nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res) 717 { 718 int status; 719 720 if ((status = ntohl(*p++))) 721 return nfs_stat_to_errno(status); 722 p = xdr_decode_fhandle(p, res->fh); 723 xdr_decode_fattr(p, res->fattr); 724 return 0; 725 } 726 727 /* 728 * Decode READLINK reply 729 */ 730 static int 731 nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) 732 { 733 struct xdr_buf *rcvbuf = &req->rq_rcv_buf; 734 struct kvec *iov = rcvbuf->head; 735 size_t hdrlen; 736 u32 len, recvd; 737 int status; 738 739 if ((status = ntohl(*p++))) 740 return nfs_stat_to_errno(status); 741 /* Convert length of symlink */ 742 len = ntohl(*p++); 743 if (len >= rcvbuf->page_len) { 744 dprintk("nfs: server returned giant symlink!\n"); 745 return -ENAMETOOLONG; 746 } 747 hdrlen = (u8 *) p - (u8 *) iov->iov_base; 748 if (iov->iov_len < hdrlen) { 749 dprintk("NFS: READLINK reply header overflowed:" 750 "length %Zu > %Zu\n", hdrlen, iov->iov_len); 751 return -errno_NFSERR_IO; 752 } else if (iov->iov_len != hdrlen) { 753 dprintk("NFS: READLINK header is short. iovec will be shifted.\n"); 754 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen); 755 } 756 recvd = req->rq_rcv_buf.len - hdrlen; 757 if (recvd < len) { 758 dprintk("NFS: server cheating in readlink reply: " 759 "count %u > recvd %u\n", len, recvd); 760 return -EIO; 761 } 762 763 xdr_terminate_string(rcvbuf, len); 764 return 0; 765 } 766 767 /* 768 * Decode WRITE reply 769 */ 770 static int 771 nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) 772 { 773 res->verf->committed = NFS_FILE_SYNC; 774 return nfs_xdr_attrstat(req, p, res->fattr); 775 } 776 777 /* 778 * Decode STATFS reply 779 */ 780 static int 781 nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res) 782 { 783 int status; 784 785 if ((status = ntohl(*p++))) 786 return nfs_stat_to_errno(status); 787 788 res->tsize = ntohl(*p++); 789 res->bsize = ntohl(*p++); 790 res->blocks = ntohl(*p++); 791 res->bfree = ntohl(*p++); 792 res->bavail = ntohl(*p++); 793 return 0; 794 } 795 796 /* 797 * We need to translate between nfs status return values and 798 * the local errno values which may not be the same. 799 */ 800 static struct { 801 int stat; 802 int errno; 803 } nfs_errtbl[] = { 804 { NFS_OK, 0 }, 805 { NFSERR_PERM, -EPERM }, 806 { NFSERR_NOENT, -ENOENT }, 807 { NFSERR_IO, -errno_NFSERR_IO}, 808 { NFSERR_NXIO, -ENXIO }, 809 /* { NFSERR_EAGAIN, -EAGAIN }, */ 810 { NFSERR_ACCES, -EACCES }, 811 { NFSERR_EXIST, -EEXIST }, 812 { NFSERR_XDEV, -EXDEV }, 813 { NFSERR_NODEV, -ENODEV }, 814 { NFSERR_NOTDIR, -ENOTDIR }, 815 { NFSERR_ISDIR, -EISDIR }, 816 { NFSERR_INVAL, -EINVAL }, 817 { NFSERR_FBIG, -EFBIG }, 818 { NFSERR_NOSPC, -ENOSPC }, 819 { NFSERR_ROFS, -EROFS }, 820 { NFSERR_MLINK, -EMLINK }, 821 { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, 822 { NFSERR_NOTEMPTY, -ENOTEMPTY }, 823 { NFSERR_DQUOT, -EDQUOT }, 824 { NFSERR_STALE, -ESTALE }, 825 { NFSERR_REMOTE, -EREMOTE }, 826 #ifdef EWFLUSH 827 { NFSERR_WFLUSH, -EWFLUSH }, 828 #endif 829 { NFSERR_BADHANDLE, -EBADHANDLE }, 830 { NFSERR_NOT_SYNC, -ENOTSYNC }, 831 { NFSERR_BAD_COOKIE, -EBADCOOKIE }, 832 { NFSERR_NOTSUPP, -ENOTSUPP }, 833 { NFSERR_TOOSMALL, -ETOOSMALL }, 834 { NFSERR_SERVERFAULT, -EREMOTEIO }, 835 { NFSERR_BADTYPE, -EBADTYPE }, 836 { NFSERR_JUKEBOX, -EJUKEBOX }, 837 { -1, -EIO } 838 }; 839 840 /* 841 * Convert an NFS error code to a local one. 842 * This one is used jointly by NFSv2 and NFSv3. 843 */ 844 int 845 nfs_stat_to_errno(int stat) 846 { 847 int i; 848 849 for (i = 0; nfs_errtbl[i].stat != -1; i++) { 850 if (nfs_errtbl[i].stat == stat) 851 return nfs_errtbl[i].errno; 852 } 853 dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat); 854 return nfs_errtbl[i].errno; 855 } 856 857 #define PROC(proc, argtype, restype, timer) \ 858 [NFSPROC_##proc] = { \ 859 .p_proc = NFSPROC_##proc, \ 860 .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \ 861 .p_decode = (kxdrproc_t) nfs_xdr_##restype, \ 862 .p_arglen = NFS_##argtype##_sz, \ 863 .p_replen = NFS_##restype##_sz, \ 864 .p_timer = timer, \ 865 .p_statidx = NFSPROC_##proc, \ 866 .p_name = #proc, \ 867 } 868 struct rpc_procinfo nfs_procedures[] = { 869 PROC(GETATTR, fhandle, attrstat, 1), 870 PROC(SETATTR, sattrargs, attrstat, 0), 871 PROC(LOOKUP, diropargs, diropres, 2), 872 PROC(READLINK, readlinkargs, readlinkres, 3), 873 PROC(READ, readargs, readres, 3), 874 PROC(WRITE, writeargs, writeres, 4), 875 PROC(CREATE, createargs, diropres, 0), 876 PROC(REMOVE, removeargs, stat, 0), 877 PROC(RENAME, renameargs, stat, 0), 878 PROC(LINK, linkargs, stat, 0), 879 PROC(SYMLINK, symlinkargs, stat, 0), 880 PROC(MKDIR, createargs, diropres, 0), 881 PROC(RMDIR, diropargs, stat, 0), 882 PROC(READDIR, readdirargs, readdirres, 3), 883 PROC(STATFS, fhandle, statfsres, 0), 884 }; 885 886 struct rpc_version nfs_version2 = { 887 .number = 2, 888 .nrprocs = ARRAY_SIZE(nfs_procedures), 889 .procs = nfs_procedures 890 }; 891