diff options
author | NeilBrown <neilb@suse.com> | 2018-12-02 19:30:30 -0500 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2018-12-19 13:52:45 -0500 |
commit | a534ecb013bfc58a7f03653c7f2976bc341da98f (patch) | |
tree | 55d3c1b4a992afc33c28b5d1d4e37943de4b1389 | |
parent | 1a80810fbf238e6dbaaaa5262a76d328ace21376 (diff) |
NFSv4: add cl_root_cred for use when machine cred is not available.
NFSv4 state management tries a root credential when no machine
credential is available, as can happen with kerberos.
It does this by replacing the cl_machine_cred with a root credential.
This means that any user of the machine credential needs to take
a lock while getting a reference to the machine credential, which is
a little cumbersome.
So introduce an explicit cl_root_cred, and never free either
credential until client shutdown. This means that no locking
is needed to reference these credentials. Future patches
will make use of this.
This is only a temporary addition. both cl_machine_cred and
cl_root_cred will disappear later in the series.
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | fs/nfs/client.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 20 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 1 |
3 files changed, 15 insertions, 8 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 96d5f8135eb9..cce151776709 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -248,6 +248,8 @@ void nfs_free_client(struct nfs_client *clp) | |||
248 | 248 | ||
249 | if (clp->cl_machine_cred != NULL) | 249 | if (clp->cl_machine_cred != NULL) |
250 | put_rpccred(clp->cl_machine_cred); | 250 | put_rpccred(clp->cl_machine_cred); |
251 | if (clp->cl_root_cred != NULL) | ||
252 | put_rpccred(clp->cl_root_cred); | ||
251 | 253 | ||
252 | put_net(clp->cl_net); | 254 | put_net(clp->cl_net); |
253 | put_nfs_version(clp->cl_nfs_mod); | 255 | put_nfs_version(clp->cl_nfs_mod); |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index d8decf2ec48f..511bcdee98f5 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -166,24 +166,28 @@ out: | |||
166 | 166 | ||
167 | struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp) | 167 | struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp) |
168 | { | 168 | { |
169 | struct rpc_cred *cred = NULL; | 169 | struct rpc_cred *cred = clp->cl_root_cred; |
170 | 170 | ||
171 | if (clp->cl_machine_cred != NULL) | 171 | if (!cred) |
172 | cred = get_rpccred(clp->cl_machine_cred); | 172 | cred = clp->cl_machine_cred; |
173 | if (cred) | ||
174 | return get_rpccred(cred); | ||
173 | return cred; | 175 | return cred; |
174 | } | 176 | } |
175 | 177 | ||
176 | static void nfs4_root_machine_cred(struct nfs_client *clp) | 178 | static void nfs4_root_machine_cred(struct nfs_client *clp) |
177 | { | 179 | { |
178 | struct rpc_cred *cred, *new; | 180 | struct rpc_cred *new; |
179 | 181 | ||
180 | new = rpc_lookup_machine_cred(NULL); | 182 | new = rpc_lookup_machine_cred(NULL); |
181 | spin_lock(&clp->cl_lock); | 183 | spin_lock(&clp->cl_lock); |
182 | cred = clp->cl_machine_cred; | 184 | if (clp->cl_root_cred == NULL) { |
183 | clp->cl_machine_cred = new; | 185 | clp->cl_root_cred = new; |
186 | new = NULL; | ||
187 | } | ||
184 | spin_unlock(&clp->cl_lock); | 188 | spin_unlock(&clp->cl_lock); |
185 | if (cred != NULL) | 189 | if (new != NULL) |
186 | put_rpccred(cred); | 190 | put_rpccred(new); |
187 | } | 191 | } |
188 | 192 | ||
189 | static struct rpc_cred * | 193 | static struct rpc_cred * |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 0fc0b9135d46..fea51b44fe50 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -59,6 +59,7 @@ struct nfs_client { | |||
59 | 59 | ||
60 | u32 cl_minorversion;/* NFSv4 minorversion */ | 60 | u32 cl_minorversion;/* NFSv4 minorversion */ |
61 | struct rpc_cred *cl_machine_cred; | 61 | struct rpc_cred *cl_machine_cred; |
62 | struct rpc_cred *cl_root_cred; /* Use when machine_cred is ineffective */ | ||
62 | 63 | ||
63 | #if IS_ENABLED(CONFIG_NFS_V4) | 64 | #if IS_ENABLED(CONFIG_NFS_V4) |
64 | struct list_head cl_ds_clients; /* auth flavor data servers */ | 65 | struct list_head cl_ds_clients; /* auth flavor data servers */ |