Merge tag 'nfs-for-4.21-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[sfrench/cifs-2.6.git] / fs / nfs / write.c
index 4f15665f0ad1c8fdd72367b8e952aa6cb6d376c6..5a0bbf917a32d45935122f8480d5492b9c65999f 100644 (file)
@@ -1233,9 +1233,12 @@ int
 nfs_key_timeout_notify(struct file *filp, struct inode *inode)
 {
        struct nfs_open_context *ctx = nfs_file_open_context(filp);
-       struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
 
-       return rpcauth_key_timeout_notify(auth, ctx->cred);
+       if (nfs_ctx_key_to_expire(ctx, inode) &&
+           !ctx->ll_cred)
+               /* Already expired! */
+               return -EACCES;
+       return 0;
 }
 
 /*
@@ -1244,8 +1247,23 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
 bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode)
 {
        struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
+       struct rpc_cred *cred = ctx->ll_cred;
+       struct auth_cred acred = {
+               .cred = ctx->cred,
+       };
 
-       return rpcauth_cred_key_to_expire(auth, ctx->cred);
+       if (cred && !cred->cr_ops->crmatch(&acred, cred, 0)) {
+               put_rpccred(cred);
+               ctx->ll_cred = NULL;
+               cred = NULL;
+       }
+       if (!cred)
+               cred = auth->au_ops->lookup_cred(auth, &acred, 0);
+       if (!cred || IS_ERR(cred))
+               return true;
+       ctx->ll_cred = cred;
+       return !!(cred->cr_ops->crkey_timeout &&
+                 cred->cr_ops->crkey_timeout(cred));
 }
 
 /*