aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-05-16 17:42:43 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-05-17 15:48:06 -0400
commit93b717fd81bf6b9a73c3702e9b079b4de8148b34 (patch)
tree0ae5ec7f5a79410e12710941fffc9725a687c6d8
parent9a8f6b5ea275ff01fc8ef3b8630a3d4ed6b0a362 (diff)
NFSv4: Label stateids with the type
In order to more easily distinguish what kind of stateid we are dealing with, introduce a type that can be used to label the stateid structure. The label will be useful both for debugging, but also when dealing with operations like SETATTR, READ and WRITE that can take several different types of stateid as arguments. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--fs/nfs/callback_xdr.c17
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c7
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayoutdev.c3
-rw-r--r--fs/nfs/nfs4_fs.h7
-rw-r--r--fs/nfs/nfs4proc.c3
-rw-r--r--fs/nfs/nfs4state.c5
-rw-r--r--fs/nfs/nfs4xdr.c42
-rw-r--r--include/linux/nfs4.h25
8 files changed, 85 insertions, 24 deletions
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 976c90608e56..d81f96aacd51 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -146,10 +146,16 @@ static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
146 p = read_buf(xdr, NFS4_STATEID_SIZE); 146 p = read_buf(xdr, NFS4_STATEID_SIZE);
147 if (unlikely(p == NULL)) 147 if (unlikely(p == NULL))
148 return htonl(NFS4ERR_RESOURCE); 148 return htonl(NFS4ERR_RESOURCE);
149 memcpy(stateid, p, NFS4_STATEID_SIZE); 149 memcpy(stateid->data, p, NFS4_STATEID_SIZE);
150 return 0; 150 return 0;
151} 151}
152 152
153static __be32 decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
154{
155 stateid->type = NFS4_DELEGATION_STATEID_TYPE;
156 return decode_stateid(xdr, stateid);
157}
158
153static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr) 159static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
154{ 160{
155 __be32 *p; 161 __be32 *p;
@@ -211,7 +217,7 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr,
211 __be32 *p; 217 __be32 *p;
212 __be32 status; 218 __be32 status;
213 219
214 status = decode_stateid(xdr, &args->stateid); 220 status = decode_delegation_stateid(xdr, &args->stateid);
215 if (unlikely(status != 0)) 221 if (unlikely(status != 0))
216 goto out; 222 goto out;
217 p = read_buf(xdr, 4); 223 p = read_buf(xdr, 4);
@@ -227,6 +233,11 @@ out:
227} 233}
228 234
229#if defined(CONFIG_NFS_V4_1) 235#if defined(CONFIG_NFS_V4_1)
236static __be32 decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
237{
238 stateid->type = NFS4_LAYOUT_STATEID_TYPE;
239 return decode_stateid(xdr, stateid);
240}
230 241
231static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, 242static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
232 struct xdr_stream *xdr, 243 struct xdr_stream *xdr,
@@ -263,7 +274,7 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
263 } 274 }
264 p = xdr_decode_hyper(p, &args->cbl_range.offset); 275 p = xdr_decode_hyper(p, &args->cbl_range.offset);
265 p = xdr_decode_hyper(p, &args->cbl_range.length); 276 p = xdr_decode_hyper(p, &args->cbl_range.length);
266 status = decode_stateid(xdr, &args->cbl_stateid); 277 status = decode_layout_stateid(xdr, &args->cbl_stateid);
267 if (unlikely(status != 0)) 278 if (unlikely(status != 0))
268 goto out; 279 goto out;
269 } else if (args->cbl_recall_type == RETURN_FSID) { 280 } else if (args->cbl_recall_type == RETURN_FSID) {
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 60d690dbc947..53b6391e0eba 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -55,14 +55,15 @@ ff_layout_free_layout_hdr(struct pnfs_layout_hdr *lo)
55 kfree(FF_LAYOUT_FROM_HDR(lo)); 55 kfree(FF_LAYOUT_FROM_HDR(lo));
56} 56}
57 57
58static int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 58static int decode_pnfs_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
59{ 59{
60 __be32 *p; 60 __be32 *p;
61 61
62 p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE); 62 p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE);
63 if (unlikely(p == NULL)) 63 if (unlikely(p == NULL))
64 return -ENOBUFS; 64 return -ENOBUFS;
65 memcpy(stateid, p, NFS4_STATEID_SIZE); 65 stateid->type = NFS4_PNFS_DS_STATEID_TYPE;
66 memcpy(stateid->data, p, NFS4_STATEID_SIZE);
66 dprintk("%s: stateid id= [%x%x%x%x]\n", __func__, 67 dprintk("%s: stateid id= [%x%x%x%x]\n", __func__,
67 p[0], p[1], p[2], p[3]); 68 p[0], p[1], p[2], p[3]);
68 return 0; 69 return 0;
@@ -465,7 +466,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
465 fls->mirror_array[i]->efficiency = be32_to_cpup(p); 466 fls->mirror_array[i]->efficiency = be32_to_cpup(p);
466 467
467 /* stateid */ 468 /* stateid */
468 rc = decode_stateid(&stream, &fls->mirror_array[i]->stateid); 469 rc = decode_pnfs_stateid(&stream, &fls->mirror_array[i]->stateid);
469 if (rc) 470 if (rc)
470 goto out_err_free; 471 goto out_err_free;
471 472
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 56296f3df19c..eeef89359ad2 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -228,7 +228,8 @@ ff_ds_error_match(const struct nfs4_ff_layout_ds_err *e1,
228 return e1->opnum < e2->opnum ? -1 : 1; 228 return e1->opnum < e2->opnum ? -1 : 1;
229 if (e1->status != e2->status) 229 if (e1->status != e2->status)
230 return e1->status < e2->status ? -1 : 1; 230 return e1->status < e2->status ? -1 : 1;
231 ret = memcmp(&e1->stateid, &e2->stateid, sizeof(e1->stateid)); 231 ret = memcmp(e1->stateid.data, e2->stateid.data,
232 sizeof(e1->stateid.data));
232 if (ret != 0) 233 if (ret != 0)
233 return ret; 234 return ret;
234 ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid)); 235 ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 4afdee420d25..b5d9f345c9f2 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -496,12 +496,15 @@ extern struct svc_version nfs4_callback_version4;
496 496
497static inline void nfs4_stateid_copy(nfs4_stateid *dst, const nfs4_stateid *src) 497static inline void nfs4_stateid_copy(nfs4_stateid *dst, const nfs4_stateid *src)
498{ 498{
499 memcpy(dst, src, sizeof(*dst)); 499 memcpy(dst->data, src->data, sizeof(dst->data));
500 dst->type = src->type;
500} 501}
501 502
502static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_stateid *src) 503static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_stateid *src)
503{ 504{
504 return memcmp(dst, src, sizeof(*dst)) == 0; 505 if (dst->type != src->type)
506 return false;
507 return memcmp(dst->data, src->data, sizeof(dst->data)) == 0;
505} 508}
506 509
507static inline bool nfs4_stateid_match_other(const nfs4_stateid *dst, const nfs4_stateid *src) 510static inline bool nfs4_stateid_match_other(const nfs4_stateid *dst, const nfs4_stateid *src)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 196e41e12621..2516467ff17f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -8675,6 +8675,9 @@ nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
8675static bool nfs41_match_stateid(const nfs4_stateid *s1, 8675static bool nfs41_match_stateid(const nfs4_stateid *s1,
8676 const nfs4_stateid *s2) 8676 const nfs4_stateid *s2)
8677{ 8677{
8678 if (s1->type != s2->type)
8679 return false;
8680
8678 if (memcmp(s1->other, s2->other, sizeof(s1->other)) != 0) 8681 if (memcmp(s1->other, s2->other, sizeof(s1->other)) != 0)
8679 return false; 8682 return false;
8680 8683
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index d854693a15b0..d630f9cca0f1 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -65,7 +65,10 @@
65 65
66#define OPENOWNER_POOL_SIZE 8 66#define OPENOWNER_POOL_SIZE 8
67 67
68const nfs4_stateid zero_stateid; 68const nfs4_stateid zero_stateid = {
69 .data = { 0 },
70 .type = NFS4_SPECIAL_STATEID_TYPE,
71};
69static DEFINE_MUTEX(nfs_clid_init_mutex); 72static DEFINE_MUTEX(nfs_clid_init_mutex);
70 73
71int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 74int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index d1c96fc62c51..661e753fe1c9 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4270,6 +4270,24 @@ static int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
4270 return decode_opaque_fixed(xdr, stateid, NFS4_STATEID_SIZE); 4270 return decode_opaque_fixed(xdr, stateid, NFS4_STATEID_SIZE);
4271} 4271}
4272 4272
4273static int decode_open_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
4274{
4275 stateid->type = NFS4_OPEN_STATEID_TYPE;
4276 return decode_stateid(xdr, stateid);
4277}
4278
4279static int decode_lock_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
4280{
4281 stateid->type = NFS4_LOCK_STATEID_TYPE;
4282 return decode_stateid(xdr, stateid);
4283}
4284
4285static int decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
4286{
4287 stateid->type = NFS4_DELEGATION_STATEID_TYPE;
4288 return decode_stateid(xdr, stateid);
4289}
4290
4273static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res) 4291static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
4274{ 4292{
4275 int status; 4293 int status;
@@ -4278,7 +4296,7 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
4278 if (status != -EIO) 4296 if (status != -EIO)
4279 nfs_increment_open_seqid(status, res->seqid); 4297 nfs_increment_open_seqid(status, res->seqid);
4280 if (!status) 4298 if (!status)
4281 status = decode_stateid(xdr, &res->stateid); 4299 status = decode_open_stateid(xdr, &res->stateid);
4282 return status; 4300 return status;
4283} 4301}
4284 4302
@@ -4937,7 +4955,7 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
4937 if (status == -EIO) 4955 if (status == -EIO)
4938 goto out; 4956 goto out;
4939 if (status == 0) { 4957 if (status == 0) {
4940 status = decode_stateid(xdr, &res->stateid); 4958 status = decode_lock_stateid(xdr, &res->stateid);
4941 if (unlikely(status)) 4959 if (unlikely(status))
4942 goto out; 4960 goto out;
4943 } else if (status == -NFS4ERR_DENIED) 4961 } else if (status == -NFS4ERR_DENIED)
@@ -4966,7 +4984,7 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
4966 if (status != -EIO) 4984 if (status != -EIO)
4967 nfs_increment_lock_seqid(status, res->seqid); 4985 nfs_increment_lock_seqid(status, res->seqid);
4968 if (status == 0) 4986 if (status == 0)
4969 status = decode_stateid(xdr, &res->stateid); 4987 status = decode_lock_stateid(xdr, &res->stateid);
4970 return status; 4988 return status;
4971} 4989}
4972 4990
@@ -5016,7 +5034,7 @@ static int decode_rw_delegation(struct xdr_stream *xdr,
5016 __be32 *p; 5034 __be32 *p;
5017 int status; 5035 int status;
5018 5036
5019 status = decode_stateid(xdr, &res->delegation); 5037 status = decode_delegation_stateid(xdr, &res->delegation);
5020 if (unlikely(status)) 5038 if (unlikely(status))
5021 return status; 5039 return status;
5022 p = xdr_inline_decode(xdr, 4); 5040 p = xdr_inline_decode(xdr, 4);
@@ -5096,7 +5114,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
5096 nfs_increment_open_seqid(status, res->seqid); 5114 nfs_increment_open_seqid(status, res->seqid);
5097 if (status) 5115 if (status)
5098 return status; 5116 return status;
5099 status = decode_stateid(xdr, &res->stateid); 5117 status = decode_open_stateid(xdr, &res->stateid);
5100 if (unlikely(status)) 5118 if (unlikely(status))
5101 return status; 5119 return status;
5102 5120
@@ -5136,7 +5154,7 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre
5136 if (status != -EIO) 5154 if (status != -EIO)
5137 nfs_increment_open_seqid(status, res->seqid); 5155 nfs_increment_open_seqid(status, res->seqid);
5138 if (!status) 5156 if (!status)
5139 status = decode_stateid(xdr, &res->stateid); 5157 status = decode_open_stateid(xdr, &res->stateid);
5140 return status; 5158 return status;
5141} 5159}
5142 5160
@@ -5148,7 +5166,7 @@ static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *re
5148 if (status != -EIO) 5166 if (status != -EIO)
5149 nfs_increment_open_seqid(status, res->seqid); 5167 nfs_increment_open_seqid(status, res->seqid);
5150 if (!status) 5168 if (!status)
5151 status = decode_stateid(xdr, &res->stateid); 5169 status = decode_open_stateid(xdr, &res->stateid);
5152 return status; 5170 return status;
5153} 5171}
5154 5172
@@ -5838,6 +5856,12 @@ out_overflow:
5838} 5856}
5839 5857
5840#if defined(CONFIG_NFS_V4_1) 5858#if defined(CONFIG_NFS_V4_1)
5859static int decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
5860{
5861 stateid->type = NFS4_LAYOUT_STATEID_TYPE;
5862 return decode_stateid(xdr, stateid);
5863}
5864
5841static int decode_getdeviceinfo(struct xdr_stream *xdr, 5865static int decode_getdeviceinfo(struct xdr_stream *xdr,
5842 struct nfs4_getdeviceinfo_res *res) 5866 struct nfs4_getdeviceinfo_res *res)
5843{ 5867{
@@ -5919,7 +5943,7 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
5919 if (unlikely(!p)) 5943 if (unlikely(!p))
5920 goto out_overflow; 5944 goto out_overflow;
5921 res->return_on_close = be32_to_cpup(p); 5945 res->return_on_close = be32_to_cpup(p);
5922 decode_stateid(xdr, &res->stateid); 5946 decode_layout_stateid(xdr, &res->stateid);
5923 p = xdr_inline_decode(xdr, 4); 5947 p = xdr_inline_decode(xdr, 4);
5924 if (unlikely(!p)) 5948 if (unlikely(!p))
5925 goto out_overflow; 5949 goto out_overflow;
@@ -5985,7 +6009,7 @@ static int decode_layoutreturn(struct xdr_stream *xdr,
5985 goto out_overflow; 6009 goto out_overflow;
5986 res->lrs_present = be32_to_cpup(p); 6010 res->lrs_present = be32_to_cpup(p);
5987 if (res->lrs_present) 6011 if (res->lrs_present)
5988 status = decode_stateid(xdr, &res->stateid); 6012 status = decode_layout_stateid(xdr, &res->stateid);
5989 return status; 6013 return status;
5990out_overflow: 6014out_overflow:
5991 print_overflow_msg(__func__, xdr); 6015 print_overflow_msg(__func__, xdr);
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 722509482e1a..e1692c96cbc8 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -50,12 +50,27 @@ struct nfs4_label {
50 50
51typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; 51typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
52 52
53struct nfs_stateid4 { 53struct nfs4_stateid_struct {
54 __be32 seqid; 54 union {
55 char other[NFS4_STATEID_OTHER_SIZE]; 55 char data[NFS4_STATEID_SIZE];
56} __attribute__ ((packed)); 56 struct {
57 __be32 seqid;
58 char other[NFS4_STATEID_OTHER_SIZE];
59 } __attribute__ ((packed));
60 };
61
62 enum {
63 NFS4_INVALID_STATEID_TYPE = 0,
64 NFS4_SPECIAL_STATEID_TYPE,
65 NFS4_OPEN_STATEID_TYPE,
66 NFS4_LOCK_STATEID_TYPE,
67 NFS4_DELEGATION_STATEID_TYPE,
68 NFS4_LAYOUT_STATEID_TYPE,
69 NFS4_PNFS_DS_STATEID_TYPE,
70 } type;
71};
57 72
58typedef struct nfs_stateid4 nfs4_stateid; 73typedef struct nfs4_stateid_struct nfs4_stateid;
59 74
60enum nfs_opnum4 { 75enum nfs_opnum4 {
61 OP_ACCESS = 3, 76 OP_ACCESS = 3,