};
 #define RPCAUTH_CRED_LOCKED    0x0001
 #define RPCAUTH_CRED_UPTODATE  0x0002
+#define RPCAUTH_CRED_NEW       0x0004
 
 #define RPCAUTH_CRED_MAGIC     0x0f4aa4f0
 
                                                 * uid/gid, fs[ug]id, gids)
                                                 */
 
+/* Flags for rpcauth_lookupcred() */
+#define RPCAUTH_LOOKUP_NEW             0x01    /* Accept an uninitialised cred */
+#define RPCAUTH_LOOKUP_ROOTCREDS       0x02    /* This really ought to go! */
+
 /*
  * Client authentication ops
  */
 
  */
 struct rpc_cred *
 rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
-               int taskflags)
+               int flags)
 {
        struct rpc_cred_cache *cache = auth->au_credcache;
        HLIST_HEAD(free);
                        *cred = NULL;
        int             nr = 0;
 
-       if (!(taskflags & RPC_TASK_ROOTCREDS))
+       if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
                nr = acred->uid & RPC_CREDCACHE_MASK;
 retry:
        spin_lock(&rpc_credcache_lock);
        hlist_for_each_safe(pos, next, &cache->hashtable[nr]) {
                struct rpc_cred *entry;
                entry = hlist_entry(pos, struct rpc_cred, cr_hash);
-               if (entry->cr_ops->crmatch(acred, entry, taskflags)) {
+               if (entry->cr_ops->crmatch(acred, entry, flags)) {
                        hlist_del(&entry->cr_hash);
                        cred = entry;
                        break;
        rpcauth_destroy_credlist(&free);
 
        if (!cred) {
-               new = auth->au_ops->crcreate(auth, acred, taskflags);
+               new = auth->au_ops->crcreate(auth, acred, flags);
                if (!IS_ERR(new)) {
 #ifdef RPC_DEBUG
                        new->cr_magic = RPCAUTH_CRED_MAGIC;
 }
 
 struct rpc_cred *
-rpcauth_lookupcred(struct rpc_auth *auth, int taskflags)
+rpcauth_lookupcred(struct rpc_auth *auth, int flags)
 {
        struct auth_cred acred = {
                .uid = current->fsuid,
        dprintk("RPC:     looking up %s cred\n",
                auth->au_ops->au_name);
        get_group_info(acred.group_info);
-       ret = auth->au_ops->lookup_cred(auth, &acred, taskflags);
+       ret = auth->au_ops->lookup_cred(auth, &acred, flags);
        put_group_info(acred.group_info);
        return ret;
 }
                .group_info = current->group_info,
        };
        struct rpc_cred *ret;
+       int flags = 0;
 
        dprintk("RPC: %4d looking up %s cred\n",
                task->tk_pid, task->tk_auth->au_ops->au_name);
        get_group_info(acred.group_info);
-       ret = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags);
+       if (task->tk_flags & RPC_TASK_ROOTCREDS)
+               flags |= RPCAUTH_LOOKUP_ROOTCREDS;
+       ret = auth->au_ops->lookup_cred(auth, &acred, flags);
        if (!IS_ERR(ret))
                task->tk_msg.rpc_cred = ret;
        else
 
        old = gss_cred->gc_ctx;
        gss_cred->gc_ctx = ctx;
        cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
+       cred->cr_flags &= ~RPCAUTH_CRED_NEW;
        write_unlock(&gss_ctx_lock);
        if (old)
                gss_put_ctx(old);
        } else {
                struct auth_cred acred = { .uid = uid };
                spin_unlock(&gss_auth->lock);
-               cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, 0);
+               cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW);
                if (IS_ERR(cred)) {
                        err = PTR_ERR(cred);
                        goto err_put_ctx;
  * Lookup RPCSEC_GSS cred for the current process
  */
 static struct rpc_cred *
-gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
+gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 {
-       return rpcauth_lookup_credcache(auth, acred, taskflags);
+       return rpcauth_lookup_credcache(auth, acred, flags);
 }
 
 static struct rpc_cred *
-gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
+gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 {
        struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
        struct gss_cred *cred = NULL;
         */
        cred->gc_flags = 0;
        cred->gc_base.cr_ops = &gss_credops;
+       cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
        cred->gc_service = gss_auth->service;
+       /* Is the caller prepared to initialise the credential? */
+       if (flags & RPCAUTH_LOOKUP_NEW)
+               goto out;
        do {
                err = gss_create_upcall(gss_auth, cred);
        } while (err == -EAGAIN);
        if (err < 0)
                goto out_err;
-
+out:
        return &cred->gc_base;
 
 out_err:
 }
 
 static int
-gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags)
+gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
 {
        struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
 
+       /*
+        * If the searchflags have set RPCAUTH_LOOKUP_NEW, then
+        * we don't really care if the credential has expired or not,
+        * since the caller should be prepared to reinitialise it.
+        */
+       if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW))
+               goto out;
        /* Don't match with creds that have expired. */
        if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
                return 0;
+out:
        return (rc->cr_uid == acred->uid);
 }
 
 
 
        atomic_set(&cred->uc_count, 1);
        cred->uc_flags = RPCAUTH_CRED_UPTODATE;
-       if (flags & RPC_TASK_ROOTCREDS) {
+       if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
                cred->uc_uid = 0;
                cred->uc_gid = 0;
                cred->uc_gids[0] = NOGROUP;
  * request root creds (e.g. for NFS swapping).
  */
 static int
-unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
+unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 {
        struct unx_cred *cred = (struct unx_cred *) rcred;
        int             i;
 
-       if (!(taskflags & RPC_TASK_ROOTCREDS)) {
+       if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
                int groups;
 
                if (cred->uc_uid != acred->uid