diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2003-09-22 05:22:55 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-09-22 05:22:55 -0700 |
| commit | ed5dc775d0ddd209713ee8e24c46e648fb3ed2f2 (patch) | |
| tree | c65cb6d9e5b38d75d3d1f43f655e2a675b9993d1 /include/linux/nfsd | |
| parent | 902773e514f21d3f51a03982fb80a5548d2a8661 (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.h | 2 | ||||
| -rw-r--r-- | include/linux/nfsd/state.h | 27 | ||||
| -rw-r--r-- | include/linux/nfsd/xdr4.h | 54 |
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 /* |
