]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sunrpc/svc_xprt.c
leds: add possibility to remove leds classdevs during suspend/resume
[linux-2.6-omap-h63xx.git] / net / sunrpc / svc_xprt.c
index 000c7dc3b82c9997cc59a95e7b1974d33f5aa4be..ea377e06afae0d1a56812e9b6771a3c055c7a410 100644 (file)
@@ -112,6 +112,34 @@ void svc_unreg_xprt_class(struct svc_xprt_class *xcl)
 }
 EXPORT_SYMBOL_GPL(svc_unreg_xprt_class);
 
+/*
+ * Format the transport list for printing
+ */
+int svc_print_xprts(char *buf, int maxlen)
+{
+       struct list_head *le;
+       char tmpstr[80];
+       int len = 0;
+       buf[0] = '\0';
+
+       spin_lock(&svc_xprt_class_lock);
+       list_for_each(le, &svc_xprt_class_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);
+               if (len + slen > maxlen)
+                       break;
+               len += slen;
+               strcat(buf, tmpstr);
+       }
+       spin_unlock(&svc_xprt_class_lock);
+
+       return len;
+}
+
 static void svc_xprt_free(struct kref *kref)
 {
        struct svc_xprt *xprt =
@@ -407,6 +435,7 @@ void svc_reserve(struct svc_rqst *rqstp, int space)
                svc_xprt_enqueue(xprt);
        }
 }
+EXPORT_SYMBOL(svc_reserve);
 
 static void svc_xprt_release(struct svc_rqst *rqstp)
 {
@@ -464,6 +493,7 @@ void svc_wake_up(struct svc_serv *serv)
                spin_unlock_bh(&pool->sp_lock);
        }
 }
+EXPORT_SYMBOL(svc_wake_up);
 
 int svc_port_is_privileged(struct sockaddr *sin)
 {
@@ -674,6 +704,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
                serv->sv_stats->netcnt++;
        return len;
 }
+EXPORT_SYMBOL(svc_recv);
 
 /*
  * Drop request
@@ -683,6 +714,7 @@ void svc_drop(struct svc_rqst *rqstp)
        dprintk("svc: xprt %p dropped request\n", rqstp->rq_xprt);
        svc_xprt_release(rqstp);
 }
+EXPORT_SYMBOL(svc_drop);
 
 /*
  * Return reply to client.
@@ -814,6 +846,7 @@ void svc_close_xprt(struct svc_xprt *xprt)
        clear_bit(XPT_BUSY, &xprt->xpt_flags);
        svc_xprt_put(xprt);
 }
+EXPORT_SYMBOL_GPL(svc_close_xprt);
 
 void svc_close_all(struct list_head *xprt_list)
 {
@@ -949,3 +982,74 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
        spin_unlock(&xprt->xpt_lock);
        return dr;
 }
+
+/*
+ * Return the transport instance pointer for the endpoint accepting
+ * connections/peer traffic from the specified transport class,
+ * address family and port.
+ *
+ * Specifying 0 for the address family or port is effectively a
+ * wild-card, and will result in matching the first transport in the
+ * service's list that has a matching class name.
+ */
+struct svc_xprt *svc_find_xprt(struct svc_serv *serv, char *xcl_name,
+                              int af, int port)
+{
+       struct svc_xprt *xprt;
+       struct svc_xprt *found = NULL;
+
+       /* Sanity check the args */
+       if (!serv || !xcl_name)
+               return found;
+
+       spin_lock_bh(&serv->sv_lock);
+       list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
+               if (strcmp(xprt->xpt_class->xcl_name, xcl_name))
+                       continue;
+               if (af != AF_UNSPEC && af != xprt->xpt_local.ss_family)
+                       continue;
+               if (port && port != svc_xprt_local_port(xprt))
+                       continue;
+               found = xprt;
+               svc_xprt_get(xprt);
+               break;
+       }
+       spin_unlock_bh(&serv->sv_lock);
+       return found;
+}
+EXPORT_SYMBOL_GPL(svc_find_xprt);
+
+/*
+ * Format a buffer with a list of the active transports. A zero for
+ * the buflen parameter disables target buffer overflow checking.
+ */
+int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen)
+{
+       struct svc_xprt *xprt;
+       char xprt_str[64];
+       int totlen = 0;
+       int len;
+
+       /* Sanity check args */
+       if (!serv)
+               return 0;
+
+       spin_lock_bh(&serv->sv_lock);
+       list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
+               len = snprintf(xprt_str, sizeof(xprt_str),
+                              "%s %d\n", xprt->xpt_class->xcl_name,
+                              svc_xprt_local_port(xprt));
+               /* If the string was truncated, replace with error string */
+               if (len >= sizeof(xprt_str))
+                       strcpy(xprt_str, "name-too-long\n");
+               /* Don't overflow buffer */
+               len = strlen(xprt_str);
+               if (buflen && (len + totlen >= buflen))
+                       break;
+               strcpy(buf+totlen, xprt_str);
+               totlen += len;
+       }
+       spin_unlock_bh(&serv->sv_lock);
+       return totlen;
+}
+EXPORT_SYMBOL_GPL(svc_xprt_names);