Commit b6784786 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: XDR cleanups in preparation for delegations.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
parent 2fa8729d
......@@ -199,11 +199,11 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st
struct nfs_fattr fattr = {
.valid = 0,
};
struct nfs_open_reclaimargs o_arg = {
struct nfs_openargs o_arg = {
.fh = NFS_FH(inode),
.seqid = sp->so_seqid,
.id = sp->so_id,
.share_access = state->state,
.open_flags = state->state,
.clientid = server->nfs4_state->cl_clientid,
.claim = NFS4_OPEN_CLAIM_PREVIOUS,
.bitmask = server->attr_bitmask,
......@@ -264,12 +264,11 @@ static int _nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct
};
struct nfs_openargs o_arg = {
.fh = NFS_FH(dir),
.share_access = flags & (FMODE_READ|FMODE_WRITE),
.opentype = (flags & O_CREAT) ? NFS4_OPEN_CREATE : NFS4_OPEN_NOCREATE,
.createmode = (flags & O_EXCL) ? NFS4_CREATE_EXCLUSIVE : NFS4_CREATE_UNCHECKED,
.open_flags = flags,
.name = name,
.server = server,
.bitmask = server->attr_bitmask,
.claim = NFS4_OPEN_CLAIM_NULL,
};
struct nfs_openres o_res = {
.f_attr = &f_attr,
......@@ -289,13 +288,12 @@ static int _nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct
dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n");
goto out_err;
}
if (o_arg.createmode & NFS4_CREATE_EXCLUSIVE){
if (flags & O_EXCL) {
u32 *p = (u32 *) o_arg.u.verifier.data;
p[0] = jiffies;
p[1] = current->pid;
} else if (o_arg.createmode == NFS4_CREATE_UNCHECKED) {
} else
o_arg.u.attrs = sattr;
}
/* Serialization for the sequence id */
down(&sp->so_sema);
o_arg.seqid = sp->so_seqid;
......@@ -516,7 +514,7 @@ static int _nfs4_do_downgrade(struct inode *inode, struct nfs4_state *state, mod
struct nfs_closeargs arg = {
.fh = NFS_FH(inode),
.seqid = sp->so_seqid,
.share_access = mode,
.open_flags = mode,
};
struct nfs_closeres res;
struct rpc_message msg = {
......
......@@ -434,6 +434,15 @@ static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
return 0;
}
static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf)
{
uint32_t *p;
p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
BUG_ON(p == NULL);
xdr_encode_opaque_fixed(p, verf->data, NFS4_VERIFIER_SIZE);
}
static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server)
{
char owner_name[IDMAP_NAMESZ];
......@@ -774,19 +783,12 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
return 0;
}
static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)
static void encode_share_access(struct xdr_stream *xdr, int open_flags)
{
int status;
uint32_t *p;
/*
* opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
* owner 4, opentype 4 = 36
*/
RESERVE_SPACE(36);
WRITE32(OP_OPEN);
WRITE32(arg->seqid);
switch (arg->share_access) {
RESERVE_SPACE(8);
switch (open_flags & (FMODE_READ|FMODE_WRITE)) {
case FMODE_READ:
WRITE32(NFS4_SHARE_ACCESS_READ);
break;
......@@ -799,84 +801,135 @@ static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)
default:
BUG();
}
WRITE32(0); /* for linux, share_deny = 0 always */
WRITE32(0); /* for linux, share_deny = 0 always */
}
static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
uint32_t *p;
/*
* opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
* owner 4 = 32
*/
RESERVE_SPACE(8);
WRITE32(OP_OPEN);
WRITE32(arg->seqid);
encode_share_access(xdr, arg->open_flags);
RESERVE_SPACE(16);
WRITE64(arg->clientid);
WRITE32(4);
WRITE32(arg->id);
WRITE32(arg->opentype);
}
if (arg->opentype == NFS4_OPEN_CREATE) {
if (arg->createmode == NFS4_CREATE_EXCLUSIVE) {
RESERVE_SPACE(12);
WRITE32(arg->createmode);
WRITEMEM(arg->u.verifier.data, sizeof(arg->u.verifier.data));
}
else if (arg->u.attrs) {
RESERVE_SPACE(4);
WRITE32(arg->createmode);
if ((status = encode_attrs(xdr, arg->u.attrs, arg->server)))
return status;
}
else {
RESERVE_SPACE(12);
WRITE32(arg->createmode);
WRITE32(0);
WRITE32(0);
}
static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
uint32_t *p;
RESERVE_SPACE(4);
switch(arg->open_flags & O_EXCL) {
case 0:
WRITE32(NFS4_CREATE_UNCHECKED);
encode_attrs(xdr, arg->u.attrs, arg->server);
break;
default:
WRITE32(NFS4_CREATE_EXCLUSIVE);
encode_nfs4_verifier(xdr, &arg->u.verifier);
}
}
RESERVE_SPACE(8 + arg->name->len);
WRITE32(NFS4_OPEN_CLAIM_NULL);
WRITE32(arg->name->len);
WRITEMEM(arg->name->name, arg->name->len);
static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
uint32_t *p;
return 0;
RESERVE_SPACE(4);
switch (arg->open_flags & O_CREAT) {
case 0:
WRITE32(NFS4_OPEN_NOCREATE);
break;
default:
BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
WRITE32(NFS4_OPEN_CREATE);
encode_createmode(xdr, arg);
}
}
static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg)
static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation_type)
{
uint32_t *p;
RESERVE_SPACE(8+sizeof(arg->stateid.data));
WRITE32(OP_OPEN_CONFIRM);
WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
WRITE32(arg->seqid);
RESERVE_SPACE(4);
switch (delegation_type) {
case 0:
WRITE32(NFS4_OPEN_DELEGATE_NONE);
break;
case FMODE_READ:
WRITE32(NFS4_OPEN_DELEGATE_READ);
break;
case FMODE_WRITE|FMODE_READ:
WRITE32(NFS4_OPEN_DELEGATE_WRITE);
break;
default:
BUG();
}
}
return 0;
static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name)
{
uint32_t *p;
RESERVE_SPACE(4);
WRITE32(NFS4_OPEN_CLAIM_NULL);
encode_string(xdr, name->len, name->name);
}
static inline void encode_claim_previous(struct xdr_stream *xdr, int type)
{
uint32_t *p;
static int encode_open_reclaim(struct xdr_stream *xdr, const struct nfs_open_reclaimargs *arg)
RESERVE_SPACE(4);
WRITE32(NFS4_OPEN_CLAIM_PREVIOUS);
encode_delegation_type(xdr, type);
}
static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid)
{
uint32_t *p;
/*
* opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
* owner 4, opentype 4, claim 4, delegation_type 4 = 44
*/
RESERVE_SPACE(44);
WRITE32(OP_OPEN);
WRITE32(arg->seqid);
switch (arg->share_access) {
case FMODE_READ:
WRITE32(NFS4_SHARE_ACCESS_READ);
RESERVE_SPACE(4+sizeof(stateid->data));
WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR);
WRITEMEM(stateid->data, sizeof(stateid->data));
encode_string(xdr, name->len, name->name);
}
static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
encode_openhdr(xdr, arg);
encode_opentype(xdr, arg);
switch (arg->claim) {
case NFS4_OPEN_CLAIM_NULL:
encode_claim_null(xdr, arg->name);
break;
case FMODE_WRITE:
WRITE32(NFS4_SHARE_ACCESS_WRITE);
case NFS4_OPEN_CLAIM_PREVIOUS:
encode_claim_previous(xdr, arg->u.delegation_type);
break;
case FMODE_READ|FMODE_WRITE:
WRITE32(NFS4_SHARE_ACCESS_BOTH);
case NFS4_OPEN_CLAIM_DELEGATE_CUR:
encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
break;
default:
BUG();
}
WRITE32(0); /* for linux, share_deny = 0 always */
WRITE64(arg->clientid);
WRITE32(4);
WRITE32(arg->id);
WRITE32(NFS4_OPEN_NOCREATE);
WRITE32(NFS4_OPEN_CLAIM_PREVIOUS);
WRITE32(NFS4_OPEN_DELEGATE_NONE);
return 0;
}
static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg)
{
uint32_t *p;
RESERVE_SPACE(8+sizeof(arg->stateid.data));
WRITE32(OP_OPEN_CONFIRM);
WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
WRITE32(arg->seqid);
return 0;
}
......@@ -884,14 +937,11 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
{
uint32_t *p;
RESERVE_SPACE(16+sizeof(arg->stateid.data));
RESERVE_SPACE(8+sizeof(arg->stateid.data));
WRITE32(OP_OPEN_DOWNGRADE);
WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
WRITE32(arg->seqid);
WRITE32(arg->share_access);
/* No deny modes */
WRITE32(0);
encode_share_access(xdr, arg->open_flags);
return 0;
}
......@@ -1377,7 +1427,7 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n
/*
* Encode an OPEN request
*/
static int nfs4_xdr_enc_open_reclaim(struct rpc_rqst *req, uint32_t *p, struct nfs_open_reclaimargs *args)
static int nfs4_xdr_enc_open_reclaim(struct rpc_rqst *req, uint32_t *p, struct nfs_openargs *args)
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
......@@ -1390,7 +1440,7 @@ static int nfs4_xdr_enc_open_reclaim(struct rpc_rqst *req, uint32_t *p, struct n
status = encode_putfh(&xdr, args->fh);
if (status)
goto out;
status = encode_open_reclaim(&xdr, args);
status = encode_open(&xdr, args);
if (status)
goto out;
status = encode_getfattr(&xdr, args->bitmask);
......
......@@ -99,20 +99,21 @@ struct nfs4_change_info {
* Arguments to the open call.
*/
struct nfs_openargs {
struct nfs_fh * fh;
const struct nfs_fh * fh;
__u32 seqid;
__u32 share_access;
int open_flags;
__u64 clientid;
__u32 id;
__u32 opentype;
__u32 createmode;
union {
struct iattr * attrs; /* UNCHECKED, GUARDED */
nfs4_verifier verifier; /* EXCLUSIVE */
nfs4_stateid delegation; /* CLAIM_DELEGATE_CUR */
int delegation_type; /* CLAIM_PREVIOUS */
} u;
const struct qstr * name;
const struct nfs_server *server; /* Needed for ID mapping */
const u32 * bitmask;
__u32 claim;
};
struct nfs_openres {
......@@ -132,7 +133,7 @@ struct nfs_openres {
* Arguments to the open_confirm call.
*/
struct nfs_open_confirmargs {
struct nfs_fh * fh;
const struct nfs_fh * fh;
nfs4_stateid stateid;
__u32 seqid;
};
......@@ -141,19 +142,6 @@ struct nfs_open_confirmres {
nfs4_stateid stateid;
};
/*
* Arguments to the open_reclaim call.
*/
struct nfs_open_reclaimargs {
struct nfs_fh * fh;
__u64 clientid;
__u32 seqid;
__u32 id;
__u32 share_access;
__u32 claim;
const __u32 * bitmask;
};
/*
* Arguments to the close call.
*/
......@@ -161,7 +149,7 @@ struct nfs_closeargs {
struct nfs_fh * fh;
nfs4_stateid stateid;
__u32 seqid;
__u32 share_access;
int open_flags;
};
struct nfs_closeres {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment