aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c5
-rw-r--r--fs/nfs/nfs4xdr.c99
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[];
318extern const u32 nfs4_fattr_bitmap[2]; 318extern const u32 nfs4_fattr_bitmap[2];
319extern const u32 nfs4_statfs_bitmap[2]; 319extern const u32 nfs4_statfs_bitmap[2];
320extern const u32 nfs4_pathconf_bitmap[2]; 320extern const u32 nfs4_pathconf_bitmap[2];
321extern const u32 nfs4_fsinfo_bitmap[2]; 321extern const u32 nfs4_fsinfo_bitmap[3];
322extern const u32 nfs4_fs_locations_bitmap[2]; 322extern 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
143const u32 nfs4_fsinfo_bitmap[2] = { FATTR4_WORD0_MAXFILESIZE 143const 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
151const u32 nfs4_fs_locations_bitmap[2] = { 152const 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
1130static void
1131encode_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
1126static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1159static 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
1132static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1165static 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
1138static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1174static 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;
3081out_overflow: 3120out_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:
4162static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) 4202static 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:
4188static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) 4228static 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:
4220static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) 4260static 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 */
4492static 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
4449static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 4511static 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);
4482xdr_error: 4547xdr_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:
6852int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, 6917int 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))