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