diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-06-28 16:29:51 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-06-28 16:29:51 -0400 |
commit | 959d921f5eb8878ea16049a7f6e9bcbb6dfbcb88 (patch) | |
tree | 83fb4d2756fab97f508b5dccaac7578ba63a76e0 /fs/nfs/nfs4xdr.c | |
parent | f112bb48994e56868870a080773c392f774fa9a2 (diff) | |
parent | 7017310ad737880d8520a7fc7e25a26b2e7e37f0 (diff) |
Merge branch 'labeled-nfs' into linux-next
* labeled-nfs:
NFS: Apply v4.1 capabilities to v4.2
NFS: Add in v4.2 callback operation
NFS: Make callbacks minor version generic
Kconfig: Add Kconfig entry for Labeled NFS V4 client
NFS: Extend NFS xattr handlers to accept the security namespace
NFS: Client implementation of Labeled-NFS
NFS: Add label lifecycle management
NFS:Add labels to client function prototypes
NFSv4: Extend fattr bitmaps to support all 3 words
NFSv4: Introduce new label structure
NFSv4: Add label recommended attribute and NFSv4 flags
NFSv4.2: Added NFS v4.2 support to the NFS client
SELinux: Add new labeling type native labels
LSM: Add flags field to security_sb_set_mnt_opts for in kernel mount data.
Security: Add Hook to test if the particular xattr is part of a MAC model.
Security: Add hook to calculate context based on a negative dentry.
NFS: Add NFSv4.2 protocol constants
Conflicts:
fs/nfs/nfs4proc.c
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 174 |
1 files changed, 137 insertions, 37 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 27cc76d88f9a..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 + \ |
@@ -974,7 +988,9 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve | |||
974 | encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); | 988 | encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); |
975 | } | 989 | } |
976 | 990 | ||
977 | 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) | ||
978 | { | 994 | { |
979 | char owner_name[IDMAP_NAMESZ]; | 995 | char owner_name[IDMAP_NAMESZ]; |
980 | char owner_group[IDMAP_NAMESZ]; | 996 | char owner_group[IDMAP_NAMESZ]; |
@@ -985,15 +1001,16 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
985 | int len; | 1001 | int len; |
986 | uint32_t bmval0 = 0; | 1002 | uint32_t bmval0 = 0; |
987 | uint32_t bmval1 = 0; | 1003 | uint32_t bmval1 = 0; |
1004 | uint32_t bmval2 = 0; | ||
988 | 1005 | ||
989 | /* | 1006 | /* |
990 | * 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. |
991 | * In the worst-case, this would be | 1008 | * In the worst-case, this would be |
992 | * 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) |
993 | * = 36 bytes, plus any contribution from variable-length fields | 1010 | * = 40 bytes, plus any contribution from variable-length fields |
994 | * such as owner/group. | 1011 | * such as owner/group. |
995 | */ | 1012 | */ |
996 | len = 16; | 1013 | len = 20; |
997 | 1014 | ||
998 | /* Sigh */ | 1015 | /* Sigh */ |
999 | if (iap->ia_valid & ATTR_SIZE) | 1016 | if (iap->ia_valid & ATTR_SIZE) |
@@ -1023,6 +1040,8 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1023 | } | 1040 | } |
1024 | len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); | 1041 | len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); |
1025 | } | 1042 | } |
1043 | if (label) | ||
1044 | len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); | ||
1026 | if (iap->ia_valid & ATTR_ATIME_SET) | 1045 | if (iap->ia_valid & ATTR_ATIME_SET) |
1027 | len += 16; | 1046 | len += 16; |
1028 | else if (iap->ia_valid & ATTR_ATIME) | 1047 | else if (iap->ia_valid & ATTR_ATIME) |
@@ -1037,9 +1056,9 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1037 | * 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 |
1038 | * buffer length to be backfilled at the end of this routine. | 1057 | * buffer length to be backfilled at the end of this routine. |
1039 | */ | 1058 | */ |
1040 | *p++ = cpu_to_be32(2); | 1059 | *p++ = cpu_to_be32(3); |
1041 | q = p; | 1060 | q = p; |
1042 | p += 3; | 1061 | p += 4; |
1043 | 1062 | ||
1044 | if (iap->ia_valid & ATTR_SIZE) { | 1063 | if (iap->ia_valid & ATTR_SIZE) { |
1045 | bmval0 |= FATTR4_WORD0_SIZE; | 1064 | bmval0 |= FATTR4_WORD0_SIZE; |
@@ -1077,6 +1096,13 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1077 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; | 1096 | bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; |
1078 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); | 1097 | *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); |
1079 | } | 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 | } | ||
1080 | 1106 | ||
1081 | /* | 1107 | /* |
1082 | * Now we backfill the bitmap and the attribute buffer length. | 1108 | * Now we backfill the bitmap and the attribute buffer length. |
@@ -1086,9 +1112,10 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
1086 | len, ((char *)p - (char *)q) + 4); | 1112 | len, ((char *)p - (char *)q) + 4); |
1087 | BUG(); | 1113 | BUG(); |
1088 | } | 1114 | } |
1089 | len = (char *)p - (char *)q - 12; | 1115 | len = (char *)p - (char *)q - 16; |
1090 | *q++ = htonl(bmval0); | 1116 | *q++ = htonl(bmval0); |
1091 | *q++ = htonl(bmval1); | 1117 | *q++ = htonl(bmval1); |
1118 | *q++ = htonl(bmval2); | ||
1092 | *q = htonl(len); | 1119 | *q = htonl(len); |
1093 | 1120 | ||
1094 | /* out: */ | 1121 | /* out: */ |
@@ -1142,7 +1169,7 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * | |||
1142 | } | 1169 | } |
1143 | 1170 | ||
1144 | encode_string(xdr, create->name->len, create->name->name); | 1171 | encode_string(xdr, create->name->len, create->name->name); |
1145 | encode_attrs(xdr, create->attrs, create->server); | 1172 | encode_attrs(xdr, create->attrs, create->label, create->server); |
1146 | } | 1173 | } |
1147 | 1174 | ||
1148 | 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) |
@@ -1194,8 +1221,10 @@ encode_getattr_three(struct xdr_stream *xdr, | |||
1194 | 1221 | ||
1195 | 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) |
1196 | { | 1223 | { |
1197 | encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], | 1224 | encode_getattr_three(xdr, bitmask[0] & nfs4_fattr_bitmap[0], |
1198 | bitmask[1] & nfs4_fattr_bitmap[1], hdr); | 1225 | bitmask[1] & nfs4_fattr_bitmap[1], |
1226 | bitmask[2] & nfs4_fattr_bitmap[2], | ||
1227 | hdr); | ||
1199 | } | 1228 | } |
1200 | 1229 | ||
1201 | 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, |
@@ -1373,11 +1402,11 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op | |||
1373 | switch(arg->createmode) { | 1402 | switch(arg->createmode) { |
1374 | case NFS4_CREATE_UNCHECKED: | 1403 | case NFS4_CREATE_UNCHECKED: |
1375 | *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); | 1404 | *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); |
1376 | encode_attrs(xdr, arg->u.attrs, arg->server); | 1405 | encode_attrs(xdr, arg->u.attrs, arg->label, arg->server); |
1377 | break; | 1406 | break; |
1378 | case NFS4_CREATE_GUARDED: | 1407 | case NFS4_CREATE_GUARDED: |
1379 | *p = cpu_to_be32(NFS4_CREATE_GUARDED); | 1408 | *p = cpu_to_be32(NFS4_CREATE_GUARDED); |
1380 | encode_attrs(xdr, arg->u.attrs, arg->server); | 1409 | encode_attrs(xdr, arg->u.attrs, arg->label, arg->server); |
1381 | break; | 1410 | break; |
1382 | case NFS4_CREATE_EXCLUSIVE: | 1411 | case NFS4_CREATE_EXCLUSIVE: |
1383 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); | 1412 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); |
@@ -1387,7 +1416,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op | |||
1387 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); | 1416 | *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); |
1388 | encode_nfs4_verifier(xdr, &arg->u.verifier); | 1417 | encode_nfs4_verifier(xdr, &arg->u.verifier); |
1389 | dummy.ia_valid = 0; | 1418 | dummy.ia_valid = 0; |
1390 | encode_attrs(xdr, &dummy, arg->server); | 1419 | encode_attrs(xdr, &dummy, arg->label, arg->server); |
1391 | } | 1420 | } |
1392 | } | 1421 | } |
1393 | 1422 | ||
@@ -1538,7 +1567,7 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, | |||
1538 | 1567 | ||
1539 | 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) |
1540 | { | 1569 | { |
1541 | uint32_t attrs[2] = { | 1570 | uint32_t attrs[3] = { |
1542 | FATTR4_WORD0_RDATTR_ERROR, | 1571 | FATTR4_WORD0_RDATTR_ERROR, |
1543 | FATTR4_WORD1_MOUNTED_ON_FILEID, | 1572 | FATTR4_WORD1_MOUNTED_ON_FILEID, |
1544 | }; | 1573 | }; |
@@ -1561,20 +1590,26 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg | |||
1561 | encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr); | 1590 | encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr); |
1562 | encode_uint64(xdr, readdir->cookie); | 1591 | encode_uint64(xdr, readdir->cookie); |
1563 | encode_nfs4_verifier(xdr, &readdir->verifier); | 1592 | encode_nfs4_verifier(xdr, &readdir->verifier); |
1564 | p = reserve_space(xdr, 20); | 1593 | p = reserve_space(xdr, encode_readdir_space); |
1565 | *p++ = cpu_to_be32(dircount); | 1594 | *p++ = cpu_to_be32(dircount); |
1566 | *p++ = cpu_to_be32(readdir->count); | 1595 | *p++ = cpu_to_be32(readdir->count); |
1567 | *p++ = cpu_to_be32(2); | 1596 | *p++ = cpu_to_be32(encode_readdir_bitmask_sz); |
1568 | |||
1569 | *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); | 1597 | *p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]); |
1570 | *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 | } | ||
1571 | memcpy(verf, readdir->verifier.data, sizeof(verf)); | 1604 | memcpy(verf, readdir->verifier.data, sizeof(verf)); |
1572 | 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", | ||
1573 | __func__, | 1607 | __func__, |
1574 | (unsigned long long)readdir->cookie, | 1608 | (unsigned long long)readdir->cookie, |
1575 | verf[0], verf[1], | 1609 | verf[0], verf[1], |
1576 | attrs[0] & readdir->bitmask[0], | 1610 | attrs[0] & readdir->bitmask[0], |
1577 | attrs[1] & readdir->bitmask[1]); | 1611 | attrs[1] & readdir->bitmask[1], |
1612 | attrs[2] & readdir->bitmask[2]); | ||
1578 | } | 1613 | } |
1579 | 1614 | ||
1580 | 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) |
@@ -1633,7 +1668,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs | |||
1633 | { | 1668 | { |
1634 | encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); | 1669 | encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); |
1635 | encode_nfs4_stateid(xdr, &arg->stateid); | 1670 | encode_nfs4_stateid(xdr, &arg->stateid); |
1636 | encode_attrs(xdr, arg->iap, server); | 1671 | encode_attrs(xdr, arg->iap, arg->label, server); |
1637 | } | 1672 | } |
1638 | 1673 | ||
1639 | 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) |
@@ -4044,6 +4079,56 @@ static int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4044 | return status; | 4079 | return status; |
4045 | } | 4080 | } |
4046 | 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 | |||
4047 | 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) |
4048 | { | 4133 | { |
4049 | int status = 0; | 4134 | int status = 0; |
@@ -4386,7 +4471,7 @@ out_overflow: | |||
4386 | 4471 | ||
4387 | 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, |
4388 | struct nfs_fattr *fattr, struct nfs_fh *fh, | 4473 | struct nfs_fattr *fattr, struct nfs_fh *fh, |
4389 | struct nfs4_fs_locations *fs_loc, | 4474 | struct nfs4_fs_locations *fs_loc, struct nfs4_label *label, |
4390 | const struct nfs_server *server) | 4475 | const struct nfs_server *server) |
4391 | { | 4476 | { |
4392 | int status; | 4477 | int status; |
@@ -4494,6 +4579,13 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4494 | if (status < 0) | 4579 | if (status < 0) |
4495 | goto xdr_error; | 4580 | goto xdr_error; |
4496 | 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 | |||
4497 | xdr_error: | 4589 | xdr_error: |
4498 | dprintk("%s: xdr returned %d\n", __func__, -status); | 4590 | dprintk("%s: xdr returned %d\n", __func__, -status); |
4499 | return status; | 4591 | return status; |
@@ -4501,7 +4593,7 @@ xdr_error: | |||
4501 | 4593 | ||
4502 | 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, |
4503 | struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc, | 4595 | struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc, |
4504 | const struct nfs_server *server) | 4596 | struct nfs4_label *label, const struct nfs_server *server) |
4505 | { | 4597 | { |
4506 | unsigned int savep; | 4598 | unsigned int savep; |
4507 | uint32_t attrlen, | 4599 | uint32_t attrlen, |
@@ -4520,7 +4612,8 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat | |||
4520 | if (status < 0) | 4612 | if (status < 0) |
4521 | goto xdr_error; | 4613 | goto xdr_error; |
4522 | 4614 | ||
4523 | 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); | ||
4524 | if (status < 0) | 4617 | if (status < 0) |
4525 | goto xdr_error; | 4618 | goto xdr_error; |
4526 | 4619 | ||
@@ -4530,10 +4623,16 @@ xdr_error: | |||
4530 | return status; | 4623 | return status; |
4531 | } | 4624 | } |
4532 | 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 | |||
4533 | 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, |
4534 | const struct nfs_server *server) | 4633 | const struct nfs_server *server) |
4535 | { | 4634 | { |
4536 | return decode_getfattr_generic(xdr, fattr, NULL, NULL, server); | 4635 | return decode_getfattr_generic(xdr, fattr, NULL, NULL, NULL, server); |
4537 | } | 4636 | } |
4538 | 4637 | ||
4539 | /* | 4638 | /* |
@@ -5925,7 +6024,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
5925 | status = decode_getfh(xdr, res->fh); | 6024 | status = decode_getfh(xdr, res->fh); |
5926 | if (status) | 6025 | if (status) |
5927 | goto out; | 6026 | goto out; |
5928 | status = decode_getfattr(xdr, res->fattr, res->server); | 6027 | status = decode_getfattr_label(xdr, res->fattr, res->label, res->server); |
5929 | out: | 6028 | out: |
5930 | return status; | 6029 | return status; |
5931 | } | 6030 | } |
@@ -5951,7 +6050,8 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, | |||
5951 | goto out; | 6050 | goto out; |
5952 | status = decode_getfh(xdr, res->fh); | 6051 | status = decode_getfh(xdr, res->fh); |
5953 | if (status == 0) | 6052 | if (status == 0) |
5954 | status = decode_getfattr(xdr, res->fattr, res->server); | 6053 | status = decode_getfattr_label(xdr, res->fattr, |
6054 | res->label, res->server); | ||
5955 | out: | 6055 | out: |
5956 | return status; | 6056 | return status; |
5957 | } | 6057 | } |
@@ -6042,7 +6142,7 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6042 | status = decode_restorefh(xdr); | 6142 | status = decode_restorefh(xdr); |
6043 | if (status) | 6143 | if (status) |
6044 | goto out; | 6144 | goto out; |
6045 | decode_getfattr(xdr, res->fattr, res->server); | 6145 | decode_getfattr_label(xdr, res->fattr, res->label, res->server); |
6046 | out: | 6146 | out: |
6047 | return status; | 6147 | return status; |
6048 | } | 6148 | } |
@@ -6071,7 +6171,7 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6071 | status = decode_getfh(xdr, res->fh); | 6171 | status = decode_getfh(xdr, res->fh); |
6072 | if (status) | 6172 | if (status) |
6073 | goto out; | 6173 | goto out; |
6074 | decode_getfattr(xdr, res->fattr, res->server); | 6174 | decode_getfattr_label(xdr, res->fattr, res->label, res->server); |
6075 | out: | 6175 | out: |
6076 | return status; | 6176 | return status; |
6077 | } | 6177 | } |
@@ -6103,7 +6203,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6103 | status = decode_putfh(xdr); | 6203 | status = decode_putfh(xdr); |
6104 | if (status) | 6204 | if (status) |
6105 | goto out; | 6205 | goto out; |
6106 | status = decode_getfattr(xdr, res->fattr, res->server); | 6206 | status = decode_getfattr_label(xdr, res->fattr, res->label, res->server); |
6107 | out: | 6207 | out: |
6108 | return status; | 6208 | return status; |
6109 | } | 6209 | } |
@@ -6236,7 +6336,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
6236 | goto out; | 6336 | goto out; |
6237 | if (res->access_request) | 6337 | if (res->access_request) |
6238 | decode_access(xdr, &res->access_supported, &res->access_result); | 6338 | decode_access(xdr, &res->access_supported, &res->access_result); |
6239 | decode_getfattr(xdr, res->f_attr, res->server); | 6339 | decode_getfattr_label(xdr, res->f_attr, res->f_label, res->server); |
6240 | out: | 6340 | out: |
6241 | return status; | 6341 | return status; |
6242 | } | 6342 | } |
@@ -6313,7 +6413,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, | |||
6313 | status = decode_setattr(xdr); | 6413 | status = decode_setattr(xdr); |
6314 | if (status) | 6414 | if (status) |
6315 | goto out; | 6415 | goto out; |
6316 | decode_getfattr(xdr, res->fattr, res->server); | 6416 | decode_getfattr_label(xdr, res->fattr, res->label, res->server); |
6317 | out: | 6417 | out: |
6318 | return status; | 6418 | return status; |
6319 | } | 6419 | } |
@@ -6702,7 +6802,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, | |||
6702 | xdr_enter_page(xdr, PAGE_SIZE); | 6802 | xdr_enter_page(xdr, PAGE_SIZE); |
6703 | status = decode_getfattr_generic(xdr, &res->fs_locations->fattr, | 6803 | status = decode_getfattr_generic(xdr, &res->fs_locations->fattr, |
6704 | NULL, res->fs_locations, | 6804 | NULL, res->fs_locations, |
6705 | res->fs_locations->server); | 6805 | NULL, res->fs_locations->server); |
6706 | out: | 6806 | out: |
6707 | return status; | 6807 | return status; |
6708 | } | 6808 | } |
@@ -7115,7 +7215,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
7115 | goto out_overflow; | 7215 | goto out_overflow; |
7116 | 7216 | ||
7117 | if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, | 7217 | if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, |
7118 | NULL, entry->server) < 0) | 7218 | NULL, entry->label, entry->server) < 0) |
7119 | goto out_overflow; | 7219 | goto out_overflow; |
7120 | if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) | 7220 | if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) |
7121 | entry->ino = entry->fattr->mounted_on_fileid; | 7221 | entry->ino = entry->fattr->mounted_on_fileid; |