|
@@ -1588,12 +1588,23 @@ free_client(struct nfs4_client *clp)
|
|
|
}
|
|
|
|
|
|
/* must be called under the client_lock */
|
|
|
-static inline void
|
|
|
+static void
|
|
|
unhash_client_locked(struct nfs4_client *clp)
|
|
|
{
|
|
|
+ struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
|
|
|
struct nfsd4_session *ses;
|
|
|
|
|
|
- list_del(&clp->cl_lru);
|
|
|
+ /* Mark the client as expired! */
|
|
|
+ clp->cl_time = 0;
|
|
|
+ /* Make it invisible */
|
|
|
+ if (!list_empty(&clp->cl_idhash)) {
|
|
|
+ list_del_init(&clp->cl_idhash);
|
|
|
+ if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags))
|
|
|
+ rb_erase(&clp->cl_namenode, &nn->conf_name_tree);
|
|
|
+ else
|
|
|
+ rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
|
|
|
+ }
|
|
|
+ list_del_init(&clp->cl_lru);
|
|
|
spin_lock(&clp->cl_lock);
|
|
|
list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
|
|
|
list_del_init(&ses->se_hash);
|
|
@@ -1601,7 +1612,17 @@ unhash_client_locked(struct nfs4_client *clp)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-destroy_client(struct nfs4_client *clp)
|
|
|
+unhash_client(struct nfs4_client *clp)
|
|
|
+{
|
|
|
+ struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
|
|
|
+
|
|
|
+ spin_lock(&nn->client_lock);
|
|
|
+ unhash_client_locked(clp);
|
|
|
+ spin_unlock(&nn->client_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+__destroy_client(struct nfs4_client *clp)
|
|
|
{
|
|
|
struct nfs4_openowner *oo;
|
|
|
struct nfs4_delegation *dp;
|
|
@@ -1634,22 +1655,24 @@ destroy_client(struct nfs4_client *clp)
|
|
|
nfsd4_shutdown_callback(clp);
|
|
|
if (clp->cl_cb_conn.cb_xprt)
|
|
|
svc_xprt_put(clp->cl_cb_conn.cb_xprt);
|
|
|
- list_del(&clp->cl_idhash);
|
|
|
- if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags))
|
|
|
- rb_erase(&clp->cl_namenode, &nn->conf_name_tree);
|
|
|
- else
|
|
|
- rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
|
|
|
spin_lock(&nn->client_lock);
|
|
|
- unhash_client_locked(clp);
|
|
|
WARN_ON_ONCE(atomic_read(&clp->cl_refcount));
|
|
|
free_client(clp);
|
|
|
spin_unlock(&nn->client_lock);
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+destroy_client(struct nfs4_client *clp)
|
|
|
+{
|
|
|
+ unhash_client(clp);
|
|
|
+ __destroy_client(clp);
|
|
|
+}
|
|
|
+
|
|
|
static void expire_client(struct nfs4_client *clp)
|
|
|
{
|
|
|
+ unhash_client(clp);
|
|
|
nfsd4_client_record_remove(clp);
|
|
|
- destroy_client(clp);
|
|
|
+ __destroy_client(clp);
|
|
|
}
|
|
|
|
|
|
static void copy_verf(struct nfs4_client *target, nfs4_verifier *source)
|