aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4client.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2013-08-09 12:49:11 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-09-03 15:26:35 -0400
commitabf79bb341bf52f75f295b850abdf5f78f584311 (patch)
tree34c31ced5f367bc01e4a767d343ad7c24346189a /fs/nfs/nfs4client.c
parenteb2a1cd3c9df70ef84e91f2fc657fd19682346ca (diff)
NFS: Add a slot table to struct nfs_client for NFSv4.0 transport blocking
Anchor an nfs4_slot_table in the nfs_client for use with NFSv4.0 transport blocking. It is initialized only for NFSv4.0 nfs_client's. Introduce appropriate minor version ops to handle nfs_client initialization and shutdown requirements that differ for each minor version. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4client.c')
-rw-r--r--fs/nfs/nfs4client.c101
1 files changed, 74 insertions, 27 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 767a5e37fe97..98c0104bb0c4 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -41,7 +41,7 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
41} 41}
42 42
43#ifdef CONFIG_NFS_V4_1 43#ifdef CONFIG_NFS_V4_1
44static void nfs4_shutdown_session(struct nfs_client *clp) 44void nfs41_shutdown_client(struct nfs_client *clp)
45{ 45{
46 if (nfs4_has_session(clp)) { 46 if (nfs4_has_session(clp)) {
47 nfs4_destroy_session(clp->cl_session); 47 nfs4_destroy_session(clp->cl_session);
@@ -49,11 +49,15 @@ static void nfs4_shutdown_session(struct nfs_client *clp)
49 } 49 }
50 50
51} 51}
52#else /* CONFIG_NFS_V4_1 */ 52#endif /* CONFIG_NFS_V4_1 */
53static void nfs4_shutdown_session(struct nfs_client *clp) 53
54void nfs40_shutdown_client(struct nfs_client *clp)
54{ 55{
56 if (clp->cl_slot_tbl) {
57 nfs4_release_slot_table(clp->cl_slot_tbl);
58 kfree(clp->cl_slot_tbl);
59 }
55} 60}
56#endif /* CONFIG_NFS_V4_1 */
57 61
58struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) 62struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
59{ 63{
@@ -97,7 +101,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
97{ 101{
98 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state)) 102 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
99 nfs4_kill_renewd(clp); 103 nfs4_kill_renewd(clp);
100 nfs4_shutdown_session(clp); 104 clp->cl_mvops->shutdown_client(clp);
101 nfs4_destroy_callback(clp); 105 nfs4_destroy_callback(clp);
102 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) 106 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
103 nfs_idmap_delete(clp); 107 nfs_idmap_delete(clp);
@@ -144,34 +148,77 @@ static int nfs4_init_callback(struct nfs_client *clp)
144 return 0; 148 return 0;
145} 149}
146 150
151/**
152 * nfs40_init_client - nfs_client initialization tasks for NFSv4.0
153 * @clp - nfs_client to initialize
154 *
155 * Returns zero on success, or a negative errno if some error occurred.
156 */
157int nfs40_init_client(struct nfs_client *clp)
158{
159 struct nfs4_slot_table *tbl;
160 int ret;
161
162 tbl = kzalloc(sizeof(*tbl), GFP_NOFS);
163 if (tbl == NULL)
164 return -ENOMEM;
165
166 ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
167 "NFSv4.0 transport Slot table");
168 if (ret) {
169 kfree(tbl);
170 return ret;
171 }
172
173 clp->cl_slot_tbl = tbl;
174 return 0;
175}
176
177#if defined(CONFIG_NFS_V4_1)
178
179/**
180 * nfs41_init_client - nfs_client initialization tasks for NFSv4.1+
181 * @clp - nfs_client to initialize
182 *
183 * Returns zero on success, or a negative errno if some error occurred.
184 */
185int nfs41_init_client(struct nfs_client *clp)
186{
187 struct nfs4_session *session = NULL;
188
189 /*
190 * Create the session and mark it expired.
191 * When a SEQUENCE operation encounters the expired session
192 * it will do session recovery to initialize it.
193 */
194 session = nfs4_alloc_session(clp);
195 if (!session)
196 return -ENOMEM;
197
198 clp->cl_session = session;
199
200 /*
201 * The create session reply races with the server back
202 * channel probe. Mark the client NFS_CS_SESSION_INITING
203 * so that the client back channel can find the
204 * nfs_client struct
205 */
206 nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
207 return 0;
208}
209
210#endif /* CONFIG_NFS_V4_1 */
211
147/* 212/*
148 * Initialize the minor version specific parts of an NFS4 client record 213 * Initialize the minor version specific parts of an NFS4 client record
149 */ 214 */
150static int nfs4_init_client_minor_version(struct nfs_client *clp) 215static int nfs4_init_client_minor_version(struct nfs_client *clp)
151{ 216{
152#if defined(CONFIG_NFS_V4_1) 217 int ret;
153 if (clp->cl_mvops->minor_version) {
154 struct nfs4_session *session = NULL;
155 /*
156 * Create the session and mark it expired.
157 * When a SEQUENCE operation encounters the expired session
158 * it will do session recovery to initialize it.
159 */
160 session = nfs4_alloc_session(clp);
161 if (!session)
162 return -ENOMEM;
163
164 clp->cl_session = session;
165 /*
166 * The create session reply races with the server back
167 * channel probe. Mark the client NFS_CS_SESSION_INITING
168 * so that the client back channel can find the
169 * nfs_client struct
170 */
171 nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
172 }
173#endif /* CONFIG_NFS_V4_1 */
174 218
219 ret = clp->cl_mvops->init_client(clp);
220 if (ret)
221 return ret;
175 return nfs4_init_callback(clp); 222 return nfs4_init_callback(clp);
176} 223}
177 224