diff options
author | Andy Adamson <andros@netapp.com> | 2012-05-23 05:02:34 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-24 16:15:47 -0400 |
commit | 88034c3d88c2c48b215f2cc5eb22e564aa817f9c (patch) | |
tree | aca4a42af31d12777a2ef7bcbf37751b28ff73c6 | |
parent | 54ac471c83aff6b1e068eb8029c797dc68a76e89 (diff) |
NFSv4.1 mdsthreshold attribute xdr
We only support one layout type per file system, so one threshold_item4 per
mdsthreshold4.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4xdr.c | 125 | ||||
-rw-r--r-- | include/linux/nfs4.h | 7 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 10 |
3 files changed, 140 insertions, 2 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 5ad2b2c2aecb..edb8ac7fce0e 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -101,9 +101,12 @@ static int nfs4_stat_to_errno(int); | |||
101 | #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) | 101 | #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) |
102 | #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) | 102 | #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) |
103 | #define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) | 103 | #define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) |
104 | /* We support only one layout type per file system */ | ||
105 | #define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) | ||
104 | /* This is based on getfattr, which uses the most attributes: */ | 106 | /* This is based on getfattr, which uses the most attributes: */ |
105 | #define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ | 107 | #define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ |
106 | 3 + 3 + 3 + nfs4_owner_maxsz + nfs4_group_maxsz)) | 108 | 3 + 3 + 3 + nfs4_owner_maxsz + \ |
109 | nfs4_group_maxsz + decode_mdsthreshold_maxsz)) | ||
107 | #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ | 110 | #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ |
108 | nfs4_fattr_value_maxsz) | 111 | nfs4_fattr_value_maxsz) |
109 | #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) | 112 | #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) |
@@ -1172,6 +1175,16 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c | |||
1172 | bitmask[1] & nfs4_fattr_bitmap[1], hdr); | 1175 | bitmask[1] & nfs4_fattr_bitmap[1], hdr); |
1173 | } | 1176 | } |
1174 | 1177 | ||
1178 | static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, | ||
1179 | struct compound_hdr *hdr) | ||
1180 | { | ||
1181 | encode_getattr_three(xdr, | ||
1182 | bitmask[0] & nfs4_fattr_bitmap[0], | ||
1183 | bitmask[1] & nfs4_fattr_bitmap[1], | ||
1184 | bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD, | ||
1185 | hdr); | ||
1186 | } | ||
1187 | |||
1175 | static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) | 1188 | static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) |
1176 | { | 1189 | { |
1177 | encode_getattr_three(xdr, | 1190 | encode_getattr_three(xdr, |
@@ -2164,7 +2177,7 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, | |||
2164 | encode_putfh(xdr, args->fh, &hdr); | 2177 | encode_putfh(xdr, args->fh, &hdr); |
2165 | encode_open(xdr, args, &hdr); | 2178 | encode_open(xdr, args, &hdr); |
2166 | encode_getfh(xdr, &hdr); | 2179 | encode_getfh(xdr, &hdr); |
2167 | encode_getfattr(xdr, args->bitmask, &hdr); | 2180 | encode_getfattr_open(xdr, args->bitmask, &hdr); |
2168 | encode_nops(&hdr); | 2181 | encode_nops(&hdr); |
2169 | } | 2182 | } |
2170 | 2183 | ||
@@ -4186,6 +4199,110 @@ xdr_error: | |||
4186 | return status; | 4199 | return status; |
4187 | } | 4200 | } |
4188 | 4201 | ||
4202 | static int decode_threshold_hint(struct xdr_stream *xdr, | ||
4203 | uint32_t *bitmap, | ||
4204 | uint64_t *res, | ||
4205 | uint32_t hint_bit) | ||
4206 | { | ||
4207 | __be32 *p; | ||
4208 | |||
4209 | *res = 0; | ||
4210 | if (likely(bitmap[0] & hint_bit)) { | ||
4211 | p = xdr_inline_decode(xdr, 8); | ||
4212 | if (unlikely(!p)) | ||
4213 | goto out_overflow; | ||
4214 | xdr_decode_hyper(p, res); | ||
4215 | } | ||
4216 | return 0; | ||
4217 | out_overflow: | ||
4218 | print_overflow_msg(__func__, xdr); | ||
4219 | return -EIO; | ||
4220 | } | ||
4221 | |||
4222 | static int decode_first_threshold_item4(struct xdr_stream *xdr, | ||
4223 | struct nfs4_threshold *res) | ||
4224 | { | ||
4225 | __be32 *p, *savep; | ||
4226 | uint32_t bitmap[3] = {0,}, attrlen; | ||
4227 | int status; | ||
4228 | |||
4229 | /* layout type */ | ||
4230 | p = xdr_inline_decode(xdr, 4); | ||
4231 | if (unlikely(!p)) { | ||
4232 | print_overflow_msg(__func__, xdr); | ||
4233 | return -EIO; | ||
4234 | } | ||
4235 | res->l_type = be32_to_cpup(p); | ||
4236 | |||
4237 | /* thi_hintset bitmap */ | ||
4238 | status = decode_attr_bitmap(xdr, bitmap); | ||
4239 | if (status < 0) | ||
4240 | goto xdr_error; | ||
4241 | |||
4242 | /* thi_hintlist length */ | ||
4243 | status = decode_attr_length(xdr, &attrlen, &savep); | ||
4244 | if (status < 0) | ||
4245 | goto xdr_error; | ||
4246 | /* thi_hintlist */ | ||
4247 | status = decode_threshold_hint(xdr, bitmap, &res->rd_sz, THRESHOLD_RD); | ||
4248 | if (status < 0) | ||
4249 | goto xdr_error; | ||
4250 | status = decode_threshold_hint(xdr, bitmap, &res->wr_sz, THRESHOLD_WR); | ||
4251 | if (status < 0) | ||
4252 | goto xdr_error; | ||
4253 | status = decode_threshold_hint(xdr, bitmap, &res->rd_io_sz, | ||
4254 | THRESHOLD_RD_IO); | ||
4255 | if (status < 0) | ||
4256 | goto xdr_error; | ||
4257 | status = decode_threshold_hint(xdr, bitmap, &res->wr_io_sz, | ||
4258 | THRESHOLD_WR_IO); | ||
4259 | if (status < 0) | ||
4260 | goto xdr_error; | ||
4261 | |||
4262 | status = verify_attr_len(xdr, savep, attrlen); | ||
4263 | res->bm = bitmap[0]; | ||
4264 | |||
4265 | dprintk("%s bm=0x%x rd_sz=%llu wr_sz=%llu rd_io=%llu wr_io=%llu\n", | ||
4266 | __func__, res->bm, res->rd_sz, res->wr_sz, res->rd_io_sz, | ||
4267 | res->wr_io_sz); | ||
4268 | xdr_error: | ||
4269 | dprintk("%s ret=%d!\n", __func__, status); | ||
4270 | return status; | ||
4271 | } | ||
4272 | |||
4273 | /* | ||
4274 | * Thresholds on pNFS direct I/O vrs MDS I/O | ||
4275 | */ | ||
4276 | static int decode_attr_mdsthreshold(struct xdr_stream *xdr, | ||
4277 | uint32_t *bitmap, | ||
4278 | struct nfs4_threshold *res) | ||
4279 | { | ||
4280 | __be32 *p; | ||
4281 | int status = 0; | ||
4282 | uint32_t num; | ||
4283 | |||
4284 | if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U))) | ||
4285 | return -EIO; | ||
4286 | if (likely(bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD)) { | ||
4287 | p = xdr_inline_decode(xdr, 4); | ||
4288 | if (unlikely(!p)) | ||
4289 | goto out_overflow; | ||
4290 | num = be32_to_cpup(p); | ||
4291 | if (num == 0) | ||
4292 | return 0; | ||
4293 | if (num > 1) | ||
4294 | printk(KERN_INFO "%s: Warning: Multiple pNFS layout " | ||
4295 | "drivers per filesystem not supported\n", | ||
4296 | __func__); | ||
4297 | |||
4298 | status = decode_first_threshold_item4(xdr, res); | ||
4299 | } | ||
4300 | return status; | ||
4301 | out_overflow: | ||
4302 | print_overflow_msg(__func__, xdr); | ||
4303 | return -EIO; | ||
4304 | } | ||
4305 | |||
4189 | static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | 4306 | static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, |
4190 | struct nfs_fattr *fattr, struct nfs_fh *fh, | 4307 | struct nfs_fattr *fattr, struct nfs_fh *fh, |
4191 | struct nfs4_fs_locations *fs_loc, | 4308 | struct nfs4_fs_locations *fs_loc, |
@@ -4292,6 +4409,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, | |||
4292 | goto xdr_error; | 4409 | goto xdr_error; |
4293 | fattr->valid |= status; | 4410 | fattr->valid |= status; |
4294 | 4411 | ||
4412 | status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); | ||
4413 | if (status < 0) | ||
4414 | goto xdr_error; | ||
4415 | |||
4295 | xdr_error: | 4416 | xdr_error: |
4296 | dprintk("%s: xdr returned %d\n", __func__, -status); | 4417 | dprintk("%s: xdr returned %d\n", __func__, -status); |
4297 | return status; | 4418 | return status; |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 0987146b0637..72b6bada0d79 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
@@ -526,6 +526,13 @@ enum lock_type4 { | |||
526 | #define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) | 526 | #define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) |
527 | #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) | 527 | #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) |
528 | #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) | 528 | #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) |
529 | #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) | ||
530 | |||
531 | /* MDS threshold bitmap bits */ | ||
532 | #define THRESHOLD_RD (1UL << 0) | ||
533 | #define THRESHOLD_WR (1UL << 1) | ||
534 | #define THRESHOLD_RD_IO (1UL << 2) | ||
535 | #define THRESHOLD_WR_IO (1UL << 3) | ||
529 | 536 | ||
530 | #define NFSPROC4_NULL 0 | 537 | #define NFSPROC4_NULL 0 |
531 | #define NFSPROC4_COMPOUND 1 | 538 | #define NFSPROC4_COMPOUND 1 |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 0872f32c8eef..201c312152fb 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -35,6 +35,15 @@ static inline int nfs_fsid_equal(const struct nfs_fsid *a, const struct nfs_fsid | |||
35 | return a->major == b->major && a->minor == b->minor; | 35 | return a->major == b->major && a->minor == b->minor; |
36 | } | 36 | } |
37 | 37 | ||
38 | struct nfs4_threshold { | ||
39 | __u32 bm; | ||
40 | __u32 l_type; | ||
41 | __u64 rd_sz; | ||
42 | __u64 wr_sz; | ||
43 | __u64 rd_io_sz; | ||
44 | __u64 wr_io_sz; | ||
45 | }; | ||
46 | |||
38 | struct nfs_fattr { | 47 | struct nfs_fattr { |
39 | unsigned int valid; /* which fields are valid */ | 48 | unsigned int valid; /* which fields are valid */ |
40 | umode_t mode; | 49 | umode_t mode; |
@@ -67,6 +76,7 @@ struct nfs_fattr { | |||
67 | unsigned long gencount; | 76 | unsigned long gencount; |
68 | struct nfs4_string *owner_name; | 77 | struct nfs4_string *owner_name; |
69 | struct nfs4_string *group_name; | 78 | struct nfs4_string *group_name; |
79 | struct nfs4_threshold *mdsthreshold; /* pNFS threshold hints */ | ||
70 | }; | 80 | }; |
71 | 81 | ||
72 | #define NFS_ATTR_FATTR_TYPE (1U << 0) | 82 | #define NFS_ATTR_FATTR_TYPE (1U << 0) |