NFS: Generalise the nfs_client structure
Generalise the nfs_client structure by:
(1) Moving nfs_client to a more general place (nfs_fs_sb.h).
(2) Renaming its maintenance routines to be non-NFS4 specific.
(3) Move those maintenance routines to a new non-NFS4 specific file (client.c)
and move the declarations to internal.h.
(4) Make nfs_find/get_client() take a full sockaddr_in to include the port
number (will be required for NFS2/3).
(5) Make nfs_find/get_client() take the NFS protocol version (again will be
required to differentiate NFS2, 3 & 4 client records).
Also:
(6) Make nfs_client construction proceed akin to inodes, marking them as under
construction and providing a function to indicate completion.
(7) Make nfs_get_client() wait interruptibly if it finds a client that it can
share, but that client is currently being constructed.
(8) Make nfs4_create_client() use (6) and (7) instead of locking cl_sem.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index fc20d6b..a727657 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -7,6 +7,66 @@
struct nfs_iostats;
/*
+ * The nfs_client identifies our client state to the server.
+ */
+struct nfs_client {
+ atomic_t cl_count;
+ int cl_cons_state; /* current construction state (-ve: init error) */
+#define NFS_CS_READY 0 /* ready to be used */
+#define NFS_CS_INITING 1 /* busy initialising */
+ int cl_nfsversion; /* NFS protocol version */
+ unsigned long cl_res_state; /* NFS resources state */
+#define NFS_CS_RPCIOD 0 /* - rpciod started */
+#define NFS_CS_CALLBACK 1 /* - callback started */
+#define NFS_CS_IDMAP 2 /* - idmap started */
+ struct sockaddr_in cl_addr; /* server identifier */
+ char * cl_hostname; /* hostname of server */
+ struct list_head cl_share_link; /* link in global client list */
+ struct list_head cl_superblocks; /* List of nfs_server structs */
+
+ struct rpc_clnt * cl_rpcclient;
+
+#ifdef CONFIG_NFS_V4
+ u64 cl_clientid; /* constant */
+ nfs4_verifier cl_confirm;
+ unsigned long cl_state;
+
+ u32 cl_lockowner_id;
+
+ /*
+ * The following rwsem ensures exclusive access to the server
+ * while we recover the state following a lease expiration.
+ */
+ struct rw_semaphore cl_sem;
+
+ struct list_head cl_delegations;
+ struct list_head cl_state_owners;
+ struct list_head cl_unused;
+ int cl_nunused;
+ spinlock_t cl_lock;
+
+ unsigned long cl_lease_time;
+ unsigned long cl_last_renewal;
+ struct work_struct cl_renewd;
+ struct work_struct cl_recoverd;
+
+ struct rpc_wait_queue cl_rpcwaitq;
+
+ /* used for the setclientid verifier */
+ struct timespec cl_boot_time;
+
+ /* idmapper */
+ struct idmap * cl_idmap;
+
+ /* Our own IP address, as a null-terminated string.
+ * This is used to generate the clientid, and the callback address.
+ */
+ char cl_ipaddr[16];
+ unsigned char cl_id_uniquifier;
+#endif
+};
+
+/*
* NFS client parameters stored in the superblock.
*/
struct nfs_server {