2626
2727#include <linux/random.h>
2828
29- const char * const bch2_btree_update_modes [] = {
29+ static const char * const bch2_btree_update_modes [] = {
3030#define x (t ) #t ,
31- BCH_WATERMARKS ()
31+ BTREE_UPDATE_MODES ()
3232#undef x
3333 NULL
3434};
@@ -850,15 +850,17 @@ static void btree_update_updated_node(struct btree_update *as, struct btree *b)
850850{
851851 struct bch_fs * c = as -> c ;
852852
853- mutex_lock (& c -> btree_interior_update_lock );
854- list_add_tail (& as -> unwritten_list , & c -> btree_interior_updates_unwritten );
855-
856853 BUG_ON (as -> mode != BTREE_UPDATE_none );
854+ BUG_ON (as -> update_level_end < b -> c .level );
857855 BUG_ON (!btree_node_dirty (b ));
858856 BUG_ON (!b -> c .level );
859857
858+ mutex_lock (& c -> btree_interior_update_lock );
859+ list_add_tail (& as -> unwritten_list , & c -> btree_interior_updates_unwritten );
860+
860861 as -> mode = BTREE_UPDATE_node ;
861862 as -> b = b ;
863+ as -> update_level_end = b -> c .level ;
862864
863865 set_btree_node_write_blocked (b );
864866 list_add (& as -> write_blocked_list , & b -> write_blocked );
@@ -1100,15 +1102,15 @@ static void bch2_btree_update_done(struct btree_update *as, struct btree_trans *
11001102
11011103static struct btree_update *
11021104bch2_btree_update_start (struct btree_trans * trans , struct btree_path * path ,
1103- unsigned level , bool split , unsigned flags )
1105+ unsigned level_start , bool split , unsigned flags )
11041106{
11051107 struct bch_fs * c = trans -> c ;
11061108 struct btree_update * as ;
11071109 u64 start_time = local_clock ();
11081110 int disk_res_flags = (flags & BCH_TRANS_COMMIT_no_enospc )
11091111 ? BCH_DISK_RESERVATION_NOFAIL : 0 ;
11101112 unsigned nr_nodes [2 ] = { 0 , 0 };
1111- unsigned update_level = level ;
1113+ unsigned level_end = level_start ;
11121114 enum bch_watermark watermark = flags & BCH_WATERMARK_MASK ;
11131115 int ret = 0 ;
11141116 u32 restart_count = trans -> restart_count ;
@@ -1140,29 +1142,29 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
11401142 }
11411143
11421144 while (1 ) {
1143- nr_nodes [!!update_level ] += 1 + split ;
1144- update_level ++ ;
1145+ nr_nodes [!!level_end ] += 1 + split ;
1146+ level_end ++ ;
11451147
1146- ret = bch2_btree_path_upgrade (trans , path , update_level + 1 );
1148+ ret = bch2_btree_path_upgrade (trans , path , level_end + 1 );
11471149 if (ret )
11481150 return ERR_PTR (ret );
11491151
1150- if (!btree_path_node (path , update_level )) {
1152+ if (!btree_path_node (path , level_end )) {
11511153 /* Allocating new root? */
11521154 nr_nodes [1 ] += split ;
1153- update_level = BTREE_MAX_DEPTH ;
1155+ level_end = BTREE_MAX_DEPTH ;
11541156 break ;
11551157 }
11561158
11571159 /*
11581160 * Always check for space for two keys, even if we won't have to
11591161 * split at prior level - it might have been a merge instead:
11601162 */
1161- if (bch2_btree_node_insert_fits (path -> l [update_level ].b ,
1163+ if (bch2_btree_node_insert_fits (path -> l [level_end ].b ,
11621164 BKEY_BTREE_PTR_U64s_MAX * 2 ))
11631165 break ;
11641166
1165- split = path -> l [update_level ].b -> nr .live_u64s > BTREE_SPLIT_THRESHOLD (c );
1167+ split = path -> l [level_end ].b -> nr .live_u64s > BTREE_SPLIT_THRESHOLD (c );
11661168 }
11671169
11681170 if (!down_read_trylock (& c -> gc_lock )) {
@@ -1176,14 +1178,15 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
11761178 as = mempool_alloc (& c -> btree_interior_update_pool , GFP_NOFS );
11771179 memset (as , 0 , sizeof (* as ));
11781180 closure_init (& as -> cl , NULL );
1179- as -> c = c ;
1180- as -> start_time = start_time ;
1181- as -> ip_started = _RET_IP_ ;
1182- as -> mode = BTREE_UPDATE_none ;
1183- as -> watermark = watermark ;
1184- as -> took_gc_lock = true;
1185- as -> btree_id = path -> btree_id ;
1186- as -> update_level = update_level ;
1181+ as -> c = c ;
1182+ as -> start_time = start_time ;
1183+ as -> ip_started = _RET_IP_ ;
1184+ as -> mode = BTREE_UPDATE_none ;
1185+ as -> watermark = watermark ;
1186+ as -> took_gc_lock = true;
1187+ as -> btree_id = path -> btree_id ;
1188+ as -> update_level_start = level_start ;
1189+ as -> update_level_end = level_end ;
11871190 INIT_LIST_HEAD (& as -> list );
11881191 INIT_LIST_HEAD (& as -> unwritten_list );
11891192 INIT_LIST_HEAD (& as -> write_blocked_list );
@@ -1373,12 +1376,12 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as,
13731376}
13741377
13751378static void
1376- __bch2_btree_insert_keys_interior (struct btree_update * as ,
1377- struct btree_trans * trans ,
1378- struct btree_path * path ,
1379- struct btree * b ,
1380- struct btree_node_iter node_iter ,
1381- struct keylist * keys )
1379+ bch2_btree_insert_keys_interior (struct btree_update * as ,
1380+ struct btree_trans * trans ,
1381+ struct btree_path * path ,
1382+ struct btree * b ,
1383+ struct btree_node_iter node_iter ,
1384+ struct keylist * keys )
13821385{
13831386 struct bkey_i * insert = bch2_keylist_front (keys );
13841387 struct bkey_packed * k ;
@@ -1534,7 +1537,7 @@ static void btree_split_insert_keys(struct btree_update *as,
15341537
15351538 bch2_btree_node_iter_init (& node_iter , b , & bch2_keylist_front (keys )-> k .p );
15361539
1537- __bch2_btree_insert_keys_interior (as , trans , path , b , node_iter , keys );
1540+ bch2_btree_insert_keys_interior (as , trans , path , b , node_iter , keys );
15381541
15391542 BUG_ON (bch2_btree_node_check_topology (trans , b ));
15401543 }
@@ -1714,27 +1717,6 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
17141717 goto out ;
17151718}
17161719
1717- static void
1718- bch2_btree_insert_keys_interior (struct btree_update * as ,
1719- struct btree_trans * trans ,
1720- struct btree_path * path ,
1721- struct btree * b ,
1722- struct keylist * keys )
1723- {
1724- struct btree_path * linked ;
1725- unsigned i ;
1726-
1727- __bch2_btree_insert_keys_interior (as , trans , path , b ,
1728- path -> l [b -> c .level ].iter , keys );
1729-
1730- btree_update_updated_node (as , b );
1731-
1732- trans_for_each_path_with_node (trans , b , linked , i )
1733- bch2_btree_node_iter_peek (& linked -> l [b -> c .level ].iter , b );
1734-
1735- bch2_trans_verify_paths (trans );
1736- }
1737-
17381720/**
17391721 * bch2_btree_insert_node - insert bkeys into a given btree node
17401722 *
@@ -1755,7 +1737,8 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
17551737 struct keylist * keys )
17561738{
17571739 struct bch_fs * c = as -> c ;
1758- struct btree_path * path = trans -> paths + path_idx ;
1740+ struct btree_path * path = trans -> paths + path_idx , * linked ;
1741+ unsigned i ;
17591742 int old_u64s = le16_to_cpu (btree_bset_last (b )-> u64s );
17601743 int old_live_u64s = b -> nr .live_u64s ;
17611744 int live_u64s_added , u64s_added ;
@@ -1784,7 +1767,13 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
17841767 return ret ;
17851768 }
17861769
1787- bch2_btree_insert_keys_interior (as , trans , path , b , keys );
1770+ bch2_btree_insert_keys_interior (as , trans , path , b ,
1771+ path -> l [b -> c .level ].iter , keys );
1772+
1773+ trans_for_each_path_with_node (trans , b , linked , i )
1774+ bch2_btree_node_iter_peek (& linked -> l [b -> c .level ].iter , b );
1775+
1776+ bch2_trans_verify_paths (trans );
17881777
17891778 live_u64s_added = (int ) b -> nr .live_u64s - old_live_u64s ;
17901779 u64s_added = (int ) le16_to_cpu (btree_bset_last (b )-> u64s ) - old_u64s ;
@@ -1798,6 +1787,7 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
17981787 bch2_maybe_compact_whiteouts (c , b ))
17991788 bch2_trans_node_reinit_iter (trans , b );
18001789
1790+ btree_update_updated_node (as , b );
18011791 bch2_btree_node_unlock_write (trans , path , b );
18021792
18031793 BUG_ON (bch2_btree_node_check_topology (trans , b ));
@@ -1807,7 +1797,7 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
18071797 * We could attempt to avoid the transaction restart, by calling
18081798 * bch2_btree_path_upgrade() and allocating more nodes:
18091799 */
1810- if (b -> c .level >= as -> update_level ) {
1800+ if (b -> c .level >= as -> update_level_end ) {
18111801 trace_and_count (c , trans_restart_split_race , trans , _THIS_IP_ , b );
18121802 return btree_trans_restart (trans , BCH_ERR_transaction_restart_split_race );
18131803 }
@@ -2519,9 +2509,11 @@ void bch2_btree_root_alloc_fake(struct bch_fs *c, enum btree_id id, unsigned lev
25192509
25202510static void bch2_btree_update_to_text (struct printbuf * out , struct btree_update * as )
25212511{
2522- prt_printf (out , "%ps: btree=%s watermark=%s mode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n" ,
2512+ prt_printf (out , "%ps: btree=%s l=%u-%u watermark=%s mode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n" ,
25232513 (void * ) as -> ip_started ,
25242514 bch2_btree_id_str (as -> btree_id ),
2515+ as -> update_level_start ,
2516+ as -> update_level_end ,
25252517 bch2_watermarks [as -> watermark ],
25262518 bch2_btree_update_modes [as -> mode ],
25272519 as -> nodes_written ,
0 commit comments