]> Pileus Git - ~andy/linux/blobdiff - net/key/af_key.c
Merge branch 'for-linus' of git://git.infradead.org/~dedekind/ubi-2.6
[~andy/linux] / net / key / af_key.c
index 162fcea3324c10219e7b4c317840b0d2fb71a0d1..8b5f486ac80f298fe6034a2a8b576c3c2ad9ea83 100644 (file)
@@ -2291,6 +2291,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        return 0;
 
 out:
+       xp->dead = 1;
        xfrm_policy_destroy(xp);
        return err;
 }
@@ -3734,21 +3735,15 @@ static struct net_proto_family pfkey_family_ops = {
 };
 
 #ifdef CONFIG_PROC_FS
-static int pfkey_read_proc(char *buffer, char **start, off_t offset,
-                          int length, int *eof, void *data)
+static int pfkey_seq_show(struct seq_file *f, void *v)
 {
-       off_t pos = 0;
-       off_t begin = 0;
-       int len = 0;
        struct sock *s;
-       struct hlist_node *node;
-
-       len += sprintf(buffer,"sk       RefCnt Rmem   Wmem   User   Inode\n");
-
-       read_lock(&pfkey_table_lock);
 
-       sk_for_each(s, node, &pfkey_table) {
-               len += sprintf(buffer+len,"%p %-6d %-6u %-6u %-6u %-6lu",
+       s = (struct sock *)v;
+       if (v == SEQ_START_TOKEN)
+               seq_printf(f ,"sk       RefCnt Rmem   Wmem   User   Inode\n");
+       else
+               seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n",
                               s,
                               atomic_read(&s->sk_refcnt),
                               atomic_read(&s->sk_rmem_alloc),
@@ -3756,45 +3751,72 @@ static int pfkey_read_proc(char *buffer, char **start, off_t offset,
                               sock_i_uid(s),
                               sock_i_ino(s)
                               );
+       return 0;
+}
+
+static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos)
+{
+       struct sock *s;
+       struct hlist_node *node;
+       loff_t pos = *ppos;
 
-               buffer[len++] = '\n';
+       read_lock(&pfkey_table_lock);
+       if (pos == 0)
+               return SEQ_START_TOKEN;
 
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-               if(pos > offset + length)
-                       goto done;
-       }
-       *eof = 1;
+       sk_for_each(s, node, &pfkey_table)
+               if (pos-- == 1)
+                       return s;
 
-done:
-       read_unlock(&pfkey_table_lock);
+       return NULL;
+}
+
+static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos)
+{
+       ++*ppos;
+       return (v == SEQ_START_TOKEN) ?
+               sk_head(&pfkey_table) :
+                       sk_next((struct sock *)v);
+}
 
-       *start = buffer + (offset - begin);
-       len -= (offset - begin);
+static void pfkey_seq_stop(struct seq_file *f, void *v)
+{
+       read_unlock(&pfkey_table_lock);
+}
 
-       if (len > length)
-               len = length;
-       if (len < 0)
-               len = 0;
+static struct seq_operations pfkey_seq_ops = {
+       .start  = pfkey_seq_start,
+       .next   = pfkey_seq_next,
+       .stop   = pfkey_seq_stop,
+       .show   = pfkey_seq_show,
+};
 
-       return len;
+static int pfkey_seq_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &pfkey_seq_ops);
 }
 
+static struct file_operations pfkey_proc_ops = {
+       .open    = pfkey_seq_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+
 static int pfkey_init_proc(void)
 {
-       if (create_proc_read_entry("pfkey", 0, init_net.proc_net,
-                               pfkey_read_proc, NULL) == NULL)
+       struct proc_dir_entry *e;
+
+       e = proc_net_fops_create(&init_net, "pfkey", 0, &pfkey_proc_ops);
+       if (e == NULL)
                return -ENOMEM;
-       else
-               return 0;
+
+       return 0;
 }
 
 static void pfkey_exit_proc(void)
 {
-       remove_proc_entry("net/pfkey", NULL);
+       proc_net_remove(&init_net, "pfkey");
 }
 #else
 static inline int pfkey_init_proc(void)