summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-07-30 14:27:18 +0200
committerJ. Bruce Fields <bfields@redhat.com>2014-08-05 16:55:04 +0200
commita0926d15271a0139606d54d0521c527746e2815b (patch)
treea4f0b952e2433fe3c505f7136c63d63934b396d9
parentnfsd: add a forget_clients "get" routine with proper locking (diff)
downloadlinux-a0926d15271a0139606d54d0521c527746e2815b.tar.xz
linux-a0926d15271a0139606d54d0521c527746e2815b.zip
nfsd: add a forget_client set_clnt routine
...that relies on the client_lock instead of client_mutex. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/fault_inject.c2
-rw-r--r--fs/nfsd/nfs4state.c28
-rw-r--r--fs/nfsd/state.h3
3 files changed, 32 insertions, 1 deletions
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index a0387fd47e14..5f3ead0c72fb 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -136,7 +136,7 @@ static struct nfsd_fault_inject_op inject_ops[] = {
.file = "forget_clients",
.get = nfsd_inject_print_clients,
.set_val = nfsd_inject_set,
- .set_clnt = nfsd_inject_set_client,
+ .set_clnt = nfsd_inject_forget_client,
.forget = nfsd_forget_client,
},
{
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 2225e1103742..c4c28f8f48a1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -5760,6 +5760,34 @@ u64 nfsd_forget_client(struct nfs4_client *clp, u64 max)
return 1;
}
+u64
+nfsd_inject_forget_client(struct nfsd_fault_inject_op *op,
+ struct sockaddr_storage *addr, size_t addr_size)
+{
+ u64 count = 0;
+ struct nfs4_client *clp;
+ struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
+ nfsd_net_id);
+
+ if (!nfsd_netns_ready(nn))
+ return count;
+
+ spin_lock(&nn->client_lock);
+ clp = nfsd_find_client(addr, addr_size);
+ if (clp) {
+ if (mark_client_expired_locked(clp) == nfs_ok)
+ ++count;
+ else
+ clp = NULL;
+ }
+ spin_unlock(&nn->client_lock);
+
+ if (clp)
+ 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 7c7580ea9680..77a1903d58ab 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -480,6 +480,9 @@ 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_forget_client_locks(struct nfs4_client*, u64);
u64 nfsd_forget_client_openowners(struct nfs4_client *, u64);
u64 nfsd_forget_client_delegations(struct nfs4_client *, u64);