Commit 094eca37 authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker

NFSv4: Fix up RCU annotations for struct nfs_netns_client

The identifier is read as an RCU protected string. Its value may
be changed during the lifetime of the network namespace by writing
a new string into the sysfs pseudofile (at which point, we free the
old string only after a call to synchronize_rcu()).
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 61ca2c4a
...@@ -79,7 +79,12 @@ static ssize_t nfs_netns_identifier_show(struct kobject *kobj, ...@@ -79,7 +79,12 @@ static ssize_t nfs_netns_identifier_show(struct kobject *kobj,
struct nfs_netns_client *c = container_of(kobj, struct nfs_netns_client *c = container_of(kobj,
struct nfs_netns_client, struct nfs_netns_client,
kobject); kobject);
return scnprintf(buf, PAGE_SIZE, "%s\n", c->identifier); ssize_t ret;
rcu_read_lock();
ret = scnprintf(buf, PAGE_SIZE, "%s\n", rcu_dereference(c->identifier));
rcu_read_unlock();
return ret;
} }
/* Strip trailing '\n' */ /* Strip trailing '\n' */
...@@ -107,7 +112,7 @@ static ssize_t nfs_netns_identifier_store(struct kobject *kobj, ...@@ -107,7 +112,7 @@ static ssize_t nfs_netns_identifier_store(struct kobject *kobj,
p = kmemdup_nul(buf, len, GFP_KERNEL); p = kmemdup_nul(buf, len, GFP_KERNEL);
if (!p) if (!p)
return -ENOMEM; return -ENOMEM;
old = xchg(&c->identifier, p); old = rcu_dereference_protected(xchg(&c->identifier, (char __rcu *)p), 1);
if (old) { if (old) {
synchronize_rcu(); synchronize_rcu();
kfree(old); kfree(old);
...@@ -121,7 +126,7 @@ static void nfs_netns_client_release(struct kobject *kobj) ...@@ -121,7 +126,7 @@ static void nfs_netns_client_release(struct kobject *kobj)
struct nfs_netns_client, struct nfs_netns_client,
kobject); kobject);
kfree(c->identifier); kfree(rcu_dereference_raw(c->identifier));
kfree(c); kfree(c);
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
struct nfs_netns_client { struct nfs_netns_client {
struct kobject kobject; struct kobject kobject;
struct net *net; struct net *net;
const char *identifier; const char __rcu *identifier;
}; };
extern struct kobject *nfs_client_kobj; extern struct kobject *nfs_client_kobj;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment