aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc_xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r--net/sunrpc/svc_xprt.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index c200d92e57e4..6f33d33cc064 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -11,6 +11,7 @@
11#include <net/sock.h> 11#include <net/sock.h>
12#include <linux/sunrpc/stats.h> 12#include <linux/sunrpc/stats.h>
13#include <linux/sunrpc/svc_xprt.h> 13#include <linux/sunrpc/svc_xprt.h>
14#include <linux/sunrpc/svcsock.h>
14 15
15#define RPCDBG_FACILITY RPCDBG_SVCXPRT 16#define RPCDBG_FACILITY RPCDBG_SVCXPRT
16 17
@@ -1097,36 +1098,58 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
1097} 1098}
1098EXPORT_SYMBOL_GPL(svc_find_xprt); 1099EXPORT_SYMBOL_GPL(svc_find_xprt);
1099 1100
1100/* 1101static int svc_one_xprt_name(const struct svc_xprt *xprt,
1101 * Format a buffer with a list of the active transports. A zero for 1102 char *pos, int remaining)
1102 * the buflen parameter disables target buffer overflow checking. 1103{
1104 int len;
1105
1106 len = snprintf(pos, remaining, "%s %u\n",
1107 xprt->xpt_class->xcl_name,
1108 svc_xprt_local_port(xprt));
1109 if (len >= remaining)
1110 return -ENAMETOOLONG;
1111 return len;
1112}
1113
1114/**
1115 * svc_xprt_names - format a buffer with a list of transport names
1116 * @serv: pointer to an RPC service
1117 * @buf: pointer to a buffer to be filled in
1118 * @buflen: length of buffer to be filled in
1119 *
1120 * Fills in @buf with a string containing a list of transport names,
1121 * each name terminated with '\n'.
1122 *
1123 * Returns positive length of the filled-in string on success; otherwise
1124 * a negative errno value is returned if an error occurs.
1103 */ 1125 */
1104int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen) 1126int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen)
1105{ 1127{
1106 struct svc_xprt *xprt; 1128 struct svc_xprt *xprt;
1107 char xprt_str[64]; 1129 int len, totlen;
1108 int totlen = 0; 1130 char *pos;
1109 int len;
1110 1131
1111 /* Sanity check args */ 1132 /* Sanity check args */
1112 if (!serv) 1133 if (!serv)
1113 return 0; 1134 return 0;
1114 1135
1115 spin_lock_bh(&serv->sv_lock); 1136 spin_lock_bh(&serv->sv_lock);
1137
1138 pos = buf;
1139 totlen = 0;
1116 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) { 1140 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
1117 len = snprintf(xprt_str, sizeof(xprt_str), 1141 len = svc_one_xprt_name(xprt, pos, buflen - totlen);
1118 "%s %d\n", xprt->xpt_class->xcl_name, 1142 if (len < 0) {
1119 svc_xprt_local_port(xprt)); 1143 *buf = '\0';
1120 /* If the string was truncated, replace with error string */ 1144 totlen = len;
1121 if (len >= sizeof(xprt_str)) 1145 }
1122 strcpy(xprt_str, "name-too-long\n"); 1146 if (len <= 0)
1123 /* Don't overflow buffer */
1124 len = strlen(xprt_str);
1125 if (buflen && (len + totlen >= buflen))
1126 break; 1147 break;
1127 strcpy(buf+totlen, xprt_str); 1148
1149 pos += len;
1128 totlen += len; 1150 totlen += len;
1129 } 1151 }
1152
1130 spin_unlock_bh(&serv->sv_lock); 1153 spin_unlock_bh(&serv->sv_lock);
1131 return totlen; 1154 return totlen;
1132} 1155}