aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--include/linux/sunrpc/svc_xprt.h2
-rw-r--r--net/sunrpc/svc_xprt.c56
3 files changed, 41 insertions, 19 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index e051847b93fb..6a1cd908e6bc 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -918,7 +918,7 @@ static ssize_t __write_ports_names(char *buf)
918{ 918{
919 if (nfsd_serv == NULL) 919 if (nfsd_serv == NULL)
920 return 0; 920 return 0;
921 return svc_xprt_names(nfsd_serv, buf, 0); 921 return svc_xprt_names(nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
922} 922}
923 923
924/* 924/*
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index d790c52525cc..2223ae0b5ed5 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -83,7 +83,7 @@ int svc_port_is_privileged(struct sockaddr *sin);
83int svc_print_xprts(char *buf, int maxlen); 83int svc_print_xprts(char *buf, int maxlen);
84struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, 84struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
85 const sa_family_t af, const unsigned short port); 85 const sa_family_t af, const unsigned short port);
86int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen); 86int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
87 87
88static inline void svc_xprt_get(struct svc_xprt *xprt) 88static inline void svc_xprt_get(struct svc_xprt *xprt)
89{ 89{
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index f200393ac877..6f33d33cc064 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -1098,36 +1098,58 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
1098} 1098}
1099EXPORT_SYMBOL_GPL(svc_find_xprt); 1099EXPORT_SYMBOL_GPL(svc_find_xprt);
1100 1100
1101/* 1101static int svc_one_xprt_name(const struct svc_xprt *xprt,
1102 * Format a buffer with a list of the active transports. A zero for 1102 char *pos, int remaining)
1103 * 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.
1104 */ 1125 */
1105int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen) 1126int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen)
1106{ 1127{
1107 struct svc_xprt *xprt; 1128 struct svc_xprt *xprt;
1108 char xprt_str[64]; 1129 int len, totlen;
1109 int totlen = 0; 1130 char *pos;
1110 int len;
1111 1131
1112 /* Sanity check args */ 1132 /* Sanity check args */
1113 if (!serv) 1133 if (!serv)
1114 return 0; 1134 return 0;
1115 1135
1116 spin_lock_bh(&serv->sv_lock); 1136 spin_lock_bh(&serv->sv_lock);
1137
1138 pos = buf;
1139 totlen = 0;
1117 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) { 1140 list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
1118 len = snprintf(xprt_str, sizeof(xprt_str), 1141 len = svc_one_xprt_name(xprt, pos, buflen - totlen);
1119 "%s %d\n", xprt->xpt_class->xcl_name, 1142 if (len < 0) {
1120 svc_xprt_local_port(xprt)); 1143 *buf = '\0';
1121 /* If the string was truncated, replace with error string */ 1144 totlen = len;
1122 if (len >= sizeof(xprt_str)) 1145 }
1123 strcpy(xprt_str, "name-too-long\n"); 1146 if (len <= 0)
1124 /* Don't overflow buffer */
1125 len = strlen(xprt_str);
1126 if (buflen && (len + totlen >= buflen))
1127 break; 1147 break;
1128 strcpy(buf+totlen, xprt_str); 1148
1149 pos += len;
1129 totlen += len; 1150 totlen += len;
1130 } 1151 }
1152
1131 spin_unlock_bh(&serv->sv_lock); 1153 spin_unlock_bh(&serv->sv_lock);
1132 return totlen; 1154 return totlen;
1133} 1155}