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 976c906..d81f96a 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 60d690d..53b6391 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 56296f3..eeef893 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 4afdee4..b5d9f34 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 196e41e..2516467 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 d854693..d630f9c 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 d1c96fc..661e753 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 7225094..e1692c9 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,