diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2010-12-23 20:32:32 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-01-06 14:47:56 -0500 |
commit | fca5238ef3232cd0cf4bf0457e751b3bb20912a9 (patch) | |
tree | 5b61da0d71e3e89b835d46a49e0f4945b5002cea /fs/nfs | |
parent | f7e8917a67980924651a9e244510e63ef05c7755 (diff) |
NFS: Allow walking nfs_client.cl_superblocks list outside client.c
We're about to move some fields from struct nfs_client to struct
nfs_server. There is a many-to-one relationship between nfs_servers
and nfs_clients. After these fields are moved to the nfs_server
struct, to visit all of the data in these fields that is owned by one
nfs_client, code will need to visit each nfs_server on the
cl_superblocks list for that nfs_client.
To serialize changes to the cl_superblocks list during these little
expeditions, protect the list with RCU.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/client.c | 44 | ||||
-rw-r--r-- | fs/nfs/nfs4renewd.c | 9 |
2 files changed, 32 insertions, 21 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 684b67771199..32b5fbfab35e 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -1003,6 +1003,27 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve | |||
1003 | target->options = source->options; | 1003 | target->options = source->options; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | static void nfs_server_insert_lists(struct nfs_server *server) | ||
1007 | { | ||
1008 | struct nfs_client *clp = server->nfs_client; | ||
1009 | |||
1010 | spin_lock(&nfs_client_lock); | ||
1011 | list_add_tail_rcu(&server->client_link, &clp->cl_superblocks); | ||
1012 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
1013 | spin_unlock(&nfs_client_lock); | ||
1014 | |||
1015 | } | ||
1016 | |||
1017 | static void nfs_server_remove_lists(struct nfs_server *server) | ||
1018 | { | ||
1019 | spin_lock(&nfs_client_lock); | ||
1020 | list_del_rcu(&server->client_link); | ||
1021 | list_del(&server->master_link); | ||
1022 | spin_unlock(&nfs_client_lock); | ||
1023 | |||
1024 | synchronize_rcu(); | ||
1025 | } | ||
1026 | |||
1006 | /* | 1027 | /* |
1007 | * Allocate and initialise a server record | 1028 | * Allocate and initialise a server record |
1008 | */ | 1029 | */ |
@@ -1046,11 +1067,8 @@ void nfs_free_server(struct nfs_server *server) | |||
1046 | { | 1067 | { |
1047 | dprintk("--> nfs_free_server()\n"); | 1068 | dprintk("--> nfs_free_server()\n"); |
1048 | 1069 | ||
1070 | nfs_server_remove_lists(server); | ||
1049 | unset_pnfs_layoutdriver(server); | 1071 | unset_pnfs_layoutdriver(server); |
1050 | spin_lock(&nfs_client_lock); | ||
1051 | list_del(&server->client_link); | ||
1052 | list_del(&server->master_link); | ||
1053 | spin_unlock(&nfs_client_lock); | ||
1054 | 1072 | ||
1055 | if (server->destroy != NULL) | 1073 | if (server->destroy != NULL) |
1056 | server->destroy(server); | 1074 | server->destroy(server); |
@@ -1125,11 +1143,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, | |||
1125 | (unsigned long long) server->fsid.major, | 1143 | (unsigned long long) server->fsid.major, |
1126 | (unsigned long long) server->fsid.minor); | 1144 | (unsigned long long) server->fsid.minor); |
1127 | 1145 | ||
1128 | spin_lock(&nfs_client_lock); | 1146 | nfs_server_insert_lists(server); |
1129 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
1130 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
1131 | spin_unlock(&nfs_client_lock); | ||
1132 | |||
1133 | server->mount_time = jiffies; | 1147 | server->mount_time = jiffies; |
1134 | nfs_free_fattr(fattr); | 1148 | nfs_free_fattr(fattr); |
1135 | return server; | 1149 | return server; |
@@ -1454,11 +1468,7 @@ static int nfs4_server_common_setup(struct nfs_server *server, | |||
1454 | if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) | 1468 | if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) |
1455 | server->namelen = NFS4_MAXNAMLEN; | 1469 | server->namelen = NFS4_MAXNAMLEN; |
1456 | 1470 | ||
1457 | spin_lock(&nfs_client_lock); | 1471 | nfs_server_insert_lists(server); |
1458 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
1459 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
1460 | spin_unlock(&nfs_client_lock); | ||
1461 | |||
1462 | server->mount_time = jiffies; | 1472 | server->mount_time = jiffies; |
1463 | out: | 1473 | out: |
1464 | nfs_free_fattr(fattr); | 1474 | nfs_free_fattr(fattr); |
@@ -1663,11 +1673,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, | |||
1663 | if (error < 0) | 1673 | if (error < 0) |
1664 | goto out_free_server; | 1674 | goto out_free_server; |
1665 | 1675 | ||
1666 | spin_lock(&nfs_client_lock); | 1676 | nfs_server_insert_lists(server); |
1667 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
1668 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
1669 | spin_unlock(&nfs_client_lock); | ||
1670 | |||
1671 | server->mount_time = jiffies; | 1677 | server->mount_time = jiffies; |
1672 | 1678 | ||
1673 | nfs_free_fattr(fattr_fsinfo); | 1679 | nfs_free_fattr(fattr_fsinfo); |
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 72b6c580af13..cde5650ee5a2 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -63,9 +63,14 @@ nfs4_renew_state(struct work_struct *work) | |||
63 | 63 | ||
64 | ops = clp->cl_mvops->state_renewal_ops; | 64 | ops = clp->cl_mvops->state_renewal_ops; |
65 | dprintk("%s: start\n", __func__); | 65 | dprintk("%s: start\n", __func__); |
66 | /* Are there any active superblocks? */ | 66 | |
67 | if (list_empty(&clp->cl_superblocks)) | 67 | rcu_read_lock(); |
68 | if (list_empty(&clp->cl_superblocks)) { | ||
69 | rcu_read_unlock(); | ||
68 | goto out; | 70 | goto out; |
71 | } | ||
72 | rcu_read_unlock(); | ||
73 | |||
69 | spin_lock(&clp->cl_lock); | 74 | spin_lock(&clp->cl_lock); |
70 | lease = clp->cl_lease_time; | 75 | lease = clp->cl_lease_time; |
71 | last = clp->cl_last_renewal; | 76 | last = clp->cl_last_renewal; |