From 80c72fe415698049a477314ac82790c1af0fa7e3 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 May 2007 03:11:29 -0700 Subject: [AFS/AF_RXRPC]: Miscellaneous fixes. Make miscellaneous fixes to AFS and AF_RXRPC: (*) Make AF_RXRPC select KEYS rather than RXKAD or AFS_FS in Kconfig. (*) Don't use FS_BINARY_MOUNTDATA. (*) Remove a done 'TODO' item in a comemnt on afs_get_sb(). (*) Don't pass a void * as the page pointer argument of kmap_atomic() as this breaks on m68k. Patch from Geert Uytterhoeven . (*) Use match_*() functions rather than doing my own parsing. Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/Kconfig | 1 - fs/afs/fsclient.c | 3 +- fs/afs/super.c | 100 +++++++++++++++++++++++------------------------------- 3 files changed, 45 insertions(+), 59 deletions(-) (limited to 'fs') diff --git a/fs/Kconfig b/fs/Kconfig index a42f767dcdd..e33c0892457 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -2020,7 +2020,6 @@ config AFS_FS tristate "Andrew File System support (AFS) (EXPERIMENTAL)" depends on INET && EXPERIMENTAL select AF_RXRPC - select KEYS help If you say Y here, you will get an experimental Andrew File System driver. It currently only supports unsecured read-only AFS access. diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 2393d2a08d7..e54e6c2ad34 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -266,7 +266,8 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call, call->unmarshall++; if (call->count < PAGE_SIZE) { - buffer = kmap_atomic(call->reply3, KM_USER0); + page = call->reply3; + buffer = kmap_atomic(page, KM_USER0); memset(buffer + PAGE_SIZE - call->count, 0, call->count); kunmap_atomic(buffer, KM_USER0); diff --git a/fs/afs/super.c b/fs/afs/super.c index cebd03c91f5..41173f81ac4 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "internal.h" #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ @@ -42,7 +43,7 @@ struct file_system_type afs_fs_type = { .name = "afs", .get_sb = afs_get_sb, .kill_sb = kill_anon_super, - .fs_flags = FS_BINARY_MOUNTDATA, + .fs_flags = 0, }; static const struct super_operations afs_super_ops = { @@ -58,6 +59,20 @@ static const struct super_operations afs_super_ops = { static struct kmem_cache *afs_inode_cachep; static atomic_t afs_count_active_inodes; +enum { + afs_no_opt, + afs_opt_cell, + afs_opt_rwpath, + afs_opt_vol, +}; + +static const match_table_t afs_options_list = { + { afs_opt_cell, "cell=%s" }, + { afs_opt_rwpath, "rwpath" }, + { afs_opt_vol, "vol=%s" }, + { afs_no_opt, NULL }, +}; + /* * initialise the filesystem */ @@ -114,31 +129,6 @@ void __exit afs_fs_exit(void) _leave(""); } -/* - * check that an argument has a value - */ -static int want_arg(char **_value, const char *option) -{ - if (!_value || !*_value || !**_value) { - printk(KERN_NOTICE "kAFS: %s: argument missing\n", option); - return 0; - } - return 1; -} - -/* - * check that there's no subsequent value - */ -static int want_no_value(char *const *_value, const char *option) -{ - if (*_value && **_value) { - printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n", - option, *_value); - return 0; - } - return 1; -} - /* * parse the mount options * - this function has been shamelessly adapted from the ext3 fs which @@ -148,48 +138,46 @@ static int afs_parse_options(struct afs_mount_params *params, char *options, const char **devname) { struct afs_cell *cell; - char *key, *value; - int ret; + substring_t args[MAX_OPT_ARGS]; + char *p; + int token; _enter("%s", options); options[PAGE_SIZE - 1] = 0; - ret = 0; - while ((key = strsep(&options, ","))) { - value = strchr(key, '='); - if (value) - *value++ = 0; - - _debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-"); + while ((p = strsep(&options, ","))) { + if (!*p) + continue; - if (strcmp(key, "rwpath") == 0) { - if (!want_no_value(&value, "rwpath")) - return -EINVAL; - params->rwpath = 1; - } else if (strcmp(key, "vol") == 0) { - if (!want_arg(&value, "vol")) - return -EINVAL; - *devname = value; - } else if (strcmp(key, "cell") == 0) { - if (!want_arg(&value, "cell")) - return -EINVAL; - cell = afs_cell_lookup(value, strlen(value)); + token = match_token(p, afs_options_list, args); + switch (token) { + case afs_opt_cell: + cell = afs_cell_lookup(args[0].from, + args[0].to - args[0].from); if (IS_ERR(cell)) return PTR_ERR(cell); afs_put_cell(params->cell); params->cell = cell; - } else { - printk("kAFS: Unknown mount option: '%s'\n", key); - ret = -EINVAL; - goto error; + break; + + case afs_opt_rwpath: + params->rwpath = 1; + break; + + case afs_opt_vol: + *devname = args[0].from; + break; + + default: + printk(KERN_ERR "kAFS:" + " Unknown or invalid mount option: '%s'\n", p); + return -EINVAL; } } - ret = 0; -error: - _leave(" = %d", ret); - return ret; + _leave(" = 0"); + return 0; } /* @@ -361,7 +349,6 @@ error: /* * get an AFS superblock - * - TODO: don't use get_sb_nodev(), but rather call sget() directly */ static int afs_get_sb(struct file_system_type *fs_type, int flags, @@ -386,7 +373,6 @@ static int afs_get_sb(struct file_system_type *fs_type, goto error; } - ret = afs_parse_device_name(¶ms, dev_name); if (ret < 0) goto error; -- cgit From fbb3fcba72ff52ee3d9990c9dec0c95cd9d0ce17 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 May 2007 03:12:46 -0700 Subject: [AFS]: Fix use of __exit functions from __init path Fix use of __exit functions from __init path. Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/callback.c | 2 +- fs/afs/internal.h | 4 ++-- fs/afs/vlocation.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/afs/callback.c b/fs/afs/callback.c index 639399f0ab6..9bdbf36a9aa 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c @@ -468,7 +468,7 @@ int __init afs_callback_update_init(void) /* * shut down the callback update process */ -void __exit afs_callback_update_kill(void) +void afs_callback_update_kill(void) { destroy_workqueue(afs_callback_update_worker); } diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 34665f7d7a1..3363e311a2f 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -392,7 +392,7 @@ extern void afs_give_up_callback(struct afs_vnode *); extern void afs_dispatch_give_up_callbacks(struct work_struct *); extern void afs_flush_callback_breaks(struct afs_server *); extern int __init afs_callback_update_init(void); -extern void __exit afs_callback_update_kill(void); +extern void afs_callback_update_kill(void); /* * cell.c @@ -591,7 +591,7 @@ extern struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *, struct key *, const char *, size_t); extern void afs_put_vlocation(struct afs_vlocation *); -extern void __exit afs_vlocation_purge(void); +extern void afs_vlocation_purge(void); /* * vnode.c diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 6c8e95a7c2c..3370cdb7256 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c @@ -602,7 +602,7 @@ int __init afs_vlocation_update_init(void) /* * discard all the volume location records for rmmod */ -void __exit afs_vlocation_purge(void) +void afs_vlocation_purge(void) { afs_vlocation_timeout = 0; -- cgit From 5b35fad9d4fc2fcaf5c23887c1de1bc3eb28ab8c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 3 May 2007 03:27:39 -0700 Subject: [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities The interface array is not freed on exit. Signed-off-by: Patrick McHardy Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/cmservice.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 6685f4cbccb..d5b2ad6575b 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -443,6 +443,7 @@ static void SRXAFSCB_GetCapabilities(struct work_struct *work) reply.ia.netmask[loop] = ifs[loop].netmask.s_addr; reply.ia.mtu[loop] = htonl(ifs[loop].mtu); } + kfree(ifs); } reply.cap.capcount = htonl(1); -- cgit From dc1f6bff6a9d6733a07b9b97905bc824c055e8f4 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 3 May 2007 03:28:49 -0700 Subject: [AFS]: Replace rtnetlink client by direct dev_base walking Replace the large and complicated rtnetlink client by two simple functions for getting the MAC address for the first ethernet device and building a list of IPv4 addresses. Signed-off-by: Patrick McHardy Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/Makefile | 2 +- fs/afs/internal.h | 1 - fs/afs/netdevices.c | 54 ++++++ fs/afs/use-rtnetlink.c | 473 ------------------------------------------------- 4 files changed, 55 insertions(+), 475 deletions(-) create mode 100644 fs/afs/netdevices.c delete mode 100644 fs/afs/use-rtnetlink.c (limited to 'fs') diff --git a/fs/afs/Makefile b/fs/afs/Makefile index 01545eb1d87..cf83e5d6351 100644 --- a/fs/afs/Makefile +++ b/fs/afs/Makefile @@ -18,7 +18,7 @@ kafs-objs := \ security.o \ server.o \ super.o \ - use-rtnetlink.o \ + netdevices.o \ vlclient.o \ vlocation.o \ vnode.o \ diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 3363e311a2f..551db896afc 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -349,7 +349,6 @@ struct afs_permits { * record of one of a system's set of network interfaces */ struct afs_interface { - unsigned index; /* interface index */ struct in_addr address; /* IPv4 address bound to interface */ struct in_addr netmask; /* netmask applied to address */ unsigned mtu; /* MTU of interface */ diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c new file mode 100644 index 00000000000..2b3087357fa --- /dev/null +++ b/fs/afs/netdevices.c @@ -0,0 +1,54 @@ +/* AFS network device helpers + * + * Copyright (c) 2007 Patrick McHardy + */ + +#include +#include +#include +#include +#include +#include "internal.h" + +int afs_get_MAC_address(u8 mac[ETH_ALEN]) +{ + struct net_device *dev; + int ret = -ENODEV; + + rtnl_lock(); + dev = __dev_getfirstbyhwtype(ARPHRD_ETHER); + if (dev) { + memcpy(mac, dev->dev_addr, ETH_ALEN); + ret = 0; + } + rtnl_unlock(); + return ret; +} + +int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, + bool wantloopback) +{ + struct net_device *dev; + struct in_device *idev; + int n = 0; + + rtnl_lock(); + for (dev = dev_base; dev; dev = dev->next) { + if (dev->type == ARPHRD_LOOPBACK && !wantloopback) + continue; + idev = __in_dev_get_rtnl(dev); + if (!idev) + continue; + for_primary_ifa(idev) { + if (n == maxbufs) + goto out; + bufs[n].address.s_addr = ifa->ifa_address; + bufs[n].netmask.s_addr = ifa->ifa_mask; + bufs[n].mtu = dev->mtu; + n++; + } endfor_ifa(idev) + } +out: + rtnl_unlock(); + return n; +} diff --git a/fs/afs/use-rtnetlink.c b/fs/afs/use-rtnetlink.c deleted file mode 100644 index f8991c700e0..00000000000 --- a/fs/afs/use-rtnetlink.c +++ /dev/null @@ -1,473 +0,0 @@ -/* RTNETLINK client - * - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include "internal.h" - -struct afs_rtm_desc { - struct socket *nlsock; - struct afs_interface *bufs; - u8 *mac; - size_t nbufs; - size_t maxbufs; - void *data; - ssize_t datalen; - size_t datamax; - int msg_seq; - unsigned mac_index; - bool wantloopback; - int (*parse)(struct afs_rtm_desc *, struct nlmsghdr *); -}; - -/* - * parse an RTM_GETADDR response - */ -static int afs_rtm_getaddr_parse(struct afs_rtm_desc *desc, - struct nlmsghdr *nlhdr) -{ - struct afs_interface *this; - struct ifaddrmsg *ifa; - struct rtattr *rtattr; - const char *name; - size_t len; - - ifa = (struct ifaddrmsg *) NLMSG_DATA(nlhdr); - - _enter("{ix=%d,af=%d}", ifa->ifa_index, ifa->ifa_family); - - if (ifa->ifa_family != AF_INET) { - _leave(" = 0 [family %d]", ifa->ifa_family); - return 0; - } - if (desc->nbufs >= desc->maxbufs) { - _leave(" = 0 [max %zu/%zu]", desc->nbufs, desc->maxbufs); - return 0; - } - - this = &desc->bufs[desc->nbufs]; - - this->index = ifa->ifa_index; - this->netmask.s_addr = inet_make_mask(ifa->ifa_prefixlen); - this->mtu = 0; - - rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)); - len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifaddrmsg)); - - name = "unknown"; - for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) { - switch (rtattr->rta_type) { - case IFA_ADDRESS: - memcpy(&this->address, RTA_DATA(rtattr), 4); - break; - case IFA_LABEL: - name = RTA_DATA(rtattr); - break; - } - } - - _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT, - name, NIPQUAD(this->address), NIPQUAD(this->netmask)); - - desc->nbufs++; - _leave(" = 0"); - return 0; -} - -/* - * parse an RTM_GETLINK response for MTUs - */ -static int afs_rtm_getlink_if_parse(struct afs_rtm_desc *desc, - struct nlmsghdr *nlhdr) -{ - struct afs_interface *this; - struct ifinfomsg *ifi; - struct rtattr *rtattr; - const char *name; - size_t len, loop; - - ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr); - - _enter("{ix=%d}", ifi->ifi_index); - - for (loop = 0; loop < desc->nbufs; loop++) { - this = &desc->bufs[loop]; - if (this->index == ifi->ifi_index) - goto found; - } - - _leave(" = 0 [no match]"); - return 0; - -found: - if (ifi->ifi_type == ARPHRD_LOOPBACK && !desc->wantloopback) { - _leave(" = 0 [loopback]"); - return 0; - } - - rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)); - len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg)); - - name = "unknown"; - for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) { - switch (rtattr->rta_type) { - case IFLA_MTU: - memcpy(&this->mtu, RTA_DATA(rtattr), 4); - break; - case IFLA_IFNAME: - name = RTA_DATA(rtattr); - break; - } - } - - _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u", - name, NIPQUAD(this->address), NIPQUAD(this->netmask), - this->mtu); - - _leave(" = 0"); - return 0; -} - -/* - * parse an RTM_GETLINK response for the MAC address belonging to the lowest - * non-internal interface - */ -static int afs_rtm_getlink_mac_parse(struct afs_rtm_desc *desc, - struct nlmsghdr *nlhdr) -{ - struct ifinfomsg *ifi; - struct rtattr *rtattr; - const char *name; - size_t remain, len; - bool set; - - ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr); - - _enter("{ix=%d}", ifi->ifi_index); - - if (ifi->ifi_index >= desc->mac_index) { - _leave(" = 0 [high]"); - return 0; - } - if (ifi->ifi_type == ARPHRD_LOOPBACK) { - _leave(" = 0 [loopback]"); - return 0; - } - - rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)); - remain = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg)); - - name = "unknown"; - set = false; - for (; RTA_OK(rtattr, remain); rtattr = RTA_NEXT(rtattr, remain)) { - switch (rtattr->rta_type) { - case IFLA_ADDRESS: - len = RTA_PAYLOAD(rtattr); - memcpy(desc->mac, RTA_DATA(rtattr), - min_t(size_t, len, 6)); - desc->mac_index = ifi->ifi_index; - set = true; - break; - case IFLA_IFNAME: - name = RTA_DATA(rtattr); - break; - } - } - - if (set) - _debug("%s: %02x:%02x:%02x:%02x:%02x:%02x", - name, - desc->mac[0], desc->mac[1], desc->mac[2], - desc->mac[3], desc->mac[4], desc->mac[5]); - - _leave(" = 0"); - return 0; -} - -/* - * read the rtnetlink response and pass to parsing routine - */ -static int afs_read_rtm(struct afs_rtm_desc *desc) -{ - struct nlmsghdr *nlhdr, tmphdr; - struct msghdr msg; - struct kvec iov[1]; - void *data; - bool last = false; - int len, ret, remain; - - _enter(""); - - do { - /* first of all peek to see how big the packet is */ - memset(&msg, 0, sizeof(msg)); - iov[0].iov_base = &tmphdr; - iov[0].iov_len = sizeof(tmphdr); - len = kernel_recvmsg(desc->nlsock, &msg, iov, 1, - sizeof(tmphdr), MSG_PEEK | MSG_TRUNC); - if (len < 0) { - _leave(" = %d [peek]", len); - return len; - } - if (len == 0) - continue; - if (len < sizeof(tmphdr) || len < NLMSG_PAYLOAD(&tmphdr, 0)) { - _leave(" = -EMSGSIZE"); - return -EMSGSIZE; - } - - if (desc->datamax < len) { - kfree(desc->data); - desc->data = NULL; - data = kmalloc(len, GFP_KERNEL); - if (!data) - return -ENOMEM; - desc->data = data; - } - desc->datamax = len; - - /* read all the data from this packet */ - iov[0].iov_base = desc->data; - iov[0].iov_len = desc->datamax; - desc->datalen = kernel_recvmsg(desc->nlsock, &msg, iov, 1, - desc->datamax, 0); - if (desc->datalen < 0) { - _leave(" = %zd [recv]", desc->datalen); - return desc->datalen; - } - - nlhdr = desc->data; - - /* check if the header is valid */ - if (!NLMSG_OK(nlhdr, desc->datalen) || - nlhdr->nlmsg_type == NLMSG_ERROR) { - _leave(" = -EIO"); - return -EIO; - } - - /* see if this is the last message */ - if (nlhdr->nlmsg_type == NLMSG_DONE || - !(nlhdr->nlmsg_flags & NLM_F_MULTI)) - last = true; - - /* parse the bits we got this time */ - nlmsg_for_each_msg(nlhdr, desc->data, desc->datalen, remain) { - ret = desc->parse(desc, nlhdr); - if (ret < 0) { - _leave(" = %d [parse]", ret); - return ret; - } - } - - } while (!last); - - _leave(" = 0"); - return 0; -} - -/* - * list the interface bound addresses to get the address and netmask - */ -static int afs_rtm_getaddr(struct afs_rtm_desc *desc) -{ - struct msghdr msg; - struct kvec iov[1]; - int ret; - - struct { - struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO))); - struct ifaddrmsg addr_msg __attribute__((aligned(NLMSG_ALIGNTO))); - } request; - - _enter(""); - - memset(&request, 0, sizeof(request)); - - request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - request.nl_msg.nlmsg_type = RTM_GETADDR; - request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - request.nl_msg.nlmsg_seq = desc->msg_seq++; - request.nl_msg.nlmsg_pid = 0; - - memset(&msg, 0, sizeof(msg)); - iov[0].iov_base = &request; - iov[0].iov_len = sizeof(request); - - ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len); - _leave(" = %d", ret); - return ret; -} - -/* - * list the interface link statuses to get the MTUs - */ -static int afs_rtm_getlink(struct afs_rtm_desc *desc) -{ - struct msghdr msg; - struct kvec iov[1]; - int ret; - - struct { - struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO))); - struct ifinfomsg link_msg __attribute__((aligned(NLMSG_ALIGNTO))); - } request; - - _enter(""); - - memset(&request, 0, sizeof(request)); - - request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - request.nl_msg.nlmsg_type = RTM_GETLINK; - request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; - request.nl_msg.nlmsg_seq = desc->msg_seq++; - request.nl_msg.nlmsg_pid = 0; - - memset(&msg, 0, sizeof(msg)); - iov[0].iov_base = &request; - iov[0].iov_len = sizeof(request); - - ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len); - _leave(" = %d", ret); - return ret; -} - -/* - * cull any interface records for which there isn't an MTU value - */ -static void afs_cull_interfaces(struct afs_rtm_desc *desc) -{ - struct afs_interface *bufs = desc->bufs; - size_t nbufs = desc->nbufs; - int loop, point = 0; - - _enter("{%zu}", nbufs); - - for (loop = 0; loop < nbufs; loop++) { - if (desc->bufs[loop].mtu != 0) { - if (loop != point) { - ASSERTCMP(loop, >, point); - bufs[point] = bufs[loop]; - } - point++; - } - } - - desc->nbufs = point; - _leave(" [%zu/%zu]", desc->nbufs, nbufs); -} - -/* - * get a list of this system's interface IPv4 addresses, netmasks and MTUs - * - returns the number of interface records in the buffer - */ -int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, - bool wantloopback) -{ - struct afs_rtm_desc desc; - int ret, loop; - - _enter(""); - - memset(&desc, 0, sizeof(desc)); - desc.bufs = bufs; - desc.maxbufs = maxbufs; - desc.wantloopback = wantloopback; - - ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, - &desc.nlsock); - if (ret < 0) { - _leave(" = %d [sock]", ret); - return ret; - } - - /* issue RTM_GETADDR */ - desc.parse = afs_rtm_getaddr_parse; - ret = afs_rtm_getaddr(&desc); - if (ret < 0) - goto error; - ret = afs_read_rtm(&desc); - if (ret < 0) - goto error; - - /* issue RTM_GETLINK */ - desc.parse = afs_rtm_getlink_if_parse; - ret = afs_rtm_getlink(&desc); - if (ret < 0) - goto error; - ret = afs_read_rtm(&desc); - if (ret < 0) - goto error; - - afs_cull_interfaces(&desc); - ret = desc.nbufs; - - for (loop = 0; loop < ret; loop++) - _debug("[%d] "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u", - bufs[loop].index, - NIPQUAD(bufs[loop].address), - NIPQUAD(bufs[loop].netmask), - bufs[loop].mtu); - -error: - kfree(desc.data); - sock_release(desc.nlsock); - _leave(" = %d", ret); - return ret; -} - -/* - * get a MAC address from a random ethernet interface that has a real one - * - the buffer should be 6 bytes in size - */ -int afs_get_MAC_address(u8 mac[6]) -{ - struct afs_rtm_desc desc; - int ret; - - _enter(""); - - memset(&desc, 0, sizeof(desc)); - desc.mac = mac; - desc.mac_index = UINT_MAX; - - ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, - &desc.nlsock); - if (ret < 0) { - _leave(" = %d [sock]", ret); - return ret; - } - - /* issue RTM_GETLINK */ - desc.parse = afs_rtm_getlink_mac_parse; - ret = afs_rtm_getlink(&desc); - if (ret < 0) - goto error; - ret = afs_read_rtm(&desc); - if (ret < 0) - goto error; - - if (desc.mac_index < UINT_MAX) { - /* got a MAC address */ - _debug("[%d] %02x:%02x:%02x:%02x:%02x:%02x", - desc.mac_index, - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - } else { - ret = -ENONET; - } - -error: - sock_release(desc.nlsock); - _leave(" = %d", ret); - return ret; -} -- cgit From ec9c948546a84d0dcee851be1009a8066958e69d Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 May 2007 03:29:41 -0700 Subject: [AFS]: Adjust the new netdevice scanning code Adjust the new netdevice scanning code provided by Patrick McHardy: (1) Restore the function banner comments that were dropped. (2) Rather than using an array size of 6 in some places and an array size of ETH_ALEN in others, pass a pointer instead and pass the array size through so that we can actually check it. (3) Do the buffer fill count check before checking the for_primary_ifa condition again. This permits us to skip that check should maxbufs be reached before we run out of interfaces. Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/internal.h | 2 +- fs/afs/main.c | 2 +- fs/afs/netdevices.c | 24 +++++++++++++++++++----- 3 files changed, 21 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 551db896afc..d90c158cd93 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -563,7 +563,7 @@ extern void afs_fs_exit(void); * use-rtnetlink.c */ extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); -extern int afs_get_MAC_address(u8 [6]); +extern int afs_get_MAC_address(u8 *, size_t); /* * vlclient.c diff --git a/fs/afs/main.c b/fs/afs/main.c index 40c2704e755..80ec6fd19a7 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -54,7 +54,7 @@ static int __init afs_get_client_UUID(void) /* read the MAC address of one of the external interfaces and construct * a UUID from it */ - ret = afs_get_MAC_address(afs_uuid.node); + ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node)); if (ret < 0) return ret; diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c index 2b3087357fa..ce08977858e 100644 --- a/fs/afs/netdevices.c +++ b/fs/afs/netdevices.c @@ -10,21 +10,33 @@ #include #include "internal.h" -int afs_get_MAC_address(u8 mac[ETH_ALEN]) +/* + * get a MAC address from a random ethernet interface that has a real one + * - the buffer will normally be 6 bytes in size + */ +int afs_get_MAC_address(u8 *mac, size_t maclen) { struct net_device *dev; int ret = -ENODEV; + if (maclen != ETH_ALEN) + BUG(); + rtnl_lock(); dev = __dev_getfirstbyhwtype(ARPHRD_ETHER); if (dev) { - memcpy(mac, dev->dev_addr, ETH_ALEN); + memcpy(mac, dev->dev_addr, maclen); ret = 0; } rtnl_unlock(); return ret; } +/* + * get a list of this system's interface IPv4 addresses, netmasks and MTUs + * - maxbufs must be at least 1 + * - returns the number of interface records in the buffer + */ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, bool wantloopback) { @@ -32,6 +44,8 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, struct in_device *idev; int n = 0; + ASSERT(maxbufs > 0); + rtnl_lock(); for (dev = dev_base; dev; dev = dev->next) { if (dev->type == ARPHRD_LOOPBACK && !wantloopback) @@ -40,13 +54,13 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, if (!idev) continue; for_primary_ifa(idev) { - if (n == maxbufs) - goto out; bufs[n].address.s_addr = ifa->ifa_address; bufs[n].netmask.s_addr = ifa->ifa_mask; bufs[n].mtu = dev->mtu; n++; - } endfor_ifa(idev) + if (n >= maxbufs) + goto out; + } endfor_ifa(idev); } out: rtnl_unlock(); -- cgit From 7562f876cd93800f2f8c89445f2a563590b24e09 Mon Sep 17 00:00:00 2001 From: Pavel Emelianov Date: Thu, 3 May 2007 15:13:45 -0700 Subject: [NET]: Rework dev_base via list_head (v3) Cleanup of dev_base list use, with the aim to simplify making device list per-namespace. In almost every occasion, use of dev_base variable and dev->next pointer could be easily replaced by for_each_netdev loop. A few most complicated places were converted to using first_netdev()/next_netdev(). Signed-off-by: Pavel Emelianov Acked-by: Kirill Korotaev Signed-off-by: David S. Miller --- fs/afs/netdevices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c index ce08977858e..fc27d4b52e5 100644 --- a/fs/afs/netdevices.c +++ b/fs/afs/netdevices.c @@ -47,7 +47,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, ASSERT(maxbufs > 0); rtnl_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (dev->type == ARPHRD_LOOPBACK && !wantloopback) continue; idev = __in_dev_get_rtnl(dev); -- cgit