summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2004-08-23 11:55:27 -0400
committerTrond Myklebust <trond.myklebust@fys.uio.no>2004-08-23 11:55:27 -0400
commitb678478658b6561dc3e6a5afa7763255f77b74a0 (patch)
treec8562f31a23b1f9471172d998aaa550bc696786b
parent2fa8729d3f444269d7600b42c24acecd5163dda0 (diff)
NFSv4: XDR cleanups in preparation for delegations.
Signed-off-by: Trond Myklebust <trond.myklebust@fys.uio.no>
-rw-r--r--fs/nfs/nfs4proc.c16
-rw-r--r--fs/nfs/nfs4xdr.c190
-rw-r--r--include/linux/nfs_xdr.h26
3 files changed, 134 insertions, 98 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 26e6e8db5f7e..89d211ad5156 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -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 = {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 3130270fff67..e22f1d6fc53a 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -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 @@ out:
/*
* 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);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 5a1e67ffc728..90fbb9d1514f 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -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;
};
@@ -142,26 +143,13 @@ struct nfs_open_confirmres {
};
/*
- * 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.
*/
struct nfs_closeargs {
struct nfs_fh * fh;
nfs4_stateid stateid;
__u32 seqid;
- __u32 share_access;
+ int open_flags;
};
struct nfs_closeres {