summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2011-06-27 23:31:46 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:38:44 -0800
commit3768ceb3dd66f929547328f4225d7805d95a88cd (patch)
treeda37ce84bf03b509db2d04df4ee3a71b77d9a749
parent70c55b8b4faf751a63eaf57fc6eff9ac196bcedd (diff)
nf: qtaguid: make procfs entry for ctrl return correct data.
(This is a direct cherry-pick from 2.6.39: I3b925802) Fixed procreader for /proc/net/xt_qtaguid/ctrl: it would just fill the output with the same entry. Simplify the **start handling. Signed-off-by: JP Abgrall <jpa@google.com> Change-Id: I3b92580228f2b57795bb2d0d6197fc95ab6be552
-rw-r--r--net/netfilter/xt_qtaguid.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 320ad84890e8..3b5ab3ff0615 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -906,42 +906,55 @@ ret_res:
return res;
}
-/* TODO: Use Documentation/filesystems/seq_file.txt? */
-static int qtaguid_ctrl_proc_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+/*
+ * Procfs reader to get all active socket tags using style "1)" as described in
+ * fs/proc/generic.c
+ */
+static int qtaguid_ctrl_proc_read(char *page, char **num_items_returned,
+ off_t items_to_skip, int char_count, int *eof,
+ void *data)
{
- char *out = page + off;
+ char *outp = page;
int len;
unsigned long flags;
uid_t uid;
struct sock_tag *sock_tag_entry;
struct rb_node *node;
- pr_debug("xt_qtaguid:proc ctrl page=%p off=%ld count=%d eof=%p\n",
- page, off, count, eof);
+ int item_index = 0;
+
+ pr_debug("xt_qtaguid:proc ctrl page=%p off=%ld char_count=%d *eof=%d\n",
+ page, items_to_skip, char_count, *eof);
+
+ if (*eof)
+ return 0;
- *eof = 0;
spin_lock_irqsave(&sock_tag_list_lock, flags);
for (node = rb_first(&sock_tag_tree);
node;
node = rb_next(node)) {
+ if (item_index++ < items_to_skip)
+ continue;
sock_tag_entry = rb_entry(node, struct sock_tag, node);
uid = get_uid_from_tag(sock_tag_entry->tag);
pr_debug("xt_qtaguid: proc_read(): sk=%p tag=0x%llx (uid=%d)\n",
sock_tag_entry->sk,
sock_tag_entry->tag,
uid);
- len = snprintf(out, count, "sock=%p tag=0x%llx (uid=%u)\n",
- sock_tag_entry->sk, sock_tag_entry->tag, uid);
- out += len;
- count -= len;
- if (!count) {
+ len = snprintf(outp, char_count,
+ "sock=%p tag=0x%llx (uid=%u)\n",
+ sock_tag_entry->sk, sock_tag_entry->tag, uid);
+ if (len >= char_count) {
spin_unlock_irqrestore(&sock_tag_list_lock, flags);
- return out - page;
+ *outp = '\0';
+ return outp - page;
}
+ outp += len;
+ char_count -= len;
+ (*num_items_returned)++;
}
- *eof = 1;
spin_unlock_irqrestore(&sock_tag_list_lock, flags);
- return out - page;
+ *eof = 1;
+ return outp - page;
}
static int qtaguid_ctrl_parse(const char *input, int count)
@@ -1146,7 +1159,7 @@ static int qtaguid_stats_proc_read(char *page, char **num_items_returned,
}
outp += len;
char_count -= len;
- (*(int *)num_items_returned)++;
+ (*num_items_returned)++;
}
spin_unlock_irqrestore(&iface_entry->tag_stat_list_lock,
flags2);