diff options
| -rw-r--r-- | fs/nfs/client.c | 93 | ||||
| -rw-r--r-- | fs/nfs/nfs4client.c | 91 |
2 files changed, 91 insertions, 93 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 0d50629d9e25..65afa382c5e3 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
| @@ -56,30 +56,6 @@ | |||
| 56 | #define NFSDBG_FACILITY NFSDBG_CLIENT | 56 | #define NFSDBG_FACILITY NFSDBG_CLIENT |
| 57 | 57 | ||
| 58 | static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); | 58 | static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); |
| 59 | #ifdef CONFIG_NFS_V4 | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Get a unique NFSv4.0 callback identifier which will be used | ||
| 63 | * by the V4.0 callback service to lookup the nfs_client struct | ||
| 64 | */ | ||
| 65 | static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion) | ||
| 66 | { | ||
| 67 | int ret = 0; | ||
| 68 | struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); | ||
| 69 | |||
| 70 | if (clp->rpc_ops->version != 4 || minorversion != 0) | ||
| 71 | return ret; | ||
| 72 | retry: | ||
| 73 | if (!idr_pre_get(&nn->cb_ident_idr, GFP_KERNEL)) | ||
| 74 | return -ENOMEM; | ||
| 75 | spin_lock(&nn->nfs_client_lock); | ||
| 76 | ret = idr_get_new(&nn->cb_ident_idr, clp, &clp->cl_cb_ident); | ||
| 77 | spin_unlock(&nn->nfs_client_lock); | ||
| 78 | if (ret == -EAGAIN) | ||
| 79 | goto retry; | ||
| 80 | return ret; | ||
| 81 | } | ||
| 82 | #endif /* CONFIG_NFS_V4 */ | ||
| 83 | 59 | ||
| 84 | /* | 60 | /* |
| 85 | * RPC cruft for NFS | 61 | * RPC cruft for NFS |
| @@ -175,75 +151,6 @@ error_0: | |||
| 175 | } | 151 | } |
| 176 | 152 | ||
| 177 | #ifdef CONFIG_NFS_V4 | 153 | #ifdef CONFIG_NFS_V4 |
| 178 | #ifdef CONFIG_NFS_V4_1 | ||
| 179 | static void nfs4_shutdown_session(struct nfs_client *clp) | ||
| 180 | { | ||
| 181 | if (nfs4_has_session(clp)) { | ||
| 182 | nfs4_destroy_session(clp->cl_session); | ||
| 183 | nfs4_destroy_clientid(clp); | ||
| 184 | } | ||
| 185 | |||
| 186 | } | ||
| 187 | #else /* CONFIG_NFS_V4_1 */ | ||
| 188 | static void nfs4_shutdown_session(struct nfs_client *clp) | ||
| 189 | { | ||
| 190 | } | ||
| 191 | #endif /* CONFIG_NFS_V4_1 */ | ||
| 192 | |||
| 193 | struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) | ||
| 194 | { | ||
| 195 | int err; | ||
| 196 | struct nfs_client *clp = nfs_alloc_client(cl_init); | ||
| 197 | if (IS_ERR(clp)) | ||
| 198 | return clp; | ||
| 199 | |||
| 200 | err = nfs_get_cb_ident_idr(clp, cl_init->minorversion); | ||
| 201 | if (err) | ||
| 202 | goto error; | ||
| 203 | |||
| 204 | spin_lock_init(&clp->cl_lock); | ||
| 205 | INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); | ||
| 206 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); | ||
| 207 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | ||
| 208 | clp->cl_minorversion = cl_init->minorversion; | ||
| 209 | clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; | ||
| 210 | return clp; | ||
| 211 | |||
| 212 | error: | ||
| 213 | kfree(clp); | ||
| 214 | return ERR_PTR(err); | ||
| 215 | } | ||
| 216 | |||
| 217 | /* | ||
| 218 | * Destroy the NFS4 callback service | ||
| 219 | */ | ||
| 220 | static void nfs4_destroy_callback(struct nfs_client *clp) | ||
| 221 | { | ||
| 222 | if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) | ||
| 223 | nfs_callback_down(clp->cl_mvops->minor_version); | ||
| 224 | } | ||
| 225 | |||
| 226 | static void nfs4_shutdown_client(struct nfs_client *clp) | ||
| 227 | { | ||
| 228 | if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state)) | ||
| 229 | nfs4_kill_renewd(clp); | ||
| 230 | nfs4_shutdown_session(clp); | ||
| 231 | nfs4_destroy_callback(clp); | ||
| 232 | if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) | ||
| 233 | nfs_idmap_delete(clp); | ||
| 234 | |||
| 235 | rpc_destroy_wait_queue(&clp->cl_rpcwaitq); | ||
| 236 | kfree(clp->cl_serverowner); | ||
| 237 | kfree(clp->cl_serverscope); | ||
| 238 | kfree(clp->cl_implid); | ||
| 239 | } | ||
| 240 | |||
| 241 | void nfs4_free_client(struct nfs_client *clp) | ||
| 242 | { | ||
| 243 | nfs4_shutdown_client(clp); | ||
| 244 | nfs_free_client(clp); | ||
| 245 | } | ||
| 246 | |||
| 247 | /* idr_remove_all is not needed as all id's are removed by nfs_put_client */ | 154 | /* idr_remove_all is not needed as all id's are removed by nfs_put_client */ |
| 248 | void nfs_cleanup_cb_ident_idr(struct net *net) | 155 | void nfs_cleanup_cb_ident_idr(struct net *net) |
| 249 | { | 156 | { |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index a71d95ecbea9..1c3f13c8e472 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
| @@ -23,6 +23,97 @@ | |||
| 23 | static bool nfs4_disable_idmapping = true; | 23 | static bool nfs4_disable_idmapping = true; |
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | * Get a unique NFSv4.0 callback identifier which will be used | ||
| 27 | * by the V4.0 callback service to lookup the nfs_client struct | ||
| 28 | */ | ||
| 29 | static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion) | ||
| 30 | { | ||
| 31 | int ret = 0; | ||
| 32 | struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); | ||
| 33 | |||
| 34 | if (clp->rpc_ops->version != 4 || minorversion != 0) | ||
| 35 | return ret; | ||
| 36 | retry: | ||
| 37 | if (!idr_pre_get(&nn->cb_ident_idr, GFP_KERNEL)) | ||
| 38 | return -ENOMEM; | ||
| 39 | spin_lock(&nn->nfs_client_lock); | ||
| 40 | ret = idr_get_new(&nn->cb_ident_idr, clp, &clp->cl_cb_ident); | ||
| 41 | spin_unlock(&nn->nfs_client_lock); | ||
| 42 | if (ret == -EAGAIN) | ||
| 43 | goto retry; | ||
| 44 | return ret; | ||
| 45 | } | ||
| 46 | |||
| 47 | #ifdef CONFIG_NFS_V4_1 | ||
| 48 | static void nfs4_shutdown_session(struct nfs_client *clp) | ||
| 49 | { | ||
| 50 | if (nfs4_has_session(clp)) { | ||
| 51 | nfs4_destroy_session(clp->cl_session); | ||
| 52 | nfs4_destroy_clientid(clp); | ||
| 53 | } | ||
| 54 | |||
| 55 | } | ||
| 56 | #else /* CONFIG_NFS_V4_1 */ | ||
| 57 | static void nfs4_shutdown_session(struct nfs_client *clp) | ||
| 58 | { | ||
| 59 | } | ||
| 60 | #endif /* CONFIG_NFS_V4_1 */ | ||
| 61 | |||
| 62 | struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) | ||
| 63 | { | ||
| 64 | int err; | ||
| 65 | struct nfs_client *clp = nfs_alloc_client(cl_init); | ||
| 66 | if (IS_ERR(clp)) | ||
| 67 | return clp; | ||
| 68 | |||
| 69 | err = nfs_get_cb_ident_idr(clp, cl_init->minorversion); | ||
| 70 | if (err) | ||
| 71 | goto error; | ||
| 72 | |||
| 73 | spin_lock_init(&clp->cl_lock); | ||
| 74 | INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); | ||
| 75 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); | ||
| 76 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | ||
| 77 | clp->cl_minorversion = cl_init->minorversion; | ||
| 78 | clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; | ||
| 79 | return clp; | ||
| 80 | |||
| 81 | error: | ||
| 82 | kfree(clp); | ||
| 83 | return ERR_PTR(err); | ||
| 84 | } | ||
| 85 | |||
| 86 | /* | ||
| 87 | * Destroy the NFS4 callback service | ||
| 88 | */ | ||
| 89 | static void nfs4_destroy_callback(struct nfs_client *clp) | ||
| 90 | { | ||
| 91 | if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) | ||
| 92 | nfs_callback_down(clp->cl_mvops->minor_version); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void nfs4_shutdown_client(struct nfs_client *clp) | ||
| 96 | { | ||
| 97 | if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state)) | ||
| 98 | nfs4_kill_renewd(clp); | ||
| 99 | nfs4_shutdown_session(clp); | ||
| 100 | nfs4_destroy_callback(clp); | ||
| 101 | if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) | ||
| 102 | nfs_idmap_delete(clp); | ||
| 103 | |||
| 104 | rpc_destroy_wait_queue(&clp->cl_rpcwaitq); | ||
| 105 | kfree(clp->cl_serverowner); | ||
| 106 | kfree(clp->cl_serverscope); | ||
| 107 | kfree(clp->cl_implid); | ||
| 108 | } | ||
| 109 | |||
| 110 | void nfs4_free_client(struct nfs_client *clp) | ||
| 111 | { | ||
| 112 | nfs4_shutdown_client(clp); | ||
| 113 | nfs_free_client(clp); | ||
| 114 | } | ||
| 115 | |||
| 116 | /* | ||
| 26 | * Initialize the NFS4 callback service | 117 | * Initialize the NFS4 callback service |
| 27 | */ | 118 | */ |
| 28 | static int nfs4_init_callback(struct nfs_client *clp) | 119 | static int nfs4_init_callback(struct nfs_client *clp) |
