aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c289
1 files changed, 248 insertions, 41 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 7c5d70efe720..3dd413f52da1 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -58,7 +58,7 @@
58/* Mapping from NFS error code to "errno" error code. */ 58/* Mapping from NFS error code to "errno" error code. */
59#define errno_NFSERR_IO EIO 59#define errno_NFSERR_IO EIO
60 60
61static int nfs_stat_to_errno(int); 61static int nfs4_stat_to_errno(int);
62 62
63/* NFSv4 COMPOUND tags are only wanted for debugging purposes */ 63/* NFSv4 COMPOUND tags are only wanted for debugging purposes */
64#ifdef DEBUG 64#ifdef DEBUG
@@ -128,7 +128,7 @@ static int nfs_stat_to_errno(int);
128#define decode_link_maxsz (op_decode_hdr_maxsz + 5) 128#define decode_link_maxsz (op_decode_hdr_maxsz + 5)
129#define encode_symlink_maxsz (op_encode_hdr_maxsz + \ 129#define encode_symlink_maxsz (op_encode_hdr_maxsz + \
130 1 + nfs4_name_maxsz + \ 130 1 + nfs4_name_maxsz + \
131 nfs4_path_maxsz + \ 131 1 + \
132 nfs4_fattr_maxsz) 132 nfs4_fattr_maxsz)
133#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) 133#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8)
134#define encode_create_maxsz (op_encode_hdr_maxsz + \ 134#define encode_create_maxsz (op_encode_hdr_maxsz + \
@@ -411,6 +411,15 @@ static int nfs_stat_to_errno(int);
411#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ 411#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \
412 decode_putfh_maxsz + \ 412 decode_putfh_maxsz + \
413 op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) 413 op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
414#define NFS4_enc_fs_locations_sz \
415 (compound_encode_hdr_maxsz + \
416 encode_putfh_maxsz + \
417 encode_getattr_maxsz)
418#define NFS4_dec_fs_locations_sz \
419 (compound_decode_hdr_maxsz + \
420 decode_putfh_maxsz + \
421 op_decode_hdr_maxsz + \
422 nfs4_fattr_bitmap_maxsz)
414 423
415static struct { 424static struct {
416 unsigned int mode; 425 unsigned int mode;
@@ -520,7 +529,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
520 if (iap->ia_valid & ATTR_MODE) 529 if (iap->ia_valid & ATTR_MODE)
521 len += 4; 530 len += 4;
522 if (iap->ia_valid & ATTR_UID) { 531 if (iap->ia_valid & ATTR_UID) {
523 owner_namelen = nfs_map_uid_to_name(server->nfs4_state, iap->ia_uid, owner_name); 532 owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name);
524 if (owner_namelen < 0) { 533 if (owner_namelen < 0) {
525 printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n", 534 printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n",
526 iap->ia_uid); 535 iap->ia_uid);
@@ -532,7 +541,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
532 len += 4 + (XDR_QUADLEN(owner_namelen) << 2); 541 len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
533 } 542 }
534 if (iap->ia_valid & ATTR_GID) { 543 if (iap->ia_valid & ATTR_GID) {
535 owner_grouplen = nfs_map_gid_to_group(server->nfs4_state, iap->ia_gid, owner_group); 544 owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group);
536 if (owner_grouplen < 0) { 545 if (owner_grouplen < 0) {
537 printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n", 546 printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n",
538 iap->ia_gid); 547 iap->ia_gid);
@@ -664,9 +673,9 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *c
664 673
665 switch (create->ftype) { 674 switch (create->ftype) {
666 case NF4LNK: 675 case NF4LNK:
667 RESERVE_SPACE(4 + create->u.symlink->len); 676 RESERVE_SPACE(4);
668 WRITE32(create->u.symlink->len); 677 WRITE32(create->u.symlink.len);
669 WRITEMEM(create->u.symlink->name, create->u.symlink->len); 678 xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len);
670 break; 679 break;
671 680
672 case NF4BLK: case NF4CHR: 681 case NF4BLK: case NF4CHR:
@@ -722,6 +731,13 @@ static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask)
722 bitmask[1] & nfs4_fsinfo_bitmap[1]); 731 bitmask[1] & nfs4_fsinfo_bitmap[1]);
723} 732}
724 733
734static int encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask)
735{
736 return encode_getattr_two(xdr,
737 bitmask[0] & nfs4_fs_locations_bitmap[0],
738 bitmask[1] & nfs4_fs_locations_bitmap[1]);
739}
740
725static int encode_getfh(struct xdr_stream *xdr) 741static int encode_getfh(struct xdr_stream *xdr)
726{ 742{
727 uint32_t *p; 743 uint32_t *p;
@@ -1144,7 +1160,7 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, con
1144 return 0; 1160 return 0;
1145} 1161}
1146 1162
1147static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client_stateid) 1163static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid)
1148{ 1164{
1149 uint32_t *p; 1165 uint32_t *p;
1150 1166
@@ -1230,7 +1246,7 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien
1230 return 0; 1246 return 0;
1231} 1247}
1232 1248
1233static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_client *client_state) 1249static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state)
1234{ 1250{
1235 uint32_t *p; 1251 uint32_t *p;
1236 1252
@@ -1929,7 +1945,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const str
1929/* 1945/*
1930 * a RENEW request 1946 * a RENEW request
1931 */ 1947 */
1932static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) 1948static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp)
1933{ 1949{
1934 struct xdr_stream xdr; 1950 struct xdr_stream xdr;
1935 struct compound_hdr hdr = { 1951 struct compound_hdr hdr = {
@@ -1959,7 +1975,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nf
1959/* 1975/*
1960 * a SETCLIENTID_CONFIRM request 1976 * a SETCLIENTID_CONFIRM request
1961 */ 1977 */
1962static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) 1978static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp)
1963{ 1979{
1964 struct xdr_stream xdr; 1980 struct xdr_stream xdr;
1965 struct compound_hdr hdr = { 1981 struct compound_hdr hdr = {
@@ -2003,6 +2019,38 @@ out:
2003} 2019}
2004 2020
2005/* 2021/*
2022 * Encode FS_LOCATIONS request
2023 */
2024static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations_arg *args)
2025{
2026 struct xdr_stream xdr;
2027 struct compound_hdr hdr = {
2028 .nops = 3,
2029 };
2030 struct rpc_auth *auth = req->rq_task->tk_auth;
2031 int replen;
2032 int status;
2033
2034 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2035 encode_compound_hdr(&xdr, &hdr);
2036 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
2037 goto out;
2038 if ((status = encode_lookup(&xdr, args->name)) != 0)
2039 goto out;
2040 if ((status = encode_fs_locations(&xdr, args->bitmask)) != 0)
2041 goto out;
2042 /* set up reply
2043 * toplevel_status + OP_PUTFH + status
2044 * + OP_LOOKUP + status + OP_GETATTR + status = 7
2045 */
2046 replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
2047 xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
2048 0, PAGE_SIZE);
2049out:
2050 return status;
2051}
2052
2053/*
2006 * START OF "GENERIC" DECODE ROUTINES. 2054 * START OF "GENERIC" DECODE ROUTINES.
2007 * These may look a little ugly since they are imported from a "generic" 2055 * These may look a little ugly since they are imported from a "generic"
2008 * set of XDR encode/decode routines which are intended to be shared by 2056 * set of XDR encode/decode routines which are intended to be shared by
@@ -2036,7 +2084,7 @@ out:
2036 } \ 2084 } \
2037} while (0) 2085} while (0)
2038 2086
2039static int decode_opaque_inline(struct xdr_stream *xdr, uint32_t *len, char **string) 2087static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string)
2040{ 2088{
2041 uint32_t *p; 2089 uint32_t *p;
2042 2090
@@ -2079,15 +2127,15 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
2079 } 2127 }
2080 READ32(nfserr); 2128 READ32(nfserr);
2081 if (nfserr != NFS_OK) 2129 if (nfserr != NFS_OK)
2082 return -nfs_stat_to_errno(nfserr); 2130 return -nfs4_stat_to_errno(nfserr);
2083 return 0; 2131 return 0;
2084} 2132}
2085 2133
2086/* Dummy routine */ 2134/* Dummy routine */
2087static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs4_client *clp) 2135static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp)
2088{ 2136{
2089 uint32_t *p; 2137 uint32_t *p;
2090 uint32_t strlen; 2138 unsigned int strlen;
2091 char *str; 2139 char *str;
2092 2140
2093 READ_BUF(12); 2141 READ_BUF(12);
@@ -2217,7 +2265,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap,
2217 return 0; 2265 return 0;
2218} 2266}
2219 2267
2220static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fsid *fsid) 2268static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
2221{ 2269{
2222 uint32_t *p; 2270 uint32_t *p;
2223 2271
@@ -2285,6 +2333,22 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t
2285 return 0; 2333 return 0;
2286} 2334}
2287 2335
2336static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
2337{
2338 uint32_t *p;
2339
2340 *fileid = 0;
2341 if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U)))
2342 return -EIO;
2343 if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) {
2344 READ_BUF(8);
2345 READ64(*fileid);
2346 bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
2347 }
2348 dprintk("%s: fileid=%Lu\n", __FUNCTION__, (unsigned long long)*fileid);
2349 return 0;
2350}
2351
2288static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 2352static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2289{ 2353{
2290 uint32_t *p; 2354 uint32_t *p;
@@ -2336,6 +2400,116 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin
2336 return status; 2400 return status;
2337} 2401}
2338 2402
2403static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
2404{
2405 int n;
2406 uint32_t *p;
2407 int status = 0;
2408
2409 READ_BUF(4);
2410 READ32(n);
2411 if (n < 0)
2412 goto out_eio;
2413 if (n == 0)
2414 goto root_path;
2415 dprintk("path ");
2416 path->ncomponents = 0;
2417 while (path->ncomponents < n) {
2418 struct nfs4_string *component = &path->components[path->ncomponents];
2419 status = decode_opaque_inline(xdr, &component->len, &component->data);
2420 if (unlikely(status != 0))
2421 goto out_eio;
2422 if (path->ncomponents != n)
2423 dprintk("/");
2424 dprintk("%s", component->data);
2425 if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS)
2426 path->ncomponents++;
2427 else {
2428 dprintk("cannot parse %d components in path\n", n);
2429 goto out_eio;
2430 }
2431 }
2432out:
2433 dprintk("\n");
2434 return status;
2435root_path:
2436/* a root pathname is sent as a zero component4 */
2437 path->ncomponents = 1;
2438 path->components[0].len=0;
2439 path->components[0].data=NULL;
2440 dprintk("path /\n");
2441 goto out;
2442out_eio:
2443 dprintk(" status %d", status);
2444 status = -EIO;
2445 goto out;
2446}
2447
2448static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res)
2449{
2450 int n;
2451 uint32_t *p;
2452 int status = -EIO;
2453
2454 if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U)))
2455 goto out;
2456 status = 0;
2457 if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
2458 goto out;
2459 dprintk("%s: fsroot ", __FUNCTION__);
2460 status = decode_pathname(xdr, &res->fs_path);
2461 if (unlikely(status != 0))
2462 goto out;
2463 READ_BUF(4);
2464 READ32(n);
2465 if (n <= 0)
2466 goto out_eio;
2467 res->nlocations = 0;
2468 while (res->nlocations < n) {
2469 int m;
2470 struct nfs4_fs_location *loc = &res->locations[res->nlocations];
2471
2472 READ_BUF(4);
2473 READ32(m);
2474 if (m <= 0)
2475 goto out_eio;
2476
2477 loc->nservers = 0;
2478 dprintk("%s: servers ", __FUNCTION__);
2479 while (loc->nservers < m) {
2480 struct nfs4_string *server = &loc->servers[loc->nservers];
2481 status = decode_opaque_inline(xdr, &server->len, &server->data);
2482 if (unlikely(status != 0))
2483 goto out_eio;
2484 dprintk("%s ", server->data);
2485 if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS)
2486 loc->nservers++;
2487 else {
2488 int i;
2489 dprintk("%s: using first %d of %d servers returned for location %d\n", __FUNCTION__, NFS4_FS_LOCATION_MAXSERVERS, m, res->nlocations);
2490 for (i = loc->nservers; i < m; i++) {
2491 int len;
2492 char *data;
2493 status = decode_opaque_inline(xdr, &len, &data);
2494 if (unlikely(status != 0))
2495 goto out_eio;
2496 }
2497 }
2498 }
2499 status = decode_pathname(xdr, &loc->rootpath);
2500 if (unlikely(status != 0))
2501 goto out_eio;
2502 if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES)
2503 res->nlocations++;
2504 }
2505out:
2506 dprintk("%s: fs_locations done, error = %d\n", __FUNCTION__, status);
2507 return status;
2508out_eio:
2509 status = -EIO;
2510 goto out;
2511}
2512
2339static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 2513static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2340{ 2514{
2341 uint32_t *p; 2515 uint32_t *p;
@@ -2462,7 +2636,7 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t
2462 return 0; 2636 return 0;
2463} 2637}
2464 2638
2465static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *uid) 2639static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *uid)
2466{ 2640{
2467 uint32_t len, *p; 2641 uint32_t len, *p;
2468 2642
@@ -2486,7 +2660,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
2486 return 0; 2660 return 0;
2487} 2661}
2488 2662
2489static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *gid) 2663static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *gid)
2490{ 2664{
2491 uint32_t len, *p; 2665 uint32_t len, *p;
2492 2666
@@ -2841,6 +3015,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
2841 bitmap[2] = {0}, 3015 bitmap[2] = {0},
2842 type; 3016 type;
2843 int status, fmode = 0; 3017 int status, fmode = 0;
3018 uint64_t fileid;
2844 3019
2845 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 3020 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
2846 goto xdr_error; 3021 goto xdr_error;
@@ -2863,18 +3038,22 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
2863 goto xdr_error; 3038 goto xdr_error;
2864 if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0) 3039 if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0)
2865 goto xdr_error; 3040 goto xdr_error;
2866 if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid_u.nfs4)) != 0) 3041 if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid)) != 0)
2867 goto xdr_error; 3042 goto xdr_error;
2868 if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0) 3043 if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0)
2869 goto xdr_error; 3044 goto xdr_error;
3045 if ((status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
3046 struct nfs4_fs_locations,
3047 fattr))) != 0)
3048 goto xdr_error;
2870 if ((status = decode_attr_mode(xdr, bitmap, &fattr->mode)) != 0) 3049 if ((status = decode_attr_mode(xdr, bitmap, &fattr->mode)) != 0)
2871 goto xdr_error; 3050 goto xdr_error;
2872 fattr->mode |= fmode; 3051 fattr->mode |= fmode;
2873 if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0) 3052 if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0)
2874 goto xdr_error; 3053 goto xdr_error;
2875 if ((status = decode_attr_owner(xdr, bitmap, server->nfs4_state, &fattr->uid)) != 0) 3054 if ((status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid)) != 0)
2876 goto xdr_error; 3055 goto xdr_error;
2877 if ((status = decode_attr_group(xdr, bitmap, server->nfs4_state, &fattr->gid)) != 0) 3056 if ((status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid)) != 0)
2878 goto xdr_error; 3057 goto xdr_error;
2879 if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0) 3058 if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0)
2880 goto xdr_error; 3059 goto xdr_error;
@@ -2886,6 +3065,10 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
2886 goto xdr_error; 3065 goto xdr_error;
2887 if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0) 3066 if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0)
2888 goto xdr_error; 3067 goto xdr_error;
3068 if ((status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid)) != 0)
3069 goto xdr_error;
3070 if (fattr->fileid == 0 && fileid != 0)
3071 fattr->fileid = fileid;
2889 if ((status = verify_attr_len(xdr, savep, attrlen)) == 0) 3072 if ((status = verify_attr_len(xdr, savep, attrlen)) == 0)
2890 fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4; 3073 fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4;
2891xdr_error: 3074xdr_error:
@@ -3071,7 +3254,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3071 if (decode_space_limit(xdr, &res->maxsize) < 0) 3254 if (decode_space_limit(xdr, &res->maxsize) < 0)
3072 return -EIO; 3255 return -EIO;
3073 } 3256 }
3074 return decode_ace(xdr, NULL, res->server->nfs4_state); 3257 return decode_ace(xdr, NULL, res->server->nfs_client);
3075} 3258}
3076 3259
3077static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) 3260static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
@@ -3172,7 +3355,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3172 struct kvec *iov = rcvbuf->head; 3355 struct kvec *iov = rcvbuf->head;
3173 unsigned int nr, pglen = rcvbuf->page_len; 3356 unsigned int nr, pglen = rcvbuf->page_len;
3174 uint32_t *end, *entry, *p, *kaddr; 3357 uint32_t *end, *entry, *p, *kaddr;
3175 uint32_t len, attrlen; 3358 uint32_t len, attrlen, xlen;
3176 int hdrlen, recvd, status; 3359 int hdrlen, recvd, status;
3177 3360
3178 status = decode_op_hdr(xdr, OP_READDIR); 3361 status = decode_op_hdr(xdr, OP_READDIR);
@@ -3194,10 +3377,10 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3194 3377
3195 BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE); 3378 BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE);
3196 kaddr = p = (uint32_t *) kmap_atomic(page, KM_USER0); 3379 kaddr = p = (uint32_t *) kmap_atomic(page, KM_USER0);
3197 end = (uint32_t *) ((char *)p + pglen + readdir->pgbase); 3380 end = p + ((pglen + readdir->pgbase) >> 2);
3198 entry = p; 3381 entry = p;
3199 for (nr = 0; *p++; nr++) { 3382 for (nr = 0; *p++; nr++) {
3200 if (p + 3 > end) 3383 if (end - p < 3)
3201 goto short_pkt; 3384 goto short_pkt;
3202 dprintk("cookie = %Lu, ", *((unsigned long long *)p)); 3385 dprintk("cookie = %Lu, ", *((unsigned long long *)p));
3203 p += 2; /* cookie */ 3386 p += 2; /* cookie */
@@ -3206,18 +3389,19 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3206 printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len); 3389 printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len);
3207 goto err_unmap; 3390 goto err_unmap;
3208 } 3391 }
3209 dprintk("filename = %*s\n", len, (char *)p); 3392 xlen = XDR_QUADLEN(len);
3210 p += XDR_QUADLEN(len); 3393 if (end - p < xlen + 1)
3211 if (p + 1 > end)
3212 goto short_pkt; 3394 goto short_pkt;
3395 dprintk("filename = %*s\n", len, (char *)p);
3396 p += xlen;
3213 len = ntohl(*p++); /* bitmap length */ 3397 len = ntohl(*p++); /* bitmap length */
3214 p += len; 3398 if (end - p < len + 1)
3215 if (p + 1 > end)
3216 goto short_pkt; 3399 goto short_pkt;
3400 p += len;
3217 attrlen = XDR_QUADLEN(ntohl(*p++)); 3401 attrlen = XDR_QUADLEN(ntohl(*p++));
3218 p += attrlen; /* attributes */ 3402 if (end - p < attrlen + 2)
3219 if (p + 2 > end)
3220 goto short_pkt; 3403 goto short_pkt;
3404 p += attrlen; /* attributes */
3221 entry = p; 3405 entry = p;
3222 } 3406 }
3223 if (!nr && (entry[0] != 0 || entry[1] == 0)) 3407 if (!nr && (entry[0] != 0 || entry[1] == 0))
@@ -3350,8 +3534,7 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
3350 attrlen, recvd); 3534 attrlen, recvd);
3351 return -EINVAL; 3535 return -EINVAL;
3352 } 3536 }
3353 if (attrlen <= *acl_len) 3537 xdr_read_pages(xdr, attrlen);
3354 xdr_read_pages(xdr, attrlen);
3355 *acl_len = attrlen; 3538 *acl_len = attrlen;
3356 } else 3539 } else
3357 status = -EOPNOTSUPP; 3540 status = -EOPNOTSUPP;
@@ -3382,7 +3565,7 @@ static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
3382 return 0; 3565 return 0;
3383} 3566}
3384 3567
3385static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp) 3568static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
3386{ 3569{
3387 uint32_t *p; 3570 uint32_t *p;
3388 uint32_t opnum; 3571 uint32_t opnum;
@@ -3415,7 +3598,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp)
3415 READ_BUF(len); 3598 READ_BUF(len);
3416 return -NFSERR_CLID_INUSE; 3599 return -NFSERR_CLID_INUSE;
3417 } else 3600 } else
3418 return -nfs_stat_to_errno(nfserr); 3601 return -nfs4_stat_to_errno(nfserr);
3419 3602
3420 return 0; 3603 return 0;
3421} 3604}
@@ -4073,7 +4256,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsi
4073 if (!status) 4256 if (!status)
4074 status = decode_fsinfo(&xdr, fsinfo); 4257 status = decode_fsinfo(&xdr, fsinfo);
4075 if (!status) 4258 if (!status)
4076 status = -nfs_stat_to_errno(hdr.status); 4259 status = -nfs4_stat_to_errno(hdr.status);
4077 return status; 4260 return status;
4078} 4261}
4079 4262
@@ -4152,7 +4335,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
4152 * a SETCLIENTID request 4335 * a SETCLIENTID request
4153 */ 4336 */
4154static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, 4337static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
4155 struct nfs4_client *clp) 4338 struct nfs_client *clp)
4156{ 4339{
4157 struct xdr_stream xdr; 4340 struct xdr_stream xdr;
4158 struct compound_hdr hdr; 4341 struct compound_hdr hdr;
@@ -4163,7 +4346,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
4163 if (!status) 4346 if (!status)
4164 status = decode_setclientid(&xdr, clp); 4347 status = decode_setclientid(&xdr, clp);
4165 if (!status) 4348 if (!status)
4166 status = -nfs_stat_to_errno(hdr.status); 4349 status = -nfs4_stat_to_errno(hdr.status);
4167 return status; 4350 return status;
4168} 4351}
4169 4352
@@ -4185,7 +4368,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s
4185 if (!status) 4368 if (!status)
4186 status = decode_fsinfo(&xdr, fsinfo); 4369 status = decode_fsinfo(&xdr, fsinfo);
4187 if (!status) 4370 if (!status)
4188 status = -nfs_stat_to_errno(hdr.status); 4371 status = -nfs4_stat_to_errno(hdr.status);
4189 return status; 4372 return status;
4190} 4373}
4191 4374
@@ -4211,6 +4394,29 @@ out:
4211 return status; 4394 return status;
4212} 4395}
4213 4396
4397/*
4398 * FS_LOCATIONS request
4399 */
4400static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations *res)
4401{
4402 struct xdr_stream xdr;
4403 struct compound_hdr hdr;
4404 int status;
4405
4406 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4407 status = decode_compound_hdr(&xdr, &hdr);
4408 if (status != 0)
4409 goto out;
4410 if ((status = decode_putfh(&xdr)) != 0)
4411 goto out;
4412 if ((status = decode_lookup(&xdr)) != 0)
4413 goto out;
4414 xdr_enter_page(&xdr, PAGE_SIZE);
4415 status = decode_getfattr(&xdr, &res->fattr, res->server);
4416out:
4417 return status;
4418}
4419
4214uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus) 4420uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
4215{ 4421{
4216 uint32_t bitmap[2] = {0}; 4422 uint32_t bitmap[2] = {0};
@@ -4315,7 +4521,7 @@ static struct {
4315 * This one is used jointly by NFSv2 and NFSv3. 4521 * This one is used jointly by NFSv2 and NFSv3.
4316 */ 4522 */
4317static int 4523static int
4318nfs_stat_to_errno(int stat) 4524nfs4_stat_to_errno(int stat)
4319{ 4525{
4320 int i; 4526 int i;
4321 for (i = 0; nfs_errtbl[i].stat != -1; i++) { 4527 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
@@ -4382,6 +4588,7 @@ struct rpc_procinfo nfs4_procedures[] = {
4382 PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn), 4588 PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn),
4383 PROC(GETACL, enc_getacl, dec_getacl), 4589 PROC(GETACL, enc_getacl, dec_getacl),
4384 PROC(SETACL, enc_setacl, dec_setacl), 4590 PROC(SETACL, enc_setacl, dec_setacl),
4591 PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations),
4385}; 4592};
4386 4593
4387struct rpc_version nfs_version4 = { 4594struct rpc_version nfs_version4 = {