Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad73a717 authored by Serge E. Hallyn's avatar Serge E. Hallyn Committed by James Morris
Browse files

KEYS: Make /proc/keys use keyid not numread as file position [try #6]



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: default avatarSerge E. Hallyn <serue@us.ibm.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 5d135440
Loading
Loading
Loading
Loading
+55 −22
Original line number Diff line number Diff line
@@ -91,57 +91,90 @@ __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)
{
	struct user_namespace *user_ns = current_user_ns();

	n = rb_next(n);
	while (n) {
		struct key *key = rb_entry(n, struct key, serial_node);
		if (key->user->user_ns == current_user_ns())
		if (key->user->user_ns == user_ns)
			break;
		n = rb_next(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 user_namespace *user_ns = current_user_ns();
	struct rb_node *n = key_serial_tree.rb_node;
	struct key *minkey = NULL;

	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;
	}

static int proc_keys_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &proc_keys_ops);
	if (!minkey)
		return NULL;

	for (;;) {
		if (minkey->user->user_ns == user_ns)
			return minkey;
		n = rb_next(&minkey->serial_node);
		if (!n)
			return NULL;
		minkey = rb_entry(n, struct key, serial_node);
	}
}

static void *proc_keys_start(struct seq_file *p, loff_t *_pos)
	__acquires(key_serial_lock)
{
	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);
	if (*_pos > INT_MAX)
		return NULL;
	key = find_ge_key(pos);
	if (!key)
		return NULL;
	*_pos = key->serial;
	return &key->serial_node;
}

	return _p;

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)