aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/nfs/nfs4_fs.h6
-rw-r--r--fs/nfs/nfs4client.c101
-rw-r--r--fs/nfs/nfs4proc.c6
3 files changed, 86 insertions, 27 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 8de9b934dcac..af2d5bf043f0 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -38,6 +38,8 @@ struct nfs4_minor_version_ops {
38 u32 minor_version; 38 u32 minor_version;
39 unsigned init_caps; 39 unsigned init_caps;
40 40
41 int (*init_client)(struct nfs_client *);
42 void (*shutdown_client)(struct nfs_client *);
41 bool (*match_stateid)(const nfs4_stateid *, 43 bool (*match_stateid)(const nfs4_stateid *,
42 const nfs4_stateid *); 44 const nfs4_stateid *);
43 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *, 45 int (*find_root_sec)(struct nfs_server *, struct nfs_fh *,
@@ -292,6 +294,10 @@ extern const u32 nfs4_pathconf_bitmap[3];
292extern const u32 nfs4_fsinfo_bitmap[3]; 294extern const u32 nfs4_fsinfo_bitmap[3];
293extern const u32 nfs4_fs_locations_bitmap[3]; 295extern const u32 nfs4_fs_locations_bitmap[3];
294 296
297void nfs40_shutdown_client(struct nfs_client *);
298void nfs41_shutdown_client(struct nfs_client *);
299int nfs40_init_client(struct nfs_client *);
300int nfs41_init_client(struct nfs_client *);
295void nfs4_free_client(struct nfs_client *); 301void nfs4_free_client(struct nfs_client *);
296 302
297struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *); 303struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *);
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
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3abd32caec2f..3b5166c20962 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -7533,6 +7533,8 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
7533 | NFS_CAP_ATOMIC_OPEN 7533 | NFS_CAP_ATOMIC_OPEN
7534 | NFS_CAP_CHANGE_ATTR 7534 | NFS_CAP_CHANGE_ATTR
7535 | NFS_CAP_POSIX_LOCK, 7535 | NFS_CAP_POSIX_LOCK,
7536 .init_client = nfs40_init_client,
7537 .shutdown_client = nfs40_shutdown_client,
7536 .match_stateid = nfs4_match_stateid, 7538 .match_stateid = nfs4_match_stateid,
7537 .find_root_sec = nfs4_find_root_sec, 7539 .find_root_sec = nfs4_find_root_sec,
7538 .free_lock_state = nfs4_release_lockowner, 7540 .free_lock_state = nfs4_release_lockowner,
@@ -7551,6 +7553,8 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
7551 | NFS_CAP_POSIX_LOCK 7553 | NFS_CAP_POSIX_LOCK
7552 | NFS_CAP_STATEID_NFSV41 7554 | NFS_CAP_STATEID_NFSV41
7553 | NFS_CAP_ATOMIC_OPEN_V1, 7555 | NFS_CAP_ATOMIC_OPEN_V1,
7556 .init_client = nfs41_init_client,
7557 .shutdown_client = nfs41_shutdown_client,
7554 .match_stateid = nfs41_match_stateid, 7558 .match_stateid = nfs41_match_stateid,
7555 .find_root_sec = nfs41_find_root_sec, 7559 .find_root_sec = nfs41_find_root_sec,
7556 .free_lock_state = nfs41_free_lock_state, 7560 .free_lock_state = nfs41_free_lock_state,
@@ -7570,6 +7574,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
7570 | NFS_CAP_POSIX_LOCK 7574 | NFS_CAP_POSIX_LOCK
7571 | NFS_CAP_STATEID_NFSV41 7575 | NFS_CAP_STATEID_NFSV41
7572 | NFS_CAP_ATOMIC_OPEN_V1, 7576 | NFS_CAP_ATOMIC_OPEN_V1,
7577 .init_client = nfs41_init_client,
7578 .shutdown_client = nfs41_shutdown_client,
7573 .match_stateid = nfs41_match_stateid, 7579 .match_stateid = nfs41_match_stateid,
7574 .find_root_sec = nfs41_find_root_sec, 7580 .find_root_sec = nfs41_find_root_sec,
7575 .free_lock_state = nfs41_free_lock_state, 7581 .free_lock_state = nfs41_free_lock_state,