summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-07-30 08:27:19 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-08-05 10:55:05 -0400
commit69fc9edf987ca451831575b1e5450a9fe49fbfe0 (patch)
tree862e96ba621daf5a341706d0101c965e8907585d
parenta0926d15271a0139606d54d0521c527746e2815b (diff)
nfsd: add nfsd_inject_forget_clients
...which uses the client_lock for protection instead of client_mutex. Also remove nfsd_forget_client as there are no more callers. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/fault_inject.c3
-rw-r--r--fs/nfsd/nfs4state.c42
-rw-r--r--fs/nfsd/state.h2
3 files changed, 30 insertions, 17 deletions
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index 5f3ead0c72fb..76ecdff37ea2 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -135,9 +135,8 @@ static struct nfsd_fault_inject_op inject_ops[] = {
{
.file = "forget_clients",
.get = nfsd_inject_print_clients,
- .set_val = nfsd_inject_set,
+ .set_val = nfsd_inject_forget_clients,
.set_clnt = nfsd_inject_forget_client,
- .forget = nfsd_forget_client,
},
{
.file = "forget_locks",
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c4c28f8f48a1..226d89e2c7b2 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -5746,20 +5746,6 @@ nfsd_inject_print_clients(struct nfsd_fault_inject_op *op)
return count;
}
-u64 nfsd_forget_client(struct nfs4_client *clp, u64 max)
-{
- __be32 ret;
- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
-
- spin_lock(&nn->client_lock);
- ret = mark_client_expired_locked(clp);
- spin_unlock(&nn->client_lock);
- if (ret != nfs_ok)
- return 0;
- expire_client(clp);
- return 1;
-}
-
u64
nfsd_inject_forget_client(struct nfsd_fault_inject_op *op,
struct sockaddr_storage *addr, size_t addr_size)
@@ -5788,6 +5774,34 @@ nfsd_inject_forget_client(struct nfsd_fault_inject_op *op,
return count;
}
+u64
+nfsd_inject_forget_clients(struct nfsd_fault_inject_op *op, u64 max)
+{
+ u64 count = 0;
+ struct nfs4_client *clp, *next;
+ struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
+ nfsd_net_id);
+ LIST_HEAD(reaplist);
+
+ if (!nfsd_netns_ready(nn))
+ return count;
+
+ spin_lock(&nn->client_lock);
+ list_for_each_entry_safe(clp, next, &nn->client_lru, cl_lru) {
+ if (mark_client_expired_locked(clp) == nfs_ok) {
+ list_add(&clp->cl_lru, &reaplist);
+ if (max != 0 && ++count >= max)
+ break;
+ }
+ }
+ spin_unlock(&nn->client_lock);
+
+ list_for_each_entry_safe(clp, next, &reaplist, cl_lru)
+ expire_client(clp);
+
+ return count;
+}
+
static void nfsd_print_count(struct nfs4_client *clp, unsigned int count,
const char *type)
{
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 77a1903d58ab..eb3b35a74795 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -479,9 +479,9 @@ u64 nfsd_for_n_state(u64, u64 (*)(struct nfs4_client *, u64));
struct nfs4_client *nfsd_find_client(struct sockaddr_storage *, size_t);
u64 nfsd_inject_print_clients(struct nfsd_fault_inject_op *op);
-u64 nfsd_forget_client(struct nfs4_client *, u64);
u64 nfsd_inject_forget_client(struct nfsd_fault_inject_op *,
struct sockaddr_storage *, size_t);
+u64 nfsd_inject_forget_clients(struct nfsd_fault_inject_op *, u64);
u64 nfsd_forget_client_locks(struct nfs4_client*, u64);
u64 nfsd_forget_client_openowners(struct nfs4_client *, u64);