summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2018-03-20 17:03:08 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2018-04-10 16:06:22 -0400
commit37c88763def8474bc0972fbd1adb0d21670104b7 (patch)
tree95a7e8b02256015ec220bc09eae30796daf73e7d /fs/nfs/nfs4xdr.c
parente8d8aa46be413930fb3e084f9a7e815f87f72f1f (diff)
NFSv4; Clean up XDR encoding of type bitmap4
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c166
1 files changed, 72 insertions, 94 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 6b08f6b1addf..80c5b519fd6a 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -958,6 +958,35 @@ static void encode_uint64(struct xdr_stream *xdr, u64 n)
958 WARN_ON_ONCE(xdr_stream_encode_u64(xdr, n) < 0); 958 WARN_ON_ONCE(xdr_stream_encode_u64(xdr, n) < 0);
959} 959}
960 960
961static ssize_t xdr_encode_bitmap4(struct xdr_stream *xdr,
962 const __u32 *bitmap, size_t len)
963{
964 ssize_t ret;
965
966 /* Trim empty words */
967 while (len > 0 && bitmap[len-1] == 0)
968 len--;
969 ret = xdr_stream_encode_uint32_array(xdr, bitmap, len);
970 if (WARN_ON_ONCE(ret < 0))
971 return ret;
972 return len;
973}
974
975static size_t mask_bitmap4(const __u32 *bitmap, const __u32 *mask,
976 __u32 *res, size_t len)
977{
978 size_t i;
979 __u32 tmp;
980
981 while (len > 0 && (bitmap[len-1] == 0 || mask[len-1] == 0))
982 len--;
983 for (i = len; i-- > 0;) {
984 tmp = bitmap[i] & mask[i];
985 res[i] = tmp;
986 }
987 return len;
988}
989
961static void encode_nfs4_seqid(struct xdr_stream *xdr, 990static void encode_nfs4_seqid(struct xdr_stream *xdr,
962 const struct nfs_seqid *seqid) 991 const struct nfs_seqid *seqid)
963{ 992{
@@ -1200,85 +1229,45 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
1200 create->server, create->server->attr_bitmask); 1229 create->server, create->server->attr_bitmask);
1201} 1230}
1202 1231
1203static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr) 1232static void encode_getattr(struct xdr_stream *xdr,
1204{ 1233 const __u32 *bitmap, const __u32 *mask, size_t len,
1205 __be32 *p; 1234 struct compound_hdr *hdr)
1206
1207 encode_op_hdr(xdr, OP_GETATTR, decode_getattr_maxsz, hdr);
1208 p = reserve_space(xdr, 8);
1209 *p++ = cpu_to_be32(1);
1210 *p = cpu_to_be32(bitmap);
1211}
1212
1213static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr)
1214{
1215 __be32 *p;
1216
1217 encode_op_hdr(xdr, OP_GETATTR, decode_getattr_maxsz, hdr);
1218 p = reserve_space(xdr, 12);
1219 *p++ = cpu_to_be32(2);
1220 *p++ = cpu_to_be32(bm0);
1221 *p = cpu_to_be32(bm1);
1222}
1223
1224static void
1225encode_getattr_three(struct xdr_stream *xdr,
1226 uint32_t bm0, uint32_t bm1, uint32_t bm2,
1227 struct compound_hdr *hdr)
1228{ 1235{
1229 __be32 *p; 1236 __u32 masked_bitmap[nfs4_fattr_bitmap_maxsz];
1230 1237
1231 encode_op_hdr(xdr, OP_GETATTR, decode_getattr_maxsz, hdr); 1238 encode_op_hdr(xdr, OP_GETATTR, decode_getattr_maxsz, hdr);
1232 if (bm2) { 1239 if (mask) {
1233 p = reserve_space(xdr, 16); 1240 if (WARN_ON_ONCE(len > ARRAY_SIZE(masked_bitmap)))
1234 *p++ = cpu_to_be32(3); 1241 len = ARRAY_SIZE(masked_bitmap);
1235 *p++ = cpu_to_be32(bm0); 1242 len = mask_bitmap4(bitmap, mask, masked_bitmap, len);
1236 *p++ = cpu_to_be32(bm1); 1243 bitmap = masked_bitmap;
1237 *p = cpu_to_be32(bm2);
1238 } else if (bm1) {
1239 p = reserve_space(xdr, 12);
1240 *p++ = cpu_to_be32(2);
1241 *p++ = cpu_to_be32(bm0);
1242 *p = cpu_to_be32(bm1);
1243 } else {
1244 p = reserve_space(xdr, 8);
1245 *p++ = cpu_to_be32(1);
1246 *p = cpu_to_be32(bm0);
1247 } 1244 }
1245 xdr_encode_bitmap4(xdr, bitmap, len);
1248} 1246}
1249 1247
1250static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1248static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1251{ 1249{
1252 encode_getattr_three(xdr, bitmask[0] & nfs4_fattr_bitmap[0], 1250 encode_getattr(xdr, nfs4_fattr_bitmap, bitmask,
1253 bitmask[1] & nfs4_fattr_bitmap[1], 1251 ARRAY_SIZE(nfs4_fattr_bitmap), hdr);
1254 bitmask[2] & nfs4_fattr_bitmap[2],
1255 hdr);
1256} 1252}
1257 1253
1258static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, 1254static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,
1259 const u32 *open_bitmap, 1255 const u32 *open_bitmap,
1260 struct compound_hdr *hdr) 1256 struct compound_hdr *hdr)
1261{ 1257{
1262 encode_getattr_three(xdr, 1258 encode_getattr(xdr, open_bitmap, bitmask, 3, hdr);
1263 bitmask[0] & open_bitmap[0],
1264 bitmask[1] & open_bitmap[1],
1265 bitmask[2] & open_bitmap[2],
1266 hdr);
1267} 1259}
1268 1260
1269static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1261static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1270{ 1262{
1271 encode_getattr_three(xdr, 1263 encode_getattr(xdr, nfs4_fsinfo_bitmap, bitmask,
1272 bitmask[0] & nfs4_fsinfo_bitmap[0], 1264 ARRAY_SIZE(nfs4_fsinfo_bitmap), hdr);
1273 bitmask[1] & nfs4_fsinfo_bitmap[1],
1274 bitmask[2] & nfs4_fsinfo_bitmap[2],
1275 hdr);
1276} 1265}
1277 1266
1278static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1267static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1279{ 1268{
1280 encode_getattr_two(xdr, bitmask[0] & nfs4_fs_locations_bitmap[0], 1269 encode_getattr(xdr, nfs4_fs_locations_bitmap, bitmask,
1281 bitmask[1] & nfs4_fs_locations_bitmap[1], hdr); 1270 ARRAY_SIZE(nfs4_fs_locations_bitmap), hdr);
1282} 1271}
1283 1272
1284static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr) 1273static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
@@ -2559,13 +2548,17 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
2559 struct compound_hdr hdr = { 2548 struct compound_hdr hdr = {
2560 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 2549 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2561 }; 2550 };
2551 const __u32 nfs4_acl_bitmap[1] = {
2552 [0] = FATTR4_WORD0_ACL,
2553 };
2562 uint32_t replen; 2554 uint32_t replen;
2563 2555
2564 encode_compound_hdr(xdr, req, &hdr); 2556 encode_compound_hdr(xdr, req, &hdr);
2565 encode_sequence(xdr, &args->seq_args, &hdr); 2557 encode_sequence(xdr, &args->seq_args, &hdr);
2566 encode_putfh(xdr, args->fh, &hdr); 2558 encode_putfh(xdr, args->fh, &hdr);
2567 replen = hdr.replen + op_decode_hdr_maxsz; 2559 replen = hdr.replen + op_decode_hdr_maxsz;
2568 encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); 2560 encode_getattr(xdr, nfs4_acl_bitmap, NULL,
2561 ARRAY_SIZE(nfs4_acl_bitmap), &hdr);
2569 2562
2570 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, 2563 xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
2571 args->acl_pages, 0, args->acl_len); 2564 args->acl_pages, 0, args->acl_len);
@@ -2644,8 +2637,8 @@ static void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
2644 encode_compound_hdr(xdr, req, &hdr); 2637 encode_compound_hdr(xdr, req, &hdr);
2645 encode_sequence(xdr, &args->seq_args, &hdr); 2638 encode_sequence(xdr, &args->seq_args, &hdr);
2646 encode_putfh(xdr, args->fh, &hdr); 2639 encode_putfh(xdr, args->fh, &hdr);
2647 encode_getattr_one(xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0], 2640 encode_getattr(xdr, nfs4_pathconf_bitmap, args->bitmask,
2648 &hdr); 2641 ARRAY_SIZE(nfs4_pathconf_bitmap), &hdr);
2649 encode_nops(&hdr); 2642 encode_nops(&hdr);
2650} 2643}
2651 2644
@@ -2663,8 +2656,8 @@ static void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
2663 encode_compound_hdr(xdr, req, &hdr); 2656 encode_compound_hdr(xdr, req, &hdr);
2664 encode_sequence(xdr, &args->seq_args, &hdr); 2657 encode_sequence(xdr, &args->seq_args, &hdr);
2665 encode_putfh(xdr, args->fh, &hdr); 2658 encode_putfh(xdr, args->fh, &hdr);
2666 encode_getattr_two(xdr, args->bitmask[0] & nfs4_statfs_bitmap[0], 2659 encode_getattr(xdr, nfs4_statfs_bitmap, args->bitmask,
2667 args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr); 2660 ARRAY_SIZE(nfs4_statfs_bitmap), &hdr);
2668 encode_nops(&hdr); 2661 encode_nops(&hdr);
2669} 2662}
2670 2663
@@ -2684,7 +2677,7 @@ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
2684 encode_compound_hdr(xdr, req, &hdr); 2677 encode_compound_hdr(xdr, req, &hdr);
2685 encode_sequence(xdr, &args->seq_args, &hdr); 2678 encode_sequence(xdr, &args->seq_args, &hdr);
2686 encode_putfh(xdr, args->fhandle, &hdr); 2679 encode_putfh(xdr, args->fhandle, &hdr);
2687 encode_getattr_three(xdr, bitmask[0], bitmask[1], bitmask[2], &hdr); 2680 encode_getattr(xdr, bitmask, NULL, 3, &hdr);
2688 encode_nops(&hdr); 2681 encode_nops(&hdr);
2689} 2682}
2690 2683
@@ -3218,34 +3211,27 @@ static int decode_ace(struct xdr_stream *xdr, void *ace)
3218 return -EIO; 3211 return -EIO;
3219} 3212}
3220 3213
3221static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) 3214static ssize_t
3215decode_bitmap4(struct xdr_stream *xdr, uint32_t *bitmap, size_t sz)
3222{ 3216{
3223 uint32_t bmlen; 3217 ssize_t ret;
3224 __be32 *p;
3225
3226 p = xdr_inline_decode(xdr, 4);
3227 if (unlikely(!p))
3228 goto out_overflow;
3229 bmlen = be32_to_cpup(p);
3230 3218
3231 bitmap[0] = bitmap[1] = bitmap[2] = 0; 3219 ret = xdr_stream_decode_uint32_array(xdr, bitmap, sz);
3232 p = xdr_inline_decode(xdr, (bmlen << 2)); 3220 if (likely(ret >= 0))
3233 if (unlikely(!p)) 3221 return ret;
3234 goto out_overflow; 3222 if (ret == -EMSGSIZE)
3235 if (bmlen > 0) { 3223 return sz;
3236 bitmap[0] = be32_to_cpup(p++);
3237 if (bmlen > 1) {
3238 bitmap[1] = be32_to_cpup(p++);
3239 if (bmlen > 2)
3240 bitmap[2] = be32_to_cpup(p);
3241 }
3242 }
3243 return 0;
3244out_overflow:
3245 print_overflow_msg(__func__, xdr); 3224 print_overflow_msg(__func__, xdr);
3246 return -EIO; 3225 return -EIO;
3247} 3226}
3248 3227
3228static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
3229{
3230 ssize_t ret;
3231 ret = decode_bitmap4(xdr, bitmap, 3);
3232 return ret < 0 ? ret : 0;
3233}
3234
3249static int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, unsigned int *savep) 3235static int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, unsigned int *savep)
3250{ 3236{
3251 __be32 *p; 3237 __be32 *p;
@@ -5471,21 +5457,13 @@ decode_savefh(struct xdr_stream *xdr)
5471 5457
5472static int decode_setattr(struct xdr_stream *xdr) 5458static int decode_setattr(struct xdr_stream *xdr)
5473{ 5459{
5474 __be32 *p;
5475 uint32_t bmlen;
5476 int status; 5460 int status;
5477 5461
5478 status = decode_op_hdr(xdr, OP_SETATTR); 5462 status = decode_op_hdr(xdr, OP_SETATTR);
5479 if (status) 5463 if (status)
5480 return status; 5464 return status;
5481 p = xdr_inline_decode(xdr, 4); 5465 if (decode_bitmap4(xdr, NULL, 0) >= 0)
5482 if (unlikely(!p))
5483 goto out_overflow;
5484 bmlen = be32_to_cpup(p);
5485 p = xdr_inline_decode(xdr, bmlen << 2);
5486 if (likely(p))
5487 return 0; 5466 return 0;
5488out_overflow:
5489 print_overflow_msg(__func__, xdr); 5467 print_overflow_msg(__func__, xdr);
5490 return -EIO; 5468 return -EIO;
5491} 5469}