#define        SVC_NEGATIVE    4
 #define        SVC_OK          5
 #define        SVC_DROP        6
-#define        SVC_DENIED      7
-#define        SVC_PENDING     8
-#define        SVC_COMPLETE    9
+#define        SVC_CLOSE       7       /* Like SVC_DROP, but request is definitely
+                                * lost so if there is a tcp connection, it
+                                * should be closed
+                                */
+#define        SVC_DENIED      8
+#define        SVC_PENDING     9
+#define        SVC_COMPLETE    10
 
 
 extern int     svc_authenticate(struct svc_rqst *rqstp, __be32 *authp);
 
        if (rqstp->rq_gssclient == NULL)
                return SVC_DENIED;
        stat = svcauth_unix_set_client(rqstp);
-       if (stat == SVC_DROP)
+       if (stat == SVC_DROP || stat == SVC_CLOSE)
                return stat;
        return SVC_OK;
 }
                return SVC_DENIED;
        memset(&rsikey, 0, sizeof(rsikey));
        if (dup_netobj(&rsikey.in_handle, &gc->gc_ctx))
-               return SVC_DROP;
+               return SVC_CLOSE;
        *authp = rpc_autherr_badverf;
        if (svc_safe_getnetobj(argv, &tmpobj)) {
                kfree(rsikey.in_handle.data);
        }
        if (dup_netobj(&rsikey.in_token, &tmpobj)) {
                kfree(rsikey.in_handle.data);
-               return SVC_DROP;
+               return SVC_CLOSE;
        }
 
        /* Perform upcall, or find upcall result: */
        rsip = rsi_lookup(&rsikey);
        rsi_free(&rsikey);
        if (!rsip)
-               return SVC_DROP;
+               return SVC_CLOSE;
        switch (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) {
        case -EAGAIN:
        case -ETIMEDOUT:
        case -ENOENT:
                /* No upcall result: */
-               return SVC_DROP;
+               return SVC_CLOSE;
        case 0:
-               ret = SVC_DROP;
+               ret = SVC_CLOSE;
                /* Got an answer to the upcall; use it: */
                if (gss_write_init_verf(rqstp, rsip))
                        goto out;
 
                goto err_bad;
        case SVC_DENIED:
                goto err_bad_auth;
+       case SVC_CLOSE:
+               if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
+                       svc_close_xprt(rqstp->rq_xprt);
        case SVC_DROP:
                goto dropit;
        case SVC_COMPLETE:
 
        switch (ret) {
        case -ENOENT:
                return ERR_PTR(-ENOENT);
+       case -ETIMEDOUT:
+               return ERR_PTR(-ESHUTDOWN);
        case 0:
                gi = get_group_info(ug->gi);
                cache_put(&ug->h, &unix_gid_cache);
        switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
                default:
                        BUG();
-               case -EAGAIN:
                case -ETIMEDOUT:
+                       return SVC_CLOSE;
+               case -EAGAIN:
                        return SVC_DROP;
                case -ENOENT:
                        return SVC_DENIED;
        switch (PTR_ERR(gi)) {
        case -EAGAIN:
                return SVC_DROP;
+       case -ESHUTDOWN:
+               return SVC_CLOSE;
        case -ENOENT:
                break;
        default:
        cred->cr_gid = (gid_t) -1;
        cred->cr_group_info = groups_alloc(0);
        if (cred->cr_group_info == NULL)
-               return SVC_DROP; /* kmalloc failure - client must retry */
+               return SVC_CLOSE; /* kmalloc failure - client must retry */
 
        /* Put NULL verifier */
        svc_putnl(resv, RPC_AUTH_NULL);
                goto badcred;
        cred->cr_group_info = groups_alloc(slen);
        if (cred->cr_group_info == NULL)
-               return SVC_DROP;
+               return SVC_CLOSE;
        for (i = 0; i < slen; i++)
                GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
        if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {