Author: marek
Date: 2010-05-21 11:59:25 +0200 (Fri, 21 May 2010)
New Revision: 1669
Modified:
trunk/batman-adv-kernelland/bat_debugfs.c
trunk/batman-adv-kernelland/bat_sysfs.c
trunk/batman-adv-kernelland/gateway_client.c
trunk/batman-adv-kernelland/gateway_client.h
trunk/batman-adv-kernelland/main.h
trunk/batman-adv-kernelland/originator.c
trunk/batman-adv-kernelland/originator.h
trunk/batman-adv-kernelland/translation-table.c
trunk/batman-adv-kernelland/translation-table.h
trunk/batman-adv-kernelland/vis.c
trunk/batman-adv-kernelland/vis.h
Log:
batman-adv: Move tables from sysfs to debugfs
Files which represent more than a single attribute aren't allowed in
sysfs. As we have some files which aren't essential and are lists or
tables aggregated from data from different places inside batman-adv, we
must place them in a filesystem without such a restriction.
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Modified: trunk/batman-adv-kernelland/bat_debugfs.c
===================================================================
--- trunk/batman-adv-kernelland/bat_debugfs.c 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/bat_debugfs.c 2010-05-21 09:59:25 UTC (rev 1669)
@@ -34,6 +34,68 @@
static struct dentry *bat_debugfs;
+static int originators_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, orig_seq_print_text, net_dev);
+}
+
+static int gateways_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, gw_client_seq_print_text, net_dev);
+}
+
+static int transtable_global_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, hna_global_seq_print_text, net_dev);
+}
+
+static int transtable_local_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, hna_local_seq_print_text, net_dev);
+}
+
+static int vis_data_open(struct inode *inode, struct file *file)
+{
+ struct net_device *net_dev = (struct net_device *)inode->i_private;
+ return single_open(file, vis_seq_print_text, net_dev);
+}
+
+struct bat_debuginfo {
+ struct attribute attr;
+ const struct file_operations fops;
+};
+
+#define BAT_DEBUGINFO(_name, _mode, _open) \
+struct bat_debuginfo bat_debuginfo_##_name = { \
+ .attr = { .name = __stringify(_name), \
+ .mode = _mode, }, \
+ .fops = { .owner = THIS_MODULE, \
+ .open = _open, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+ } \
+};
+
+static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
+static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open);
+static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
+static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
+static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
+
+static struct bat_debuginfo *mesh_debuginfos[] = {
+ &bat_debuginfo_originators,
+ &bat_debuginfo_gateways,
+ &bat_debuginfo_transtable_global,
+ &bat_debuginfo_transtable_local,
+ &bat_debuginfo_vis_data,
+ NULL,
+};
+
void debugfs_init(void)
{
bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
@@ -50,6 +112,8 @@
int debugfs_add_meshif(struct net_device *dev)
{
struct bat_priv *bat_priv = netdev_priv(dev);
+ struct bat_debuginfo **bat_debug;
+ struct dentry *file;
if (!bat_debugfs)
goto out;
@@ -60,7 +124,22 @@
bat_socket_setup(bat_priv);
+ for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) {
+ file = debugfs_create_file(((*bat_debug)->attr).name,
+ S_IFREG | ((*bat_debug)->attr).mode,
+ bat_priv->debug_dir,
+ dev, &(*bat_debug)->fops);
+ if (!file) {
+ printk(KERN_ERR "batman-adv:Can't add debugfs file: "
+ "%s/%s\n", dev->name, ((*bat_debug)->attr).name);
+ goto rem_attr;
+ }
+ }
+
return 0;
+rem_attr:
+ debugfs_remove_recursive(bat_priv->debug_dir);
+ bat_priv->debug_dir = NULL;
out:
return -ENOMEM;
}
Modified: trunk/batman-adv-kernelland/bat_sysfs.c
===================================================================
--- trunk/batman-adv-kernelland/bat_sysfs.c 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/bat_sysfs.c 2010-05-21 09:59:25 UTC (rev 1669)
@@ -39,14 +39,6 @@
.store = _store, \
};
-#define BAT_BIN_ATTR(_name, _mode, _read, _write) \
-struct bin_attribute bat_attr_##_name = { \
- .attr = { .name = __stringify(_name), \
- .mode = _mode, }, \
- .read = _read, \
- .write = _write, \
-};
-
static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr,
char *buff)
{
@@ -305,77 +297,11 @@
NULL,
};
-static ssize_t transtable_local_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
-{
- struct device *dev = to_dev(kobj->parent);
- struct net_device *net_dev = to_net_dev(dev);
-
- return hna_local_fill_buffer_text(net_dev, buff, count, off);
-}
-
-static ssize_t transtable_global_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
-{
- struct device *dev = to_dev(kobj->parent);
- struct net_device *net_dev = to_net_dev(dev);
-
- return hna_global_fill_buffer_text(net_dev, buff, count, off);
-}
-
-static ssize_t originators_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
-{
- struct device *dev = to_dev(kobj->parent);
- struct net_device *net_dev = to_net_dev(dev);
-
- return orig_fill_buffer_text(net_dev, buff, count, off);
-}
-
-static ssize_t gateways_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
-{
- struct device *dev = to_dev(kobj->parent);
- struct net_device *net_dev = to_net_dev(dev);
-
- return gw_client_fill_buffer_text(net_dev, buff, count, off);
-}
-
-static ssize_t vis_data_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buff, loff_t off, size_t count)
-{
- struct device *dev = to_dev(kobj->parent);
- struct net_device *net_dev = to_net_dev(dev);
-
- return vis_fill_buffer_text(net_dev, buff, count, off);
-}
-
-static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL);
-static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL);
-static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL);
-static BAT_BIN_ATTR(gateways, S_IRUGO, gateways_read, NULL);
-static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
-
-static struct bin_attribute *mesh_bin_attrs[] = {
- &bat_attr_transtable_local,
- &bat_attr_transtable_global,
- &bat_attr_originators,
- &bat_attr_gateways,
- &bat_attr_vis_data,
- NULL,
-};
-
int sysfs_add_meshif(struct net_device *dev)
{
struct kobject *batif_kobject = &dev->dev.kobj;
struct bat_priv *bat_priv = netdev_priv(dev);
struct bat_attribute **bat_attr;
- struct bin_attribute **bin_attr;
int err;
/* FIXME: should be done in the general mesh setup
@@ -411,21 +337,8 @@
}
}
- for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) {
- err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr));
- if (err) {
- printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n",
- dev->name, SYSFS_IF_MESH_SUBDIR,
- ((*bin_attr)->attr).name);
- goto rem_bin_attr;
- }
- }
-
return 0;
-rem_bin_attr:
- for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
- sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
rem_attr:
for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
@@ -440,11 +353,7 @@
{
struct bat_priv *bat_priv = netdev_priv(dev);
struct bat_attribute **bat_attr;
- struct bin_attribute **bin_attr;
- for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr)
- sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr));
-
for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
Modified: trunk/batman-adv-kernelland/gateway_client.c
===================================================================
--- trunk/batman-adv-kernelland/gateway_client.c 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/gateway_client.c 2010-05-21 09:59:25 UTC (rev 1669)
@@ -317,8 +317,7 @@
spin_unlock(&gw_list_lock);
}
-static int _write_buffer_text(unsigned char *buff, int bytes_written,
- struct gw_node *gw_node)
+static int _write_buffer_text(struct seq_file *seq, struct gw_node *gw_node)
{
int down, up;
char gw_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
@@ -327,8 +326,7 @@
addr_to_string(router_str, gw_node->orig_node->router->addr);
gw_srv_class_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
- return sprintf(buff + bytes_written,
- "%s %-17s (%3i) %17s [%10s]: %3i - %i%s/%i%s\n",
+ return seq_printf(seq, "%s %-17s (%3i) %17s [%10s]: %3i - %i%s/%i%s\n",
(curr_gateway == gw_node ? "=>" : " "),
gw_str,
gw_node->orig_node->router->tq_avg,
@@ -341,51 +339,38 @@
(up > 2048 ? "MBit" : "KBit"));
}
-int gw_client_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off)
+int gw_client_seq_print_text(struct seq_file *seq, void *offset)
{
+ struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct gw_node *gw_node;
- size_t hdr_len, tmp_len;
- int bytes_written = 0, gw_count = 0;
+ int gw_count = 0;
rcu_read_lock();
if (!bat_priv->primary_if) {
rcu_read_unlock();
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - please "
- "specify interfaces to enable it\n",
- net_dev->name);
-
- return 0;
+ return seq_printf(seq, "BATMAN mesh %s disabled - please "
+ "specify interfaces to enable it\n",
+ net_dev->name);
}
if (bat_priv->primary_if->if_status != IF_ACTIVE) {
rcu_read_unlock();
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - "
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
"primary interface not active\n",
net_dev->name);
-
- return 0;
}
- hdr_len = sprintf(buff, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
- "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
- "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
- "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
- bat_priv->primary_if->dev,
- bat_priv->primary_if->addr_str,
- net_dev->name);
+ seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
+ "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
+ "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
+ "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
+ bat_priv->primary_if->dev, bat_priv->primary_if->addr_str,
+ net_dev->name);
rcu_read_unlock();
- if (off < hdr_len)
- bytes_written = hdr_len;
-
rcu_read_lock();
list_for_each_entry_rcu(gw_node, &gw_list, list) {
if (gw_node->deleted)
@@ -394,26 +379,15 @@
if (!gw_node->orig_node->router)
continue;
- if (count < bytes_written + (2 * ETH_STR_LEN) + 30)
- break;
-
- tmp_len = _write_buffer_text(buff, bytes_written, gw_node);
+ _write_buffer_text(seq, gw_node);
gw_count++;
-
- hdr_len += tmp_len;
-
- if (off >= hdr_len)
- continue;
-
- bytes_written += tmp_len;
}
rcu_read_unlock();
- if ((gw_count == 0) && (off == 0))
- bytes_written += sprintf(buff + bytes_written,
- "No gateways in range ...\n");
+ if (gw_count == 0)
+ seq_printf(seq, "No gateways in range ...\n");
- return bytes_written;
+ return 0;
}
bool gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
Modified: trunk/batman-adv-kernelland/gateway_client.h
===================================================================
--- trunk/batman-adv-kernelland/gateway_client.h 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/gateway_client.h 2010-05-21 09:59:25 UTC (rev 1669)
@@ -27,6 +27,5 @@
void gw_node_delete(struct orig_node *orig_node);
void gw_node_purge_deleted(void);
void gw_node_list_free(void);
-int gw_client_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off);
+int gw_client_seq_print_text(struct seq_file *seq, void *offset);
bool gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb);
Modified: trunk/batman-adv-kernelland/main.h
===================================================================
--- trunk/batman-adv-kernelland/main.h 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/main.h 2010-05-21 09:59:25 UTC (rev 1669)
@@ -123,6 +123,7 @@
#include <linux/workqueue.h> /* workqueue */
#include <net/sock.h> /* struct sock */
#include <linux/jiffies.h>
+#include <linux/seq_file.h>
#include "types.h"
#ifndef REVISION_VERSION
Modified: trunk/batman-adv-kernelland/originator.c
===================================================================
--- trunk/batman-adv-kernelland/originator.c 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/originator.c 2010-05-21 09:59:25 UTC (rev 1669)
@@ -284,38 +284,31 @@
start_purge_timer();
}
-ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off)
+int orig_seq_print_text(struct seq_file *seq, void *offset)
{
HASHIT(hashit);
+ struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct orig_node *orig_node;
struct neigh_node *neigh_node;
- size_t hdr_len, tmp_len;
- int batman_count = 0, bytes_written = 0;
+ int batman_count = 0;
unsigned long flags;
char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
if ((!bat_priv->primary_if) ||
(bat_priv->primary_if->if_status != IF_ACTIVE)) {
- if (off > 0)
- return 0;
-
if (!bat_priv->primary_if)
- return sprintf(buff,
- "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
- return sprintf(buff,
- "BATMAN mesh %s "
- "disabled - primary interface not active\n",
- net_dev->name);
+ return seq_printf(seq, "BATMAN mesh %s "
+ "disabled - primary interface not active\n",
+ net_dev->name);
}
rcu_read_lock();
- hdr_len = sprintf(buff,
- " %-14s (%s/%i) %17s [%10s]: %20s "
+ seq_printf(seq, " %-14s (%s/%i) %17s [%10s]: %20s "
"... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
"Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
"Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
@@ -323,9 +316,6 @@
net_dev->name);
rcu_read_unlock();
- if (off < hdr_len)
- bytes_written = hdr_len;
-
spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
@@ -338,44 +328,29 @@
if (orig_node->router->tq_avg == 0)
continue;
- /* estimated line length */
- if (count < bytes_written + 200)
- break;
-
addr_to_string(orig_str, orig_node->orig);
addr_to_string(router_str, orig_node->router->addr);
- tmp_len = sprintf(buff + bytes_written,
- "%-17s (%3i) %17s [%10s]:",
- orig_str, orig_node->router->tq_avg,
- router_str,
- orig_node->router->if_incoming->dev);
+ seq_printf(seq, "%-17s (%3i) %17s [%10s]:",
+ orig_str, orig_node->router->tq_avg, router_str,
+ orig_node->router->if_incoming->dev);
list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
addr_to_string(orig_str, neigh_node->addr);
- tmp_len += sprintf(buff + bytes_written + tmp_len,
- " %17s (%3i)", orig_str,
+ seq_printf(seq, " %17s (%3i)", orig_str,
neigh_node->tq_avg);
}
- tmp_len += sprintf(buff + bytes_written + tmp_len, "\n");
-
+ seq_printf(seq, "\n");
batman_count++;
- hdr_len += tmp_len;
-
- if (off >= hdr_len)
- continue;
-
- bytes_written += tmp_len;
}
spin_unlock_irqrestore(&orig_hash_lock, flags);
- if ((batman_count == 0) && (off == 0))
- bytes_written += sprintf(buff + bytes_written,
- "No batman nodes in range ...\n");
+ if ((batman_count == 0))
+ seq_printf(seq, "No batman nodes in range ...\n");
- return bytes_written;
+ return 0;
}
static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
Modified: trunk/batman-adv-kernelland/originator.h
===================================================================
--- trunk/batman-adv-kernelland/originator.h 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/originator.h 2010-05-21 09:59:25 UTC (rev 1669)
@@ -28,7 +28,6 @@
struct neigh_node *
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
uint8_t *neigh, struct batman_if *if_incoming);
-ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off);
+int orig_seq_print_text(struct seq_file *seq, void *offset);
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num);
int orig_hash_del_if(struct batman_if *batman_if, int max_if_num);
Modified: trunk/batman-adv-kernelland/translation-table.c
===================================================================
--- trunk/batman-adv-kernelland/translation-table.c 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/translation-table.c 2010-05-21 09:59:25 UTC (rev 1669)
@@ -161,59 +161,59 @@
return i;
}
-int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off)
+int hna_local_seq_print_text(struct seq_file *seq, void *offset)
{
+ struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct hna_local_entry *hna_local_entry;
HASHIT(hashit);
- int bytes_written = 0;
+ HASHIT(hashit_count);
unsigned long flags;
- size_t hdr_len;
+ size_t buf_size, pos;
+ char *buff;
if (!bat_priv->primary_if) {
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
-
- return 0;
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
}
- hdr_len = sprintf(buff,
- "Locally retrieved addresses (from %s) "
- "announced via HNA:\n",
- net_dev->name);
+ seq_printf(seq, "Locally retrieved addresses (from %s) "
+ "announced via HNA:\n",
+ net_dev->name);
- if (off < hdr_len)
- bytes_written = hdr_len;
-
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (hash_iterate(hna_local_hash, &hashit)) {
- hdr_len += 21;
+ buf_size = 1;
+ /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
+ while (hash_iterate(hna_local_hash, &hashit_count))
+ buf_size += 21;
- if (count < bytes_written + 22)
- break;
+ buff = kmalloc(buf_size, GFP_ATOMIC);
+ if (!buff) {
+ spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+ return -ENOMEM;
+ }
+ buff[0] = '\0';
+ pos = 0;
- if (off >= hdr_len)
- continue;
-
+ while (hash_iterate(hna_local_hash, &hashit)) {
hna_local_entry = hashit.bucket->data;
- bytes_written += snprintf(buff + bytes_written, 22,
- " * " MAC_FMT "\n",
- hna_local_entry->addr[0],
- hna_local_entry->addr[1],
- hna_local_entry->addr[2],
- hna_local_entry->addr[3],
- hna_local_entry->addr[4],
- hna_local_entry->addr[5]);
+ pos += snprintf(buff + pos, 22, " * " MAC_FMT "\n",
+ hna_local_entry->addr[0],
+ hna_local_entry->addr[1],
+ hna_local_entry->addr[2],
+ hna_local_entry->addr[3],
+ hna_local_entry->addr[4],
+ hna_local_entry->addr[5]);
}
spin_unlock_irqrestore(&hna_local_hash_lock, flags);
- return bytes_written;
+
+ seq_printf(seq, "%s", buff);
+ kfree(buff);
+ return 0;
}
static void _hna_local_del(void *data)
@@ -379,64 +379,65 @@
spin_unlock_irqrestore(&hna_global_hash_lock, flags);
}
-int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off)
+int hna_global_seq_print_text(struct seq_file *seq, void *offset)
{
+ struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct hna_global_entry *hna_global_entry;
HASHIT(hashit);
- int bytes_written = 0;
+ HASHIT(hashit_count);
unsigned long flags;
- size_t hdr_len;
+ size_t buf_size, pos;
+ char *buff;
if (!bat_priv->primary_if) {
- if (off == 0)
- return sprintf(buff,
- "BATMAN mesh %s disabled - "
- "please specify interfaces to enable it\n",
- net_dev->name);
-
- return 0;
+ return seq_printf(seq, "BATMAN mesh %s disabled - "
+ "please specify interfaces to enable it\n",
+ net_dev->name);
}
- hdr_len = sprintf(buff,
- "Globally announced HNAs received via the mesh %s\n",
- net_dev->name);
+ seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
+ net_dev->name);
- if (off < hdr_len)
- bytes_written = hdr_len;
-
spin_lock_irqsave(&hna_global_hash_lock, flags);
- while (hash_iterate(hna_global_hash, &hashit)) {
- hdr_len += 43;
+ buf_size = 1;
+ /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
+ while (hash_iterate(hna_global_hash, &hashit_count))
+ buf_size += 43;
- if (count < bytes_written + 44)
- break;
+ buff = kmalloc(buf_size, GFP_ATOMIC);
+ if (!buff) {
+ spin_unlock_irqrestore(&hna_global_hash_lock, flags);
+ return -ENOMEM;
+ }
+ buff[0] = '\0';
+ pos = 0;
- if (off >= hdr_len)
- continue;
-
+ while (hash_iterate(hna_global_hash, &hashit)) {
hna_global_entry = hashit.bucket->data;
- bytes_written += snprintf(buff + bytes_written, 44,
- " * " MAC_FMT " via " MAC_FMT "\n",
- hna_global_entry->addr[0],
- hna_global_entry->addr[1],
- hna_global_entry->addr[2],
- hna_global_entry->addr[3],
- hna_global_entry->addr[4],
- hna_global_entry->addr[5],
- hna_global_entry->orig_node->orig[0],
- hna_global_entry->orig_node->orig[1],
- hna_global_entry->orig_node->orig[2],
- hna_global_entry->orig_node->orig[3],
- hna_global_entry->orig_node->orig[4],
- hna_global_entry->orig_node->orig[5]);
+ pos += snprintf(buff + pos, 44,
+ " * " MAC_FMT " via " MAC_FMT "\n",
+ hna_global_entry->addr[0],
+ hna_global_entry->addr[1],
+ hna_global_entry->addr[2],
+ hna_global_entry->addr[3],
+ hna_global_entry->addr[4],
+ hna_global_entry->addr[5],
+ hna_global_entry->orig_node->orig[0],
+ hna_global_entry->orig_node->orig[1],
+ hna_global_entry->orig_node->orig[2],
+ hna_global_entry->orig_node->orig[3],
+ hna_global_entry->orig_node->orig[4],
+ hna_global_entry->orig_node->orig[5]);
}
spin_unlock_irqrestore(&hna_global_hash_lock, flags);
- return bytes_written;
+
+ seq_printf(seq, "%s", buff);
+ kfree(buff);
+ return 0;
}
void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
Modified: trunk/batman-adv-kernelland/translation-table.h
===================================================================
--- trunk/batman-adv-kernelland/translation-table.h 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/translation-table.h 2010-05-21 09:59:25 UTC (rev 1669)
@@ -25,15 +25,13 @@
void hna_local_add(uint8_t *addr);
void hna_local_remove(uint8_t *addr, char *message);
int hna_local_fill_buffer(unsigned char *buff, int buff_len);
-int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off);
+int hna_local_seq_print_text(struct seq_file *seq, void *offset);
void hna_local_purge(struct work_struct *work);
void hna_local_free(void);
int hna_global_init(void);
void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff,
int hna_buff_len);
-int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off);
+int hna_global_seq_print_text(struct seq_file *seq, void *offset);
void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
char *orig_str);
void hna_global_del_orig(struct orig_node *orig_node, char *message);
Modified: trunk/batman-adv-kernelland/vis.c
===================================================================
--- trunk/batman-adv-kernelland/vis.c 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/vis.c 2010-05-21 09:59:25 UTC (rev 1669)
@@ -116,7 +116,7 @@
}
/* its a new address, add it to the list */
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
return;
memcpy(entry->addr, interface, ETH_ALEN);
@@ -143,12 +143,29 @@
return len;
}
+static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
+{
+ struct if_list_entry *entry;
+ struct hlist_node *pos;
+ size_t count = 0;
+
+ hlist_for_each_entry(entry, pos, if_list, list) {
+ if (entry->primary)
+ count += 9;
+ else
+ count += 23;
+ }
+
+ return count;
+}
+
/* read an entry */
static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
uint8_t *src, bool primary)
{
- char to[40];
+ char to[18];
+ /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
addr_to_string(to, entry->dest);
if (primary && entry->quality == 0)
return sprintf(buff, "HNA %s, ", to);
@@ -158,38 +175,74 @@
return 0;
}
-ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off)
+int vis_seq_print_text(struct seq_file *seq, void *offset)
{
HASHIT(hashit);
+ HASHIT(hashit_count);
struct vis_info *info;
struct vis_info_entry *entries;
+ struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
HLIST_HEAD(vis_if_list);
struct if_list_entry *entry;
struct hlist_node *pos, *n;
- size_t hdr_len, tmp_len;
- int i, bytes_written = 0;
+ int i;
char tmp_addr_str[ETH_STR_LEN];
unsigned long flags;
int vis_server = atomic_read(&bat_priv->vis_mode);
+ size_t buff_pos, buf_size;
+ char *buff;
if ((!bat_priv->primary_if) ||
(vis_server == VIS_TYPE_CLIENT_UPDATE))
return 0;
- hdr_len = 0;
+ buf_size = 1;
+ /* Estimate length */
+ spin_lock_irqsave(&vis_hash_lock, flags);
+ while (hash_iterate(vis_hash, &hashit_count)) {
+ info = hashit_count.bucket->data;
+ entries = (struct vis_info_entry *)
+ ((char *)info + sizeof(struct vis_info));
- spin_lock_irqsave(&vis_hash_lock, flags);
+ for (i = 0; i < info->packet.entries; i++) {
+ if (entries[i].quality == 0)
+ continue;
+ vis_data_insert_interface(entries[i].src, &vis_if_list,
+ compare_orig(entries[i].src,
+ info->packet.vis_orig));
+ }
+
+ hlist_for_each_entry(entry, pos, &vis_if_list, list) {
+ buf_size += 18 + 26 * info->packet.entries;
+
+ /* add primary/secondary records */
+ if (compare_orig(entry->addr, info->packet.vis_orig))
+ buf_size +=
+ vis_data_count_prim_sec(&vis_if_list);
+
+ buf_size += 1;
+ }
+
+ hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
+ hlist_del(&entry->list);
+ kfree(entry);
+ }
+ }
+
+ buff = kmalloc(buf_size, GFP_ATOMIC);
+ if (!buff) {
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+ return -ENOMEM;
+ }
+ buff[0] = '\0';
+ buff_pos = 0;
+
while (hash_iterate(vis_hash, &hashit)) {
info = hashit.bucket->data;
entries = (struct vis_info_entry *)
((char *)info + sizeof(struct vis_info));
- /* estimated line length */
- if (count < bytes_written + 200)
- break;
-
for (i = 0; i < info->packet.entries; i++) {
if (entries[i].quality == 0)
continue;
@@ -200,30 +253,22 @@
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
addr_to_string(tmp_addr_str, entry->addr);
- tmp_len = sprintf(buff + bytes_written,
- "%s,", tmp_addr_str);
+ buff_pos += sprintf(buff + buff_pos, "%s,",
+ tmp_addr_str);
for (i = 0; i < info->packet.entries; i++)
- tmp_len += vis_data_read_entry(
- buff + bytes_written + tmp_len,
- &entries[i], entry->addr,
- entry->primary);
+ buff_pos += vis_data_read_entry(buff + buff_pos,
+ &entries[i],
+ entry->addr,
+ entry->primary);
/* add primary/secondary records */
if (compare_orig(entry->addr, info->packet.vis_orig))
- tmp_len += vis_data_read_prim_sec(
- buff + bytes_written + tmp_len,
- &vis_if_list);
+ buff_pos +=
+ vis_data_read_prim_sec(buff + buff_pos,
+ &vis_if_list);
- tmp_len += sprintf(buff + bytes_written + tmp_len,
- "\n");
-
- hdr_len += tmp_len;
-
- if (off >= hdr_len)
- continue;
-
- bytes_written += tmp_len;
+ buff_pos += sprintf(buff + buff_pos, "\n");
}
hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
@@ -231,9 +276,13 @@
kfree(entry);
}
}
+
spin_unlock_irqrestore(&vis_hash_lock, flags);
- return bytes_written;
+ seq_printf(seq, "%s", buff);
+ kfree(buff);
+
+ return 0;
}
/* add the info packet to the send list, if it was not
Modified: trunk/batman-adv-kernelland/vis.h
===================================================================
--- trunk/batman-adv-kernelland/vis.h 2010-05-21 09:59:24 UTC (rev 1668)
+++ trunk/batman-adv-kernelland/vis.h 2010-05-21 09:59:25 UTC (rev 1669)
@@ -47,8 +47,7 @@
extern struct hashtable_t *vis_hash;
extern spinlock_t vis_hash_lock;
-ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
- size_t count, loff_t off);
+int vis_seq_print_text(struct seq_file *seq, void *offset);
void receive_server_sync_packet(struct bat_priv *bat_priv,
struct vis_packet *vis_packet,
int vis_info_len);