Commit 469c9f8e authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] NFSv4 server OPEN_CONFIRM

From: "William A.(Andy) Adamson" <andros@citi.umich.edu>

Add OPEN_CONFIRM functionality to the nfsv4 server, including a
preprocess_seqid_op function that will be used in subsequent patches.
parent 121bed24
...@@ -140,10 +140,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open ...@@ -140,10 +140,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
status = nfsd4_process_open2(rqstp, current_fh, open); status = nfsd4_process_open2(rqstp, current_fh, open);
if (status) if (status)
return status; return status;
/*
* To finish the open response, we just need to set the rflags.
*/
open->op_rflags = 0;
return 0; return 0;
} }
...@@ -609,6 +605,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -609,6 +605,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
case OP_OPEN: case OP_OPEN:
op->status = nfsd4_open(rqstp, &current_fh, &op->u.open); op->status = nfsd4_open(rqstp, &current_fh, &op->u.open);
break; break;
case OP_OPEN_CONFIRM:
op->status = nfsd4_open_confirm(rqstp, &current_fh, &op->u.open_confirm);
break;
case OP_PUTFH: case OP_PUTFH:
op->status = nfsd4_putfh(rqstp, &current_fh, &op->u.putfh); op->status = nfsd4_putfh(rqstp, &current_fh, &op->u.putfh);
break; break;
......
This diff is collapsed.
...@@ -659,6 +659,19 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) ...@@ -659,6 +659,19 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
DECODE_TAIL; DECODE_TAIL;
} }
static int
nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
{
DECODE_HEAD;
READ_BUF(4 + sizeof(stateid_t));
READ32(open_conf->oc_req_stateid.si_generation);
COPYMEM(&open_conf->oc_req_stateid.si_opaque, sizeof(stateid_opaque_t));
READ32(open_conf->oc_seqid);
DECODE_TAIL;
}
static int static int
nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
{ {
...@@ -953,6 +966,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) ...@@ -953,6 +966,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
case OP_OPEN: case OP_OPEN:
op->status = nfsd4_decode_open(argp, &op->u.open); op->status = nfsd4_decode_open(argp, &op->u.open);
break; break;
case OP_OPEN_CONFIRM:
op->status = nfsd4_decode_open_confirm(argp, &op->u.open_confirm);
break;
case OP_PUTFH: case OP_PUTFH:
op->status = nfsd4_decode_putfh(argp, &op->u.putfh); op->status = nfsd4_decode_putfh(argp, &op->u.putfh);
break; break;
...@@ -1057,6 +1073,21 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) ...@@ -1057,6 +1073,21 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
} while (0) } while (0)
#define ADJUST_ARGS() resp->p = p #define ADJUST_ARGS() resp->p = p
/*
* Routine for encoding the result of a
* "seqid-mutating" NFSv4 operation. This is
* where seqids are incremented
*/
#define ENCODE_SEQID_OP_TAIL(stateowner) \
BUG_ON(!stateowner); \
if (seqid_mutating_err(nfserr) && stateowner) { \
if (stateowner->so_confirmed) \
stateowner->so_seqid++; \
} \
return nfserr;
static u32 nfs4_ftypes[16] = { static u32 nfs4_ftypes[16] = {
NF4BAD, NF4FIFO, NF4CHR, NF4BAD, NF4BAD, NF4FIFO, NF4CHR, NF4BAD,
NF4DIR, NF4BAD, NF4BLK, NF4BAD, NF4DIR, NF4BAD, NF4BLK, NF4BAD,
...@@ -1701,6 +1732,21 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open ...@@ -1701,6 +1732,21 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open
} }
} }
static int
nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc)
{
ENCODE_HEAD;
if (!nfserr) {
RESERVE_SPACE(sizeof(stateid_t));
WRITE32(oc->oc_resp_stateid.si_generation);
WRITEMEM(&oc->oc_resp_stateid.si_opaque, sizeof(stateid_opaque_t));
ADJUST_ARGS();
}
ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
}
static int static int
nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read)
{ {
...@@ -2013,6 +2059,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) ...@@ -2013,6 +2059,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
case OP_OPEN: case OP_OPEN:
nfsd4_encode_open(resp, op->status, &op->u.open); nfsd4_encode_open(resp, op->status, &op->u.open);
break; break;
case OP_OPEN_CONFIRM:
nfsd4_encode_open_confirm(resp, op->status, &op->u.open_confirm);
break;
case OP_PUTFH: case OP_PUTFH:
break; break;
case OP_PUTROOTFH: case OP_PUTROOTFH:
......
...@@ -92,7 +92,6 @@ update_stateid(stateid_t *stateid) ...@@ -92,7 +92,6 @@ update_stateid(stateid_t *stateid)
stateid->si_generation++; stateid->si_generation++;
} }
/* /*
* nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner * nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner
* *
...@@ -100,6 +99,7 @@ stateid->si_generation++; ...@@ -100,6 +99,7 @@ stateid->si_generation++;
* reverences when we release a stateowner. * reverences when we release a stateowner.
*/ */
struct nfs4_stateowner { struct nfs4_stateowner {
struct list_head so_idhash; /* hash by so_id */
struct list_head so_strhash; /* hash by op_name */ struct list_head so_strhash; /* hash by op_name */
struct list_head so_perclient; /* nfs4_client->cl_perclient */ struct list_head so_perclient; /* nfs4_client->cl_perclient */
struct list_head so_peropenstate; /* list: nfs4_stateid */ struct list_head so_peropenstate; /* list: nfs4_stateid */
...@@ -136,6 +136,7 @@ struct nfs4_file { ...@@ -136,6 +136,7 @@ struct nfs4_file {
*/ */
struct nfs4_stateid { struct nfs4_stateid {
struct list_head st_hash; /* openstateid_hashtbl[]*/
struct list_head st_perfile; /* file_hashtbl[]*/ struct list_head st_perfile; /* file_hashtbl[]*/
struct list_head st_peropenstate; /* nfs4_stateowner->so_peropenstate */ struct list_head st_peropenstate; /* nfs4_stateowner->so_peropenstate */
struct nfs4_stateowner * st_stateowner; struct nfs4_stateowner * st_stateowner;
...@@ -147,4 +148,14 @@ struct nfs4_stateid { ...@@ -147,4 +148,14 @@ struct nfs4_stateid {
unsigned int st_share_deny; unsigned int st_share_deny;
}; };
/* flags for preprocess_seqid_op() */
#define CHECK_FH 0x00000001
#define CONFIRM 0x00000002
#define seqid_mutating_err(err) \
(((err) != nfserr_stale_clientid) && \
((err) != nfserr_bad_seqid) && \
((err) != nfserr_stale_stateid) && \
((err) != nfserr_bad_stateid))
#endif /* NFSD4_STATE_H */ #endif /* NFSD4_STATE_H */
...@@ -147,6 +147,13 @@ struct nfsd4_open { ...@@ -147,6 +147,13 @@ struct nfsd4_open {
#define op_iattr u.iattr #define op_iattr u.iattr
#define op_verf u.verf #define op_verf u.verf
struct nfsd4_open_confirm {
stateid_t oc_req_stateid /* request */;
u32 oc_seqid /* request */;
stateid_t oc_resp_stateid /* response */;
struct nfs4_stateowner * oc_stateowner; /* response */
};
struct nfsd4_read { struct nfsd4_read {
stateid_t rd_stateid; /* request */ stateid_t rd_stateid; /* request */
u64 rd_offset; /* request */ u64 rd_offset; /* request */
...@@ -252,6 +259,7 @@ struct nfsd4_op { ...@@ -252,6 +259,7 @@ struct nfsd4_op {
struct nfsd4_lookup lookup; struct nfsd4_lookup lookup;
struct nfsd4_verify nverify; struct nfsd4_verify nverify;
struct nfsd4_open open; struct nfsd4_open open;
struct nfsd4_open_confirm open_confirm;
struct nfsd4_putfh putfh; struct nfsd4_putfh putfh;
struct nfsd4_read read; struct nfsd4_read read;
struct nfsd4_readdir readdir; struct nfsd4_readdir readdir;
...@@ -315,16 +323,23 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) ...@@ -315,16 +323,23 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
} }
int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *); int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *);
int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *, struct nfsd4_compoundargs *); int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *,
int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *, struct nfsd4_compoundres *); struct nfsd4_compoundargs *);
int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *,
struct nfsd4_compoundres *);
void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval); struct dentry *dentry, u32 *buffer, int *countp,
extern int nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid); u32 *bmval);
extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm); extern int nfsd4_setclientid(struct svc_rqst *rqstp,
struct nfsd4_setclientid *setclid);
extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
struct nfsd4_setclientid_confirm *setclientid_confirm);
extern int nfsd4_process_open1(struct nfsd4_open *open); extern int nfsd4_process_open1(struct nfsd4_open *open);
extern int nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open); extern int nfsd4_process_open2(struct svc_rqst *rqstp,
struct svc_fh *current_fh, struct nfsd4_open *open);
extern int nfsd4_open_confirm(struct svc_rqst *rqstp,
struct svc_fh *current_fh, struct nfsd4_open_confirm *oc);
#endif #endif
/* /*
......
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