diff options
Diffstat (limited to 'security/keys/key.c')
-rw-r--r-- | security/keys/key.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index ac9326c5f1d..700400d801d 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -188,6 +188,7 @@ static inline void key_alloc_serial(struct key *key) spin_lock(&key_serial_lock); +attempt_insertion: parent = NULL; p = &key_serial_tree.rb_node; @@ -202,39 +203,33 @@ static inline void key_alloc_serial(struct key *key) else goto serial_exists; } - goto insert_here; + + /* we've found a suitable hole - arrange for this key to occupy it */ + rb_link_node(&key->serial_node, parent, p); + rb_insert_color(&key->serial_node, &key_serial_tree); + + spin_unlock(&key_serial_lock); + return; /* we found a key with the proposed serial number - walk the tree from * that point looking for the next unused serial number */ serial_exists: for (;;) { key->serial++; - if (key->serial < 2) - key->serial = 2; - - if (!rb_parent(parent)) - p = &key_serial_tree.rb_node; - else if (rb_parent(parent)->rb_left == parent) - p = &(rb_parent(parent)->rb_left); - else - p = &(rb_parent(parent)->rb_right); + if (key->serial < 3) { + key->serial = 3; + goto attempt_insertion; + } parent = rb_next(parent); if (!parent) - break; + goto attempt_insertion; xkey = rb_entry(parent, struct key, serial_node); if (key->serial < xkey->serial) - goto insert_here; + goto attempt_insertion; } - /* we've found a suitable hole - arrange for this key to occupy it */ -insert_here: - rb_link_node(&key->serial_node, parent, p); - rb_insert_color(&key->serial_node, &key_serial_tree); - - spin_unlock(&key_serial_lock); - } /* end key_alloc_serial() */ /*****************************************************************************/ |