aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 16:48:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 16:48:29 -0400
commit74eb94b218d087798a52c0b4f1379b635287a4b8 (patch)
tree4e467c3014c2b1169f6f71d88cf5d1598f3ce28e /fs/nfs/nfs4xdr.c
parent7b6181e06841f5ad15c4ff708b967b4db65a64de (diff)
parent9a84d38031c258a17bb39beed1e500eadee67407 (diff)
Merge branch 'nfs-for-2.6.37' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'nfs-for-2.6.37' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (67 commits) SUNRPC: Cleanup duplicate assignment in rpcauth_refreshcred nfs: fix unchecked value Ask for time_delta during fsinfo probe Revalidate caches on lock SUNRPC: After calling xprt_release(), we must restart from call_reserve NFSv4: Fix up the 'dircount' hint in encode_readdir NFSv4: Clean up nfs4_decode_dirent NFSv4: nfs4_decode_dirent must clear entry->fattr->valid NFSv4: Fix a regression in decode_getfattr NFSv4: Fix up decode_attr_filehandle() to handle the case of empty fh pointer NFS: Ensure we check all allocation return values in new readdir code NFS: Readdir plus in v4 NFS: introduce generic decode_getattr function NFS: check xdr_decode for errors NFS: nfs_readdir_filler catch all errors NFS: readdir with vmapped pages NFS: remove page size checking code NFS: decode_dirent should use an xdr_stream SUNRPC: Add a helper function xdr_inline_peek NFS: remove readdir plus limit ...
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c340
1 files changed, 197 insertions, 143 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 08ef91291132..bd2101d918c8 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -816,7 +816,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
816 if (iap->ia_valid & ATTR_MODE) 816 if (iap->ia_valid & ATTR_MODE)
817 len += 4; 817 len += 4;
818 if (iap->ia_valid & ATTR_UID) { 818 if (iap->ia_valid & ATTR_UID) {
819 owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name); 819 owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name, IDMAP_NAMESZ);
820 if (owner_namelen < 0) { 820 if (owner_namelen < 0) {
821 dprintk("nfs: couldn't resolve uid %d to string\n", 821 dprintk("nfs: couldn't resolve uid %d to string\n",
822 iap->ia_uid); 822 iap->ia_uid);
@@ -828,7 +828,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
828 len += 4 + (XDR_QUADLEN(owner_namelen) << 2); 828 len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
829 } 829 }
830 if (iap->ia_valid & ATTR_GID) { 830 if (iap->ia_valid & ATTR_GID) {
831 owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group); 831 owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group, IDMAP_NAMESZ);
832 if (owner_grouplen < 0) { 832 if (owner_grouplen < 0) {
833 dprintk("nfs: couldn't resolve gid %d to string\n", 833 dprintk("nfs: couldn't resolve gid %d to string\n",
834 iap->ia_gid); 834 iap->ia_gid);
@@ -1385,24 +1385,35 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
1385 1385
1386static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1386static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
1387{ 1387{
1388 uint32_t attrs[2] = { 1388 uint32_t attrs[2] = {0, 0};
1389 FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID, 1389 uint32_t dircount = readdir->count >> 1;
1390 FATTR4_WORD1_MOUNTED_ON_FILEID,
1391 };
1392 __be32 *p; 1390 __be32 *p;
1393 1391
1392 if (readdir->plus) {
1393 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
1394 FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE;
1395 attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER|
1396 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
1397 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
1398 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
1399 dircount >>= 1;
1400 }
1401 attrs[0] |= FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID;
1402 attrs[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID;
1403 /* Switch to mounted_on_fileid if the server supports it */
1404 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
1405 attrs[0] &= ~FATTR4_WORD0_FILEID;
1406 else
1407 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1408
1394 p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20); 1409 p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20);
1395 *p++ = cpu_to_be32(OP_READDIR); 1410 *p++ = cpu_to_be32(OP_READDIR);
1396 p = xdr_encode_hyper(p, readdir->cookie); 1411 p = xdr_encode_hyper(p, readdir->cookie);
1397 p = xdr_encode_opaque_fixed(p, readdir->verifier.data, NFS4_VERIFIER_SIZE); 1412 p = xdr_encode_opaque_fixed(p, readdir->verifier.data, NFS4_VERIFIER_SIZE);
1398 *p++ = cpu_to_be32(readdir->count >> 1); /* We're not doing readdirplus */ 1413 *p++ = cpu_to_be32(dircount);
1399 *p++ = cpu_to_be32(readdir->count); 1414 *p++ = cpu_to_be32(readdir->count);
1400 *p++ = cpu_to_be32(2); 1415 *p++ = cpu_to_be32(2);
1401 /* Switch to mounted_on_fileid if the server supports it */ 1416
1402 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
1403 attrs[0] &= ~FATTR4_WORD0_FILEID;
1404 else
1405 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1406 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); 1417 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]);
1407 *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); 1418 *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]);
1408 hdr->nops++; 1419 hdr->nops++;
@@ -1823,7 +1834,7 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
1823/* 1834/*
1824 * Encode RENAME request 1835 * Encode RENAME request
1825 */ 1836 */
1826static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs4_rename_arg *args) 1837static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs_renameargs *args)
1827{ 1838{
1828 struct xdr_stream xdr; 1839 struct xdr_stream xdr;
1829 struct compound_hdr hdr = { 1840 struct compound_hdr hdr = {
@@ -2676,7 +2687,10 @@ out_overflow:
2676static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) 2687static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask)
2677{ 2688{
2678 if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) { 2689 if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) {
2679 decode_attr_bitmap(xdr, bitmask); 2690 int ret;
2691 ret = decode_attr_bitmap(xdr, bitmask);
2692 if (unlikely(ret < 0))
2693 return ret;
2680 bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; 2694 bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS;
2681 } else 2695 } else
2682 bitmask[0] = bitmask[1] = 0; 2696 bitmask[0] = bitmask[1] = 0;
@@ -2848,6 +2862,56 @@ out_overflow:
2848 return -EIO; 2862 return -EIO;
2849} 2863}
2850 2864
2865static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap)
2866{
2867 __be32 *p;
2868
2869 if (unlikely(bitmap[0] & (FATTR4_WORD0_RDATTR_ERROR - 1U)))
2870 return -EIO;
2871 if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) {
2872 p = xdr_inline_decode(xdr, 4);
2873 if (unlikely(!p))
2874 goto out_overflow;
2875 bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
2876 }
2877 return 0;
2878out_overflow:
2879 print_overflow_msg(__func__, xdr);
2880 return -EIO;
2881}
2882
2883static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fh *fh)
2884{
2885 __be32 *p;
2886 int len;
2887
2888 if (fh != NULL)
2889 memset(fh, 0, sizeof(*fh));
2890
2891 if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEHANDLE - 1U)))
2892 return -EIO;
2893 if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) {
2894 p = xdr_inline_decode(xdr, 4);
2895 if (unlikely(!p))
2896 goto out_overflow;
2897 len = be32_to_cpup(p);
2898 if (len > NFS4_FHSIZE)
2899 return -EIO;
2900 p = xdr_inline_decode(xdr, len);
2901 if (unlikely(!p))
2902 goto out_overflow;
2903 if (fh != NULL) {
2904 memcpy(fh->data, p, len);
2905 fh->size = len;
2906 }
2907 bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE;
2908 }
2909 return 0;
2910out_overflow:
2911 print_overflow_msg(__func__, xdr);
2912 return -EIO;
2913}
2914
2851static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 2915static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2852{ 2916{
2853 __be32 *p; 2917 __be32 *p;
@@ -3521,6 +3585,24 @@ static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, s
3521 return status; 3585 return status;
3522} 3586}
3523 3587
3588static int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap,
3589 struct timespec *time)
3590{
3591 int status = 0;
3592
3593 time->tv_sec = 0;
3594 time->tv_nsec = 0;
3595 if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_DELTA - 1U)))
3596 return -EIO;
3597 if (likely(bitmap[1] & FATTR4_WORD1_TIME_DELTA)) {
3598 status = decode_attr_time(xdr, time);
3599 bitmap[1] &= ~FATTR4_WORD1_TIME_DELTA;
3600 }
3601 dprintk("%s: time_delta=%ld %ld\n", __func__, (long)time->tv_sec,
3602 (long)time->tv_nsec);
3603 return status;
3604}
3605
3524static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) 3606static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
3525{ 3607{
3526 int status = 0; 3608 int status = 0;
@@ -3744,29 +3826,14 @@ xdr_error:
3744 return status; 3826 return status;
3745} 3827}
3746 3828
3747static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, 3829static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
3830 struct nfs_fattr *fattr, struct nfs_fh *fh,
3748 const struct nfs_server *server, int may_sleep) 3831 const struct nfs_server *server, int may_sleep)
3749{ 3832{
3750 __be32 *savep;
3751 uint32_t attrlen,
3752 bitmap[2] = {0},
3753 type;
3754 int status; 3833 int status;
3755 umode_t fmode = 0; 3834 umode_t fmode = 0;
3756 uint64_t fileid; 3835 uint64_t fileid;
3757 3836 uint32_t type;
3758 status = decode_op_hdr(xdr, OP_GETATTR);
3759 if (status < 0)
3760 goto xdr_error;
3761
3762 status = decode_attr_bitmap(xdr, bitmap);
3763 if (status < 0)
3764 goto xdr_error;
3765
3766 status = decode_attr_length(xdr, &attrlen, &savep);
3767 if (status < 0)
3768 goto xdr_error;
3769
3770 3837
3771 status = decode_attr_type(xdr, bitmap, &type); 3838 status = decode_attr_type(xdr, bitmap, &type);
3772 if (status < 0) 3839 if (status < 0)
@@ -3792,6 +3859,14 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3792 goto xdr_error; 3859 goto xdr_error;
3793 fattr->valid |= status; 3860 fattr->valid |= status;
3794 3861
3862 status = decode_attr_error(xdr, bitmap);
3863 if (status < 0)
3864 goto xdr_error;
3865
3866 status = decode_attr_filehandle(xdr, bitmap, fh);
3867 if (status < 0)
3868 goto xdr_error;
3869
3795 status = decode_attr_fileid(xdr, bitmap, &fattr->fileid); 3870 status = decode_attr_fileid(xdr, bitmap, &fattr->fileid);
3796 if (status < 0) 3871 if (status < 0)
3797 goto xdr_error; 3872 goto xdr_error;
@@ -3862,12 +3937,46 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3862 fattr->valid |= status; 3937 fattr->valid |= status;
3863 } 3938 }
3864 3939
3940xdr_error:
3941 dprintk("%s: xdr returned %d\n", __func__, -status);
3942 return status;
3943}
3944
3945static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3946 struct nfs_fh *fh, const struct nfs_server *server, int may_sleep)
3947{
3948 __be32 *savep;
3949 uint32_t attrlen,
3950 bitmap[2] = {0};
3951 int status;
3952
3953 status = decode_op_hdr(xdr, OP_GETATTR);
3954 if (status < 0)
3955 goto xdr_error;
3956
3957 status = decode_attr_bitmap(xdr, bitmap);
3958 if (status < 0)
3959 goto xdr_error;
3960
3961 status = decode_attr_length(xdr, &attrlen, &savep);
3962 if (status < 0)
3963 goto xdr_error;
3964
3965 status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server, may_sleep);
3966 if (status < 0)
3967 goto xdr_error;
3968
3865 status = verify_attr_len(xdr, savep, attrlen); 3969 status = verify_attr_len(xdr, savep, attrlen);
3866xdr_error: 3970xdr_error:
3867 dprintk("%s: xdr returned %d\n", __func__, -status); 3971 dprintk("%s: xdr returned %d\n", __func__, -status);
3868 return status; 3972 return status;
3869} 3973}
3870 3974
3975static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
3976 const struct nfs_server *server, int may_sleep)
3977{
3978 return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep);
3979}
3871 3980
3872static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 3981static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
3873{ 3982{
@@ -3894,6 +4003,9 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
3894 if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) 4003 if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0)
3895 goto xdr_error; 4004 goto xdr_error;
3896 fsinfo->wtpref = fsinfo->wtmax; 4005 fsinfo->wtpref = fsinfo->wtmax;
4006 status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta);
4007 if (status != 0)
4008 goto xdr_error;
3897 4009
3898 status = verify_attr_len(xdr, savep, attrlen); 4010 status = verify_attr_len(xdr, savep, attrlen);
3899xdr_error: 4011xdr_error:
@@ -3950,13 +4062,13 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
3950 __be32 *p; 4062 __be32 *p;
3951 uint32_t namelen, type; 4063 uint32_t namelen, type;
3952 4064
3953 p = xdr_inline_decode(xdr, 32); 4065 p = xdr_inline_decode(xdr, 32); /* read 32 bytes */
3954 if (unlikely(!p)) 4066 if (unlikely(!p))
3955 goto out_overflow; 4067 goto out_overflow;
3956 p = xdr_decode_hyper(p, &offset); 4068 p = xdr_decode_hyper(p, &offset); /* read 2 8-byte long words */
3957 p = xdr_decode_hyper(p, &length); 4069 p = xdr_decode_hyper(p, &length);
3958 type = be32_to_cpup(p++); 4070 type = be32_to_cpup(p++); /* 4 byte read */
3959 if (fl != NULL) { 4071 if (fl != NULL) { /* manipulate file lock */
3960 fl->fl_start = (loff_t)offset; 4072 fl->fl_start = (loff_t)offset;
3961 fl->fl_end = fl->fl_start + (loff_t)length - 1; 4073 fl->fl_end = fl->fl_start + (loff_t)length - 1;
3962 if (length == ~(uint64_t)0) 4074 if (length == ~(uint64_t)0)
@@ -3966,9 +4078,9 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
3966 fl->fl_type = F_RDLCK; 4078 fl->fl_type = F_RDLCK;
3967 fl->fl_pid = 0; 4079 fl->fl_pid = 0;
3968 } 4080 }
3969 p = xdr_decode_hyper(p, &clientid); 4081 p = xdr_decode_hyper(p, &clientid); /* read 8 bytes */
3970 namelen = be32_to_cpup(p); 4082 namelen = be32_to_cpup(p); /* read 4 bytes */ /* have read all 32 bytes now */
3971 p = xdr_inline_decode(xdr, namelen); 4083 p = xdr_inline_decode(xdr, namelen); /* variable size field */
3972 if (likely(p)) 4084 if (likely(p))
3973 return -NFS4ERR_DENIED; 4085 return -NFS4ERR_DENIED;
3974out_overflow: 4086out_overflow:
@@ -4200,12 +4312,9 @@ out_overflow:
4200static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) 4312static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir)
4201{ 4313{
4202 struct xdr_buf *rcvbuf = &req->rq_rcv_buf; 4314 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
4203 struct page *page = *rcvbuf->pages;
4204 struct kvec *iov = rcvbuf->head; 4315 struct kvec *iov = rcvbuf->head;
4205 size_t hdrlen; 4316 size_t hdrlen;
4206 u32 recvd, pglen = rcvbuf->page_len; 4317 u32 recvd, pglen = rcvbuf->page_len;
4207 __be32 *end, *entry, *p, *kaddr;
4208 unsigned int nr = 0;
4209 int status; 4318 int status;
4210 4319
4211 status = decode_op_hdr(xdr, OP_READDIR); 4320 status = decode_op_hdr(xdr, OP_READDIR);
@@ -4225,71 +4334,8 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
4225 pglen = recvd; 4334 pglen = recvd;
4226 xdr_read_pages(xdr, pglen); 4335 xdr_read_pages(xdr, pglen);
4227 4336
4228 BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE); 4337
4229 kaddr = p = kmap_atomic(page, KM_USER0);
4230 end = p + ((pglen + readdir->pgbase) >> 2);
4231 entry = p;
4232
4233 /* Make sure the packet actually has a value_follows and EOF entry */
4234 if ((entry + 1) > end)
4235 goto short_pkt;
4236
4237 for (; *p++; nr++) {
4238 u32 len, attrlen, xlen;
4239 if (end - p < 3)
4240 goto short_pkt;
4241 dprintk("cookie = %Lu, ", *((unsigned long long *)p));
4242 p += 2; /* cookie */
4243 len = ntohl(*p++); /* filename length */
4244 if (len > NFS4_MAXNAMLEN) {
4245 dprintk("NFS: giant filename in readdir (len 0x%x)\n",
4246 len);
4247 goto err_unmap;
4248 }
4249 xlen = XDR_QUADLEN(len);
4250 if (end - p < xlen + 1)
4251 goto short_pkt;
4252 dprintk("filename = %*s\n", len, (char *)p);
4253 p += xlen;
4254 len = ntohl(*p++); /* bitmap length */
4255 if (end - p < len + 1)
4256 goto short_pkt;
4257 p += len;
4258 attrlen = XDR_QUADLEN(ntohl(*p++));
4259 if (end - p < attrlen + 2)
4260 goto short_pkt;
4261 p += attrlen; /* attributes */
4262 entry = p;
4263 }
4264 /*
4265 * Apparently some server sends responses that are a valid size, but
4266 * contain no entries, and have value_follows==0 and EOF==0. For
4267 * those, just set the EOF marker.
4268 */
4269 if (!nr && entry[1] == 0) {
4270 dprintk("NFS: readdir reply truncated!\n");
4271 entry[1] = 1;
4272 }
4273out:
4274 kunmap_atomic(kaddr, KM_USER0);
4275 return 0; 4338 return 0;
4276short_pkt:
4277 /*
4278 * When we get a short packet there are 2 possibilities. We can
4279 * return an error, or fix up the response to look like a valid
4280 * response and return what we have so far. If there are no
4281 * entries and the packet was short, then return -EIO. If there
4282 * are valid entries in the response, return them and pretend that
4283 * the call was successful, but incomplete. The caller can retry the
4284 * readdir starting at the last cookie.
4285 */
4286 dprintk("%s: short packet at entry %d\n", __func__, nr);
4287 entry[0] = entry[1] = 0;
4288 if (nr)
4289 goto out;
4290err_unmap:
4291 kunmap_atomic(kaddr, KM_USER0);
4292 return -errno_NFSERR_IO;
4293} 4339}
4294 4340
4295static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) 4341static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
@@ -4299,7 +4345,6 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
4299 size_t hdrlen; 4345 size_t hdrlen;
4300 u32 len, recvd; 4346 u32 len, recvd;
4301 __be32 *p; 4347 __be32 *p;
4302 char *kaddr;
4303 int status; 4348 int status;
4304 4349
4305 status = decode_op_hdr(xdr, OP_READLINK); 4350 status = decode_op_hdr(xdr, OP_READLINK);
@@ -4330,9 +4375,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
4330 * and and null-terminate the text (the VFS expects 4375 * and and null-terminate the text (the VFS expects
4331 * null-termination). 4376 * null-termination).
4332 */ 4377 */
4333 kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0); 4378 xdr_terminate_string(rcvbuf, len);
4334 kaddr[len+rcvbuf->page_base] = '\0';
4335 kunmap_atomic(kaddr, KM_USER0);
4336 return 0; 4379 return 0;
4337out_overflow: 4380out_overflow:
4338 print_overflow_msg(__func__, xdr); 4381 print_overflow_msg(__func__, xdr);
@@ -4668,7 +4711,6 @@ static int decode_sequence(struct xdr_stream *xdr,
4668 struct rpc_rqst *rqstp) 4711 struct rpc_rqst *rqstp)
4669{ 4712{
4670#if defined(CONFIG_NFS_V4_1) 4713#if defined(CONFIG_NFS_V4_1)
4671 struct nfs4_slot *slot;
4672 struct nfs4_sessionid id; 4714 struct nfs4_sessionid id;
4673 u32 dummy; 4715 u32 dummy;
4674 int status; 4716 int status;
@@ -4700,15 +4742,14 @@ static int decode_sequence(struct xdr_stream *xdr,
4700 goto out_overflow; 4742 goto out_overflow;
4701 4743
4702 /* seqid */ 4744 /* seqid */
4703 slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid];
4704 dummy = be32_to_cpup(p++); 4745 dummy = be32_to_cpup(p++);
4705 if (dummy != slot->seq_nr) { 4746 if (dummy != res->sr_slot->seq_nr) {
4706 dprintk("%s Invalid sequence number\n", __func__); 4747 dprintk("%s Invalid sequence number\n", __func__);
4707 goto out_err; 4748 goto out_err;
4708 } 4749 }
4709 /* slot id */ 4750 /* slot id */
4710 dummy = be32_to_cpup(p++); 4751 dummy = be32_to_cpup(p++);
4711 if (dummy != res->sr_slotid) { 4752 if (dummy != res->sr_slot - res->sr_session->fc_slot_table.slots) {
4712 dprintk("%s Invalid slot id\n", __func__); 4753 dprintk("%s Invalid slot id\n", __func__);
4713 goto out_err; 4754 goto out_err;
4714 } 4755 }
@@ -4873,7 +4914,7 @@ out:
4873/* 4914/*
4874 * Decode RENAME response 4915 * Decode RENAME response
4875 */ 4916 */
4876static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_rename_res *res) 4917static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs_renameres *res)
4877{ 4918{
4878 struct xdr_stream xdr; 4919 struct xdr_stream xdr;
4879 struct compound_hdr hdr; 4920 struct compound_hdr hdr;
@@ -5760,23 +5801,35 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, uint32_t *p,
5760} 5801}
5761#endif /* CONFIG_NFS_V4_1 */ 5802#endif /* CONFIG_NFS_V4_1 */
5762 5803
5763__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus) 5804__be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
5805 struct nfs_server *server, int plus)
5764{ 5806{
5765 uint32_t bitmap[2] = {0}; 5807 uint32_t bitmap[2] = {0};
5766 uint32_t len; 5808 uint32_t len;
5767 5809 __be32 *p = xdr_inline_decode(xdr, 4);
5768 if (!*p++) { 5810 if (unlikely(!p))
5769 if (!*p) 5811 goto out_overflow;
5812 if (!ntohl(*p++)) {
5813 p = xdr_inline_decode(xdr, 4);
5814 if (unlikely(!p))
5815 goto out_overflow;
5816 if (!ntohl(*p++))
5770 return ERR_PTR(-EAGAIN); 5817 return ERR_PTR(-EAGAIN);
5771 entry->eof = 1; 5818 entry->eof = 1;
5772 return ERR_PTR(-EBADCOOKIE); 5819 return ERR_PTR(-EBADCOOKIE);
5773 } 5820 }
5774 5821
5822 p = xdr_inline_decode(xdr, 12);
5823 if (unlikely(!p))
5824 goto out_overflow;
5775 entry->prev_cookie = entry->cookie; 5825 entry->prev_cookie = entry->cookie;
5776 p = xdr_decode_hyper(p, &entry->cookie); 5826 p = xdr_decode_hyper(p, &entry->cookie);
5777 entry->len = ntohl(*p++); 5827 entry->len = ntohl(*p++);
5828
5829 p = xdr_inline_decode(xdr, entry->len);
5830 if (unlikely(!p))
5831 goto out_overflow;
5778 entry->name = (const char *) p; 5832 entry->name = (const char *) p;
5779 p += XDR_QUADLEN(entry->len);
5780 5833
5781 /* 5834 /*
5782 * In case the server doesn't return an inode number, 5835 * In case the server doesn't return an inode number,
@@ -5784,32 +5837,33 @@ __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
5784 * since glibc seems to choke on it...) 5837 * since glibc seems to choke on it...)
5785 */ 5838 */
5786 entry->ino = 1; 5839 entry->ino = 1;
5840 entry->fattr->valid = 0;
5787 5841
5788 len = ntohl(*p++); /* bitmap length */ 5842 if (decode_attr_bitmap(xdr, bitmap) < 0)
5789 if (len-- > 0) { 5843 goto out_overflow;
5790 bitmap[0] = ntohl(*p++); 5844
5791 if (len-- > 0) { 5845 if (decode_attr_length(xdr, &len, &p) < 0)
5792 bitmap[1] = ntohl(*p++); 5846 goto out_overflow;
5793 p += len; 5847
5794 } 5848 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, server, 1) < 0)
5795 } 5849 goto out_overflow;
5796 len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */ 5850 if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
5797 if (len > 0) { 5851 entry->ino = entry->fattr->fileid;
5798 if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) { 5852
5799 bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; 5853 if (verify_attr_len(xdr, p, len) < 0)
5800 /* Ignore the return value of rdattr_error for now */ 5854 goto out_overflow;
5801 p++; 5855
5802 len--; 5856 p = xdr_inline_peek(xdr, 8);
5803 } 5857 if (p != NULL)
5804 if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID) 5858 entry->eof = !p[0] && p[1];
5805 xdr_decode_hyper(p, &entry->ino); 5859 else
5806 else if (bitmap[0] == FATTR4_WORD0_FILEID) 5860 entry->eof = 0;
5807 xdr_decode_hyper(p, &entry->ino);
5808 p += len;
5809 }
5810 5861
5811 entry->eof = !p[0] && p[1];
5812 return p; 5862 return p;
5863
5864out_overflow:
5865 print_overflow_msg(__func__, xdr);
5866 return ERR_PTR(-EIO);
5813} 5867}
5814 5868
5815/* 5869/*