summaryrefslogtreecommitdiff
path: root/include/linux/nfsd
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2003-09-22 05:22:55 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-09-22 05:22:55 -0700
commited5dc775d0ddd209713ee8e24c46e648fb3ed2f2 (patch)
treec65cb6d9e5b38d75d3d1f43f655e2a675b9993d1 /include/linux/nfsd
parent902773e514f21d3f51a03982fb80a5548d2a8661 (diff)
[PATCH] knfsd: nfsd byte range locking - LOCK
From: "William A.(Andy) Adamson" <andros@citi.umich.edu> This implements the nfsv4 LOCK operation.
Diffstat (limited to 'include/linux/nfsd')
-rw-r--r--include/linux/nfsd/nfsd.h2
-rw-r--r--include/linux/nfsd/state.h27
-rw-r--r--include/linux/nfsd/xdr4.h54
3 files changed, 78 insertions, 5 deletions
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 3e3be1abc991..8c4fb5cfff21 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -172,6 +172,8 @@ 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_denied __constant_htonl(NFSERR_DENIED)
+#define nfserr_deadlock __constant_htonl(NFSERR_DEADLOCK)
#define nfserr_expired __constant_htonl(NFSERR_EXPIRED)
#define nfserr_bad_cookie __constant_htonl(NFSERR_BAD_COOKIE)
#define nfserr_same __constant_htonl(NFSERR_SAME)
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index c0975c670e42..b48b36201585 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -117,16 +117,24 @@ struct nfs4_replay {
};
/*
-* nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner
+* nfs4_stateowner can either be an open_owner, or a lock_owner
*
-* o so_perfilestate list is used to ensure no dangling nfs4_stateid
-* reverences when we release a stateowner.
+* so_idhash: stateid_hashtbl[] for open owner, lockstateid_hashtbl[]
+* for lock_owner
+* so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[]
+* for lock_owner
+* so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client
+* struct is reaped.
+* so_perfilestate: heads the list of nfs4_stateid (either open or lock)
+* and is used to ensure no dangling nfs4_stateid references when we
+* release a 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_perclient; /* nfs4_client->cl_perclient */
struct list_head so_perfilestate; /* list: nfs4_stateid */
+ int so_is_open_owner; /* 1=openowner,0=lockowner */
u32 so_id;
struct nfs4_client * so_client;
u32 so_seqid;
@@ -152,12 +160,18 @@ struct nfs4_file {
* nfs4_stateid can either be an open stateid or (eventually) a lock stateid
*
* (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file
+*
+* st_hash: stateid_hashtbl[] entry or lockstateid_hashtbl entry
+* st_perfile: file_hashtbl[] entry.
+* st_perfile_state: nfs4_stateowner->so_perfilestate
+* st_share_access: used only for open stateid
+* st_share_deny: used only for open stateid
*/
struct nfs4_stateid {
- struct list_head st_hash;
+ struct list_head st_hash;
struct list_head st_perfile;
- struct list_head st_perfilestate;
+ struct list_head st_perfilestate;
struct nfs4_stateowner * st_stateowner;
struct nfs4_file * st_file;
stateid_t st_stateid;
@@ -170,6 +184,9 @@ struct nfs4_stateid {
/* flags for preprocess_seqid_op() */
#define CHECK_FH 0x00000001
#define CONFIRM 0x00000002
+#define OPEN_STATE 0x00000004
+#define LOCK_STATE 0x00000008
+#define RDWR_STATE 0x00000010
#define seqid_mutating_err(err) \
(((err) != nfserr_stale_clientid) && \
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 254d5d2c5647..bbb037e08f18 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -40,6 +40,7 @@
#define _LINUX_NFSD_XDR4_H
#define NFSD4_MAX_TAGLEN 128
+#define XDR_LEN(n) (((n) + 3) & ~3)
typedef u32 delegation_zero_t;
typedef u32 delegation_boot_t;
@@ -111,6 +112,56 @@ struct nfsd4_link {
struct nfsd4_change_info li_cinfo; /* response */
};
+struct nfsd4_lock_denied {
+ struct nfs4_stateowner *ld_sop;
+ u64 ld_start;
+ u64 ld_length;
+ u32 ld_type;
+};
+
+struct nfsd4_lock {
+ /* request */
+ u32 lk_type;
+ u32 lk_reclaim; /* boolean */
+ u64 lk_offset;
+ u64 lk_length;
+ u32 lk_is_new;
+ union {
+ struct {
+ u32 open_seqid;
+ stateid_t open_stateid;
+ u32 lock_seqid;
+ clientid_t clientid;
+ struct xdr_netobj owner;
+ } new;
+ struct {
+ stateid_t lock_stateid;
+ u32 lock_seqid;
+ } old;
+ } v;
+
+ /* response */
+ union {
+ struct {
+ stateid_t stateid;
+ } ok;
+ struct nfsd4_lock_denied denied;
+ } u;
+
+ struct nfs4_stateowner *lk_stateowner;
+};
+#define lk_new_open_seqid v.new.open_seqid
+#define lk_new_open_stateid v.new.open_stateid
+#define lk_new_lock_seqid v.new.lock_seqid
+#define lk_new_clientid v.new.clientid
+#define lk_new_owner v.new.owner
+#define lk_old_lock_stateid v.old.lock_stateid
+#define lk_old_lock_seqid v.old.lock_seqid
+
+#define lk_rflags u.ok.rflags
+#define lk_resp_stateid u.ok.stateid
+#define lk_denied u.denied
+
struct nfsd4_lookup {
u32 lo_len; /* request */
char * lo_name; /* request */
@@ -266,6 +317,7 @@ struct nfsd4_op {
struct nfsd4_getattr getattr;
struct svc_fh * getfh;
struct nfsd4_link link;
+ struct nfsd4_lock lock;
struct nfsd4_lookup lookup;
struct nfsd4_verify nverify;
struct nfsd4_open open;
@@ -357,6 +409,8 @@ extern int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh,
struct nfsd4_close *close);
extern int nfsd4_open_downgrade(struct svc_rqst *rqstp,
struct svc_fh *current_fh, struct nfsd4_open_downgrade *od);
+extern int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+ struct nfsd4_lock *lock);
#endif
/*