diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 182 |
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 | |||
871 | const u32 nfs41_maxgetdevinfo_overhead = ((RPC_MAX_REPHEADER_WITH_AUTH + | ||
872 | compound_decode_hdr_maxsz + | ||
873 | decode_sequence_maxsz) * | ||
874 | XDR_UNIT); | ||
875 | EXPORT_SYMBOL_GPL(nfs41_maxgetdevinfo_overhead); | ||
856 | #endif /* CONFIG_NFS_V4_1 */ | 876 | #endif /* CONFIG_NFS_V4_1 */ |
857 | 877 | ||
858 | static const umode_t nfs_type2fmt[] = { | 878 | static 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 | ||
971 | static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server) | 991 | static 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 | ||
1142 | static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) | 1175 | static 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 | ||
1189 | static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1222 | static 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 | ||
1195 | static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, | 1230 | static 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 | ||
1533 | static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) | 1568 | static 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 | ||
1574 | static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr) | 1615 | static 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 | ||
1633 | static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) | 1674 | static 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 | ||
4082 | static 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 | |||
4127 | out_overflow: | ||
4128 | print_overflow_msg(__func__, xdr); | ||
4129 | return -EIO; | ||
4130 | } | ||
4131 | |||
4041 | static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) | 4132 | static 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 | ||
4381 | static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | 4472 | static 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 | |||
4491 | xdr_error: | 4589 | xdr_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 | ||
4496 | static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr, | 4594 | static 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 | ||
4626 | static 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 | |||
4527 | static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, | 4632 | static 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); |
5923 | out: | 6028 | out: |
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); | ||
5949 | out: | 6055 | out: |
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); |
6040 | out: | 6146 | out: |
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); |
6069 | out: | 6175 | out: |
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); |
6101 | out: | 6207 | out: |
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); |
6234 | out: | 6340 | out: |
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); |
6311 | out: | 6417 | out: |
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); |
6700 | out: | 6806 | out: |
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; |