diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/client.c | 1 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 5 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 99 |
4 files changed, 87 insertions, 20 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index a9b18483cb24..de00a373f085 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -936,6 +936,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, | |||
936 | if (server->wsize > NFS_MAX_FILE_IO_SIZE) | 936 | if (server->wsize > NFS_MAX_FILE_IO_SIZE) |
937 | server->wsize = NFS_MAX_FILE_IO_SIZE; | 937 | server->wsize = NFS_MAX_FILE_IO_SIZE; |
938 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 938 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
939 | server->pnfs_blksize = fsinfo->blksize; | ||
939 | set_pnfs_layoutdriver(server, mntfh, fsinfo->layouttype); | 940 | set_pnfs_layoutdriver(server, mntfh, fsinfo->layouttype); |
940 | 941 | ||
941 | server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL); | 942 | server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL); |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 1909ee8be350..1ec1a85fa71c 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -318,7 +318,7 @@ extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[]; | |||
318 | extern const u32 nfs4_fattr_bitmap[2]; | 318 | extern const u32 nfs4_fattr_bitmap[2]; |
319 | extern const u32 nfs4_statfs_bitmap[2]; | 319 | extern const u32 nfs4_statfs_bitmap[2]; |
320 | extern const u32 nfs4_pathconf_bitmap[2]; | 320 | extern const u32 nfs4_pathconf_bitmap[2]; |
321 | extern const u32 nfs4_fsinfo_bitmap[2]; | 321 | extern const u32 nfs4_fsinfo_bitmap[3]; |
322 | extern const u32 nfs4_fs_locations_bitmap[2]; | 322 | extern const u32 nfs4_fs_locations_bitmap[2]; |
323 | 323 | ||
324 | /* nfs4renewd.c */ | 324 | /* nfs4renewd.c */ |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index af32d3df0544..e86de799dd12 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -140,12 +140,13 @@ const u32 nfs4_pathconf_bitmap[2] = { | |||
140 | 0 | 140 | 0 |
141 | }; | 141 | }; |
142 | 142 | ||
143 | const u32 nfs4_fsinfo_bitmap[2] = { FATTR4_WORD0_MAXFILESIZE | 143 | const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE |
144 | | FATTR4_WORD0_MAXREAD | 144 | | FATTR4_WORD0_MAXREAD |
145 | | FATTR4_WORD0_MAXWRITE | 145 | | FATTR4_WORD0_MAXWRITE |
146 | | FATTR4_WORD0_LEASE_TIME, | 146 | | FATTR4_WORD0_LEASE_TIME, |
147 | FATTR4_WORD1_TIME_DELTA | 147 | FATTR4_WORD1_TIME_DELTA |
148 | | FATTR4_WORD1_FS_LAYOUT_TYPES | 148 | | FATTR4_WORD1_FS_LAYOUT_TYPES, |
149 | FATTR4_WORD2_LAYOUT_BLKSIZE | ||
149 | }; | 150 | }; |
150 | 151 | ||
151 | const u32 nfs4_fs_locations_bitmap[2] = { | 152 | const u32 nfs4_fs_locations_bitmap[2] = { |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 5f769f8d05b0..026166993d11 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -113,7 +113,11 @@ static int nfs4_stat_to_errno(int); | |||
113 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) | 113 | #define encode_restorefh_maxsz (op_encode_hdr_maxsz) |
114 | #define decode_restorefh_maxsz (op_decode_hdr_maxsz) | 114 | #define decode_restorefh_maxsz (op_decode_hdr_maxsz) |
115 | #define encode_fsinfo_maxsz (encode_getattr_maxsz) | 115 | #define encode_fsinfo_maxsz (encode_getattr_maxsz) |
116 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 15) | 116 | /* The 5 accounts for the PNFS attributes, and assumes that at most three |
117 | * layout types will be returned. | ||
118 | */ | ||
119 | #define decode_fsinfo_maxsz (op_decode_hdr_maxsz + \ | ||
120 | nfs4_fattr_bitmap_maxsz + 4 + 8 + 5) | ||
117 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) | 121 | #define encode_renew_maxsz (op_encode_hdr_maxsz + 3) |
118 | #define decode_renew_maxsz (op_decode_hdr_maxsz) | 122 | #define decode_renew_maxsz (op_decode_hdr_maxsz) |
119 | #define encode_setclientid_maxsz \ | 123 | #define encode_setclientid_maxsz \ |
@@ -1123,6 +1127,35 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm | |||
1123 | hdr->replen += decode_getattr_maxsz; | 1127 | hdr->replen += decode_getattr_maxsz; |
1124 | } | 1128 | } |
1125 | 1129 | ||
1130 | static void | ||
1131 | encode_getattr_three(struct xdr_stream *xdr, | ||
1132 | uint32_t bm0, uint32_t bm1, uint32_t bm2, | ||
1133 | struct compound_hdr *hdr) | ||
1134 | { | ||
1135 | __be32 *p; | ||
1136 | |||
1137 | p = reserve_space(xdr, 4); | ||
1138 | *p = cpu_to_be32(OP_GETATTR); | ||
1139 | if (bm2) { | ||
1140 | p = reserve_space(xdr, 16); | ||
1141 | *p++ = cpu_to_be32(3); | ||
1142 | *p++ = cpu_to_be32(bm0); | ||
1143 | *p++ = cpu_to_be32(bm1); | ||
1144 | *p = cpu_to_be32(bm2); | ||
1145 | } else if (bm1) { | ||
1146 | p = reserve_space(xdr, 12); | ||
1147 | *p++ = cpu_to_be32(2); | ||
1148 | *p++ = cpu_to_be32(bm0); | ||
1149 | *p = cpu_to_be32(bm1); | ||
1150 | } else { | ||
1151 | p = reserve_space(xdr, 8); | ||
1152 | *p++ = cpu_to_be32(1); | ||
1153 | *p = cpu_to_be32(bm0); | ||
1154 | } | ||
1155 | hdr->nops++; | ||
1156 | hdr->replen += decode_getattr_maxsz; | ||
1157 | } | ||
1158 | |||
1126 | static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1159 | static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) |
1127 | { | 1160 | { |
1128 | encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], | 1161 | encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0], |
@@ -1131,8 +1164,11 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c | |||
1131 | 1164 | ||
1132 | static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1165 | static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) |
1133 | { | 1166 | { |
1134 | encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0], | 1167 | encode_getattr_three(xdr, |
1135 | bitmask[1] & nfs4_fsinfo_bitmap[1], hdr); | 1168 | bitmask[0] & nfs4_fsinfo_bitmap[0], |
1169 | bitmask[1] & nfs4_fsinfo_bitmap[1], | ||
1170 | bitmask[2] & nfs4_fsinfo_bitmap[2], | ||
1171 | hdr); | ||
1136 | } | 1172 | } |
1137 | 1173 | ||
1138 | static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1174 | static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) |
@@ -2643,7 +2679,7 @@ static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, | |||
2643 | struct compound_hdr hdr = { | 2679 | struct compound_hdr hdr = { |
2644 | .nops = 0, | 2680 | .nops = 0, |
2645 | }; | 2681 | }; |
2646 | const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; | 2682 | const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME }; |
2647 | 2683 | ||
2648 | encode_compound_hdr(xdr, req, &hdr); | 2684 | encode_compound_hdr(xdr, req, &hdr); |
2649 | encode_setclientid_confirm(xdr, arg, &hdr); | 2685 | encode_setclientid_confirm(xdr, arg, &hdr); |
@@ -2787,7 +2823,7 @@ static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, | |||
2787 | struct compound_hdr hdr = { | 2823 | struct compound_hdr hdr = { |
2788 | .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), | 2824 | .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), |
2789 | }; | 2825 | }; |
2790 | const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; | 2826 | const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME }; |
2791 | 2827 | ||
2792 | encode_compound_hdr(xdr, req, &hdr); | 2828 | encode_compound_hdr(xdr, req, &hdr); |
2793 | encode_sequence(xdr, &args->la_seq_args, &hdr); | 2829 | encode_sequence(xdr, &args->la_seq_args, &hdr); |
@@ -3068,14 +3104,17 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | |||
3068 | goto out_overflow; | 3104 | goto out_overflow; |
3069 | bmlen = be32_to_cpup(p); | 3105 | bmlen = be32_to_cpup(p); |
3070 | 3106 | ||
3071 | bitmap[0] = bitmap[1] = 0; | 3107 | bitmap[0] = bitmap[1] = bitmap[2] = 0; |
3072 | p = xdr_inline_decode(xdr, (bmlen << 2)); | 3108 | p = xdr_inline_decode(xdr, (bmlen << 2)); |
3073 | if (unlikely(!p)) | 3109 | if (unlikely(!p)) |
3074 | goto out_overflow; | 3110 | goto out_overflow; |
3075 | if (bmlen > 0) { | 3111 | if (bmlen > 0) { |
3076 | bitmap[0] = be32_to_cpup(p++); | 3112 | bitmap[0] = be32_to_cpup(p++); |
3077 | if (bmlen > 1) | 3113 | if (bmlen > 1) { |
3078 | bitmap[1] = be32_to_cpup(p); | 3114 | bitmap[1] = be32_to_cpup(p++); |
3115 | if (bmlen > 2) | ||
3116 | bitmap[2] = be32_to_cpup(p); | ||
3117 | } | ||
3079 | } | 3118 | } |
3080 | return 0; | 3119 | return 0; |
3081 | out_overflow: | 3120 | out_overflow: |
@@ -3107,8 +3146,9 @@ static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint3 | |||
3107 | return ret; | 3146 | return ret; |
3108 | bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; | 3147 | bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; |
3109 | } else | 3148 | } else |
3110 | bitmask[0] = bitmask[1] = 0; | 3149 | bitmask[0] = bitmask[1] = bitmask[2] = 0; |
3111 | dprintk("%s: bitmask=%08x:%08x\n", __func__, bitmask[0], bitmask[1]); | 3150 | dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__, |
3151 | bitmask[0], bitmask[1], bitmask[2]); | ||
3112 | return 0; | 3152 | return 0; |
3113 | } | 3153 | } |
3114 | 3154 | ||
@@ -4162,7 +4202,7 @@ out_overflow: | |||
4162 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) | 4202 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) |
4163 | { | 4203 | { |
4164 | __be32 *savep; | 4204 | __be32 *savep; |
4165 | uint32_t attrlen, bitmap[2] = {0}; | 4205 | uint32_t attrlen, bitmap[3] = {0}; |
4166 | int status; | 4206 | int status; |
4167 | 4207 | ||
4168 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4208 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4188,7 +4228,7 @@ xdr_error: | |||
4188 | static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) | 4228 | static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) |
4189 | { | 4229 | { |
4190 | __be32 *savep; | 4230 | __be32 *savep; |
4191 | uint32_t attrlen, bitmap[2] = {0}; | 4231 | uint32_t attrlen, bitmap[3] = {0}; |
4192 | int status; | 4232 | int status; |
4193 | 4233 | ||
4194 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4234 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4220,7 +4260,7 @@ xdr_error: | |||
4220 | static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) | 4260 | static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) |
4221 | { | 4261 | { |
4222 | __be32 *savep; | 4262 | __be32 *savep; |
4223 | uint32_t attrlen, bitmap[2] = {0}; | 4263 | uint32_t attrlen, bitmap[3] = {0}; |
4224 | int status; | 4264 | int status; |
4225 | 4265 | ||
4226 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4266 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4360,7 +4400,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat | |||
4360 | { | 4400 | { |
4361 | __be32 *savep; | 4401 | __be32 *savep; |
4362 | uint32_t attrlen, | 4402 | uint32_t attrlen, |
4363 | bitmap[2] = {0}; | 4403 | bitmap[3] = {0}; |
4364 | int status; | 4404 | int status; |
4365 | 4405 | ||
4366 | status = decode_op_hdr(xdr, OP_GETATTR); | 4406 | status = decode_op_hdr(xdr, OP_GETATTR); |
@@ -4446,10 +4486,32 @@ static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4446 | return status; | 4486 | return status; |
4447 | } | 4487 | } |
4448 | 4488 | ||
4489 | /* | ||
4490 | * The prefered block size for layout directed io | ||
4491 | */ | ||
4492 | static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap, | ||
4493 | uint32_t *res) | ||
4494 | { | ||
4495 | __be32 *p; | ||
4496 | |||
4497 | dprintk("%s: bitmap is %x\n", __func__, bitmap[2]); | ||
4498 | *res = 0; | ||
4499 | if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) { | ||
4500 | p = xdr_inline_decode(xdr, 4); | ||
4501 | if (unlikely(!p)) { | ||
4502 | print_overflow_msg(__func__, xdr); | ||
4503 | return -EIO; | ||
4504 | } | ||
4505 | *res = be32_to_cpup(p); | ||
4506 | bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE; | ||
4507 | } | ||
4508 | return 0; | ||
4509 | } | ||
4510 | |||
4449 | static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) | 4511 | static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) |
4450 | { | 4512 | { |
4451 | __be32 *savep; | 4513 | __be32 *savep; |
4452 | uint32_t attrlen, bitmap[2]; | 4514 | uint32_t attrlen, bitmap[3]; |
4453 | int status; | 4515 | int status; |
4454 | 4516 | ||
4455 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 4517 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
@@ -4477,6 +4539,9 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) | |||
4477 | status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); | 4539 | status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); |
4478 | if (status != 0) | 4540 | if (status != 0) |
4479 | goto xdr_error; | 4541 | goto xdr_error; |
4542 | status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); | ||
4543 | if (status) | ||
4544 | goto xdr_error; | ||
4480 | 4545 | ||
4481 | status = verify_attr_len(xdr, savep, attrlen); | 4546 | status = verify_attr_len(xdr, savep, attrlen); |
4482 | xdr_error: | 4547 | xdr_error: |
@@ -4896,7 +4961,7 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
4896 | { | 4961 | { |
4897 | __be32 *savep; | 4962 | __be32 *savep; |
4898 | uint32_t attrlen, | 4963 | uint32_t attrlen, |
4899 | bitmap[2] = {0}; | 4964 | bitmap[3] = {0}; |
4900 | struct kvec *iov = req->rq_rcv_buf.head; | 4965 | struct kvec *iov = req->rq_rcv_buf.head; |
4901 | int status; | 4966 | int status; |
4902 | 4967 | ||
@@ -6852,7 +6917,7 @@ out: | |||
6852 | int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | 6917 | int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, |
6853 | int plus) | 6918 | int plus) |
6854 | { | 6919 | { |
6855 | uint32_t bitmap[2] = {0}; | 6920 | uint32_t bitmap[3] = {0}; |
6856 | uint32_t len; | 6921 | uint32_t len; |
6857 | __be32 *p = xdr_inline_decode(xdr, 4); | 6922 | __be32 *p = xdr_inline_decode(xdr, 4); |
6858 | if (unlikely(!p)) | 6923 | if (unlikely(!p)) |