summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 15:09:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 15:09:43 -0400
commitbe0c5d8c0bb0023e11f5c6d38e90f7b0f24edb64 (patch)
tree6d7a6e290f8ed2f2ca250965a8debdd9f02a9cc9 /fs/nfs/nfs4xdr.c
parent1f792dd1765e6f047ecd2d5f6a81f025b50d471a (diff)
parent959d921f5eb8878ea16049a7f6e9bcbb6dfbcb88 (diff)
Merge tag 'nfs-for-3.11-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Feature highlights include: - Add basic client support for NFSv4.2 - Add basic client support for Labeled NFS (selinux for NFSv4.2) - Fix the use of credentials in NFSv4.1 stateful operations, and add support for NFSv4.1 state protection. Bugfix highlights: - Fix another NFSv4 open state recovery race - Fix an NFSv4.1 back channel session regression - Various rpc_pipefs races - Fix another issue with NFSv3 auth negotiation Please note that Labeled NFS does require some additional support from the security subsystem. The relevant changesets have all been reviewed and acked by James Morris." * tag 'nfs-for-3.11-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (54 commits) NFS: Set NFS_CS_MIGRATION for NFSv4 mounts NFSv4.1 Refactor nfs4_init_session and nfs4_init_channel_attrs nfs: have NFSv3 try server-specified auth flavors in turn nfs: have nfs_mount fake up a auth_flavs list when the server didn't provide it nfs: move server_authlist into nfs_try_mount_request nfs: refactor "need_mount" code out of nfs_try_mount SUNRPC: PipeFS MOUNT notification optimization for dying clients SUNRPC: split client creation routine into setup and registration SUNRPC: fix races on PipeFS UMOUNT notifications SUNRPC: fix races on PipeFS MOUNT notifications NFSv4.1 use pnfs_device maxcount for the objectlayout gdia_maxcount NFSv4.1 use pnfs_device maxcount for the blocklayout gdia_maxcount NFSv4.1 Fix gdia_maxcount calculation to fit in ca_maxresponsesize NFS: Improve legacy idmapping fallback NFSv4.1 end back channel session draining NFS: Apply v4.1 capabilities to v4.2 NFSv4.1: Clean up layout segment comparison helper names NFSv4.1: layout segment comparison helpers should take 'const' parameters NFSv4: Move the DNS resolver into the NFSv4 module rpc_pipefs: only set rpc_dentry_ops if d_op isn't already set ...
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c182
1 files changed, 144 insertions, 38 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 4be8d135ed61..0abfb8466e79 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -102,12 +102,23 @@ static int nfs4_stat_to_errno(int);
102#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) 102#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
103#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 103#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
104#define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 104#define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
105#ifdef CONFIG_NFS_V4_SECURITY_LABEL
106/* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */
107#define nfs4_label_maxsz (4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN))
108#define encode_readdir_space 24
109#define encode_readdir_bitmask_sz 3
110#else
111#define nfs4_label_maxsz 0
112#define encode_readdir_space 20
113#define encode_readdir_bitmask_sz 2
114#endif
105/* We support only one layout type per file system */ 115/* We support only one layout type per file system */
106#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) 116#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8)
107/* This is based on getfattr, which uses the most attributes: */ 117/* This is based on getfattr, which uses the most attributes: */
108#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ 118#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
109 3 + 3 + 3 + nfs4_owner_maxsz + \ 119 3 + 3 + 3 + nfs4_owner_maxsz + \
110 nfs4_group_maxsz + decode_mdsthreshold_maxsz)) 120 nfs4_group_maxsz + nfs4_label_maxsz + \
121 decode_mdsthreshold_maxsz))
111#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ 122#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
112 nfs4_fattr_value_maxsz) 123 nfs4_fattr_value_maxsz)
113#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) 124#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
@@ -115,6 +126,7 @@ static int nfs4_stat_to_errno(int);
115 1 + 2 + 1 + \ 126 1 + 2 + 1 + \
116 nfs4_owner_maxsz + \ 127 nfs4_owner_maxsz + \
117 nfs4_group_maxsz + \ 128 nfs4_group_maxsz + \
129 nfs4_label_maxsz + \
118 4 + 4) 130 4 + 4)
119#define encode_savefh_maxsz (op_encode_hdr_maxsz) 131#define encode_savefh_maxsz (op_encode_hdr_maxsz)
120#define decode_savefh_maxsz (op_decode_hdr_maxsz) 132#define decode_savefh_maxsz (op_decode_hdr_maxsz)
@@ -192,9 +204,11 @@ static int nfs4_stat_to_errno(int);
192 encode_stateid_maxsz + 3) 204 encode_stateid_maxsz + 3)
193#define decode_read_maxsz (op_decode_hdr_maxsz + 2) 205#define decode_read_maxsz (op_decode_hdr_maxsz + 2)
194#define encode_readdir_maxsz (op_encode_hdr_maxsz + \ 206#define encode_readdir_maxsz (op_encode_hdr_maxsz + \
195 2 + encode_verifier_maxsz + 5) 207 2 + encode_verifier_maxsz + 5 + \
208 nfs4_label_maxsz)
196#define decode_readdir_maxsz (op_decode_hdr_maxsz + \ 209#define decode_readdir_maxsz (op_decode_hdr_maxsz + \
197 decode_verifier_maxsz) 210 decode_verifier_maxsz + \
211 nfs4_label_maxsz + nfs4_fattr_maxsz)
198#define encode_readlink_maxsz (op_encode_hdr_maxsz) 212#define encode_readlink_maxsz (op_encode_hdr_maxsz)
199#define decode_readlink_maxsz (op_decode_hdr_maxsz + 1) 213#define decode_readlink_maxsz (op_decode_hdr_maxsz + 1)
200#define encode_write_maxsz (op_encode_hdr_maxsz + \ 214#define encode_write_maxsz (op_encode_hdr_maxsz + \
@@ -853,6 +867,12 @@ const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
853 decode_sequence_maxsz + 867 decode_sequence_maxsz +
854 decode_putfh_maxsz) * 868 decode_putfh_maxsz) *
855 XDR_UNIT); 869 XDR_UNIT);
870
871const u32 nfs41_maxgetdevinfo_overhead = ((RPC_MAX_REPHEADER_WITH_AUTH +
872 compound_decode_hdr_maxsz +
873 decode_sequence_maxsz) *
874 XDR_UNIT);
875EXPORT_SYMBOL_GPL(nfs41_maxgetdevinfo_overhead);
856#endif /* CONFIG_NFS_V4_1 */ 876#endif /* CONFIG_NFS_V4_1 */
857 877
858static const umode_t nfs_type2fmt[] = { 878static const umode_t nfs_type2fmt[] = {
@@ -968,7 +988,9 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
968 encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); 988 encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE);
969} 989}
970 990
971static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server) 991static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
992 const struct nfs4_label *label,
993 const struct nfs_server *server)
972{ 994{
973 char owner_name[IDMAP_NAMESZ]; 995 char owner_name[IDMAP_NAMESZ];
974 char owner_group[IDMAP_NAMESZ]; 996 char owner_group[IDMAP_NAMESZ];
@@ -979,15 +1001,16 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
979 int len; 1001 int len;
980 uint32_t bmval0 = 0; 1002 uint32_t bmval0 = 0;
981 uint32_t bmval1 = 0; 1003 uint32_t bmval1 = 0;
1004 uint32_t bmval2 = 0;
982 1005
983 /* 1006 /*
984 * We reserve enough space to write the entire attribute buffer at once. 1007 * We reserve enough space to write the entire attribute buffer at once.
985 * In the worst-case, this would be 1008 * In the worst-case, this would be
986 * 12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) 1009 * 16(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
987 * = 36 bytes, plus any contribution from variable-length fields 1010 * = 40 bytes, plus any contribution from variable-length fields
988 * such as owner/group. 1011 * such as owner/group.
989 */ 1012 */
990 len = 16; 1013 len = 20;
991 1014
992 /* Sigh */ 1015 /* Sigh */
993 if (iap->ia_valid & ATTR_SIZE) 1016 if (iap->ia_valid & ATTR_SIZE)
@@ -1017,6 +1040,8 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
1017 } 1040 }
1018 len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); 1041 len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);
1019 } 1042 }
1043 if (label)
1044 len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);
1020 if (iap->ia_valid & ATTR_ATIME_SET) 1045 if (iap->ia_valid & ATTR_ATIME_SET)
1021 len += 16; 1046 len += 16;
1022 else if (iap->ia_valid & ATTR_ATIME) 1047 else if (iap->ia_valid & ATTR_ATIME)
@@ -1031,9 +1056,9 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
1031 * We write the bitmap length now, but leave the bitmap and the attribute 1056 * We write the bitmap length now, but leave the bitmap and the attribute
1032 * buffer length to be backfilled at the end of this routine. 1057 * buffer length to be backfilled at the end of this routine.
1033 */ 1058 */
1034 *p++ = cpu_to_be32(2); 1059 *p++ = cpu_to_be32(3);
1035 q = p; 1060 q = p;
1036 p += 3; 1061 p += 4;
1037 1062
1038 if (iap->ia_valid & ATTR_SIZE) { 1063 if (iap->ia_valid & ATTR_SIZE) {
1039 bmval0 |= FATTR4_WORD0_SIZE; 1064 bmval0 |= FATTR4_WORD0_SIZE;
@@ -1071,6 +1096,13 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
1071 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; 1096 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
1072 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); 1097 *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1073 } 1098 }
1099 if (label) {
1100 bmval2 |= FATTR4_WORD2_SECURITY_LABEL;
1101 *p++ = cpu_to_be32(label->lfs);
1102 *p++ = cpu_to_be32(label->pi);
1103 *p++ = cpu_to_be32(label->len);
1104 p = xdr_encode_opaque_fixed(p, label->label, label->len);
1105 }
1074 1106
1075 /* 1107 /*
1076 * Now we backfill the bitmap and the attribute buffer length. 1108 * Now we backfill the bitmap and the attribute buffer length.
@@ -1080,9 +1112,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
1080 len, ((char *)p - (char *)q) + 4); 1112 len, ((char *)p - (char *)q) + 4);
1081 BUG(); 1113 BUG();
1082 } 1114 }
1083 len = (char *)p - (char *)q - 12; 1115 len = (char *)p - (char *)q - 16;
1084 *q++ = htonl(bmval0); 1116 *q++ = htonl(bmval0);
1085 *q++ = htonl(bmval1); 1117 *q++ = htonl(bmval1);
1118 *q++ = htonl(bmval2);
1086 *q = htonl(len); 1119 *q = htonl(len);
1087 1120
1088/* out: */ 1121/* out: */
@@ -1136,7 +1169,7 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
1136 } 1169 }
1137 1170
1138 encode_string(xdr, create->name->len, create->name->name); 1171 encode_string(xdr, create->name->len, create->name->name);
1139 encode_attrs(xdr, create->attrs, create->server); 1172 encode_attrs(xdr, create->attrs, create->label, create->server);
1140} 1173}
1141 1174
1142static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) 1175static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr)
@@ -1188,8 +1221,10 @@ encode_getattr_three(struct xdr_stream *xdr,
1188 1221
1189static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1222static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1190{ 1223{
1191 encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], 1224 encode_getattr_three(xdr, bitmask[0] & nfs4_fattr_bitmap[0],
1192 bitmask[1] & nfs4_fattr_bitmap[1], hdr); 1225 bitmask[1] & nfs4_fattr_bitmap[1],
1226 bitmask[2] & nfs4_fattr_bitmap[2],
1227 hdr);
1193} 1228}
1194 1229
1195static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, 1230static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,
@@ -1367,11 +1402,11 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
1367 switch(arg->createmode) { 1402 switch(arg->createmode) {
1368 case NFS4_CREATE_UNCHECKED: 1403 case NFS4_CREATE_UNCHECKED:
1369 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); 1404 *p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
1370 encode_attrs(xdr, arg->u.attrs, arg->server); 1405 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server);
1371 break; 1406 break;
1372 case NFS4_CREATE_GUARDED: 1407 case NFS4_CREATE_GUARDED:
1373 *p = cpu_to_be32(NFS4_CREATE_GUARDED); 1408 *p = cpu_to_be32(NFS4_CREATE_GUARDED);
1374 encode_attrs(xdr, arg->u.attrs, arg->server); 1409 encode_attrs(xdr, arg->u.attrs, arg->label, arg->server);
1375 break; 1410 break;
1376 case NFS4_CREATE_EXCLUSIVE: 1411 case NFS4_CREATE_EXCLUSIVE:
1377 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); 1412 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
@@ -1381,7 +1416,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
1381 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); 1416 *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
1382 encode_nfs4_verifier(xdr, &arg->u.verifier); 1417 encode_nfs4_verifier(xdr, &arg->u.verifier);
1383 dummy.ia_valid = 0; 1418 dummy.ia_valid = 0;
1384 encode_attrs(xdr, &dummy, arg->server); 1419 encode_attrs(xdr, &dummy, arg->label, arg->server);
1385 } 1420 }
1386} 1421}
1387 1422
@@ -1532,7 +1567,7 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
1532 1567
1533static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 1568static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
1534{ 1569{
1535 uint32_t attrs[2] = { 1570 uint32_t attrs[3] = {
1536 FATTR4_WORD0_RDATTR_ERROR, 1571 FATTR4_WORD0_RDATTR_ERROR,
1537 FATTR4_WORD1_MOUNTED_ON_FILEID, 1572 FATTR4_WORD1_MOUNTED_ON_FILEID,
1538 }; 1573 };
@@ -1555,20 +1590,26 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1555 encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr); 1590 encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr);
1556 encode_uint64(xdr, readdir->cookie); 1591 encode_uint64(xdr, readdir->cookie);
1557 encode_nfs4_verifier(xdr, &readdir->verifier); 1592 encode_nfs4_verifier(xdr, &readdir->verifier);
1558 p = reserve_space(xdr, 20); 1593 p = reserve_space(xdr, encode_readdir_space);
1559 *p++ = cpu_to_be32(dircount); 1594 *p++ = cpu_to_be32(dircount);
1560 *p++ = cpu_to_be32(readdir->count); 1595 *p++ = cpu_to_be32(readdir->count);
1561 *p++ = cpu_to_be32(2); 1596 *p++ = cpu_to_be32(encode_readdir_bitmask_sz);
1562
1563 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); 1597 *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]);
1564 *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]); 1598 *p = cpu_to_be32(attrs[1] & readdir->bitmask[1]);
1599 if (encode_readdir_bitmask_sz > 2) {
1600 if (hdr->minorversion > 1)
1601 attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
1602 p++, *p++ = cpu_to_be32(attrs[2] & readdir->bitmask[2]);
1603 }
1565 memcpy(verf, readdir->verifier.data, sizeof(verf)); 1604 memcpy(verf, readdir->verifier.data, sizeof(verf));
1566 dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", 1605
1606 dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n",
1567 __func__, 1607 __func__,
1568 (unsigned long long)readdir->cookie, 1608 (unsigned long long)readdir->cookie,
1569 verf[0], verf[1], 1609 verf[0], verf[1],
1570 attrs[0] & readdir->bitmask[0], 1610 attrs[0] & readdir->bitmask[0],
1571 attrs[1] & readdir->bitmask[1]); 1611 attrs[1] & readdir->bitmask[1],
1612 attrs[2] & readdir->bitmask[2]);
1572} 1613}
1573 1614
1574static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr) 1615static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr)
@@ -1627,7 +1668,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
1627{ 1668{
1628 encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); 1669 encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr);
1629 encode_nfs4_stateid(xdr, &arg->stateid); 1670 encode_nfs4_stateid(xdr, &arg->stateid);
1630 encode_attrs(xdr, arg->iap, server); 1671 encode_attrs(xdr, arg->iap, arg->label, server);
1631} 1672}
1632 1673
1633static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) 1674static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
@@ -1889,7 +1930,7 @@ encode_getdeviceinfo(struct xdr_stream *xdr,
1889 p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data, 1930 p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data,
1890 NFS4_DEVICEID4_SIZE); 1931 NFS4_DEVICEID4_SIZE);
1891 *p++ = cpu_to_be32(args->pdev->layout_type); 1932 *p++ = cpu_to_be32(args->pdev->layout_type);
1892 *p++ = cpu_to_be32(args->pdev->pglen); /* gdia_maxcount */ 1933 *p++ = cpu_to_be32(args->pdev->maxcount); /* gdia_maxcount */
1893 *p++ = cpu_to_be32(0); /* bitmap length 0 */ 1934 *p++ = cpu_to_be32(0); /* bitmap length 0 */
1894} 1935}
1895 1936
@@ -4038,6 +4079,56 @@ static int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap,
4038 return status; 4079 return status;
4039} 4080}
4040 4081
4082static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
4083 struct nfs4_label *label)
4084{
4085 uint32_t pi = 0;
4086 uint32_t lfs = 0;
4087 __u32 len;
4088 __be32 *p;
4089 int status = 0;
4090
4091 if (unlikely(bitmap[2] & (FATTR4_WORD2_SECURITY_LABEL - 1U)))
4092 return -EIO;
4093 if (likely(bitmap[2] & FATTR4_WORD2_SECURITY_LABEL)) {
4094 p = xdr_inline_decode(xdr, 4);
4095 if (unlikely(!p))
4096 goto out_overflow;
4097 lfs = be32_to_cpup(p++);
4098 p = xdr_inline_decode(xdr, 4);
4099 if (unlikely(!p))
4100 goto out_overflow;
4101 pi = be32_to_cpup(p++);
4102 p = xdr_inline_decode(xdr, 4);
4103 if (unlikely(!p))
4104 goto out_overflow;
4105 len = be32_to_cpup(p++);
4106 p = xdr_inline_decode(xdr, len);
4107 if (unlikely(!p))
4108 goto out_overflow;
4109 if (len < NFS4_MAXLABELLEN) {
4110 if (label) {
4111 memcpy(label->label, p, len);
4112 label->len = len;
4113 label->pi = pi;
4114 label->lfs = lfs;
4115 status = NFS_ATTR_FATTR_V4_SECURITY_LABEL;
4116 }
4117 bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
4118 } else
4119 printk(KERN_WARNING "%s: label too long (%u)!\n",
4120 __func__, len);
4121 }
4122 if (label && label->label)
4123 dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__,
4124 (char *)label->label, label->len, label->pi, label->lfs);
4125 return status;
4126
4127out_overflow:
4128 print_overflow_msg(__func__, xdr);
4129 return -EIO;
4130}
4131
4041static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) 4132static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
4042{ 4133{
4043 int status = 0; 4134 int status = 0;
@@ -4380,7 +4471,7 @@ out_overflow:
4380 4471
4381static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, 4472static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4382 struct nfs_fattr *fattr, struct nfs_fh *fh, 4473 struct nfs_fattr *fattr, struct nfs_fh *fh,
4383 struct nfs4_fs_locations *fs_loc, 4474 struct nfs4_fs_locations *fs_loc, struct nfs4_label *label,
4384 const struct nfs_server *server) 4475 const struct nfs_server *server)
4385{ 4476{
4386 int status; 4477 int status;
@@ -4488,6 +4579,13 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4488 if (status < 0) 4579 if (status < 0)
4489 goto xdr_error; 4580 goto xdr_error;
4490 4581
4582 if (label) {
4583 status = decode_attr_security_label(xdr, bitmap, label);
4584 if (status < 0)
4585 goto xdr_error;
4586 fattr->valid |= status;
4587 }
4588
4491xdr_error: 4589xdr_error:
4492 dprintk("%s: xdr returned %d\n", __func__, -status); 4590 dprintk("%s: xdr returned %d\n", __func__, -status);
4493 return status; 4591 return status;
@@ -4495,7 +4593,7 @@ xdr_error:
4495 4593
4496static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr, 4594static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4497 struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc, 4595 struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc,
4498 const struct nfs_server *server) 4596 struct nfs4_label *label, const struct nfs_server *server)
4499{ 4597{
4500 unsigned int savep; 4598 unsigned int savep;
4501 uint32_t attrlen, 4599 uint32_t attrlen,
@@ -4514,7 +4612,8 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
4514 if (status < 0) 4612 if (status < 0)
4515 goto xdr_error; 4613 goto xdr_error;
4516 4614
4517 status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, server); 4615 status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc,
4616 label, server);
4518 if (status < 0) 4617 if (status < 0)
4519 goto xdr_error; 4618 goto xdr_error;
4520 4619
@@ -4524,10 +4623,16 @@ xdr_error:
4524 return status; 4623 return status;
4525} 4624}
4526 4625
4626static int decode_getfattr_label(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4627 struct nfs4_label *label, const struct nfs_server *server)
4628{
4629 return decode_getfattr_generic(xdr, fattr, NULL, NULL, label, server);
4630}
4631
4527static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, 4632static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
4528 const struct nfs_server *server) 4633 const struct nfs_server *server)
4529{ 4634{
4530 return decode_getfattr_generic(xdr, fattr, NULL, NULL, server); 4635 return decode_getfattr_generic(xdr, fattr, NULL, NULL, NULL, server);
4531} 4636}
4532 4637
4533/* 4638/*
@@ -5919,7 +6024,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5919 status = decode_getfh(xdr, res->fh); 6024 status = decode_getfh(xdr, res->fh);
5920 if (status) 6025 if (status)
5921 goto out; 6026 goto out;
5922 status = decode_getfattr(xdr, res->fattr, res->server); 6027 status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
5923out: 6028out:
5924 return status; 6029 return status;
5925} 6030}
@@ -5945,7 +6050,8 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
5945 goto out; 6050 goto out;
5946 status = decode_getfh(xdr, res->fh); 6051 status = decode_getfh(xdr, res->fh);
5947 if (status == 0) 6052 if (status == 0)
5948 status = decode_getfattr(xdr, res->fattr, res->server); 6053 status = decode_getfattr_label(xdr, res->fattr,
6054 res->label, res->server);
5949out: 6055out:
5950 return status; 6056 return status;
5951} 6057}
@@ -6036,7 +6142,7 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6036 status = decode_restorefh(xdr); 6142 status = decode_restorefh(xdr);
6037 if (status) 6143 if (status)
6038 goto out; 6144 goto out;
6039 decode_getfattr(xdr, res->fattr, res->server); 6145 decode_getfattr_label(xdr, res->fattr, res->label, res->server);
6040out: 6146out:
6041 return status; 6147 return status;
6042} 6148}
@@ -6065,7 +6171,7 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6065 status = decode_getfh(xdr, res->fh); 6171 status = decode_getfh(xdr, res->fh);
6066 if (status) 6172 if (status)
6067 goto out; 6173 goto out;
6068 decode_getfattr(xdr, res->fattr, res->server); 6174 decode_getfattr_label(xdr, res->fattr, res->label, res->server);
6069out: 6175out:
6070 return status; 6176 return status;
6071} 6177}
@@ -6097,7 +6203,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6097 status = decode_putfh(xdr); 6203 status = decode_putfh(xdr);
6098 if (status) 6204 if (status)
6099 goto out; 6205 goto out;
6100 status = decode_getfattr(xdr, res->fattr, res->server); 6206 status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
6101out: 6207out:
6102 return status; 6208 return status;
6103} 6209}
@@ -6230,7 +6336,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6230 goto out; 6336 goto out;
6231 if (res->access_request) 6337 if (res->access_request)
6232 decode_access(xdr, &res->access_supported, &res->access_result); 6338 decode_access(xdr, &res->access_supported, &res->access_result);
6233 decode_getfattr(xdr, res->f_attr, res->server); 6339 decode_getfattr_label(xdr, res->f_attr, res->f_label, res->server);
6234out: 6340out:
6235 return status; 6341 return status;
6236} 6342}
@@ -6307,7 +6413,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp,
6307 status = decode_setattr(xdr); 6413 status = decode_setattr(xdr);
6308 if (status) 6414 if (status)
6309 goto out; 6415 goto out;
6310 decode_getfattr(xdr, res->fattr, res->server); 6416 decode_getfattr_label(xdr, res->fattr, res->label, res->server);
6311out: 6417out:
6312 return status; 6418 return status;
6313} 6419}
@@ -6696,7 +6802,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
6696 xdr_enter_page(xdr, PAGE_SIZE); 6802 xdr_enter_page(xdr, PAGE_SIZE);
6697 status = decode_getfattr_generic(xdr, &res->fs_locations->fattr, 6803 status = decode_getfattr_generic(xdr, &res->fs_locations->fattr,
6698 NULL, res->fs_locations, 6804 NULL, res->fs_locations,
6699 res->fs_locations->server); 6805 NULL, res->fs_locations->server);
6700out: 6806out:
6701 return status; 6807 return status;
6702} 6808}
@@ -7109,7 +7215,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
7109 goto out_overflow; 7215 goto out_overflow;
7110 7216
7111 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, 7217 if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
7112 NULL, entry->server) < 0) 7218 NULL, entry->label, entry->server) < 0)
7113 goto out_overflow; 7219 goto out_overflow;
7114 if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) 7220 if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
7115 entry->ino = entry->fattr->mounted_on_fileid; 7221 entry->ino = entry->fattr->mounted_on_fileid;