@@ -902,6 +902,44 @@ static inline void ma_set_meta(struct maple_node *mn, enum maple_type mt,
902902 meta -> end = end ;
903903}
904904
905+ /*
906+ * mas_clear_meta() - clear the metadata information of a node, if it exists
907+ * @mas: The maple state
908+ * @mn: The maple node
909+ * @mt: The maple node type
910+ * @offset: The offset of the highest sub-gap in this node.
911+ * @end: The end of the data in this node.
912+ */
913+ static inline void mas_clear_meta (struct ma_state * mas , struct maple_node * mn ,
914+ enum maple_type mt )
915+ {
916+ struct maple_metadata * meta ;
917+ unsigned long * pivots ;
918+ void __rcu * * slots ;
919+ void * next ;
920+
921+ switch (mt ) {
922+ case maple_range_64 :
923+ pivots = mn -> mr64 .pivot ;
924+ if (unlikely (pivots [MAPLE_RANGE64_SLOTS - 2 ])) {
925+ slots = mn -> mr64 .slot ;
926+ next = mas_slot_locked (mas , slots ,
927+ MAPLE_RANGE64_SLOTS - 1 );
928+ if (unlikely ((mte_to_node (next ) && mte_node_type (next ))))
929+ return ; /* The last slot is a node, no metadata */
930+ }
931+ fallthrough ;
932+ case maple_arange_64 :
933+ meta = ma_meta (mn , mt );
934+ break ;
935+ default :
936+ return ;
937+ }
938+
939+ meta -> gap = 0 ;
940+ meta -> end = 0 ;
941+ }
942+
905943/*
906944 * ma_meta_end() - Get the data end of a node from the metadata
907945 * @mn: The maple node
@@ -5441,20 +5479,22 @@ static inline int mas_rev_alloc(struct ma_state *mas, unsigned long min,
54415479 * mas_dead_leaves() - Mark all leaves of a node as dead.
54425480 * @mas: The maple state
54435481 * @slots: Pointer to the slot array
5482+ * @type: The maple node type
54445483 *
54455484 * Must hold the write lock.
54465485 *
54475486 * Return: The number of leaves marked as dead.
54485487 */
54495488static inline
5450- unsigned char mas_dead_leaves (struct ma_state * mas , void __rcu * * slots )
5489+ unsigned char mas_dead_leaves (struct ma_state * mas , void __rcu * * slots ,
5490+ enum maple_type mt )
54515491{
54525492 struct maple_node * node ;
54535493 enum maple_type type ;
54545494 void * entry ;
54555495 int offset ;
54565496
5457- for (offset = 0 ; offset < mt_slot_count ( mas -> node ) ; offset ++ ) {
5497+ for (offset = 0 ; offset < mt_slots [ mt ] ; offset ++ ) {
54585498 entry = mas_slot_locked (mas , slots , offset );
54595499 type = mte_node_type (entry );
54605500 node = mte_to_node (entry );
@@ -5473,14 +5513,13 @@ unsigned char mas_dead_leaves(struct ma_state *mas, void __rcu **slots)
54735513
54745514static void __rcu * * mas_dead_walk (struct ma_state * mas , unsigned char offset )
54755515{
5476- struct maple_node * node , * next ;
5516+ struct maple_node * next ;
54775517 void __rcu * * slots = NULL ;
54785518
54795519 next = mas_mn (mas );
54805520 do {
5481- mas -> node = ma_enode_ptr (next );
5482- node = mas_mn (mas );
5483- slots = ma_slots (node , node -> type );
5521+ mas -> node = mt_mk_node (next , next -> type );
5522+ slots = ma_slots (next , next -> type );
54845523 next = mas_slot_locked (mas , slots , offset );
54855524 offset = 0 ;
54865525 } while (!ma_is_leaf (next -> type ));
@@ -5544,11 +5583,14 @@ static inline void __rcu **mas_destroy_descend(struct ma_state *mas,
55445583 node = mas_mn (mas );
55455584 slots = ma_slots (node , mte_node_type (mas -> node ));
55465585 next = mas_slot_locked (mas , slots , 0 );
5547- if ((mte_dead_node (next )))
5586+ if ((mte_dead_node (next ))) {
5587+ mte_to_node (next )-> type = mte_node_type (next );
55485588 next = mas_slot_locked (mas , slots , 1 );
5589+ }
55495590
55505591 mte_set_node_dead (mas -> node );
55515592 node -> type = mte_node_type (mas -> node );
5593+ mas_clear_meta (mas , node , node -> type );
55525594 node -> piv_parent = prev ;
55535595 node -> parent_slot = offset ;
55545596 offset = 0 ;
@@ -5568,21 +5610,27 @@ static void mt_destroy_walk(struct maple_enode *enode, unsigned char ma_flags,
55685610
55695611 MA_STATE (mas , & mt , 0 , 0 );
55705612
5571- if (mte_is_leaf (enode ))
5613+ mas .node = enode ;
5614+ if (mte_is_leaf (enode )) {
5615+ node -> type = mte_node_type (enode );
55725616 goto free_leaf ;
5617+ }
55735618
5619+ ma_flags &= ~MT_FLAGS_LOCK_MASK ;
55745620 mt_init_flags (& mt , ma_flags );
55755621 mas_lock (& mas );
55765622
5577- mas .node = start = enode ;
5623+ mte_to_node (enode )-> ma_flags = ma_flags ;
5624+ start = enode ;
55785625 slots = mas_destroy_descend (& mas , start , 0 );
55795626 node = mas_mn (& mas );
55805627 do {
55815628 enum maple_type type ;
55825629 unsigned char offset ;
55835630 struct maple_enode * parent , * tmp ;
55845631
5585- node -> slot_len = mas_dead_leaves (& mas , slots );
5632+ node -> type = mte_node_type (mas .node );
5633+ node -> slot_len = mas_dead_leaves (& mas , slots , node -> type );
55865634 if (free )
55875635 mt_free_bulk (node -> slot_len , slots );
55885636 offset = node -> parent_slot + 1 ;
@@ -5606,7 +5654,8 @@ static void mt_destroy_walk(struct maple_enode *enode, unsigned char ma_flags,
56065654 } while (start != mas .node );
56075655
56085656 node = mas_mn (& mas );
5609- node -> slot_len = mas_dead_leaves (& mas , slots );
5657+ node -> type = mte_node_type (mas .node );
5658+ node -> slot_len = mas_dead_leaves (& mas , slots , node -> type );
56105659 if (free )
56115660 mt_free_bulk (node -> slot_len , slots );
56125661
@@ -5616,6 +5665,8 @@ static void mt_destroy_walk(struct maple_enode *enode, unsigned char ma_flags,
56165665free_leaf :
56175666 if (free )
56185667 mt_free_rcu (& node -> rcu );
5668+ else
5669+ mas_clear_meta (& mas , node , node -> type );
56195670}
56205671
56215672/*
0 commit comments