+static
+int ja_linear_node_set_nth(const struct rcu_ja_type *type,
+ struct rcu_ja_node *node,
+ uint8_t n,
+ struct rcu_ja_node_flag *child_node_flag)
+{
+ uint8_t nr_child;
+ uint8_t *values, *nr_child_ptr;
+ struct rcu_ja_node_flag **pointers;
+ unsigned int i;
+
+ assert(type->type_class == RCU_JA_LINEAR || type->type_class == RCU_JA_POOL);
+
+ nr_child_ptr = &node->u.data[0];
+ nr_child = *nr_child_ptr;
+ assert(nr_child <= type->max_linear_child);
+ assert(type->type_class != RCU_JA_LINEAR || nr_child >= type->min_child);
+
+ values = &node->u.data[1];
+ for (i = 0; i < nr_child; i++) {
+ if (values[i] == n)
+ return -EEXIST;
+ }
+ if (nr_child >= type->max_linear_child) {
+ /* No space left in this node type */
+ return -ENOSPC;
+ }
+ pointers = (struct rcu_ja_node_flag **) align_ptr_size(&values[type->max_linear_child]);
+ pointers[nr_child] = child_node_flag;
+ (*nr_child_ptr)++;
+ return 0;
+}
+
+static
+int ja_pool_node_set_nth(const struct rcu_ja_type *type,
+ struct rcu_ja_node *node,
+ uint8_t n,
+ struct rcu_ja_node_flag *child_node_flag)
+{
+ struct rcu_ja_node *linear;
+
+ assert(type->type_class == RCU_JA_POOL);
+ linear = (struct rcu_ja_node *)
+ &node->u.data[((unsigned long) n >> (CHAR_BIT - type->nr_pool_order)) << type->pool_size_order];
+ return ja_linear_node_set_nth(type, linear, n, child_node_flag);
+}
+
+static
+int ja_pigeon_node_set_nth(const struct rcu_ja_type *type,
+ struct rcu_ja_node *node,
+ uint8_t n,
+ struct rcu_ja_node_flag *child_node_flag)
+{
+ struct rcu_ja_node_flag **ptr;
+
+ assert(type->type_class == RCU_JA_PIGEON);
+ ptr = &((struct rcu_ja_node_flag **) node->u.data)[n];
+ if (*ptr != NULL)
+ return -EEXIST;
+ rcu_assign_pointer(*ptr, child_node_flag);
+ return 0;
+}
+