rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt,
                struct dentry *dentry)
 {
-       return exp_get_by_name(rqstp->rq_client, mnt, dentry,
-                                               &rqstp->rq_chandle);
+       struct auth_domain *clp;
+
+       clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
+       return exp_get_by_name(clp, mnt, dentry, &rqstp->rq_chandle);
 }
 
 struct svc_export *
 rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv)
 {
-       return exp_find(rqstp->rq_client, fsid_type, fsidv,
-                                               &rqstp->rq_chandle);
+       struct auth_domain *clp;
+
+       clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
+       return exp_find(clp, fsid_type, fsidv, &rqstp->rq_chandle);
 }
 
 struct svc_export *
 rqst_exp_parent(struct svc_rqst *rqstp, struct vfsmount *mnt,
                struct dentry *dentry)
 {
+       struct auth_domain *clp;
+
+       clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
        return exp_parent(rqstp->rq_client, mnt, dentry, &rqstp->rq_chandle);
 }
 
 
        return ret;
 }
 
+static char *
+rqst_authname(struct svc_rqst *rqstp)
+{
+       struct auth_domain *clp;
+
+       clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
+       return clp->name;
+}
+
 static int
 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
                uid_t *id)
                return -EINVAL;
        memcpy(key.name, name, namelen);
        key.name[namelen] = '\0';
-       strlcpy(key.authname, rqstp->rq_client->name, sizeof(key.authname));
+       strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
        ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item);
        if (ret == -ENOENT)
                ret = -ESRCH; /* nfserr_badname */
        };
        int ret;
 
-       strlcpy(key.authname, rqstp->rq_client->name, sizeof(key.authname));
+       strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
        ret = idmap_lookup(rqstp, idtoname_lookup, &key, &idtoname_cache, &item);
        if (ret == -ENOENT)
                return sprintf(name, "%u", id);
 
                int data_left = fh->fh_size/4;
 
                error = nfserr_stale;
-               if (rqstp->rq_client == NULL)
-                       goto out;
                if (rqstp->rq_vers > 2)
                        error = nfserr_badhandle;
                if (rqstp->rq_vers == 4 && fh->fh_size == 0)
 
                                                 */
        /* Catering to nfsd */
        struct auth_domain *    rq_client;      /* RPC peer info */
+       struct auth_domain *    rq_gssclient;   /* "gss/"-style peer info */
        struct svc_cacherep *   rq_cacherep;    /* cache info */
        struct knfsd_fh *       rq_reffh;       /* Referrence filehandle, used to
                                                 * determine what device number
 
 extern int auth_unix_forget_old(struct auth_domain *dom);
 extern void svcauth_unix_purge(void);
 extern void svcauth_unix_info_release(void *);
+extern int svcauth_unix_set_client(struct svc_rqst *rqstp);
 
 static inline unsigned long hash_str(char *name, int bits)
 {
 
        struct gss_svc_data *svcdata = rqstp->rq_auth_data;
        struct rsc *rsci = svcdata->rsci;
        struct rpc_gss_wire_cred *gc = &svcdata->clcred;
+       int stat;
 
-       rqstp->rq_client = find_gss_auth_domain(rsci->mechctx, gc->gc_svc);
-       if (rqstp->rq_client == NULL)
+       /*
+        * A gss export can be specified either by:
+        *      export  *(sec=krb5,rw)
+        * or by
+        *      export gss/krb5(rw)
+        * The latter is deprecated; but for backwards compatibility reasons
+        * the nfsd code will still fall back on trying it if the former
+        * doesn't work; so we try to make both available to nfsd, below.
+        */
+       rqstp->rq_gssclient = find_gss_auth_domain(rsci->mechctx, gc->gc_svc);
+       if (rqstp->rq_gssclient == NULL)
                return SVC_DENIED;
+       stat = svcauth_unix_set_client(rqstp);
+       if (stat == SVC_DROP)
+               return stat;
        return SVC_OK;
 }
 
                        svc_putnl(resv, GSS_SEQ_WIN);
                        if (svc_safe_putnetobj(resv, &rsip->out_token))
                                goto drop;
-                       rqstp->rq_client = NULL;
                }
                goto complete;
        case RPC_GSS_PROC_DESTROY:
        if (rqstp->rq_client)
                auth_domain_put(rqstp->rq_client);
        rqstp->rq_client = NULL;
+       if (rqstp->rq_gssclient)
+               auth_domain_put(rqstp->rq_gssclient);
+       rqstp->rq_gssclient = NULL;
        if (rqstp->rq_cred.cr_group_info)
                put_group_info(rqstp->rq_cred.cr_group_info);
        rqstp->rq_cred.cr_group_info = NULL;
 
        }
 }
 
-static int
+int
 svcauth_unix_set_client(struct svc_rqst *rqstp)
 {
        struct sockaddr_in *sin = svc_addr_in(rqstp);
        return SVC_OK;
 }
 
+EXPORT_SYMBOL(svcauth_unix_set_client);
+
 static int
 svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
 {