+ knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     knfsd: allow sockets to be passed to nfsd via 'portlist'

has been added to the -mm tree.  Its filename is

     knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: knfsd: allow sockets to be passed to nfsd via 'portlist'
From: NeilBrown <neilb@xxxxxxx>

Userspace should create and bind a socket (but not connectted) and write the
'fd' to portlist.  This will cause the nfs server to listen on that socket.

To close a socket, the name of the socket - as read from 'portlist' can be
written to 'portlist' with a preceding '-'.

Signed-off-by: Neil Brown <neilb@xxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 fs/nfsd/nfsctl.c               |   59 ++++++++++++++++++++++++++-----
 fs/nfsd/nfssvc.c               |    4 --
 include/linux/nfsd/nfsd.h      |    1 
 include/linux/sunrpc/svcsock.h |    6 ++-
 net/sunrpc/svcsock.c           |   49 +++++++++++++++++++++++--
 5 files changed, 102 insertions(+), 17 deletions(-)

diff -puN fs/nfsd/nfsctl.c~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist fs/nfsd/nfsctl.c
--- a/fs/nfsd/nfsctl.c~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist
+++ a/fs/nfsd/nfsctl.c
@@ -23,9 +23,11 @@
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/ctype.h>
 
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
+#include <linux/lockd/bind.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfsd/nfsd.h>
@@ -425,16 +427,55 @@ static ssize_t write_versions(struct fil
 
 static ssize_t write_ports(struct file *file, char *buf, size_t size)
 {
-	/* for now, ignore what was written and just
-	 * return known ports
-	 * AF proto address port
+	if (size == 0) {
+		int len = 0;
+		lock_kernel();
+		if (nfsd_serv)
+			len = svc_sock_names(buf, nfsd_serv, NULL);
+		unlock_kernel();
+		return len;
+	}
+	/* Either a single 'fd' number is written, in which
+	 * case it must be for a socket of a supported family/protocol,
+	 * and we use it as an nfsd socket, or
+	 * A '-' followed by the 'name' of a socket in which case
+	 * we close the socket.
 	 */
-	int len = 0;
-	lock_kernel();
-	if (nfsd_serv)
-		len = svc_sock_names(buf, nfsd_serv);
-	unlock_kernel();
-	return len;
+	if (isdigit(buf[0])) {
+		char *mesg = buf;
+		int fd;
+		int err;
+		err = get_int(&mesg, &fd);
+		if (err)
+			return -EINVAL;
+		if (fd < 0)
+			return -EINVAL;
+		err = nfsd_create_serv();
+		if (!err) {
+			int proto = 0;
+			err = svc_addsock(nfsd_serv, fd, buf, &proto);
+			/* Decrease the count, but don't shutdown the
+			 * the service
+			 */
+			if (err >= 0)
+				lockd_up(proto);
+			nfsd_serv->sv_nrthreads--;
+		}
+		return err;
+	}
+	if (buf[0] == '-') {
+		char *toclose = kstrdup(buf+1, GFP_KERNEL);
+		int len = 0;
+		if (!toclose)
+			return -ENOMEM;
+		lock_kernel();
+		if (nfsd_serv)
+			len = svc_sock_names(buf, nfsd_serv, toclose);
+		unlock_kernel();
+		kfree(toclose);
+		return len;
+	}
+	return -EINVAL;
 }
 
 #ifdef CONFIG_NFSD_V4
diff -puN fs/nfsd/nfssvc.c~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist
+++ a/fs/nfsd/nfssvc.c
@@ -195,7 +195,7 @@ void nfsd_reset_versions(void)
 	}
 }
 
-static int nfsd_create_serv(void)
+int nfsd_create_serv(void)
 {
 	int err = 0;
 	lock_kernel();
@@ -210,8 +210,6 @@ static int nfsd_create_serv(void)
 			       nfsd_last_thread);
 	if (nfsd_serv == NULL)
 		err = -ENOMEM;
-	else
-		nfsd_serv->sv_nrthreads++;
 	unlock_kernel();
 	do_gettimeofday(&nfssvc_boot);		/* record boot time */
 	return err;
diff -puN include/linux/nfsd/nfsd.h~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist include/linux/nfsd/nfsd.h
--- a/include/linux/nfsd/nfsd.h~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist
+++ a/include/linux/nfsd/nfsd.h
@@ -143,6 +143,7 @@ int nfsd_set_posix_acl(struct svc_fh *, 
 enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL };
 int nfsd_vers(int vers, enum vers_op change);
 void nfsd_reset_versions(void);
+int nfsd_create_serv(void);
 
 
 /* 
diff -puN include/linux/sunrpc/svcsock.h~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist include/linux/sunrpc/svcsock.h
--- a/include/linux/sunrpc/svcsock.h~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist
+++ a/include/linux/sunrpc/svcsock.h
@@ -61,6 +61,10 @@ int		svc_recv(struct svc_serv *, struct 
 int		svc_send(struct svc_rqst *);
 void		svc_drop(struct svc_rqst *);
 void		svc_sock_update_bufs(struct svc_serv *serv);
-int		svc_sock_names(char *buf, struct svc_serv *serv);
+int		svc_sock_names(char *buf, struct svc_serv *serv, char *toclose);
+int		svc_addsock(struct svc_serv *serv,
+			    int fd,
+			    char *name_return,
+			    int *proto);
 
 #endif /* SUNRPC_SVCSOCK_H */
diff -puN net/sunrpc/svcsock.c~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist net/sunrpc/svcsock.c
--- a/net/sunrpc/svcsock.c~knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist
+++ a/net/sunrpc/svcsock.c
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/file.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -451,9 +452,9 @@ static int one_sock_name(char *buf, stru
 }
 
 int
-svc_sock_names(char *buf, struct svc_serv *serv)
+svc_sock_names(char *buf, struct svc_serv *serv, char *toclose)
 {
-	struct svc_sock *svsk;
+	struct svc_sock *svsk, *closesk = NULL;
 	int len = 0;
 
 	if (!serv)
@@ -461,9 +462,14 @@ svc_sock_names(char *buf, struct svc_ser
 	spin_lock(&serv->sv_lock);
 	list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
 		int onelen = one_sock_name(buf+len, svsk);
-		len += onelen;
+		if (toclose && strcmp(toclose, buf+len) == 0)
+			closesk = svsk;
+		else
+			len += onelen;
 	}
 	spin_unlock(&serv->sv_lock);
+	if (closesk)
+		svc_delete_socket(closesk);
 	return len;
 }
 EXPORT_SYMBOL(svc_sock_names);
@@ -1417,6 +1423,38 @@ svc_setup_socket(struct svc_serv *serv, 
 	return svsk;
 }
 
+int svc_addsock(struct svc_serv *serv,
+		int fd,
+		char *name_return,
+		int *proto)
+{
+	int err = 0;
+	struct socket *so = sockfd_lookup(fd, &err);
+	struct svc_sock *svsk = NULL;
+
+	if (!so)
+		return err;
+	if (so->sk->sk_family != AF_INET)
+		err =  -EAFNOSUPPORT;
+	else if (so->sk->sk_protocol != IPPROTO_TCP &&
+	    so->sk->sk_protocol != IPPROTO_UDP)
+		err =  -EPROTONOSUPPORT;
+	else if (so->state > SS_UNCONNECTED)
+		err = -EISCONN;
+	else {
+		svsk = svc_setup_socket(serv, so, &err, 1);
+		if (svsk)
+			err = 0;
+	}
+	if (err) {
+		sockfd_put(so);
+		return err;
+	}
+	if (proto) *proto = so->sk->sk_protocol;
+	return one_sock_name(name_return, svsk);
+}
+EXPORT_SYMBOL_GPL(svc_addsock);
+
 /*
  * Create socket for RPC service.
  */
@@ -1494,7 +1532,10 @@ svc_delete_socket(struct svc_sock *svsk)
 
 	if (!svsk->sk_inuse) {
 		spin_unlock_bh(&serv->sv_lock);
-		sock_release(svsk->sk_sock);
+		if (svsk->sk_sock->file)
+			sockfd_put(svsk->sk_sock);
+		else
+			sock_release(svsk->sk_sock);
 		kfree(svsk);
 	} else {
 		spin_unlock_bh(&serv->sv_lock);
_

Patches currently in -mm which might be from neilb@xxxxxxx are

ext3-avoid-triggering-ext3_error-on-bad-nfs-file-handle.patch
ext3-avoid-triggering-ext3_error-on-bad-nfs-file-handle-fix.patch
git-klibc.patch
ext3-reject-filehandles-referring-to-special-files.patch
ext2-reject-file-handles-with-bad-inode-numbers-early.patch
knfsd-knfsd-add-some-missing-newlines-in-printks.patch
knfsd-knfsd-remove-an-unused-variable-from-e_show.patch
knfsd-knfsd-remove-an-unused-variable-from-auth_unix_lookup.patch
knfsd-add-a-callback-for-when-last-rpc-thread-finishes.patch
knfsd-add-a-callback-for-when-last-rpc-thread-finishes-tidy.patch
knfsd-be-more-selective-in-which-sockets-lockd-listens-on.patch
knfsd-remove-nfsd_versbits-as-intermediate-storage-for-desired-versions.patch
knfsd-separate-out-some-parts-of-nfsd_svc-which-start-nfs-servers.patch
knfsd-separate-out-some-parts-of-nfsd_svc-which-start-nfs-servers-tweaks.patch
knfsd-define-new-nfsdfs-file-portlist-contains-list-of-ports.patch
knfsd-define-new-nfsdfs-file-portlist-contains-list-of-ports-tidy.patch
knfsd-allow-sockets-to-be-passed-to-nfsd-via-portlist.patch
md-dm-reduce-stack-usage-with-stacked-block-devices.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux