Skip to content

Commit 4ee7ba4

Browse files
Mike SnitzerAnna Schumaker
authored andcommitted
nfs_common: move localio_lock to new lock member of nfs_uuid_t
Remove cl_localio_lock from 'struct nfs_client' in favor of adding a lock to the nfs_uuid_t struct (which is embedded in each nfs_client). Push nfs_local_{enable,disable} implementation down to nfs_common. Those methods now call nfs_localio_{enable,disable}_client. This allows implementing nfs_localio_invalidate_clients in terms of nfs_localio_disable_client. Signed-off-by: Mike Snitzer <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent b49f049 commit 4ee7ba4

File tree

5 files changed

+50
-29
lines changed

5 files changed

+50
-29
lines changed

fs/nfs/client.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
186186
seqlock_init(&clp->cl_boot_lock);
187187
ktime_get_real_ts64(&clp->cl_nfssvc_boot);
188188
nfs_uuid_init(&clp->cl_uuid);
189-
spin_lock_init(&clp->cl_localio_lock);
190189
#endif /* CONFIG_NFS_LOCALIO */
191190

192191
clp->cl_principal = "*";

fs/nfs/localio.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,23 +126,17 @@ const struct rpc_program nfslocalio_program = {
126126
*/
127127
static void nfs_local_enable(struct nfs_client *clp)
128128
{
129-
spin_lock(&clp->cl_localio_lock);
130-
set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags);
131129
trace_nfs_local_enable(clp);
132-
spin_unlock(&clp->cl_localio_lock);
130+
nfs_localio_enable_client(clp);
133131
}
134132

135133
/*
136134
* nfs_local_disable - disable local i/o for an nfs_client
137135
*/
138136
void nfs_local_disable(struct nfs_client *clp)
139137
{
140-
spin_lock(&clp->cl_localio_lock);
141-
if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) {
142-
trace_nfs_local_disable(clp);
143-
nfs_localio_disable_client(&clp->cl_uuid);
144-
}
145-
spin_unlock(&clp->cl_localio_lock);
138+
trace_nfs_local_disable(clp);
139+
nfs_localio_disable_client(clp);
146140
}
147141

148142
/*
@@ -184,7 +178,7 @@ static bool nfs_server_uuid_is_local(struct nfs_client *clp)
184178
rpc_shutdown_client(rpcclient_localio);
185179

186180
/* Server is only local if it initialized required struct members */
187-
if (status || !clp->cl_uuid.net || !clp->cl_uuid.dom)
181+
if (status || !rcu_access_pointer(clp->cl_uuid.net) || !clp->cl_uuid.dom)
188182
return false;
189183

190184
return true;

fs/nfs_common/nfslocalio.c

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include <linux/module.h>
88
#include <linux/list.h>
99
#include <linux/nfslocalio.h>
10+
#include <linux/nfs3.h>
11+
#include <linux/nfs4.h>
12+
#include <linux/nfs_fs_sb.h>
1013
#include <net/netns/generic.h>
1114

1215
MODULE_LICENSE("GPL");
@@ -25,6 +28,7 @@ void nfs_uuid_init(nfs_uuid_t *nfs_uuid)
2528
nfs_uuid->net = NULL;
2629
nfs_uuid->dom = NULL;
2730
INIT_LIST_HEAD(&nfs_uuid->list);
31+
spin_lock_init(&nfs_uuid->lock);
2832
}
2933
EXPORT_SYMBOL_GPL(nfs_uuid_init);
3034

@@ -94,40 +98,59 @@ void nfs_uuid_is_local(const uuid_t *uuid, struct list_head *list,
9498
}
9599
EXPORT_SYMBOL_GPL(nfs_uuid_is_local);
96100

101+
void nfs_localio_enable_client(struct nfs_client *clp)
102+
{
103+
nfs_uuid_t *nfs_uuid = &clp->cl_uuid;
104+
105+
spin_lock(&nfs_uuid->lock);
106+
set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags);
107+
spin_unlock(&nfs_uuid->lock);
108+
}
109+
EXPORT_SYMBOL_GPL(nfs_localio_enable_client);
110+
97111
static void nfs_uuid_put_locked(nfs_uuid_t *nfs_uuid)
98112
{
99-
if (nfs_uuid->net) {
100-
module_put(nfsd_mod);
101-
nfs_uuid->net = NULL;
102-
}
113+
if (!nfs_uuid->net)
114+
return;
115+
module_put(nfsd_mod);
116+
RCU_INIT_POINTER(nfs_uuid->net, NULL);
117+
103118
if (nfs_uuid->dom) {
104119
auth_domain_put(nfs_uuid->dom);
105120
nfs_uuid->dom = NULL;
106121
}
107122
list_del_init(&nfs_uuid->list);
108123
}
109124

110-
void nfs_localio_invalidate_clients(struct list_head *list)
125+
void nfs_localio_disable_client(struct nfs_client *clp)
111126
{
112-
nfs_uuid_t *nfs_uuid, *tmp;
113-
114-
spin_lock(&nfs_uuid_lock);
115-
list_for_each_entry_safe(nfs_uuid, tmp, list, list)
116-
nfs_uuid_put_locked(nfs_uuid);
117-
spin_unlock(&nfs_uuid_lock);
118-
}
119-
EXPORT_SYMBOL_GPL(nfs_localio_invalidate_clients);
127+
nfs_uuid_t *nfs_uuid = &clp->cl_uuid;
120128

121-
void nfs_localio_disable_client(nfs_uuid_t *nfs_uuid)
122-
{
123-
if (nfs_uuid->net) {
129+
spin_lock(&nfs_uuid->lock);
130+
if (test_and_clear_bit(NFS_CS_LOCAL_IO, &clp->cl_flags)) {
124131
spin_lock(&nfs_uuid_lock);
125132
nfs_uuid_put_locked(nfs_uuid);
126133
spin_unlock(&nfs_uuid_lock);
127134
}
135+
spin_unlock(&nfs_uuid->lock);
128136
}
129137
EXPORT_SYMBOL_GPL(nfs_localio_disable_client);
130138

139+
void nfs_localio_invalidate_clients(struct list_head *cl_uuid_list)
140+
{
141+
nfs_uuid_t *nfs_uuid, *tmp;
142+
143+
spin_lock(&nfs_uuid_lock);
144+
list_for_each_entry_safe(nfs_uuid, tmp, cl_uuid_list, list) {
145+
struct nfs_client *clp =
146+
container_of(nfs_uuid, struct nfs_client, cl_uuid);
147+
148+
nfs_localio_disable_client(clp);
149+
}
150+
spin_unlock(&nfs_uuid_lock);
151+
}
152+
EXPORT_SYMBOL_GPL(nfs_localio_invalidate_clients);
153+
131154
struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid,
132155
struct rpc_clnt *rpc_clnt, const struct cred *cred,
133156
const struct nfs_fh *nfs_fh, const fmode_t fmode)

include/linux/nfs_fs_sb.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ struct nfs_client {
132132
struct timespec64 cl_nfssvc_boot;
133133
seqlock_t cl_boot_lock;
134134
nfs_uuid_t cl_uuid;
135-
spinlock_t cl_localio_lock;
136135
#endif /* CONFIG_NFS_LOCALIO */
137136
};
138137

include/linux/nfslocalio.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef __LINUX_NFSLOCALIO_H
77
#define __LINUX_NFSLOCALIO_H
88

9+
910
/* nfsd_file structure is purposely kept opaque to NFS client */
1011
struct nfsd_file;
1112

@@ -19,6 +20,8 @@ struct nfsd_file;
1920
#include <linux/nfs.h>
2021
#include <net/net_namespace.h>
2122

23+
struct nfs_client;
24+
2225
/*
2326
* Useful to allow a client to negotiate if localio
2427
* possible with its server.
@@ -27,6 +30,8 @@ struct nfsd_file;
2730
*/
2831
typedef struct {
2932
uuid_t uuid;
33+
/* sadly this struct is just over a cacheline, avoid bouncing */
34+
spinlock_t ____cacheline_aligned lock;
3035
struct list_head list;
3136
struct net __rcu *net; /* nfsd's network namespace */
3237
struct auth_domain *dom; /* auth_domain for localio */
@@ -38,7 +43,8 @@ void nfs_uuid_end(nfs_uuid_t *);
3843
void nfs_uuid_is_local(const uuid_t *, struct list_head *,
3944
struct net *, struct auth_domain *, struct module *);
4045

41-
void nfs_localio_disable_client(nfs_uuid_t *nfs_uuid);
46+
void nfs_localio_enable_client(struct nfs_client *clp);
47+
void nfs_localio_disable_client(struct nfs_client *clp);
4248
void nfs_localio_invalidate_clients(struct list_head *list);
4349

4450
/* localio needs to map filehandle -> struct nfsd_file */

0 commit comments

Comments
 (0)