diff options
-rw-r--r-- | fs/nfsd/nfsctl.c | 20 | ||||
-rw-r--r-- | include/linux/sunrpc/svcsock.h | 1 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 40 |
3 files changed, 61 insertions, 0 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index d6881774ea57..d4041a05bc19 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -23,10 +23,12 @@ | |||
23 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | #include <linux/smp_lock.h> | ||
26 | 27 | ||
27 | #include <linux/nfs.h> | 28 | #include <linux/nfs.h> |
28 | #include <linux/nfsd_idmap.h> | 29 | #include <linux/nfsd_idmap.h> |
29 | #include <linux/sunrpc/svc.h> | 30 | #include <linux/sunrpc/svc.h> |
31 | #include <linux/sunrpc/svcsock.h> | ||
30 | #include <linux/nfsd/nfsd.h> | 32 | #include <linux/nfsd/nfsd.h> |
31 | #include <linux/nfsd/cache.h> | 33 | #include <linux/nfsd/cache.h> |
32 | #include <linux/nfsd/xdr.h> | 34 | #include <linux/nfsd/xdr.h> |
@@ -51,6 +53,7 @@ enum { | |||
51 | NFSD_Fh, | 53 | NFSD_Fh, |
52 | NFSD_Threads, | 54 | NFSD_Threads, |
53 | NFSD_Versions, | 55 | NFSD_Versions, |
56 | NFSD_Ports, | ||
54 | /* | 57 | /* |
55 | * The below MUST come last. Otherwise we leave a hole in nfsd_files[] | 58 | * The below MUST come last. Otherwise we leave a hole in nfsd_files[] |
56 | * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops | 59 | * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops |
@@ -74,6 +77,7 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size); | |||
74 | static ssize_t write_filehandle(struct file *file, char *buf, size_t size); | 77 | static ssize_t write_filehandle(struct file *file, char *buf, size_t size); |
75 | static ssize_t write_threads(struct file *file, char *buf, size_t size); | 78 | static ssize_t write_threads(struct file *file, char *buf, size_t size); |
76 | static ssize_t write_versions(struct file *file, char *buf, size_t size); | 79 | static ssize_t write_versions(struct file *file, char *buf, size_t size); |
80 | static ssize_t write_ports(struct file *file, char *buf, size_t size); | ||
77 | #ifdef CONFIG_NFSD_V4 | 81 | #ifdef CONFIG_NFSD_V4 |
78 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); | 82 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); |
79 | static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); | 83 | static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); |
@@ -90,6 +94,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { | |||
90 | [NFSD_Fh] = write_filehandle, | 94 | [NFSD_Fh] = write_filehandle, |
91 | [NFSD_Threads] = write_threads, | 95 | [NFSD_Threads] = write_threads, |
92 | [NFSD_Versions] = write_versions, | 96 | [NFSD_Versions] = write_versions, |
97 | [NFSD_Ports] = write_ports, | ||
93 | #ifdef CONFIG_NFSD_V4 | 98 | #ifdef CONFIG_NFSD_V4 |
94 | [NFSD_Leasetime] = write_leasetime, | 99 | [NFSD_Leasetime] = write_leasetime, |
95 | [NFSD_RecoveryDir] = write_recoverydir, | 100 | [NFSD_RecoveryDir] = write_recoverydir, |
@@ -419,6 +424,20 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size) | |||
419 | return len; | 424 | return len; |
420 | } | 425 | } |
421 | 426 | ||
427 | static ssize_t write_ports(struct file *file, char *buf, size_t size) | ||
428 | { | ||
429 | /* for now, ignore what was written and just | ||
430 | * return known ports | ||
431 | * AF proto address port | ||
432 | */ | ||
433 | int len = 0; | ||
434 | lock_kernel(); | ||
435 | if (nfsd_serv) | ||
436 | len = svc_sock_names(buf, nfsd_serv); | ||
437 | unlock_kernel(); | ||
438 | return len; | ||
439 | } | ||
440 | |||
422 | #ifdef CONFIG_NFSD_V4 | 441 | #ifdef CONFIG_NFSD_V4 |
423 | extern time_t nfs4_leasetime(void); | 442 | extern time_t nfs4_leasetime(void); |
424 | 443 | ||
@@ -482,6 +501,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
482 | [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR}, | 501 | [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR}, |
483 | [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, | 502 | [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, |
484 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, | 503 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, |
504 | [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, | ||
485 | #ifdef CONFIG_NFSD_V4 | 505 | #ifdef CONFIG_NFSD_V4 |
486 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, | 506 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
487 | [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, | 507 | [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, |
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index b4acb3d37c3f..3caf92d72a81 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h | |||
@@ -61,5 +61,6 @@ int svc_recv(struct svc_serv *, struct svc_rqst *, long); | |||
61 | int svc_send(struct svc_rqst *); | 61 | int svc_send(struct svc_rqst *); |
62 | void svc_drop(struct svc_rqst *); | 62 | void svc_drop(struct svc_rqst *); |
63 | void svc_sock_update_bufs(struct svc_serv *serv); | 63 | void svc_sock_update_bufs(struct svc_serv *serv); |
64 | int svc_sock_names(char *buf, struct svc_serv *serv); | ||
64 | 65 | ||
65 | #endif /* SUNRPC_SVCSOCK_H */ | 66 | #endif /* SUNRPC_SVCSOCK_H */ |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 5b0fe1b66a23..3ee4b78742b1 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -429,6 +429,46 @@ out: | |||
429 | } | 429 | } |
430 | 430 | ||
431 | /* | 431 | /* |
432 | * Report socket names for nfsdfs | ||
433 | */ | ||
434 | static int one_sock_name(char *buf, struct svc_sock *svsk) | ||
435 | { | ||
436 | int len; | ||
437 | |||
438 | switch(svsk->sk_sk->sk_family) { | ||
439 | case AF_INET: | ||
440 | len = sprintf(buf, "ipv4 %s %u.%u.%u.%u %d\n", | ||
441 | svsk->sk_sk->sk_protocol==IPPROTO_UDP? | ||
442 | "udp" : "tcp", | ||
443 | NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr), | ||
444 | inet_sk(svsk->sk_sk)->num); | ||
445 | break; | ||
446 | default: | ||
447 | len = sprintf(buf, "*unknown-%d*\n", | ||
448 | svsk->sk_sk->sk_family); | ||
449 | } | ||
450 | return len; | ||
451 | } | ||
452 | |||
453 | int | ||
454 | svc_sock_names(char *buf, struct svc_serv *serv) | ||
455 | { | ||
456 | struct svc_sock *svsk; | ||
457 | int len = 0; | ||
458 | |||
459 | if (!serv) | ||
460 | return 0; | ||
461 | spin_lock(&serv->sv_lock); | ||
462 | list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) { | ||
463 | int onelen = one_sock_name(buf+len, svsk); | ||
464 | len += onelen; | ||
465 | } | ||
466 | spin_unlock(&serv->sv_lock); | ||
467 | return len; | ||
468 | } | ||
469 | EXPORT_SYMBOL(svc_sock_names); | ||
470 | |||
471 | /* | ||
432 | * Check input queue length | 472 | * Check input queue length |
433 | */ | 473 | */ |
434 | static int | 474 | static int |