--- zzzz-none-000/linux-2.6.19.2/net/sunrpc/svcsock.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/net/sunrpc/svcsock.c 2007-01-11 07:38:19.000000000 +0000 @@ -299,15 +299,9 @@ static inline void svc_sock_put(struct svc_sock *svsk) { - if (atomic_dec_and_test(&svsk->sk_inuse) && - test_bit(SK_DEAD, &svsk->sk_flags)) { + if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) { dprintk("svc: releasing dead socket\n"); - if (svsk->sk_sock->file) - sockfd_put(svsk->sk_sock); - else - sock_release(svsk->sk_sock); - if (svsk->sk_info_authunix != NULL) - svcauth_unix_info_release(svsk->sk_info_authunix); + sock_release(svsk->sk_sock); kfree(svsk); } } @@ -1610,13 +1604,20 @@ if (test_bit(SK_TEMP, &svsk->sk_flags)) serv->sv_tmpcnt--; - /* This atomic_inc should be needed - svc_delete_socket - * should have the semantic of dropping a reference. - * But it doesn't yet.... - */ - atomic_inc(&svsk->sk_inuse); - spin_unlock_bh(&serv->sv_lock); - svc_sock_put(svsk); + if (!atomic_read(&svsk->sk_inuse)) { + spin_unlock_bh(&serv->sv_lock); + if (svsk->sk_sock->file) + sockfd_put(svsk->sk_sock); + else + sock_release(svsk->sk_sock); + if (svsk->sk_info_authunix != NULL) + svcauth_unix_info_release(svsk->sk_info_authunix); + kfree(svsk); + } else { + spin_unlock_bh(&serv->sv_lock); + dprintk(KERN_NOTICE "svc: server socket destroy delayed\n"); + /* svsk->sk_server = NULL; */ + } } /*