@@ -60,6 +60,70 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi)
6060}
6161
6262#ifdef CONFIG_DEBUG_FS
63+ static void update_multidevice_stats (struct f2fs_sb_info * sbi )
64+ {
65+ struct f2fs_stat_info * si = F2FS_STAT (sbi );
66+ struct f2fs_dev_stats * dev_stats = si -> dev_stats ;
67+ int i , j ;
68+
69+ if (!f2fs_is_multi_device (sbi ))
70+ return ;
71+
72+ memset (dev_stats , 0 , sizeof (struct f2fs_dev_stats ) * sbi -> s_ndevs );
73+ for (i = 0 ; i < sbi -> s_ndevs ; i ++ ) {
74+ unsigned int start_segno , end_segno ;
75+ block_t start_blk , end_blk ;
76+
77+ if (i == 0 ) {
78+ start_blk = MAIN_BLKADDR (sbi );
79+ end_blk = FDEV (i ).end_blk + 1 - SEG0_BLKADDR (sbi );
80+ } else {
81+ start_blk = FDEV (i ).start_blk ;
82+ end_blk = FDEV (i ).end_blk + 1 ;
83+ }
84+
85+ start_segno = GET_SEGNO (sbi , start_blk );
86+ end_segno = GET_SEGNO (sbi , end_blk );
87+
88+ for (j = start_segno ; j < end_segno ; j ++ ) {
89+ unsigned int seg_blks , sec_blks ;
90+
91+ seg_blks = get_seg_entry (sbi , j )-> valid_blocks ;
92+
93+ /* update segment stats */
94+ if (IS_CURSEG (sbi , j ))
95+ dev_stats [i ].devstats [0 ][DEVSTAT_INUSE ]++ ;
96+ else if (seg_blks == BLKS_PER_SEG (sbi ))
97+ dev_stats [i ].devstats [0 ][DEVSTAT_FULL ]++ ;
98+ else if (seg_blks != 0 )
99+ dev_stats [i ].devstats [0 ][DEVSTAT_DIRTY ]++ ;
100+ else if (!test_bit (j , FREE_I (sbi )-> free_segmap ))
101+ dev_stats [i ].devstats [0 ][DEVSTAT_FREE ]++ ;
102+ else
103+ dev_stats [i ].devstats [0 ][DEVSTAT_PREFREE ]++ ;
104+
105+ if (!__is_large_section (sbi ) ||
106+ (j % SEGS_PER_SEC (sbi )) != 0 )
107+ continue ;
108+
109+ sec_blks = get_sec_entry (sbi , j )-> valid_blocks ;
110+
111+ /* update section stats */
112+ if (IS_CURSEC (sbi , GET_SEC_FROM_SEG (sbi , j )))
113+ dev_stats [i ].devstats [1 ][DEVSTAT_INUSE ]++ ;
114+ else if (sec_blks == BLKS_PER_SEC (sbi ))
115+ dev_stats [i ].devstats [1 ][DEVSTAT_FULL ]++ ;
116+ else if (sec_blks != 0 )
117+ dev_stats [i ].devstats [1 ][DEVSTAT_DIRTY ]++ ;
118+ else if (!test_bit (GET_SEC_FROM_SEG (sbi , j ),
119+ FREE_I (sbi )-> free_secmap ))
120+ dev_stats [i ].devstats [1 ][DEVSTAT_FREE ]++ ;
121+ else
122+ dev_stats [i ].devstats [1 ][DEVSTAT_PREFREE ]++ ;
123+ }
124+ }
125+ }
126+
63127static void update_general_status (struct f2fs_sb_info * sbi )
64128{
65129 struct f2fs_stat_info * si = F2FS_STAT (sbi );
@@ -214,6 +278,8 @@ static void update_general_status(struct f2fs_sb_info *sbi)
214278 si -> valid_blks [type ] += blks ;
215279 }
216280
281+ update_multidevice_stats (sbi );
282+
217283 for (i = 0 ; i < MAX_CALL_TYPE ; i ++ )
218284 si -> cp_call_count [i ] = atomic_read (& sbi -> cp_call_count [i ]);
219285
@@ -498,6 +564,36 @@ static int stat_show(struct seq_file *s, void *v)
498564 si -> dirty_count );
499565 seq_printf (s , " - Prefree: %d\n - Free: %d (%d)\n\n" ,
500566 si -> prefree_count , si -> free_segs , si -> free_secs );
567+ if (f2fs_is_multi_device (sbi )) {
568+ seq_puts (s , "Multidevice stats:\n" );
569+ seq_printf (s , " [seg: %8s %8s %8s %8s %8s]" ,
570+ "inuse" , "dirty" , "full" , "free" , "prefree" );
571+ if (__is_large_section (sbi ))
572+ seq_printf (s , " [sec: %8s %8s %8s %8s %8s]\n" ,
573+ "inuse" , "dirty" , "full" , "free" , "prefree" );
574+ else
575+ seq_puts (s , "\n" );
576+
577+ for (i = 0 ; i < sbi -> s_ndevs ; i ++ ) {
578+ seq_printf (s , " #%-2d %8u %8u %8u %8u %8u" , i ,
579+ si -> dev_stats [i ].devstats [0 ][DEVSTAT_INUSE ],
580+ si -> dev_stats [i ].devstats [0 ][DEVSTAT_DIRTY ],
581+ si -> dev_stats [i ].devstats [0 ][DEVSTAT_FULL ],
582+ si -> dev_stats [i ].devstats [0 ][DEVSTAT_FREE ],
583+ si -> dev_stats [i ].devstats [0 ][DEVSTAT_PREFREE ]);
584+ if (!__is_large_section (sbi )) {
585+ seq_puts (s , "\n" );
586+ continue ;
587+ }
588+ seq_printf (s , " %8u %8u %8u %8u %8u\n" ,
589+ si -> dev_stats [i ].devstats [1 ][DEVSTAT_INUSE ],
590+ si -> dev_stats [i ].devstats [1 ][DEVSTAT_DIRTY ],
591+ si -> dev_stats [i ].devstats [1 ][DEVSTAT_FULL ],
592+ si -> dev_stats [i ].devstats [1 ][DEVSTAT_FREE ],
593+ si -> dev_stats [i ].devstats [1 ][DEVSTAT_PREFREE ]);
594+ }
595+ seq_puts (s , "\n" );
596+ }
501597 seq_printf (s , "CP calls: %d (BG: %d)\n" ,
502598 si -> cp_call_count [TOTAL_CALL ],
503599 si -> cp_call_count [BACKGROUND ]);
@@ -665,13 +761,23 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
665761{
666762 struct f2fs_super_block * raw_super = F2FS_RAW_SUPER (sbi );
667763 struct f2fs_stat_info * si ;
764+ struct f2fs_dev_stats * dev_stats ;
668765 unsigned long flags ;
669766 int i ;
670767
671768 si = f2fs_kzalloc (sbi , sizeof (struct f2fs_stat_info ), GFP_KERNEL );
672769 if (!si )
673770 return - ENOMEM ;
674771
772+ dev_stats = f2fs_kzalloc (sbi , sizeof (struct f2fs_dev_stats ) *
773+ sbi -> s_ndevs , GFP_KERNEL );
774+ if (!dev_stats ) {
775+ kfree (si );
776+ return - ENOMEM ;
777+ }
778+
779+ si -> dev_stats = dev_stats ;
780+
675781 si -> all_area_segs = le32_to_cpu (raw_super -> segment_count );
676782 si -> sit_area_segs = le32_to_cpu (raw_super -> segment_count_sit );
677783 si -> nat_area_segs = le32_to_cpu (raw_super -> segment_count_nat );
@@ -724,6 +830,7 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi)
724830 list_del (& si -> stat_list );
725831 raw_spin_unlock_irqrestore (& f2fs_stat_lock , flags );
726832
833+ kfree (si -> dev_stats );
727834 kfree (si );
728835}
729836
0 commit comments