summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/nfs.h9
-rw-r--r--include/linux/nfsd/nfsd.h6
-rw-r--r--include/linux/nfsd/state.h66
-rw-r--r--include/linux/nfsd/xdr4.h4
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
/*