From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932842AbZHDUlE (ORCPT ); Tue, 4 Aug 2009 16:41:04 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932723AbZHDUkq (ORCPT ); Tue, 4 Aug 2009 16:40:46 -0400 Received: from mx2.redhat.com ([66.187.237.31]:58473 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932682AbZHDUkm (ORCPT ); Tue, 4 Aug 2009 16:40:42 -0400 Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells Subject: [PATCH 5/6] KEYS: Make /proc/keys use keyid not numread as file position [ver #2] To: torvalds@osdl.org, akpm@linux-foundation.org, jmorris@namei.org Cc: serue@us.ibm.com, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, "Serge E. Hallyn" , David Howells Date: Tue, 04 Aug 2009 21:39:44 +0100 Message-ID: <20090804203943.25094.68091.stgit@warthog.procyon.org.uk> In-Reply-To: <20090804203923.25094.78702.stgit@warthog.procyon.org.uk> References: <20090804203923.25094.78702.stgit@warthog.procyon.org.uk> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Serge E. Hallyn Make the file position maintained by /proc/keys represent the ID of the key just read rather than the number of keys read. This should make it faster to perform a lookup as we don't have to scan the key ID tree from the beginning to find the current position. Signed-off-by: Serge E. Hallyn Signed-off-by: David Howells --- security/keys/proc.c | 62 +++++++++++++++++++++++++++++++++----------------- 1 files changed, 41 insertions(+), 21 deletions(-) diff --git a/security/keys/proc.c b/security/keys/proc.c index 769f9bd..643ecf0 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -91,8 +91,9 @@ __initcall(key_proc_init); */ #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS -static struct rb_node *__key_serial_next(struct rb_node *n) +static struct rb_node *key_serial_next(struct rb_node *n) { + n = rb_next(n); while (n) { struct key *key = rb_entry(n, struct key, serial_node); if (key->user->user_ns == current_user_ns()) @@ -102,45 +103,64 @@ static struct rb_node *__key_serial_next(struct rb_node *n) return n; } -static struct rb_node *key_serial_next(struct rb_node *n) +static int proc_keys_open(struct inode *inode, struct file *file) { - return __key_serial_next(rb_next(n)); + return seq_open(file, &proc_keys_ops); } -static struct rb_node *key_serial_first(struct rb_root *r) +static struct key *find_ge_key(key_serial_t id) { - struct rb_node *n = rb_first(r); - return __key_serial_next(n); -} + struct rb_node *n = key_serial_tree.rb_node; + struct key *minkey = NULL; -static int proc_keys_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &proc_keys_ops); + while (n) { + struct key *key = rb_entry(n, struct key, serial_node); + if (id < key->serial) { + if (!minkey || minkey->serial > key->serial) + minkey = key; + n = n->rb_left; + } else if (id > key->serial) { + n = n->rb_right; + } else { + minkey = key; + break; + } + key = NULL; + } + return minkey; } static void *proc_keys_start(struct seq_file *p, loff_t *_pos) { - struct rb_node *_p; - loff_t pos = *_pos; + key_serial_t pos = *_pos; + struct key *key; spin_lock(&key_serial_lock); - _p = key_serial_first(&key_serial_tree); - while (pos > 0 && _p) { - pos--; - _p = key_serial_next(_p); - } - - return _p; + if (*_pos > INT_MAX) + return NULL; + key = find_ge_key(pos); + if (!key) + return NULL; + *_pos = key->serial; + return &key->serial_node; +} +static inline key_serial_t key_node_serial(struct rb_node *n) +{ + struct key *key = rb_entry(n, struct key, serial_node); + return key->serial; } static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos) { - (*_pos)++; - return key_serial_next((struct rb_node *) v); + struct rb_node *n; + n = key_serial_next(v); + if (n) + *_pos = key_node_serial(n); + return n; } static void proc_keys_stop(struct seq_file *p, void *v)