Esempio n. 1
0
void rb_insert(struct rb_tree *t, struct rb_node *n, struct rb_callbacks *cb) {
  /* insert node into the correct location in the tree, then link it in to
     recolor the tree */
  struct rb_node *parent = t->root;

  while (parent) {
    if (cb->cmp(n, parent) < 0) {
      if (!parent->left) {
        parent->left = n;
        break;
      }

      parent = parent->left;
    } else {
      if (!parent->right) {
        parent->right = n;
        break;
      }

      parent = parent->right;
    }
  }

  n->parent = parent;

  rb_link(t, n, cb);
}
Esempio n. 2
0
static struct fs_entry *vfs_lookup(struct fs_entry *dir, const char *name,
			bool create, int *rc)
{
	struct fs_node *node = dir->node;
	struct rb_node **plink = &dir->children.root;
	struct rb_node *parent = 0;

	if (!node->ops->lookup) {
		*rc = -ENOTSUP;
		return 0;
	}

	const bool enabled = spin_lock_irqsave(&dir->lock);

	while (*plink) {
		struct fs_entry *entry = TREE_ENTRY(*plink, struct fs_entry,
			link);

		const int cmp = strcmp(entry->name, name);

		if (!cmp) {
			*rc = 0;
			vfs_entry_get(entry);
			spin_unlock_irqrestore(&dir->lock, enabled);
			return entry;
		}

		parent = *plink;
		if (cmp < 0)
			plink = &parent->right;
		else
			plink = &parent->left;
	}

	struct fs_entry *entry = vfs_entry_create(name);

	if (!entry) {
		spin_unlock_irqrestore(&dir->lock, enabled);
		*rc = -ENOMEM;
		return 0;
	}

	rb_link(&entry->link, parent, plink);
	rb_insert(&entry->link, &dir->children);
	entry->parent = vfs_entry_get(dir);
	entry->cached = true;
	spin_unlock_irqrestore(&dir->lock, enabled);

	*rc = node->ops->lookup(node, entry);
	if (*rc && !create) {
		vfs_entry_put(entry);
		return 0;
	}

	return entry;
}