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>
This commit is contained in:
Trond Myklebust 2016-05-16 17:42:43 -04:00 committed by Anna Schumaker
parent 9a8f6b5ea2
commit 93b717fd81
8 changed files with 85 additions and 24 deletions

View File

@ -146,10 +146,16 @@ static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
p = read_buf(xdr, NFS4_STATEID_SIZE); p = read_buf(xdr, NFS4_STATEID_SIZE);
if (unlikely(p == NULL)) if (unlikely(p == NULL))
return htonl(NFS4ERR_RESOURCE); return htonl(NFS4ERR_RESOURCE);
memcpy(stateid, p, NFS4_STATEID_SIZE); memcpy(stateid->data, p, NFS4_STATEID_SIZE);
return 0; 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) static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
{ {
__be32 *p; __be32 *p;
@ -211,7 +217,7 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr,
__be32 *p; __be32 *p;
__be32 status; __be32 status;
status = decode_stateid(xdr, &args->stateid); status = decode_delegation_stateid(xdr, &args->stateid);
if (unlikely(status != 0)) if (unlikely(status != 0))
goto out; goto out;
p = read_buf(xdr, 4); p = read_buf(xdr, 4);
@ -227,6 +233,11 @@ out:
} }
#if defined(CONFIG_NFS_V4_1) #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, static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
struct xdr_stream *xdr, 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.offset);
p = xdr_decode_hyper(p, &args->cbl_range.length); 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)) if (unlikely(status != 0))
goto out; goto out;
} else if (args->cbl_recall_type == RETURN_FSID) { } else if (args->cbl_recall_type == RETURN_FSID) {

View File

@ -55,14 +55,15 @@ ff_layout_free_layout_hdr(struct pnfs_layout_hdr *lo)
kfree(FF_LAYOUT_FROM_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; __be32 *p;
p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE); p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE);
if (unlikely(p == NULL)) if (unlikely(p == NULL))
return -ENOBUFS; 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__, dprintk("%s: stateid id= [%x%x%x%x]\n", __func__,
p[0], p[1], p[2], p[3]); p[0], p[1], p[2], p[3]);
return 0; return 0;
@ -465,7 +466,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
fls->mirror_array[i]->efficiency = be32_to_cpup(p); fls->mirror_array[i]->efficiency = be32_to_cpup(p);
/* stateid */ /* stateid */
rc = decode_stateid(&stream, &fls->mirror_array[i]->stateid); rc = decode_pnfs_stateid(&stream, &fls->mirror_array[i]->stateid);
if (rc) if (rc)
goto out_err_free; goto out_err_free;

View File

@ -228,7 +228,8 @@ ff_ds_error_match(const struct nfs4_ff_layout_ds_err *e1,
return e1->opnum < e2->opnum ? -1 : 1; return e1->opnum < e2->opnum ? -1 : 1;
if (e1->status != e2->status) if (e1->status != e2->status)
return e1->status < e2->status ? -1 : 1; 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) if (ret != 0)
return ret; return ret;
ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid)); ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));

View 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) 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) 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) static inline bool nfs4_stateid_match_other(const nfs4_stateid *dst, const nfs4_stateid *src)

View 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, static bool nfs41_match_stateid(const nfs4_stateid *s1,
const nfs4_stateid *s2) const nfs4_stateid *s2)
{ {
if (s1->type != s2->type)
return false;
if (memcmp(s1->other, s2->other, sizeof(s1->other)) != 0) if (memcmp(s1->other, s2->other, sizeof(s1->other)) != 0)
return false; return false;

View File

@ -65,7 +65,10 @@
#define OPENOWNER_POOL_SIZE 8 #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); static DEFINE_MUTEX(nfs_clid_init_mutex);
int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)

View 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); 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) static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
{ {
int status; int status;
@ -4278,7 +4296,7 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
if (status != -EIO) if (status != -EIO)
nfs_increment_open_seqid(status, res->seqid); nfs_increment_open_seqid(status, res->seqid);
if (!status) if (!status)
status = decode_stateid(xdr, &res->stateid); status = decode_open_stateid(xdr, &res->stateid);
return status; return status;
} }
@ -4937,7 +4955,7 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
if (status == -EIO) if (status == -EIO)
goto out; goto out;
if (status == 0) { if (status == 0) {
status = decode_stateid(xdr, &res->stateid); status = decode_lock_stateid(xdr, &res->stateid);
if (unlikely(status)) if (unlikely(status))
goto out; goto out;
} else if (status == -NFS4ERR_DENIED) } 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) if (status != -EIO)
nfs_increment_lock_seqid(status, res->seqid); nfs_increment_lock_seqid(status, res->seqid);
if (status == 0) if (status == 0)
status = decode_stateid(xdr, &res->stateid); status = decode_lock_stateid(xdr, &res->stateid);
return status; return status;
} }
@ -5016,7 +5034,7 @@ static int decode_rw_delegation(struct xdr_stream *xdr,
__be32 *p; __be32 *p;
int status; int status;
status = decode_stateid(xdr, &res->delegation); status = decode_delegation_stateid(xdr, &res->delegation);
if (unlikely(status)) if (unlikely(status))
return status; return status;
p = xdr_inline_decode(xdr, 4); 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); nfs_increment_open_seqid(status, res->seqid);
if (status) if (status)
return status; return status;
status = decode_stateid(xdr, &res->stateid); status = decode_open_stateid(xdr, &res->stateid);
if (unlikely(status)) if (unlikely(status))
return status; return status;
@ -5136,7 +5154,7 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre
if (status != -EIO) if (status != -EIO)
nfs_increment_open_seqid(status, res->seqid); nfs_increment_open_seqid(status, res->seqid);
if (!status) if (!status)
status = decode_stateid(xdr, &res->stateid); status = decode_open_stateid(xdr, &res->stateid);
return status; return status;
} }
@ -5148,7 +5166,7 @@ static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *re
if (status != -EIO) if (status != -EIO)
nfs_increment_open_seqid(status, res->seqid); nfs_increment_open_seqid(status, res->seqid);
if (!status) if (!status)
status = decode_stateid(xdr, &res->stateid); status = decode_open_stateid(xdr, &res->stateid);
return status; return status;
} }
@ -5838,6 +5856,12 @@ out_overflow:
} }
#if defined(CONFIG_NFS_V4_1) #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, static int decode_getdeviceinfo(struct xdr_stream *xdr,
struct nfs4_getdeviceinfo_res *res) struct nfs4_getdeviceinfo_res *res)
{ {
@ -5919,7 +5943,7 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
if (unlikely(!p)) if (unlikely(!p))
goto out_overflow; goto out_overflow;
res->return_on_close = be32_to_cpup(p); 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); p = xdr_inline_decode(xdr, 4);
if (unlikely(!p)) if (unlikely(!p))
goto out_overflow; goto out_overflow;
@ -5985,7 +6009,7 @@ static int decode_layoutreturn(struct xdr_stream *xdr,
goto out_overflow; goto out_overflow;
res->lrs_present = be32_to_cpup(p); res->lrs_present = be32_to_cpup(p);
if (res->lrs_present) if (res->lrs_present)
status = decode_stateid(xdr, &res->stateid); status = decode_layout_stateid(xdr, &res->stateid);
return status; return status;
out_overflow: out_overflow:
print_overflow_msg(__func__, xdr); print_overflow_msg(__func__, xdr);

View File

@ -50,12 +50,27 @@ struct nfs4_label {
typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
struct nfs_stateid4 { struct nfs4_stateid_struct {
union {
char data[NFS4_STATEID_SIZE];
struct {
__be32 seqid; __be32 seqid;
char other[NFS4_STATEID_OTHER_SIZE]; char other[NFS4_STATEID_OTHER_SIZE];
} __attribute__ ((packed)); } __attribute__ ((packed));
};
typedef struct nfs_stateid4 nfs4_stateid; 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 nfs4_stateid_struct nfs4_stateid;
enum nfs_opnum4 { enum nfs_opnum4 {
OP_ACCESS = 3, OP_ACCESS = 3,