diff options
Diffstat (limited to 'lib/xarray.c')
| -rw-r--r-- | lib/xarray.c | 23 | 
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/xarray.c b/lib/xarray.c index 39f07bfc4dcc..5e7d6334d70d 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -969,8 +969,22 @@ static unsigned int node_get_marks(struct xa_node *node, unsigned int offset)  	return marks;  } +static inline void node_mark_slots(struct xa_node *node, unsigned int sibs, +		xa_mark_t mark) +{ +	int i; + +	if (sibs == 0) +		node_mark_all(node, mark); +	else { +		for (i = 0; i < XA_CHUNK_SIZE; i += sibs + 1) +			node_set_mark(node, i, mark); +	} +} +  static void node_set_marks(struct xa_node *node, unsigned int offset, -			struct xa_node *child, unsigned int marks) +			struct xa_node *child, unsigned int sibs, +			unsigned int marks)  {  	xa_mark_t mark = XA_MARK_0; @@ -978,7 +992,7 @@ static void node_set_marks(struct xa_node *node, unsigned int offset,  		if (marks & (1 << (__force unsigned int)mark)) {  			node_set_mark(node, offset, mark);  			if (child) -				node_mark_all(child, mark); +				node_mark_slots(child, sibs, mark);  		}  		if (mark == XA_MARK_MAX)  			break; @@ -1077,7 +1091,8 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)  			child->nr_values = xa_is_value(entry) ?  					XA_CHUNK_SIZE : 0;  			RCU_INIT_POINTER(child->parent, node); -			node_set_marks(node, offset, child, marks); +			node_set_marks(node, offset, child, xas->xa_sibs, +					marks);  			rcu_assign_pointer(node->slots[offset],  					xa_mk_node(child));  			if (xa_is_value(curr)) @@ -1086,7 +1101,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)  		} else {  			unsigned int canon = offset - xas->xa_sibs; -			node_set_marks(node, canon, NULL, marks); +			node_set_marks(node, canon, NULL, 0, marks);  			rcu_assign_pointer(node->slots[canon], entry);  			while (offset > canon)  				rcu_assign_pointer(node->slots[offset--],  | 
