NFSv4: Label stateids with the type
authorTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 16 May 2016 21:42:43 +0000 (17:42 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 17 May 2016 19:48:06 +0000 (15:48 -0400)
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>
fs/nfs/callback_xdr.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c
include/linux/nfs4.h

index 976c90608e5618103d385a3436cafe461873a867..d81f96aacd51e71b1da710b477e7d44ff9a90b24 100644 (file)
@@ -146,10 +146,16 @@ static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
        p = read_buf(xdr, NFS4_STATEID_SIZE);
        if (unlikely(p == NULL))
                return htonl(NFS4ERR_RESOURCE);
-       memcpy(stateid, p, NFS4_STATEID_SIZE);
+       memcpy(stateid->data, p, NFS4_STATEID_SIZE);
        return 0;
 }
 
+static __be32 decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+{
+       stateid->type = NFS4_DELEGATION_STATEID_TYPE;
+       return decode_stateid(xdr, stateid);
+}
+
 static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
 {
        __be32 *p;
@@ -211,7 +217,7 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr,
        __be32 *p;
        __be32 status;
 
-       status = decode_stateid(xdr, &args->stateid);
+       status = decode_delegation_stateid(xdr, &args->stateid);
        if (unlikely(status != 0))
                goto out;
        p = read_buf(xdr, 4);
@@ -227,6 +233,11 @@ out:
 }
 
 #if defined(CONFIG_NFS_V4_1)
+static __be32 decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+{
+       stateid->type = NFS4_LAYOUT_STATEID_TYPE;
+       return decode_stateid(xdr, stateid);
+}
 
 static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
                                       struct xdr_stream *xdr,
@@ -263,7 +274,7 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
                }
                p = xdr_decode_hyper(p, &args->cbl_range.offset);
                p = xdr_decode_hyper(p, &args->cbl_range.length);
-               status = decode_stateid(xdr, &args->cbl_stateid);
+               status = decode_layout_stateid(xdr, &args->cbl_stateid);
                if (unlikely(status != 0))
                        goto out;
        } else if (args->cbl_recall_type == RETURN_FSID) {
index 60d690dbc947675fb81303f3b42971bff17f9a42..53b6391e0ebace7f791a376e5f59a3268af1890d 100644 (file)
@@ -55,14 +55,15 @@ ff_layout_free_layout_hdr(struct pnfs_layout_hdr *lo)
        kfree(FF_LAYOUT_FROM_HDR(lo));
 }
 
-static int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+static int decode_pnfs_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
 {
        __be32 *p;
 
        p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE);
        if (unlikely(p == NULL))
                return -ENOBUFS;
-       memcpy(stateid, p, NFS4_STATEID_SIZE);
+       stateid->type = NFS4_PNFS_DS_STATEID_TYPE;
+       memcpy(stateid->data, p, NFS4_STATEID_SIZE);
        dprintk("%s: stateid id= [%x%x%x%x]\n", __func__,
                p[0], p[1], p[2], p[3]);
        return 0;
@@ -465,7 +466,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
                fls->mirror_array[i]->efficiency = be32_to_cpup(p);
 
                /* stateid */
-               rc = decode_stateid(&stream, &fls->mirror_array[i]->stateid);
+               rc = decode_pnfs_stateid(&stream, &fls->mirror_array[i]->stateid);
                if (rc)
                        goto out_err_free;
 
index 56296f3df19c33d8f381a8144397f1feb3c07ece..eeef89359ad22223100a7437d6db40572d4642ef 100644 (file)
@@ -228,7 +228,8 @@ ff_ds_error_match(const struct nfs4_ff_layout_ds_err *e1,
                return e1->opnum < e2->opnum ? -1 : 1;
        if (e1->status != e2->status)
                return e1->status < e2->status ? -1 : 1;
-       ret = memcmp(&e1->stateid, &e2->stateid, sizeof(e1->stateid));
+       ret = memcmp(e1->stateid.data, e2->stateid.data,
+                       sizeof(e1->stateid.data));
        if (ret != 0)
                return ret;
        ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
index 4afdee420d253862e7dded0d84f6743b00de337f..b5d9f345c9f2f2d1f441babccdddde45208df817 100644 (file)
@@ -496,12 +496,15 @@ extern struct svc_version nfs4_callback_version4;
 
 static inline void nfs4_stateid_copy(nfs4_stateid *dst, const nfs4_stateid *src)
 {
-       memcpy(dst, src, sizeof(*dst));
+       memcpy(dst->data, src->data, sizeof(dst->data));
+       dst->type = src->type;
 }
 
 static inline bool nfs4_stateid_match(const nfs4_stateid *dst, const nfs4_stateid *src)
 {
-       return memcmp(dst, src, sizeof(*dst)) == 0;
+       if (dst->type != src->type)
+               return false;
+       return memcmp(dst->data, src->data, sizeof(dst->data)) == 0;
 }
 
 static inline bool nfs4_stateid_match_other(const nfs4_stateid *dst, const nfs4_stateid *src)
index 196e41e126212ced0927068c27e23c8aaa5abfff..2516467ff17f412b6ff73abaccf11be528e5973b 100644 (file)
@@ -8675,6 +8675,9 @@ nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
 static bool nfs41_match_stateid(const nfs4_stateid *s1,
                const nfs4_stateid *s2)
 {
+       if (s1->type != s2->type)
+               return false;
+
        if (memcmp(s1->other, s2->other, sizeof(s1->other)) != 0)
                return false;
 
index d854693a15b0e2443779986552d29d9db3f6cdc2..d630f9cca0f1dd489aa9d9bbb63538d3986911c5 100644 (file)
 
 #define OPENOWNER_POOL_SIZE    8
 
-const nfs4_stateid zero_stateid;
+const nfs4_stateid zero_stateid = {
+       .data = { 0 },
+       .type = NFS4_SPECIAL_STATEID_TYPE,
+};
 static DEFINE_MUTEX(nfs_clid_init_mutex);
 
 int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
index d1c96fc62c5174b70518fe9556e66a2cdb9aa0f1..661e753fe1c93d0c6be59fd26c0339316d50ee12 100644 (file)
@@ -4270,6 +4270,24 @@ static int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
        return decode_opaque_fixed(xdr, stateid, NFS4_STATEID_SIZE);
 }
 
+static int decode_open_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+{
+       stateid->type = NFS4_OPEN_STATEID_TYPE;
+       return decode_stateid(xdr, stateid);
+}
+
+static int decode_lock_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+{
+       stateid->type = NFS4_LOCK_STATEID_TYPE;
+       return decode_stateid(xdr, stateid);
+}
+
+static int decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+{
+       stateid->type = NFS4_DELEGATION_STATEID_TYPE;
+       return decode_stateid(xdr, stateid);
+}
+
 static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
 {
        int status;
@@ -4278,7 +4296,7 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
        if (status != -EIO)
                nfs_increment_open_seqid(status, res->seqid);
        if (!status)
-               status = decode_stateid(xdr, &res->stateid);
+               status = decode_open_stateid(xdr, &res->stateid);
        return status;
 }
 
@@ -4937,7 +4955,7 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
        if (status == -EIO)
                goto out;
        if (status == 0) {
-               status = decode_stateid(xdr, &res->stateid);
+               status = decode_lock_stateid(xdr, &res->stateid);
                if (unlikely(status))
                        goto out;
        } else if (status == -NFS4ERR_DENIED)
@@ -4966,7 +4984,7 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
        if (status != -EIO)
                nfs_increment_lock_seqid(status, res->seqid);
        if (status == 0)
-               status = decode_stateid(xdr, &res->stateid);
+               status = decode_lock_stateid(xdr, &res->stateid);
        return status;
 }
 
@@ -5016,7 +5034,7 @@ static int decode_rw_delegation(struct xdr_stream *xdr,
        __be32 *p;
        int status;
 
-       status = decode_stateid(xdr, &res->delegation);
+       status = decode_delegation_stateid(xdr, &res->delegation);
        if (unlikely(status))
                return status;
        p = xdr_inline_decode(xdr, 4);
@@ -5096,7 +5114,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
        nfs_increment_open_seqid(status, res->seqid);
        if (status)
                return status;
-       status = decode_stateid(xdr, &res->stateid);
+       status = decode_open_stateid(xdr, &res->stateid);
        if (unlikely(status))
                return status;
 
@@ -5136,7 +5154,7 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre
        if (status != -EIO)
                nfs_increment_open_seqid(status, res->seqid);
        if (!status)
-               status = decode_stateid(xdr, &res->stateid);
+               status = decode_open_stateid(xdr, &res->stateid);
        return status;
 }
 
@@ -5148,7 +5166,7 @@ static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *re
        if (status != -EIO)
                nfs_increment_open_seqid(status, res->seqid);
        if (!status)
-               status = decode_stateid(xdr, &res->stateid);
+               status = decode_open_stateid(xdr, &res->stateid);
        return status;
 }
 
@@ -5838,6 +5856,12 @@ out_overflow:
 }
 
 #if defined(CONFIG_NFS_V4_1)
+static int decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+{
+       stateid->type = NFS4_LAYOUT_STATEID_TYPE;
+       return decode_stateid(xdr, stateid);
+}
+
 static int decode_getdeviceinfo(struct xdr_stream *xdr,
                                struct nfs4_getdeviceinfo_res *res)
 {
@@ -5919,7 +5943,7 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
        if (unlikely(!p))
                goto out_overflow;
        res->return_on_close = be32_to_cpup(p);
-       decode_stateid(xdr, &res->stateid);
+       decode_layout_stateid(xdr, &res->stateid);
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(!p))
                goto out_overflow;
@@ -5985,7 +6009,7 @@ static int decode_layoutreturn(struct xdr_stream *xdr,
                goto out_overflow;
        res->lrs_present = be32_to_cpup(p);
        if (res->lrs_present)
-               status = decode_stateid(xdr, &res->stateid);
+               status = decode_layout_stateid(xdr, &res->stateid);
        return status;
 out_overflow:
        print_overflow_msg(__func__, xdr);
index 722509482e1aada428bbb4b6fc3096f1a096b353..e1692c96cbc822e749e45931672266579c566f55 100644 (file)
@@ -50,12 +50,27 @@ struct nfs4_label {
 
 typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
 
-struct nfs_stateid4 {
-       __be32 seqid;
-       char other[NFS4_STATEID_OTHER_SIZE];
-} __attribute__ ((packed));
+struct nfs4_stateid_struct {
+       union {
+               char data[NFS4_STATEID_SIZE];
+               struct {
+                       __be32 seqid;
+                       char other[NFS4_STATEID_OTHER_SIZE];
+               } __attribute__ ((packed));
+       };
+
+       enum {
+               NFS4_INVALID_STATEID_TYPE = 0,
+               NFS4_SPECIAL_STATEID_TYPE,
+               NFS4_OPEN_STATEID_TYPE,
+               NFS4_LOCK_STATEID_TYPE,
+               NFS4_DELEGATION_STATEID_TYPE,
+               NFS4_LAYOUT_STATEID_TYPE,
+               NFS4_PNFS_DS_STATEID_TYPE,
+       } type;
+};
 
-typedef struct nfs_stateid4 nfs4_stateid;
+typedef struct nfs4_stateid_struct nfs4_stateid;
 
 enum nfs_opnum4 {
        OP_ACCESS = 3,