BKL: remove extraneous #include <smp_lock.h>
[pandora-kernel.git] / net / sunrpc / svc_xprt.c
index 95fc3e8..ea2ff78 100644 (file)
@@ -5,7 +5,6 @@
  */
 
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
@@ -100,16 +99,14 @@ EXPORT_SYMBOL_GPL(svc_unreg_xprt_class);
  */
 int svc_print_xprts(char *buf, int maxlen)
 {
-       struct list_head *le;
+       struct svc_xprt_class *xcl;
        char tmpstr[80];
        int len = 0;
        buf[0] = '\0';
 
        spin_lock(&svc_xprt_class_lock);
-       list_for_each(le, &svc_xprt_class_list) {
+       list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
                int slen;
-               struct svc_xprt_class *xcl =
-                       list_entry(le, struct svc_xprt_class, xcl_list);
 
                sprintf(tmpstr, "%s %d\n", xcl->xcl_name, xcl->xcl_max_payload);
                slen = strlen(tmpstr);
@@ -128,9 +125,9 @@ static void svc_xprt_free(struct kref *kref)
        struct svc_xprt *xprt =
                container_of(kref, struct svc_xprt, xpt_ref);
        struct module *owner = xprt->xpt_class->xcl_owner;
-       if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags) &&
-           xprt->xpt_auth_cache != NULL)
-               svcauth_unix_info_release(xprt->xpt_auth_cache);
+       if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags))
+               svcauth_unix_info_release(xprt);
+       put_net(xprt->xpt_net);
        xprt->xpt_ops->xpo_free(xprt);
        module_put(owner);
 }
@@ -156,15 +153,18 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
        INIT_LIST_HEAD(&xprt->xpt_list);
        INIT_LIST_HEAD(&xprt->xpt_ready);
        INIT_LIST_HEAD(&xprt->xpt_deferred);
+       INIT_LIST_HEAD(&xprt->xpt_users);
        mutex_init(&xprt->xpt_mutex);
        spin_lock_init(&xprt->xpt_lock);
        set_bit(XPT_BUSY, &xprt->xpt_flags);
        rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
+       xprt->xpt_net = get_net(&init_net);
 }
 EXPORT_SYMBOL_GPL(svc_xprt_init);
 
 static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
                                         struct svc_serv *serv,
+                                        struct net *net,
                                         const int family,
                                         const unsigned short port,
                                         int flags)
@@ -199,12 +199,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
                return ERR_PTR(-EAFNOSUPPORT);
        }
 
-       return xcl->xcl_ops->xpo_create(serv, sap, len, flags);
+       return xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
 }
 
 int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
-                   const int family, const unsigned short port,
-                   int flags)
+                   struct net *net, const int family,
+                   const unsigned short port, int flags)
 {
        struct svc_xprt_class *xcl;
 
@@ -220,7 +220,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
                        goto err;
 
                spin_unlock(&svc_xprt_class_lock);
-               newxprt = __svc_xpo_create(xcl, serv, family, port, flags);
+               newxprt = __svc_xpo_create(xcl, serv, net, family, port, flags);
                if (IS_ERR(newxprt)) {
                        module_put(xcl->xcl_owner);
                        return PTR_ERR(newxprt);
@@ -329,12 +329,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
                       "svc_xprt_enqueue: "
                       "threads and transports both waiting??\n");
 
-       if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
-               /* Don't enqueue dead transports */
-               dprintk("svc: transport %p is dead, not enqueued\n", xprt);
-               goto out_unlock;
-       }
-
        pool->sp_stats.packets++;
 
        /* Mark transport as busy. It will remain in this state until
@@ -879,6 +873,19 @@ static void svc_age_temp_xprts(unsigned long closure)
        mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
 }
 
+static void call_xpt_users(struct svc_xprt *xprt)
+{
+       struct svc_xpt_user *u;
+
+       spin_lock(&xprt->xpt_lock);
+       while (!list_empty(&xprt->xpt_users)) {
+               u = list_first_entry(&xprt->xpt_users, struct svc_xpt_user, list);
+               list_del(&u->list);
+               u->callback(u);
+       }
+       spin_unlock(&xprt->xpt_lock);
+}
+
 /*
  * Remove a dead transport
  */
@@ -889,7 +896,7 @@ void svc_delete_xprt(struct svc_xprt *xprt)
 
        /* Only do this once */
        if (test_and_set_bit(XPT_DEAD, &xprt->xpt_flags))
-               return;
+               BUG();
 
        dprintk("svc: svc_delete_xprt(%p)\n", xprt);
        xprt->xpt_ops->xpo_detach(xprt);
@@ -911,6 +918,7 @@ void svc_delete_xprt(struct svc_xprt *xprt)
        while ((dr = svc_deferred_dequeue(xprt)) != NULL)
                kfree(dr);
 
+       call_xpt_users(xprt);
        svc_xprt_put(xprt);
 }
 
@@ -921,10 +929,7 @@ void svc_close_xprt(struct svc_xprt *xprt)
                /* someone else will have to effect the close */
                return;
 
-       svc_xprt_get(xprt);
        svc_delete_xprt(xprt);
-       clear_bit(XPT_BUSY, &xprt->xpt_flags);
-       svc_xprt_put(xprt);
 }
 EXPORT_SYMBOL_GPL(svc_close_xprt);