diff options
-rw-r--r-- | fs/nfsd/nfsctl.c | 2 | ||||
-rw-r--r-- | include/linux/sunrpc/svc_xprt.h | 2 | ||||
-rw-r--r-- | net/sunrpc/svc_xprt.c | 56 |
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); | |||
83 | int svc_print_xprts(char *buf, int maxlen); | 83 | int svc_print_xprts(char *buf, int maxlen); |
84 | struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, | 84 | struct 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); |
86 | int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen); | 86 | int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen); |
87 | 87 | ||
88 | static inline void svc_xprt_get(struct svc_xprt *xprt) | 88 | static 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 | } |
1099 | EXPORT_SYMBOL_GPL(svc_find_xprt); | 1099 | EXPORT_SYMBOL_GPL(svc_find_xprt); |
1100 | 1100 | ||
1101 | /* | 1101 | static 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 | */ |
1105 | int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen) | 1126 | int 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 | } |