*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2012, 2015, Intel Corporation.
+ * Copyright (c) 2015, 2017, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#include <lnet/lib-lnet.h>
static int
-kernel_sock_unlocked_ioctl(struct file *filp, int cmd, unsigned long arg)
-{
- mm_segment_t oldfs = get_fs();
- int err;
-
- set_fs(KERNEL_DS);
- err = filp->f_op->unlocked_ioctl(filp, cmd, arg);
- set_fs(oldfs);
-
- return err;
-}
-
-static int
lnet_sock_ioctl(int cmd, unsigned long arg)
{
- struct file *sock_filp;
- struct socket *sock;
- int fd = -1;
- int rc;
+ struct socket *sock;
+ int rc;
- rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock);
+#ifdef HAVE_SOCK_CREATE_KERN_USE_NET
+ rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock);
+#else
+ rc = sock_create_kern(PF_INET, SOCK_STREAM, 0, &sock);
+#endif
if (rc != 0) {
CERROR("Can't create socket: %d\n", rc);
return rc;
}
-#if !defined(HAVE_SOCK_ALLOC_FILE) && !defined(HAVE_SOCK_ALLOC_FILE_3ARGS)
- fd = sock_map_fd(sock, 0);
- if (fd < 0) {
- rc = fd;
- sock_release(sock);
- goto out;
- }
- sock_filp = fget(fd);
-#else
-# ifdef HAVE_SOCK_ALLOC_FILE_3ARGS
- sock_filp = sock_alloc_file(sock, 0, NULL);
-# else
- sock_filp = sock_alloc_file(sock, 0);
-# endif
-#endif
- if (IS_ERR(sock_filp)) {
- rc = PTR_ERR(sock_filp);
- sock_release(sock);
- goto out;
+ if (cmd == SIOCGIFFLAGS) {
+ /* This cmd is used only to get IFF_UP flag */
+ struct ifreq *ifr = (struct ifreq *) arg;
+ struct net_device *dev;
+
+ dev = dev_get_by_name(sock_net(sock->sk), ifr->ifr_name);
+ if (dev) {
+ ifr->ifr_flags = dev->flags;
+ dev_put(dev);
+ rc = 0;
+ } else {
+ rc = -ENODEV;
+ }
+ } else {
+ rc = kernel_sock_ioctl(sock, cmd, arg);
}
+ sock_release(sock);
- rc = kernel_sock_unlocked_ioctl(sock_filp, cmd, arg);
-
- fput(sock_filp);
-out:
- if (fd >= 0)
- sys_close(fd);
return rc;
}
lnet_ipif_enumerate(char ***namesp)
{
/* Allocate and fill in 'names', returning # interfaces/error */
- char **names;
- int toobig;
- int nalloc;
- int nfound;
- struct ifreq *ifr;
- struct ifconf ifc;
- int rc;
- int nob;
- int i;
+ struct net_device *dev;
+ struct socket *sock;
+ char **names;
+ int toobig;
+ int nalloc;
+ int nfound;
+ int rc;
+ int nob;
+ int i;
nalloc = 16; /* first guess at max interfaces */
toobig = 0;
- for (;;) {
- if (nalloc * sizeof(*ifr) > PAGE_CACHE_SIZE) {
- toobig = 1;
- nalloc = PAGE_CACHE_SIZE/sizeof(*ifr);
- CWARN("Too many interfaces: only enumerating "
- "first %d\n", nalloc);
- }
-
- LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
- if (ifr == NULL) {
- CERROR("ENOMEM enumerating up to %d interfaces\n",
- nalloc);
- rc = -ENOMEM;
- goto out0;
- }
-
- ifc.ifc_buf = (char *)ifr;
- ifc.ifc_len = nalloc * sizeof(*ifr);
-
- rc = lnet_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
- if (rc < 0) {
- CERROR("Error %d enumerating interfaces\n", rc);
- goto out1;
- }
-
- LASSERT(rc == 0);
+ nfound = 0;
- nfound = ifc.ifc_len/sizeof(*ifr);
- LASSERT(nfound <= nalloc);
-
- if (nfound < nalloc || toobig)
- break;
-
- LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
- nalloc *= 2;
+#ifdef HAVE_SOCK_CREATE_KERN_USE_NET
+ rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock);
+#else
+ rc = sock_create_kern(PF_INET, SOCK_STREAM, 0, &sock);
+#endif
+ if (rc) {
+ CERROR("Can't create socket: %d\n", rc);
+ return rc;
}
+ for_each_netdev(sock_net(sock->sk), dev)
+ nfound++;
+
if (nfound == 0)
- goto out1;
+ goto out_release_sock;
LIBCFS_ALLOC(names, nfound * sizeof(*names));
if (names == NULL) {
rc = -ENOMEM;
- goto out1;
+ goto out_release_sock;
}
- for (i = 0; i < nfound; i++) {
- nob = strnlen(ifr[i].ifr_name, IFNAMSIZ);
+ i = 0;
+ for_each_netdev(sock_net(sock->sk), dev) {
+ nob = strnlen(dev->name, IFNAMSIZ);
if (nob == IFNAMSIZ) {
/* no space for terminating NULL */
CERROR("interface name %.*s too long (%d max)\n",
- nob, ifr[i].ifr_name, IFNAMSIZ);
+ nob, dev->name, IFNAMSIZ);
rc = -ENAMETOOLONG;
- goto out2;
+ goto out_free_names;
}
LIBCFS_ALLOC(names[i], IFNAMSIZ);
- if (names[i] == NULL) {
+ if (!names[i]) {
rc = -ENOMEM;
- goto out2;
+ goto out_free_names;
}
- memcpy(names[i], ifr[i].ifr_name, nob);
+ memcpy(names[i], dev->name, nob);
names[i][nob] = 0;
+ i++;
}
*namesp = names;
- rc = nfound;
+ rc = i;
- out2:
+out_free_names:
if (rc < 0)
lnet_ipif_free_enumeration(names, nfound);
- out1:
- LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
- out0:
+out_release_sock:
+ sock_release(sock);
return rc;
}
EXPORT_SYMBOL(lnet_ipif_enumerate);
/* All errors are fatal except bind failure if the port is in use */
*fatal = 1;
- rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock);
+#ifdef HAVE_SOCK_CREATE_KERN_USE_NET
+ rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock);
+#else
+ rc = sock_create_kern(PF_INET, SOCK_STREAM, 0, &sock);
+#endif
*sockp = sock;
if (rc != 0) {
CERROR("Can't create socket: %d\n", rc);
int
lnet_sock_accept(struct socket **newsockp, struct socket *sock)
{
- wait_queue_t wait;
+ wait_queue_entry_t wait;
struct socket *newsock;
int rc;
newsock->ops = sock->ops;
+#ifdef HAVE_KERN_SOCK_ACCEPT_FLAG_ARG
+ rc = sock->ops->accept(sock, newsock, O_NONBLOCK, false);
+#else
rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
+#endif
if (rc == -EAGAIN) {
/* Nothing ready, so wait for activity */
init_waitqueue_entry(&wait, current);
set_current_state(TASK_INTERRUPTIBLE);
schedule();
remove_wait_queue(sk_sleep(sock->sk), &wait);
+#ifdef HAVE_KERN_SOCK_ACCEPT_FLAG_ARG
+ rc = sock->ops->accept(sock, newsock, O_NONBLOCK, false);
+#else
rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
+#endif
}
if (rc != 0)