@@ -199,6 +199,8 @@ class TestScrubChecks(CephFSTestCase):
199199
200200 MDSS_REQUIRED = 1
201201 CLIENTS_REQUIRED = 1
202+ def get_dsplits (self , dir_ino ):
203+ return self .fs .rank_asok (['dump' , 'inode' , str (dir_ino )])['dirfragtree' ]['splits' ]
202204
203205 def test_scrub_checks (self ):
204206 self ._checks (0 )
@@ -362,6 +364,86 @@ def test_scrub_repair(self):
362364 # fragstat should be fixed
363365 self .mount_a .run_shell (["rmdir" , test_dir ])
364366
367+ def test_scrub_merge_dirfrags (self ):
368+ """
369+ That a directory is merged during scrub.
370+ """
371+
372+ test_path = "testdir"
373+ abs_test_path = f"/{ test_path } "
374+ split_size = 20
375+ merge_size = 5
376+ split_bits = 1
377+ self .config_set ('mds' , 'mds_bal_split_size' , split_size )
378+ self .config_set ('mds' , 'mds_bal_merge_size' , merge_size )
379+ self .config_set ('mds' , 'mds_bal_split_bits' , split_bits )
380+
381+ self .mount_a .run_shell (["mkdir" , test_path ])
382+ dir_ino = self .mount_a .path_to_ino (test_path )
383+
384+ self .assertEqual (len (self .get_dsplits (dir_ino )), 0 )
385+ self .mount_a .create_n_files (f"{ test_path } /file" , split_size * 2 )
386+
387+ self .mount_a .umount_wait ()
388+
389+ self .fs .flush ()
390+ self .fs .mds_fail_restart ()
391+ self .fs .wait_for_daemons ()
392+
393+ split_size = 100
394+ merge_size = 30
395+ self .config_set ('mds' , 'mds_bal_split_size' , split_size )
396+ self .config_set ('mds' , 'mds_bal_merge_size' , merge_size )
397+
398+ #Assert to ensure split is present
399+ self .assertGreater (len (self .get_dsplits (dir_ino )), 0 )
400+ out_json = self .fs .run_scrub (["start" , abs_test_path , "recursive" ])
401+ self .assertNotEqual (out_json , None )
402+
403+ #Wait until no splits to confirm merge by scrub
404+ self .wait_until_true (
405+ lambda : len (self .get_dsplits (dir_ino )) == 0 ,
406+ timeout = 30
407+ )
408+
409+ def test_scrub_split_dirfrags (self ):
410+ """
411+ That a directory is split during scrub.
412+ """
413+
414+ test_path = "testdir"
415+ abs_test_path = f"/{ test_path } "
416+ split_size = 20
417+ merge_size = 5
418+ split_bits = 1
419+
420+ self .mount_a .run_shell (["mkdir" , test_path ])
421+ dir_ino = self .mount_a .path_to_ino (test_path )
422+
423+ self .assertEqual (len (self .get_dsplits (dir_ino )), 0 )
424+ self .mount_a .create_n_files (f"{ test_path } /file" , split_size + 1 )
425+
426+ self .mount_a .umount_wait ()
427+
428+ self .fs .flush ()
429+ self .fs .mds_fail_restart ()
430+ self .fs .wait_for_daemons ()
431+
432+ self .config_set ('mds' , 'mds_bal_split_size' , split_size )
433+ self .config_set ('mds' , 'mds_bal_merge_size' , merge_size )
434+ self .config_set ('mds' , 'mds_bal_split_bits' , split_bits )
435+
436+ #Assert to ensure no splits are present
437+ self .assertEqual (len (self .get_dsplits (dir_ino )), 0 )
438+ out_json = self .fs .run_scrub (["start" , abs_test_path , "recursive" ])
439+ self .assertNotEqual (out_json , None )
440+
441+ #Wait until split is present to confirm split by scrub
442+ self .wait_until_true (
443+ lambda : len (self .get_dsplits (dir_ino )) > 0 ,
444+ timeout = 30
445+ )
446+
365447 def test_stray_evaluation_with_scrub (self ):
366448 """
367449 test that scrub can iterate over ~mdsdir and evaluate strays
0 commit comments