nf: qtaguid: make procfs entry for ctrl return correct data.
authorJP Abgrall <jpa@google.com>
Tue, 28 Jun 2011 06:31:46 +0000 (23:31 -0700)
committermgross <mark.gross@intel.com>
Wed, 9 Nov 2011 20:09:20 +0000 (12:09 -0800)
(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

net/netfilter/xt_qtaguid.c

index 320ad84..3b5ab3f 100644 (file)
@@ -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);