diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2003-05-20 06:20:41 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-05-20 06:20:41 -0700 |
| commit | 448d25b80b05679c2d70438530b9cff354eb3d7a (patch) | |
| tree | d97334c2afb25cc71aa64bc3a3d742157fda3824 /include | |
| parent | 9c88ef1f872a99f914b8fe607d01ecd2a965c34b (diff) | |
[PATCH] kNFSd: NFSv4 open share state patch
From: "William A.(Andy) Adamson" <andros@citi.umich.edu>
this open share state patch creates all the structures and hash tables needed
to create and destroy share state on OPEN.
a struct nfs4_stateowner is introduced. this is currently only used for share
state, but will also be used as an anchor for byte-range lock state. e.g. it
will be either an (open)stateowner or a (lock)stateower.
a struct nfs4_stateid is introduced with holds stateid info for openfiles per
(open)stateowner. this struct will also hold byte-range lock info for
(lock)stateowners.
ownerstr_hashtbl[] holds nfs4_stateowners hashed by the nfs4_open owner and
clientid, and is used to lookup nfs4_stateowners on OPEN.
a struct nfs4_file is introduced which holds info on open files with state.
file_hashtbl[] holds nfs4_files, and is used to find a file in order to search
for conflicting share locks on OPEN. delegation info will hang off the
nf4_file struct.
i moved nfsd4_process_open1() into nfs4state.c, and added nfs4_process_open2()
there as well
i've left lease management, state reclaim, and the special replay management
on sequenceid mutating operations like OPEN for subsequent patches.
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/nfs.h | 9 | ||||
| -rw-r--r-- | include/linux/nfsd/nfsd.h | 6 | ||||
| -rw-r--r-- | include/linux/nfsd/state.h | 66 | ||||
| -rw-r--r-- | include/linux/nfsd/xdr4.h | 4 |
4 files changed, 80 insertions, 5 deletions
diff --git a/include/linux/nfs.h b/include/linux/nfs.h index d99650a19b55..a68c459779e8 100644 --- a/include/linux/nfs.h +++ b/include/linux/nfs.h @@ -85,9 +85,9 @@ NFSERR_NOFILEHANDLE = 10020, /* v4 */ NFSERR_MINOR_VERS_MISMATCH = 10021, /* v4 */ NFSERR_STALE_CLIENTID = 10022, /* v4 */ - NFSERR_STALE_STATEID = 10023, /* v4 */ - NFSERR_OLD_STATEID = 10024, /* v4 */ - NFSERR_BAD_STATEID = 10025, /* v4 */ + NFSERR_STALE_STATEID = 10023, /* v4 */ + NFSERR_OLD_STATEID = 10024, /* v4 */ + NFSERR_BAD_STATEID = 10025, /* v4 */ NFSERR_BAD_SEQID = 10026, /* v4 */ NFSERR_NOT_SAME = 10027, /* v4 */ NFSERR_LOCK_RANGE = 10028, /* v4 */ @@ -99,7 +99,8 @@ NFSERR_RECLAIM_BAD = 10034, /* v4 */ NFSERR_RECLAIM_CONFLICT = 10035,/* v4 */ NFSERR_BAD_XDR = 10036, /* v4 */ - NFSERR_LOCKS_HELD = 10037 /* v4 */ + NFSERR_LOCKS_HELD = 10037, /* v4 */ + NFSERR_REPLAY_ME = 10038 /* v4 */ }; /* NFSv2 file types - beware, these are not the same in NFSv3 */ diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 379b77114c5b..c7726a375b38 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h @@ -170,6 +170,7 @@ void nfsd_lockd_shutdown(void); #define nfserr_serverfault __constant_htonl(NFSERR_SERVERFAULT) #define nfserr_badtype __constant_htonl(NFSERR_BADTYPE) #define nfserr_jukebox __constant_htonl(NFSERR_JUKEBOX) +#define nfserr_expired __constant_htonl(NFSERR_EXPIRED) #define nfserr_bad_cookie __constant_htonl(NFSERR_BAD_COOKIE) #define nfserr_same __constant_htonl(NFSERR_SAME) #define nfserr_clid_inuse __constant_htonl(NFSERR_CLID_INUSE) @@ -177,6 +178,11 @@ void nfsd_lockd_shutdown(void); #define nfserr_resource __constant_htonl(NFSERR_RESOURCE) #define nfserr_nofilehandle __constant_htonl(NFSERR_NOFILEHANDLE) #define nfserr_minor_vers_mismatch __constant_htonl(NFSERR_MINOR_VERS_MISMATCH) +#define nfserr_share_denied __constant_htonl(NFSERR_SHARE_DENIED) +#define nfserr_stale_stateid __constant_htonl(NFSERR_STALE_STATEID) +#define nfserr_old_stateid __constant_htonl(NFSERR_OLD_STATEID) +#define nfserr_bad_stateid __constant_htonl(NFSERR_BAD_STATEID) +#define nfserr_bad_seqid __constant_htonl(NFSERR_BAD_SEQID) #define nfserr_symlink __constant_htonl(NFSERR_SYMLINK) #define nfserr_not_same __constant_htonl(NFSERR_NOT_SAME) #define nfserr_readdir_nospc __constant_htonl(NFSERR_READDIR_NOSPC) diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index 51ee4f74b68a..11327bf38604 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h @@ -65,10 +65,14 @@ typedef struct { * * o Each nfs4_clients is also hashed by name * (the opaque quantity initially sent by the client to identify itself). + * + * o cl_perclient list is used to ensure no dangling stateowner references + * when we expire the nfs4_client */ struct nfs4_client { struct list_head cl_idhash; /* hash by cl_clientid.id */ struct list_head cl_strhash; /* hash by cl_name */ + struct list_head cl_perclient; /* list: stateowners */ struct xdr_netobj cl_name; /* id generated by client */ nfs4_verifier cl_verifier; /* generated by client */ u32 cl_addr; /* client ipaddress */ @@ -76,4 +80,66 @@ struct nfs4_client { clientid_t cl_clientid; /* generated by server */ nfs4_verifier cl_confirm; /* generated by server */ }; + +static inline void +update_stateid(stateid_t *stateid) +{ +stateid->si_generation++; +} + + +/* +* nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner +* +* o so_peropenstate list is used to ensure no dangling nfs4_stateid +* reverences when we release a stateowner. +*/ +struct nfs4_stateowner { + struct list_head so_strhash; /* hash by op_name */ + struct list_head so_perclient; /* nfs4_client->cl_perclient */ + struct list_head so_peropenstate; /* list: nfs4_stateid */ + u32 so_id; + struct nfs4_client * so_client; + u32 so_seqid; + struct xdr_netobj so_owner; /* open owner name */ + int so_confirmed; /* successful OPEN_CONFIRM? */ +}; + +typedef struct { + u32 dev; /* super_block->s_dev */ + unsigned long ino; + u32 generation; +} nfs4_ino_desc_t; + +/* +* nfs4_file: a file opened by some number of (open) nfs4_stateowners. +* o fi_perfile list is used to search for conflicting +* share_acces, share_deny on the file. +*/ +struct nfs4_file { + struct list_head fi_hash; /* hash by nfs4_ino_desc_t fields */ + struct list_head fi_perfile; /* list: nfs4_stateid */ + nfs4_ino_desc_t fi_ino; + u32 fi_id; /* used with stateowner->so_id + * for openstateid_hashtbl hash */ +}; + +/* +* nfs4_stateid can either be an open stateid or (eventually) a lock stateid +* +* (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file +*/ + +struct nfs4_stateid { + struct list_head st_perfile; /* file_hashtbl[]*/ + struct list_head st_peropenstate; /* nfs4_stateowner->so_peropenstate */ + struct nfs4_stateowner * st_stateowner; + struct nfs4_file * st_file; + stateid_t st_stateid; + struct file st_vfs_file; + int st_vfs_set; + unsigned int st_share_access; + unsigned int st_share_deny; +}; + #endif /* NFSD4_STATE_H */ diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index 00040f56e697..2d670ad4893d 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h @@ -141,6 +141,7 @@ struct nfsd4_open { struct nfsd4_change_info op_cinfo; /* response */ u32 op_rflags; /* response */ int op_truncate; /* used during processing */ + struct nfs4_stateowner *op_stateowner; /* used during processing */ }; #define op_iattr u.iattr @@ -322,7 +323,8 @@ int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval); 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_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open); #endif /* |
