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.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index dddfb5795d7b..c3ccd2c46834 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1452,26 +1452,25 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
1452 1452
1453static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1453static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
1454{ 1454{
1455 uint32_t attrs[2] = {0, 0}; 1455 uint32_t attrs[2] = {
1456 FATTR4_WORD0_RDATTR_ERROR,
1457 FATTR4_WORD1_MOUNTED_ON_FILEID,
1458 };
1456 uint32_t dircount = readdir->count >> 1; 1459 uint32_t dircount = readdir->count >> 1;
1457 __be32 *p; 1460 __be32 *p;
1458 1461
1459 if (readdir->plus) { 1462 if (readdir->plus) {
1460 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| 1463 attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
1461 FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE; 1464 FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID;
1462 attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER| 1465 attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER|
1463 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| 1466 FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
1464 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| 1467 FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
1465 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 1468 FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
1466 dircount >>= 1; 1469 dircount >>= 1;
1467 } 1470 }
1468 attrs[0] |= FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID; 1471 /* Use mounted_on_fileid only if the server supports it */
1469 attrs[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID; 1472 if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID))
1470 /* Switch to mounted_on_fileid if the server supports it */ 1473 attrs[0] |= FATTR4_WORD0_FILEID;
1471 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
1472 attrs[0] &= ~FATTR4_WORD0_FILEID;
1473 else
1474 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1475 1474
1476 p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20); 1475 p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20);
1477 *p++ = cpu_to_be32(OP_READDIR); 1476 *p++ = cpu_to_be32(OP_READDIR);
@@ -3140,7 +3139,7 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma
3140 goto out_overflow; 3139 goto out_overflow;
3141 xdr_decode_hyper(p, fileid); 3140 xdr_decode_hyper(p, fileid);
3142 bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; 3141 bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
3143 ret = NFS_ATTR_FATTR_FILEID; 3142 ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID;
3144 } 3143 }
3145 dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); 3144 dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
3146 return ret; 3145 return ret;
@@ -4002,7 +4001,6 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4002{ 4001{
4003 int status; 4002 int status;
4004 umode_t fmode = 0; 4003 umode_t fmode = 0;
4005 uint64_t fileid;
4006 uint32_t type; 4004 uint32_t type;
4007 4005
4008 status = decode_attr_type(xdr, bitmap, &type); 4006 status = decode_attr_type(xdr, bitmap, &type);
@@ -4101,13 +4099,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4101 goto xdr_error; 4099 goto xdr_error;
4102 fattr->valid |= status; 4100 fattr->valid |= status;
4103 4101
4104 status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid); 4102 status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid);
4105 if (status < 0) 4103 if (status < 0)
4106 goto xdr_error; 4104 goto xdr_error;
4107 if (status != 0 && !(fattr->valid & status)) { 4105 fattr->valid |= status;
4108 fattr->fileid = fileid;
4109 fattr->valid |= status;
4110 }
4111 4106
4112xdr_error: 4107xdr_error:
4113 dprintk("%s: xdr returned %d\n", __func__, -status); 4108 dprintk("%s: xdr returned %d\n", __func__, -status);
@@ -4838,17 +4833,21 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
4838 struct nfs4_secinfo_flavor *sec_flavor; 4833 struct nfs4_secinfo_flavor *sec_flavor;
4839 int status; 4834 int status;
4840 __be32 *p; 4835 __be32 *p;
4841 int i; 4836 int i, num_flavors;
4842 4837
4843 status = decode_op_hdr(xdr, OP_SECINFO); 4838 status = decode_op_hdr(xdr, OP_SECINFO);
4839 if (status)
4840 goto out;
4844 p = xdr_inline_decode(xdr, 4); 4841 p = xdr_inline_decode(xdr, 4);
4845 if (unlikely(!p)) 4842 if (unlikely(!p))
4846 goto out_overflow; 4843 goto out_overflow;
4847 res->flavors->num_flavors = be32_to_cpup(p);
4848 4844
4849 for (i = 0; i < res->flavors->num_flavors; i++) { 4845 res->flavors->num_flavors = 0;
4846 num_flavors = be32_to_cpup(p);
4847
4848 for (i = 0; i < num_flavors; i++) {
4850 sec_flavor = &res->flavors->flavors[i]; 4849 sec_flavor = &res->flavors->flavors[i];
4851 if ((char *)&sec_flavor[1] - (char *)res > PAGE_SIZE) 4850 if ((char *)&sec_flavor[1] - (char *)res->flavors > PAGE_SIZE)
4852 break; 4851 break;
4853 4852
4854 p = xdr_inline_decode(xdr, 4); 4853 p = xdr_inline_decode(xdr, 4);
@@ -4857,13 +4856,15 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
4857 sec_flavor->flavor = be32_to_cpup(p); 4856 sec_flavor->flavor = be32_to_cpup(p);
4858 4857
4859 if (sec_flavor->flavor == RPC_AUTH_GSS) { 4858 if (sec_flavor->flavor == RPC_AUTH_GSS) {
4860 if (decode_secinfo_gss(xdr, sec_flavor)) 4859 status = decode_secinfo_gss(xdr, sec_flavor);
4861 break; 4860 if (status)
4861 goto out;
4862 } 4862 }
4863 res->flavors->num_flavors++;
4863 } 4864 }
4864 4865
4865 return 0; 4866out:
4866 4867 return status;
4867out_overflow: 4868out_overflow:
4868 print_overflow_msg(__func__, xdr); 4869 print_overflow_msg(__func__, xdr);
4869 return -EIO; 4870 return -EIO;
@@ -6408,7 +6409,9 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
6408 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, 6409 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
6409 entry->server, 1) < 0) 6410 entry->server, 1) < 0)
6410 goto out_overflow; 6411 goto out_overflow;
6411 if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) 6412 if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
6413 entry->ino = entry->fattr->mounted_on_fileid;
6414 else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
6412 entry->ino = entry->fattr->fileid; 6415 entry->ino = entry->fattr->fileid;
6413 6416
6414 entry->d_type = DT_UNKNOWN; 6417 entry->d_type = DT_UNKNOWN;