@@ -7532,18 +7532,18 @@ static int ocfs2_trim_group(struct super_block *sb,
7532
7532
return count ;
7533
7533
}
7534
7534
7535
- int ocfs2_trim_fs (struct super_block * sb , struct fstrim_range * range )
7535
+ static
7536
+ int ocfs2_trim_mainbm (struct super_block * sb , struct fstrim_range * range )
7536
7537
{
7537
7538
struct ocfs2_super * osb = OCFS2_SB (sb );
7538
- u64 start , len , trimmed , first_group , last_group , group ;
7539
+ u64 start , len , trimmed = 0 , first_group , last_group = 0 , group = 0 ;
7539
7540
int ret , cnt ;
7540
7541
u32 first_bit , last_bit , minlen ;
7541
7542
struct buffer_head * main_bm_bh = NULL ;
7542
7543
struct inode * main_bm_inode = NULL ;
7543
7544
struct buffer_head * gd_bh = NULL ;
7544
7545
struct ocfs2_dinode * main_bm ;
7545
7546
struct ocfs2_group_desc * gd = NULL ;
7546
- struct ocfs2_trim_fs_info info , * pinfo = NULL ;
7547
7547
7548
7548
start = range -> start >> osb -> s_clustersize_bits ;
7549
7549
len = range -> len >> osb -> s_clustersize_bits ;
@@ -7552,6 +7552,9 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range)
7552
7552
if (minlen >= osb -> bitmap_cpg || range -> len < sb -> s_blocksize )
7553
7553
return - EINVAL ;
7554
7554
7555
+ trace_ocfs2_trim_mainbm (start , len , minlen );
7556
+
7557
+ next_group :
7555
7558
main_bm_inode = ocfs2_get_system_file_inode (osb ,
7556
7559
GLOBAL_BITMAP_SYSTEM_INODE ,
7557
7560
OCFS2_INVALID_SLOT );
@@ -7570,64 +7573,34 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range)
7570
7573
}
7571
7574
main_bm = (struct ocfs2_dinode * )main_bm_bh -> b_data ;
7572
7575
7573
- if (start >= le32_to_cpu (main_bm -> i_clusters )) {
7574
- ret = - EINVAL ;
7575
- goto out_unlock ;
7576
- }
7577
-
7578
- len = range -> len >> osb -> s_clustersize_bits ;
7579
- if (start + len > le32_to_cpu (main_bm -> i_clusters ))
7580
- len = le32_to_cpu (main_bm -> i_clusters ) - start ;
7581
-
7582
- trace_ocfs2_trim_fs (start , len , minlen );
7583
-
7584
- ocfs2_trim_fs_lock_res_init (osb );
7585
- ret = ocfs2_trim_fs_lock (osb , NULL , 1 );
7586
- if (ret < 0 ) {
7587
- if (ret != - EAGAIN ) {
7588
- mlog_errno (ret );
7589
- ocfs2_trim_fs_lock_res_uninit (osb );
7576
+ /*
7577
+ * Do some check before trim the first group.
7578
+ */
7579
+ if (!group ) {
7580
+ if (start >= le32_to_cpu (main_bm -> i_clusters )) {
7581
+ ret = - EINVAL ;
7590
7582
goto out_unlock ;
7591
7583
}
7592
7584
7593
- mlog (ML_NOTICE , "Wait for trim on device (%s) to "
7594
- "finish, which is running from another node.\n" ,
7595
- osb -> dev_str );
7596
- ret = ocfs2_trim_fs_lock (osb , & info , 0 );
7597
- if (ret < 0 ) {
7598
- mlog_errno (ret );
7599
- ocfs2_trim_fs_lock_res_uninit (osb );
7600
- goto out_unlock ;
7601
- }
7585
+ if (start + len > le32_to_cpu (main_bm -> i_clusters ))
7586
+ len = le32_to_cpu (main_bm -> i_clusters ) - start ;
7602
7587
7603
- if (info .tf_valid && info .tf_success &&
7604
- info .tf_start == start && info .tf_len == len &&
7605
- info .tf_minlen == minlen ) {
7606
- /* Avoid sending duplicated trim to a shared device */
7607
- mlog (ML_NOTICE , "The same trim on device (%s) was "
7608
- "just done from node (%u), return.\n" ,
7609
- osb -> dev_str , info .tf_nodenum );
7610
- range -> len = info .tf_trimlen ;
7611
- goto out_trimunlock ;
7612
- }
7588
+ /*
7589
+ * Determine first and last group to examine based on
7590
+ * start and len
7591
+ */
7592
+ first_group = ocfs2_which_cluster_group (main_bm_inode , start );
7593
+ if (first_group == osb -> first_cluster_group_blkno )
7594
+ first_bit = start ;
7595
+ else
7596
+ first_bit = start - ocfs2_blocks_to_clusters (sb ,
7597
+ first_group );
7598
+ last_group = ocfs2_which_cluster_group (main_bm_inode ,
7599
+ start + len - 1 );
7600
+ group = first_group ;
7613
7601
}
7614
7602
7615
- info .tf_nodenum = osb -> node_num ;
7616
- info .tf_start = start ;
7617
- info .tf_len = len ;
7618
- info .tf_minlen = minlen ;
7619
-
7620
- /* Determine first and last group to examine based on start and len */
7621
- first_group = ocfs2_which_cluster_group (main_bm_inode , start );
7622
- if (first_group == osb -> first_cluster_group_blkno )
7623
- first_bit = start ;
7624
- else
7625
- first_bit = start - ocfs2_blocks_to_clusters (sb , first_group );
7626
- last_group = ocfs2_which_cluster_group (main_bm_inode , start + len - 1 );
7627
- last_bit = osb -> bitmap_cpg ;
7628
-
7629
- trimmed = 0 ;
7630
- for (group = first_group ; group <= last_group ;) {
7603
+ do {
7631
7604
if (first_bit + len >= osb -> bitmap_cpg )
7632
7605
last_bit = osb -> bitmap_cpg ;
7633
7606
else
@@ -7659,21 +7632,81 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range)
7659
7632
group = ocfs2_clusters_to_blocks (sb , osb -> bitmap_cpg );
7660
7633
else
7661
7634
group += ocfs2_clusters_to_blocks (sb , osb -> bitmap_cpg );
7662
- }
7663
- range -> len = trimmed * sb -> s_blocksize ;
7635
+ } while (0 );
7664
7636
7665
- info .tf_trimlen = range -> len ;
7666
- info .tf_success = (ret ? 0 : 1 );
7667
- pinfo = & info ;
7668
- out_trimunlock :
7669
- ocfs2_trim_fs_unlock (osb , pinfo );
7670
- ocfs2_trim_fs_lock_res_uninit (osb );
7671
7637
out_unlock :
7672
7638
ocfs2_inode_unlock (main_bm_inode , 0 );
7673
7639
brelse (main_bm_bh );
7640
+ main_bm_bh = NULL ;
7674
7641
out_mutex :
7675
7642
inode_unlock (main_bm_inode );
7676
7643
iput (main_bm_inode );
7644
+
7645
+ /*
7646
+ * If all the groups trim are not done or failed, but we should release
7647
+ * main_bm related locks for avoiding the current IO starve, then go to
7648
+ * trim the next group
7649
+ */
7650
+ if (ret >= 0 && group <= last_group )
7651
+ goto next_group ;
7677
7652
out :
7653
+ range -> len = trimmed * sb -> s_blocksize ;
7654
+ return ret ;
7655
+ }
7656
+
7657
+ int ocfs2_trim_fs (struct super_block * sb , struct fstrim_range * range )
7658
+ {
7659
+ int ret ;
7660
+ struct ocfs2_super * osb = OCFS2_SB (sb );
7661
+ struct ocfs2_trim_fs_info info , * pinfo = NULL ;
7662
+
7663
+ ocfs2_trim_fs_lock_res_init (osb );
7664
+
7665
+ trace_ocfs2_trim_fs (range -> start , range -> len , range -> minlen );
7666
+
7667
+ ret = ocfs2_trim_fs_lock (osb , NULL , 1 );
7668
+ if (ret < 0 ) {
7669
+ if (ret != - EAGAIN ) {
7670
+ mlog_errno (ret );
7671
+ ocfs2_trim_fs_lock_res_uninit (osb );
7672
+ return ret ;
7673
+ }
7674
+
7675
+ mlog (ML_NOTICE , "Wait for trim on device (%s) to "
7676
+ "finish, which is running from another node.\n" ,
7677
+ osb -> dev_str );
7678
+ ret = ocfs2_trim_fs_lock (osb , & info , 0 );
7679
+ if (ret < 0 ) {
7680
+ mlog_errno (ret );
7681
+ ocfs2_trim_fs_lock_res_uninit (osb );
7682
+ return ret ;
7683
+ }
7684
+
7685
+ if (info .tf_valid && info .tf_success &&
7686
+ info .tf_start == range -> start &&
7687
+ info .tf_len == range -> len &&
7688
+ info .tf_minlen == range -> minlen ) {
7689
+ /* Avoid sending duplicated trim to a shared device */
7690
+ mlog (ML_NOTICE , "The same trim on device (%s) was "
7691
+ "just done from node (%u), return.\n" ,
7692
+ osb -> dev_str , info .tf_nodenum );
7693
+ range -> len = info .tf_trimlen ;
7694
+ goto out ;
7695
+ }
7696
+ }
7697
+
7698
+ info .tf_nodenum = osb -> node_num ;
7699
+ info .tf_start = range -> start ;
7700
+ info .tf_len = range -> len ;
7701
+ info .tf_minlen = range -> minlen ;
7702
+
7703
+ ret = ocfs2_trim_mainbm (sb , range );
7704
+
7705
+ info .tf_trimlen = range -> len ;
7706
+ info .tf_success = (ret < 0 ? 0 : 1 );
7707
+ pinfo = & info ;
7708
+ out :
7709
+ ocfs2_trim_fs_unlock (osb , pinfo );
7710
+ ocfs2_trim_fs_lock_res_uninit (osb );
7678
7711
return ret ;
7679
7712
}
0 commit comments