summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2004-02-07 17:03:03 +0100
committerTrond Myklebust <trond.myklebust@fys.uio.no>2004-02-07 17:03:03 +0100
commit3f1990d30fe3d6e62d41d0224c27855b59517b8b (patch)
treeafa4964cbad232477dc10db58dea4e0a6ddce60f /include/linux
parent1f37cd43d9e866e99f81ffe6141b49cc6f83f619 (diff)
NFSv4: Add support for POSIX file locking.
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/nfs4.h3
-rw-r--r--include/linux/nfs_fs.h37
-rw-r--r--include/linux/nfs_page.h1
-rw-r--r--include/linux/nfs_xdr.h65
4 files changed, 102 insertions, 4 deletions
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 4a61a4682718..35baf20a5b5c 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -297,6 +297,9 @@ enum {
NFSPROC4_CLNT_RENEW,
NFSPROC4_CLNT_SETCLIENTID,
NFSPROC4_CLNT_SETCLIENTID_CONFIRM,
+ NFSPROC4_CLNT_LOCK,
+ NFSPROC4_CLNT_LOCKT,
+ NFSPROC4_CLNT_LOCKU,
};
#endif
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 512d9203905f..524eb6d04d7b 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -542,19 +542,43 @@ struct nfs4_state_owner {
/*
* struct nfs4_state maintains the client-side state for a given
- * (state_owner,inode) tuple.
+ * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
*
+ * OPEN:
* In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server,
* we need to know how many files are open for reading or writing on a
* given inode. This information too is stored here.
+ *
+ * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
*/
+
+struct nfs4_lock_state {
+ struct list_head ls_locks; /* Other lock stateids */
+ fl_owner_t ls_owner; /* POSIX lock owner */
+ struct nfs4_state * ls_parent; /* Parent nfs4_state */
+ u32 ls_seqid;
+ u32 ls_id;
+ nfs4_stateid ls_stateid;
+ atomic_t ls_count;
+};
+
+/* bits for nfs4_state->flags */
+enum {
+ LK_STATE_IN_USE,
+};
+
struct nfs4_state {
struct list_head open_states; /* List of states for the same state_owner */
struct list_head inode_states; /* List of states for the same inode */
+ struct list_head lock_states; /* List of subservient lock stateids */
struct nfs4_state_owner *owner; /* Pointer to the open owner */
struct inode *inode; /* Pointer to the inode */
+ unsigned long flags; /* Do we hold any locks? */
+ struct semaphore lock_sema; /* Serializes file locking operations */
+ rwlock_t state_lock; /* Protects the lock_states list */
+
nfs4_stateid stateid;
unsigned int nreaders;
@@ -589,6 +613,8 @@ extern void init_nfsv4_state(struct nfs_server *);
extern void destroy_nfsv4_state(struct nfs_server *);
extern struct nfs4_client *nfs4_get_client(struct in_addr *);
extern void nfs4_put_client(struct nfs4_client *clp);
+extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
+
extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
extern void nfs4_put_state_owner(struct nfs4_state_owner *);
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
@@ -598,6 +624,15 @@ extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mod
extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
extern int nfs4_handle_error(struct nfs_server *, int);
extern void nfs4_schedule_state_recovery(struct nfs4_client *);
+extern struct nfs4_lock_state *nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t);
+extern struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t);
+extern void nfs4_put_lock_state(struct nfs4_lock_state *state);
+extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
+extern void nfs4_notify_setlk(struct inode *, struct file_lock *, struct nfs4_lock_state *);
+extern void nfs4_notify_unlck(struct inode *, struct file_lock *, struct nfs4_lock_state *);
+extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
+
+
struct nfs4_mount_data;
#else
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 42677b62e92b..c41a4e75555e 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -26,6 +26,7 @@ struct nfs_page {
struct list_head wb_list, /* Defines state of page: */
*wb_list_head; /* read/write/commit */
struct file *wb_file;
+ fl_owner_t wb_lockowner;
struct inode *wb_inode;
struct rpc_cred *wb_cred;
struct nfs4_state *wb_state;
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 21827ad1a71e..a3ecfab78bc6 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -109,7 +109,6 @@ struct nfs_openargs {
};
struct nfs_openres {
- __u32 status;
nfs4_stateid stateid;
struct nfs_fh fh;
struct nfs4_change_info * cinfo;
@@ -129,7 +128,6 @@ struct nfs_open_confirmargs {
};
struct nfs_open_confirmres {
- __u32 status;
nfs4_stateid stateid;
};
@@ -157,10 +155,68 @@ struct nfs_closeargs {
};
struct nfs_closeres {
- __u32 status;
nfs4_stateid stateid;
};
+/*
+ * * Arguments to the lock,lockt, and locku call.
+ * */
+struct nfs_lowner {
+ __u64 clientid;
+ u32 id;
+};
+
+struct nfs_open_to_lock {
+ __u32 open_seqid;
+ nfs4_stateid open_stateid;
+ __u32 lock_seqid;
+ struct nfs_lowner lock_owner;
+};
+
+struct nfs_exist_lock {
+ nfs4_stateid stateid;
+ __u32 seqid;
+};
+struct nfs_lock_opargs {
+ __u32 reclaim;
+ __u32 new_lock_owner;
+ union {
+ struct nfs_open_to_lock *open_lock;
+ struct nfs_exist_lock *exist_lock;
+ } u;
+};
+
+struct nfs_locku_opargs {
+ __u32 seqid;
+ nfs4_stateid stateid;
+};
+
+struct nfs_lockargs {
+ struct nfs_fh * fh;
+ __u32 type;
+ __u64 offset;
+ __u64 length;
+ union {
+ struct nfs_lock_opargs *lock; /* LOCK */
+ struct nfs_lowner *lockt; /* LOCKT */
+ struct nfs_locku_opargs *locku; /* LOCKU */
+ } u;
+};
+
+struct nfs_lock_denied {
+ __u64 offset;
+ __u64 length;
+ __u32 type;
+ struct nfs_lowner owner;
+};
+
+struct nfs_lockres {
+ union {
+ nfs4_stateid stateid;/* LOCK success, LOCKU */
+ struct nfs_lock_denied denied; /* LOCK failed, LOCKT success */
+ } u;
+ struct nfs_server * server;
+};
/*
* Arguments to the read call.
@@ -605,6 +661,7 @@ struct nfs_read_data {
struct rpc_task task;
struct inode *inode;
struct rpc_cred *cred;
+ fl_owner_t lockowner;
struct nfs_fattr fattr; /* fattr storage */
struct list_head pages; /* Coalesced read requests */
struct page *pagevec[NFS_READ_MAXIOV];
@@ -620,6 +677,7 @@ struct nfs_write_data {
struct rpc_task task;
struct inode *inode;
struct rpc_cred *cred;
+ fl_owner_t lockowner;
struct nfs_fattr fattr;
struct nfs_writeverf verf;
struct list_head pages; /* Coalesced requests we wish to flush */
@@ -686,6 +744,7 @@ struct nfs_rpc_ops {
int (*file_release) (struct inode *, struct file *);
void (*request_init)(struct nfs_page *, struct file *);
int (*request_compatible)(struct nfs_page *, struct file *, struct page *);
+ int (*lock)(struct file *, int, struct file_lock *);
};
/*